feat(vim): gt / gT cycle workspace tabs (T-405 part 2)
Closes out the T-403 cross-pane vim layer. gt/gT bind to the existing workspace.tab.next/previous commands (also on ctrl+pagedown/up for every preset), resolved by the focused editor's matcher or a pane's PaneKeyNav — bare-g sequences stay editor/pane-local (T-404's global matcher only engages on modified-chord prefixes), so no global-matcher surgery. - vim.yaml: g t -> command:workspace.tab.next, g shift+t -> .previous (vim.normal); shares the `g` prefix with `g g` (docStart / nav.top), distinguished by the final chord. - PaneKeyNav now EXECUTES non-editor.vim.* command intents (e.g. workspace.tab.*) instead of swallowing all command intents, so gt/gT work from a focused pane; editor.vim.* buffer edits stay blocked in panes. Tests: vim-preset resolution (gt/gT bind, gg intact), PaneKeyNav executes the command from a pane, and editor.vim.* is never run from a pane. make test green; analyze + format clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,8 @@
|
||||
/// intent here and to the editor motion in the editor — see vim.yaml.
|
||||
library;
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
@@ -101,15 +103,20 @@ class _PaneKeyNavState extends State<PaneKeyNav> {
|
||||
final r = _matcher!.feed(chord);
|
||||
switch (r.outcome) {
|
||||
case SeqOutcome.fired:
|
||||
// The vim preset also binds these keys to editor.vim.* motions; in a
|
||||
// pane only nav.* applies, and editor.vim.* (an InvokeCommandIntent) is
|
||||
// swallowed — never run buffer edits from a pane. A typed *app* intent
|
||||
// (e.g. the ex-line `:` / ZZ) bubbles to the app-root Actions for its
|
||||
// global handler (T-407).
|
||||
// The vim preset binds these keys to several intent kinds. In a pane:
|
||||
// - nav.* drives the pane (onNav);
|
||||
// - editor.vim.* buffer edits are swallowed — never edit from a pane;
|
||||
// - other commands (workspace.tab.* gt/gT, panel.*) execute (T-405);
|
||||
// - a typed app intent (ex-line `:` / ZZ) bubbles to the app-root
|
||||
// Actions for its global handler (T-407).
|
||||
final fired = r.intent;
|
||||
if (fired is NavIntent) {
|
||||
widget.onNav(fired, r.count);
|
||||
} else if (fired != null && fired is! InvokeCommandIntent) {
|
||||
} else if (fired is InvokeCommandIntent) {
|
||||
if (!fired.commandId.startsWith('editor.vim.')) {
|
||||
unawaited(kernel.commands.execute(fired.commandId));
|
||||
}
|
||||
} else if (fired != null) {
|
||||
Actions.maybeInvoke(context, fired);
|
||||
}
|
||||
return KeyEventResult.handled;
|
||||
|
||||
Reference in New Issue
Block a user