T-207, first foundation piece of the Vim layer (T-65 epic). A
VimModeService (ChangeNotifier) owns the normal/insert/visual mode and
mirrors it into the keymap as mutually-exclusive vim.normal/vim.insert/
vim.visual scope flags. Those flags are the public mode interface: the
editor (T-206) will read them to decide insert-vs-command, and vim.yaml
(T-65) guards bindings with `when: vim.*`. Nothing reaches across the
builtin boundary into the service object.
The layer is gated on the active preset — the builtin.vim extension
ties VimModeService.enabled to app.keymap.preset and re-checks on every
keymap reload, so i/v/Esc never hijack input under non-Vim presets. Mode
commands (vim.mode.{normal,insert,visual}) carry no default binding for
the same reason; only vim.yaml binds keys to them. A status-bar item
shows `-- NORMAL --` etc. while enabled.
Exposes KeymapService on the extension context so the layer can publish
scope flags.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
59 lines
1.8 KiB
Dart
59 lines
1.8 KiB
Dart
/// T-207: the status-bar mode indicator shows `-- MODE --` while the Vim
|
|
/// layer is enabled and renders nothing otherwise.
|
|
library;
|
|
|
|
import 'package:clide/builtin/vim/vim.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import '../../helpers/kernel_fixture.dart';
|
|
import '../../helpers/widget_harness.dart';
|
|
|
|
void main() {
|
|
late KernelFixture f;
|
|
late VimModeService mode;
|
|
|
|
setUp(() async {
|
|
f = await KernelFixture.create();
|
|
mode = VimModeService(f.services.keymap);
|
|
});
|
|
tearDown(() {
|
|
mode.dispose();
|
|
return f.dispose();
|
|
});
|
|
|
|
testWidgets('renders nothing while disabled', (tester) async {
|
|
await tester.pumpWidget(harness(f, VimModeIndicator(service: mode)));
|
|
await tester.pumpAndSettle();
|
|
expect(find.textContaining('NORMAL'), findsNothing);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('shows the active mode and updates on transition', (tester) async {
|
|
mode.enabled = true;
|
|
await tester.pumpWidget(harness(f, VimModeIndicator(service: mode)));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('-- NORMAL --'), findsOneWidget);
|
|
|
|
mode.enterInsert();
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('-- INSERT --'), findsOneWidget);
|
|
expect(find.text('-- NORMAL --'), findsNothing);
|
|
|
|
mode.enterVisual();
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('-- VISUAL --'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('disabling hides the indicator', (tester) async {
|
|
mode.enabled = true;
|
|
await tester.pumpWidget(harness(f, VimModeIndicator(service: mode)));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('-- NORMAL --'), findsOneWidget);
|
|
|
|
mode.enabled = false;
|
|
await tester.pumpAndSettle();
|
|
expect(find.textContaining('NORMAL'), findsNothing);
|
|
});
|
|
}
|