Add vim visual modes (v, V) to query editor#172
Open
chasleslr wants to merge 8 commits intoMaxteabag:mainfrom
Open
Add vim visual modes (v, V) to query editor#172chasleslr wants to merge 8 commits intoMaxteabag:mainfrom
chasleslr wants to merge 8 commits intoMaxteabag:mainfrom
Conversation
Adds Shift+V visual line mode for selecting entire lines in the query editor, matching vim's native behavior. Selected lines can be yanked (y), deleted (d), changed (c), or executed (Enter). - New VimMode.VISUAL_LINE enum value and query_visual_line binding context - QueryVisualLineModeState for action validation and footer bindings - QueryEditingVisualLineMixin with enter/exit, selection tracking, and line-wise yank/delete/change/execute operators - Selection updates via TextArea.selection directly to avoid cursor_location clearing the highlight - Arrow key support via QueryTextArea action overrides - V-LINE mode indicator in status bar and help text Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds both charwise visual mode (v) and visual line mode (V) to the query editor, matching vim's native behavior. Visual mode (v): character-wise selection using all standard motions (h/j/k/l, w/b, 0/$, f/t, G/gg, %, etc). Operators y/d/c act on the exact selection, Enter executes selected text. Visual line mode (V): selects entire lines, j/k/G/gg extend by full lines. Operators act linewise. Both modes support toggling between each other (v↔V), arrow key navigation, and display a VISUAL/V-LINE indicator in the status bar. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The tree explorer's ConnectionMixin already defines _update_visual_selection for tree visual mode. Rename the query editor's method to _update_query_visual_selection to avoid the name conflict. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Unit tests (22): binding context resolution, state machine action validation, key routing, and footer bindings for both VISUAL and VISUAL LINE modes. UI integration tests (19): enter/exit, mode toggling (v↔V), motion-based selection extension, and operators (yank, delete, change) using Textual pilot. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove duplicate 0.15s clear timers in visual_yank and visual_line_yank — _flash_yank_range already schedules its own. Two competing callbacks could clobber a new selection if the user re-enters visual mode within 150ms. - Clear _visual_anchor before delegating to _change_selection() in action_visual_change, so the anchor can't leak if the delegate raises. - Fix notification color for VISUAL/VISUAL_LINE modes: use insert_color only for INSERT, not as the fallback for all non-NORMAL modes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Vim visual mode includes both the anchor and cursor characters in the selection. Textual's Selection is half-open (end exclusive), so extend the far end by one character to match vim behavior. Also highlight the character under the cursor immediately on entering visual mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
In vim, x in visual mode is equivalent to d — both delete the selection. Add x as a secondary binding for visual_delete and visual_line_delete. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The inclusive selection extends the far end by +1, but cursor_location returns that extended position. Motions reading cursor_location would operate from the wrong position, making h/left appear stuck when the cursor was on the same line as the anchor. Track the logical cursor position in _visual_cursor separately from the TextArea selection endpoint. Motion functions now read from _visual_cursor in charwise visual mode instead of cursor_location. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
The query editor supports extensive vim motions and operators (
d{motion},y{motion},c{motion}), but lacks visual mode — one of vim's most fundamental features for interactive text selection. Without it, users must rely on operator + motion combinations for every edit, which is less intuitive for selecting arbitrary ranges of SQL.Changes
This PR adds both charwise visual mode (
v) and visual line mode (V) to the query editor.Visual mode (
v)Enters character-wise selection at the cursor. All standard motions extend the selection:
h/j/k/l,w/b,0/$/^,f/t/F/T,%,G/gg, and arrow keys.Visual line mode (
V)Enters line-wise selection on the current line. Vertical motions (
j/k/G/gg, arrow keys) extend the selection by full lines.Common behavior
y(yank),d(delete),c(change),Enter(execute selected SQL)v↔Vtoggles between charwise and linewise selectionEscexits back to NORMAL modeVISUALorV-LINEmode indicatorImplementation notes
TreeVisualModeStatepattern for state classesoperator_delete/operator_yankwith appropriateMotionTypefor operatorsTextArea.selectiondirectly rather thancursor_locationto prevent Textual from clearing the highlight on cursor movesaction_cursor_up/down/left/rightonQueryTextAreato intercept TextArea's built-in arrow key bindings in visual modesDemo
Screen.Recording.2026-04-01.at.10.01.03.PM.mov
Test plan
venters charwise visual mode;Venters visual line modev/Vy,d,c,Enteroperate on selection correctlyEscexits cleanly back to NORMAL mode