返回 CodeWhale
vim_mode.rs
根目录 / crates / tui / src / tui / vim_mode.rs
1 //! Composer vim Normal-mode keybindings.
2
3 use crate::tui::app::{App, VimMode};
4
5 /// Handle a plain character key press when the composer is in vim Normal mode.
6 ///
7 /// Implements the core set of normal-mode bindings:
8 /// - `h` / `l` — left / right by character
9 /// - `j` / `k` — down / up by logical line (falls back to prev/next history)
10 /// - `w` / `b` — word forward / backward
11 /// - `0` / `$` — line start / end
12 /// - `x` — delete character under cursor
13 /// - `d` (×2) — delete current line (`dd`)
14 /// - `i` — enter Insert before cursor
15 /// - `a` — enter Insert after cursor
16 /// - `o` — open new line below and enter Insert
17 /// - `v` — enter Visual mode
18 /// - `G` — move to end of buffer
19 pub(super) fn handle_vim_normal_key(app: &mut App, c: char) {
20 // Handle pending `d` (waiting for second `d` to complete `dd`).
21 if app.composer.vim_pending_d {
22 app.composer.vim_pending_d = false;
23 if c == 'd' {
24 app.vim_delete_line();
25 }
26 // Any other key cancels the pending operator.
27 return;
28 }
29
30 match c {
31 'h' => app.move_cursor_left(),
32 'l' => app.move_cursor_right(),
33 'j' => app.vim_move_down(),
34 'k' => app.vim_move_up(),
35 'w' => app.vim_move_word_forward(),
36 'b' => app.vim_move_word_backward(),
37 '0' => app.vim_move_line_start(),
38 '$' => app.vim_move_line_end(),
39 'x' => app.vim_delete_char_under_cursor(),
40 'd' => {
41 // Start the `dd` operator sequence.
42 app.composer.vim_pending_d = true;
43 }
44 'i' => app.vim_enter_insert(),
45 'a' => app.vim_enter_append(),
46 'o' => app.vim_open_line_below(),
47 'v' => {
48 app.composer.vim_mode = VimMode::Visual;
49 app.needs_redraw = true;
50 }
51 'G' => app.move_cursor_end(),
52 _ => {
53 // Unknown normal-mode key — silently ignored in Normal mode.
54 }
55 }
56 }
57
57 lines RUST