ship the Vim keymap preset
T-65 — the capstone of the Vim epic. assets/keymaps/vim.yaml binds the muscle-memory set guarded on vim.normal/insert/visual: hjkl/w/b/e/0/$/^/ gg/G motions, x/dd/dw/D/yy/p/P/cc/cw edits, i/a/I/A/o/O insert entries, v + d/y/c in visual, Esc back to normal, and counts via the matcher. App shortcuts (palette, find, zoom) are carried in the preset so they survive under Vim. The editor now feeds Shift chords to the matcher (Vim's capitals: G, D, A, P, $) while still bubbling Ctrl/Alt/Meta to the global handler. The keybindings-ui stub gains palette commands (`Keymap: Vim` / `Keymap: Default`) to switch presets — the user-facing way to turn Vim on. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -201,10 +201,13 @@ class _EditorViewState extends State<EditorView> {
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
|
||||
// Normal / visual mode. Modified chords are app shortcuts (palette,
|
||||
// find, …) — let them bubble to the global handler. Bare keys drive
|
||||
// the Vim matcher and never reach text input.
|
||||
if (chord.modifiers.isNotEmpty) return KeyEventResult.ignored;
|
||||
// Normal / visual mode. Ctrl/Alt/Meta chords are app shortcuts
|
||||
// (palette, find, …) — let them bubble to the global handler. Bare
|
||||
// keys and Shift chords (Vim's capitals: G, D, A, P, $) drive the
|
||||
// matcher and never reach text input.
|
||||
if (chord.modifiers.any((m) => m != KeyModifier.shift)) {
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
|
||||
final r = _matcher!.feed(chord);
|
||||
switch (r.outcome) {
|
||||
|
||||
@@ -1,17 +1,49 @@
|
||||
import 'package:clide/clide.dart';
|
||||
import 'package:clide/extension/extension.dart';
|
||||
import 'package:clide/kernel/kernel.dart';
|
||||
|
||||
/// Tier-0 stub. Real implementation lands in a later tier; the extension
|
||||
/// is registered so the extensions-ui surface can list it as "installed,
|
||||
/// not yet implemented" and its id is reserved.
|
||||
/// Keymap preset switching. The full keybindings editor lands in a later
|
||||
/// tier; today this contributes palette commands to switch the active
|
||||
/// keymap preset (the user-facing "select it in settings" affordance for
|
||||
/// the Vim / VS Code / JetBrains presets — T-64/65/66).
|
||||
class KeybindingsUiExtension extends ClideExtension {
|
||||
@override
|
||||
String get id => 'builtin.keybindings-ui';
|
||||
@override
|
||||
String get title => 'Keybindings UI';
|
||||
@override
|
||||
String get version => '0.0.0-stub';
|
||||
String get version => '0.1.0';
|
||||
@override
|
||||
List<String> get dependsOn => const [];
|
||||
|
||||
KeymapService? _keymap;
|
||||
|
||||
@override
|
||||
List<ContributionPoint> get contributions => const [];
|
||||
Future<void> activate(ClideExtensionContext ctx) async {
|
||||
_keymap = ctx.keymap;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deactivate() async => _keymap = null;
|
||||
|
||||
/// Presets that ship today. VS Code / JetBrains (T-64/T-66) join here
|
||||
/// once their YAMLs land.
|
||||
static const _presets = <String, String>{
|
||||
'default': 'Keymap: Default',
|
||||
'vim': 'Keymap: Vim',
|
||||
};
|
||||
|
||||
@override
|
||||
List<ContributionPoint> get contributions => [
|
||||
for (final entry in _presets.entries)
|
||||
CommandContribution(
|
||||
id: 'keymap.preset.${entry.key}',
|
||||
command: 'keymap.preset.${entry.key}',
|
||||
title: entry.value,
|
||||
run: (_) async {
|
||||
await _keymap?.setPreset(entry.key);
|
||||
return IpcResponse.ok(id: '', data: {'preset': entry.key});
|
||||
},
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user