add Vim mode service, mode commands, and status indicator
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>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import 'package:clide/builtin/vim/src/vim_mode_service.dart';
|
||||
import 'package:clide/kernel/kernel.dart';
|
||||
import 'package:clide/widgets/widgets.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
/// Status-bar item showing the current Vim mode (`-- NORMAL --`). Renders
|
||||
/// nothing while the Vim layer is disabled, so it's invisible under
|
||||
/// non-Vim presets (T-207).
|
||||
class VimModeIndicator extends StatelessWidget {
|
||||
const VimModeIndicator({super.key, required this.service});
|
||||
|
||||
final VimModeService service;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListenableBuilder(
|
||||
listenable: service,
|
||||
builder: (context, _) {
|
||||
if (!service.enabled) return const SizedBox.shrink();
|
||||
final tokens = ClideTheme.of(context).surface;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: ClideText(
|
||||
'-- ${service.mode.label} --',
|
||||
fontFamily: clideMonoFamily,
|
||||
fontSize: clideFontCaption,
|
||||
color: tokens.statusBarForeground,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user