fix(tui): Ctrl+C with input selection actually preserves input (lift handler to app level)

Previous fix in 9dbf1ec6 handled Ctrl+C inside textInput but the APP-level
useInputHandlers fires the same keypress in a separate React hook and ran
clearIn() regardless. Net effect: the OSC 52 copy succeeded but the input
wiped right after, so Brooklyn only noticed the wipe.

Lift the selection-aware Ctrl+C to a single place by threading input
selection state through a new nanostore (src/app/inputSelectionStore.ts).
textInput syncs its derived `selected` range + a clear() callback to the
store on every selection change, and the app-level Ctrl+C handler reads
the store before its clear/interrupt/die chain:

  - terminal-level selection (scrollback) → copy, existing behavior
  - in-input selection present → copy + clear selection, preserve input
  - input has text, no selection → clearIn(), existing behavior
  - empty + busy → interrupt turn
  - empty + idle → die

textInput no longer has its own Ctrl+C block; keypress falls through to
app-level like it did before 9dbf1ec6.
This commit is contained in:
Brooklyn Nicholson 2026-04-18 16:28:51 -05:00
parent bfac5d039d
commit fb06bc67de
3 changed files with 59 additions and 15 deletions

View file

@ -0,0 +1,14 @@
import { atom } from 'nanostores'
export interface InputSelection {
clear: () => void
end: number
start: number
value: string
}
export const $inputSelection = atom<InputSelection | null>(null)
export const setInputSelection = (next: InputSelection | null) => $inputSelection.set(next)
export const getInputSelection = () => $inputSelection.get()