Add Shift+Tab to toggle select all/deselect all in MultiChoice prompts#54
Conversation
096b08d to
34048d6
Compare
…t all` in `MultiChoice` prompts Add `SHIFT_TAB` key event that maps to the CSI sequence `ESC[Z` (`backtab`), supported universally across iTerm2, Apple Terminal, and Linux terminals. In `MultiChoice` prompts, `Shift+Tab` now toggles all items at once: - If all currently filtered items are selected, it deselects them all - Otherwise, it selects them all - Respects active text filter (only affects filtered items) - Preserves selection state of non-filtered items This also fixes a possible latent bug where pressing `Shift+Tab` would cause a `MatchError` in `CharCollector` since `CSI_Started` had no case for 'Z'. The instruction text is updated to show the new keybinding: "Tab to toggle, Shift+Tab to toggle all, Enter to submit."
34048d6 to
1fbff82
Compare
Shift+Tab toggle all/deselect all for MultiChoice promptsShift+Tab to toggle select all/deselect all in MultiChoice prompts
|
Hi! Directionally I'm okay with this, it's useful. My only question is whether this will work on windows (which we currently support somewhat) - otherwise I'll take a closer look the PR once I'm back at my laptop in a couple of days. |
…t all` in `MultiChoice` prompts for Windows Add Windows support for `SHIFT_TAB` in `CharCollector` and Scala Native The previous commit added `Shift+Tab` support via the ANSI `ESC[Z` sequence, which works on macOS and Linux. On Windows, terminal input uses scan codes via `_getch()`, and `Shift+Tab` produces a `0x00` prefix followed by scan code `15` (`0x0F`), which was not handled. - Add `case 15 => SHIFT_TAB` to `ScanCode_Started` in `CharCollector` so the Windows scan code path correctly decodes `Shift+Tab`. - Normalize `0x00` to `0xE0` in Scala Native `ChangeModeWindows.getchar()` to match the existing JVM `ChangeModeWindows` behavior. Without this, the `0x00` prefix byte is silently skipped by `KeyboardReadingThread`'s `if lastRead != 0` guard, causing the subsequent scan code to be misinterpreted as a regular character. - Add `CharCollectorTests` to verify `SHIFT_TAB` decoding through both the ANSI CSI path (`ESC[Z`) and the Windows scan code path (`ScanCode_Started` + `15`).
@keynmol Thank you! Oh, that’s a very good point. Sorry, I hadn’t done anything for Windows because my app was targeting macOS and Linux for now. My bad. I’ve just made some updates for Windows and committed them. My Windows machine is only for gaming, so it doesn't have a build env for this yet, but I'll still try building it there and see how it goes. FYI, here is what I found. Platform analysis:
Why
|
|
Looked at the PR:
I recorded a video in my windows VM: CleanShot.2026-04-07.at.09.06.49.mp4Given I don't have a windows machine to comfortably develop this, I will merge and release this PR with a windows caveat and address it later. Thanks for your work! |
|
@keynmol Thank you! I had a really long journey building it on Windows, and finally found that even the
|
|
@keynmol Oh, it’s already out?! 😃 That’s awesome! Thanks so much! |
Close #55: Add
Shift+Tabto toggleselect all/deselect allinMultiChoicepromptsAdd
SHIFT_TABkey event that maps to the CSI sequenceESC[Z(backtab), supported universally across iTerm2, Apple Terminal, and Linux terminals.In
MultiChoiceprompts,Shift+Tabnow toggles all items at once:This also fixes a possible latent bug where pressing
Shift+Tabwould cause aMatchErrorinCharCollectorsinceCSI_Startedhad no case for 'Z'.The instruction text is updated to show the new keybinding: "Tab to toggle, Shift+Tab to toggle all, Enter to submit."
Update for Windows:
Add Windows support for
SHIFT_TABinCharCollectorand Scala NativeThe previous commit added
Shift+Tabsupport via the ANSIESC[Zsequence, which works on macOS and Linux.On Windows, terminal input uses scan codes via
_getch(), andShift+Tabproduces a0x00prefix followed by scan code15(0x0F), which was not handled.case 15 => SHIFT_TABtoScanCode_StartedinCharCollectorso the Windows scan code path correctly decodesShift+Tab.0x00to0xE0in Scala NativeChangeModeWindows.getchar()to match the existing JVMChangeModeWindowsbehavior. Without this, the0x00prefix byte is silently skipped byKeyboardReadingThread'sif lastRead != 0guard, causing the subsequent scan code to be misinterpreted as a regular character.CharCollectorTeststo verifySHIFT_TABdecoding through both the ANSI CSI path (ESC[Z) and the Windows scan code path (ScanCode_Started+15).Shift+Tab:



