qwen-code/packages/cli
John London 93c5ce162f
fix(search): make empty-query exit synchronous and normalize Windows Backspace (#3981)
* fix(search): make empty-query exit synchronous and normalize Windows Backspace

Two fixes to useSessionSearchInput that caused 'Backspace edits the query;
emptying it returns to list mode' to fail on Windows:

1. Replaced the useEffect-based onExitToList mechanism with a ref-backed
   setSearchQuery that detects the non-empty → empty transition
   synchronously inside the state updater. The previous useEffect approach
   introduced a one-frame delay where the component rendered in search
   mode with an empty query before the effect fired, causing the
   'Press / to search' hint to be absent on Windows.

2. Added isDeletionKey() helper that recognizes Backspace from both the
   key.name field ('backspace'/'delete') and the raw sequence bytes
   (\x7f DEL and \b BS), so Windows terminals that deliver Backspace
   without normalizing the key name are handled correctly.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

* fix(search): address review feedback on PR #3981

- Update onExitToList JSDoc: describe synchronous ref-backed detection instead of stale useEffect reference
- Update test suite comments: replace useEffect references with ref-backed setter description
- Add assertion that implicit entry (empty→non-empty via setSearchQuery) does NOT trigger onExitToList
- Add tests for Backspace/Esc/Ctrl+U/Ctrl+L on already-empty query: must not trigger onExitToList

* fix(search): address remaining review feedback on PR #3981

- Add isDeletionKey byte-fallback tests (\x7f DEL and \b BS)
- Update setSearchQuery JSDoc to document synchronous onExitToList side-effect
- Stabilize callback deps: read onExitToList via ref so setSearchQuery
  and handleSearchKey are not recreated on parent re-render
- Clarify onExitToList JSDoc: fires before React re-renders, ref is
  current but state variable is stale
- Add test for setSearchQuery('') direct-empty path (non-empty → empty)
- Add test for setSearchQuery('') on already-empty query (no spurious exit)

* test: stabilize flaky export format cycling test on Windows CI

Increase wait from 50ms to 350ms after typing '/export md' to allow
the useEffect in useExportCompletion to fire and set cyclingActiveRef
before the Down keypress arrives. This matches the pattern used by other
tests in this file that depend on useEffect timing.

* fix(search): guard isDeletionKey byte fallback against ctrl/meta modifiers

The byte fallback in isDeletionKey (key.sequence === '\x7f' / '\b')
previously fired even when ctrl or meta modifiers were active.
Ctrl+H delivers name:'h', ctrl:true, sequence:'\b' on many terminals
and was incorrectly treated as Backspace, deleting the last query char.

Add !key.ctrl && !key.meta guard so the byte fallback only activates
when the terminal truly did not normalize the key name.

Also add two tests:
- Ctrl+H (BS byte with ctrl) must not be treated as deletion key
- Meta+DEL byte must not be treated as deletion key

---------

Co-authored-by: Mistral Vibe <vibe@mistral.ai>
2026-05-14 09:03:16 +08:00
..
src fix(search): make empty-query exit synchronous and normalize Windows Backspace (#3981) 2026-05-14 09:03:16 +08:00
index.ts fix(cli): stop double-wrapping and double-printing API errors in non-interactive mode (#3749) 2026-05-03 08:39:31 +08:00
package.json feat(cli,sdk): qwen serve daemon (Stage 1) (#3889) 2026-05-13 14:47:47 +08:00
test-setup.ts fix: prevent bogus shell permission rules in tests 2026-03-20 17:55:33 +08:00
tsconfig.json Add background agent resume and continuation (#3739) 2026-05-01 12:14:33 +08:00
vitest.config.ts refactor(core): Unify package exports and improve dev experience 2026-02-01 11:59:05 +08:00