commit 87343a5fc63c320e6fdffd01f6c84b9e9cf46f8b
parent baae6b1c0e2820a3e39f0dc2c1bfad4b9381dfa1
Author: Bharatvaj Hemanth <bharatvaj@yahoo.com>
Date: Tue, 13 Oct 2026 23:08:21 +0530
parent baae6b1c0e2820a3e39f0dc2c1bfad4b9381dfa1
Author: Bharatvaj Hemanth <bharatvaj@yahoo.com>
Date: Tue, 13 Oct 2026 23:08:21 +0530
Return to vi normal mode on Escape from insert mode
4 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/HACKING b/HACKING @@ -61,7 +61,7 @@ Default mode is emacs-ish, but pragmatic: - Ctrl+D / Ctrl+U: page down/up list - Ctrl+W: cut selection - Ctrl+Alt+V: toggle vi mode -- Esc: exit +- Esc: exit, except in vi insert mode where it returns to normal mode Use -default-controls for normal Windows edit behavior. @@ -80,7 +80,8 @@ Release checklist 3. Check a slow pipe shows the bottom progress bar animating; search a loaded large file and check the same bar shows search progress. 4. Check Alt-Tab back focuses the input. -5. Check Esc exits from input and list focus. +5. Check Esc exits from input and list focus; in vi insert mode it returns to + normal mode instead. 6. Update the version string in wmenu.c. 7. Do not commit build outputs (*.obj, *.exe) unless intentionally packaging.
diff --git a/README b/README @@ -46,7 +46,7 @@ Default keys: ``` Enter print selection and exit -Esc exit +Esc exit (vi insert mode: return to normal mode) Up/Down move list selection Ctrl+N/P next/previous item Ctrl+D/U page down/up
diff --git a/test_stream.c b/test_stream.c @@ -77,6 +77,15 @@ int main(int argc, char **argv) UpdateWindow(list_hwnd); assert(SendMessageW(list_hwnd, LB_GETCOUNT, 0, 0) == 1); assert(draw_calls > 0); /* First streamed row must actually paint. */ + vi_mode = true; + normal_mode = false; + assert(InputProc(input_hwnd, WM_KEYDOWN, VK_ESCAPE, 0) == 0 && normal_mode); + MSG quit; + assert(!PeekMessageW(&quit, NULL, WM_QUIT, WM_QUIT, PM_NOREMOVE)); + normal_mode = false; + assert(ListProc(list_hwnd, WM_KEYDOWN, VK_ESCAPE, 0) == 0 && normal_mode); + assert(!PeekMessageW(&quit, NULL, WM_QUIT, WM_QUIT, PM_NOREMOVE)); + vi_mode = normal_mode = false; for (int i = 1; i < 60000; ++i) { char buf[2700]; sprintf(buf, "item-%d", i);
diff --git a/wmenu.c b/wmenu.c @@ -574,7 +574,11 @@ static bool handle_global_keys(WORD key, struct key_state k) if (k.ctrl && key == 'I') { visit_location(1); return true; } if (k.ctrl && key == VK_RETURN && multi_select) { add_selection(); return true; } if (key == VK_RETURN) { finish(); return true; } - if (key == VK_ESCAPE) { PostQuitMessage(0); return true; } + if (key == VK_ESCAPE) { + if (vi_mode && !normal_mode) normal_mode = true; + else PostQuitMessage(0); + return true; + } if (key == VK_DOWN) { list_move(1); return true; } if (key == VK_UP) { list_move(-1); return true; } return false; @@ -645,7 +649,7 @@ static LRESULT CALLBACK InputProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) static LRESULT CALLBACK ListProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { if (msg == WM_KEYDOWN) { - if (wp == VK_ESCAPE) { PostQuitMessage(0); return 0; } + if (wp == VK_ESCAPE) { handle_global_keys(VK_ESCAPE, key_state()); return 0; } if (wp == VK_RETURN) { finish(); return 0; } } LRESULT r = CallWindowProcW(old_list_proc, hwnd, msg, wp, lp);
: nply/wmenu