fix(tui): only cycle history at input boundaries on arrows
Follow-up on #13726 from blitz feedback: Up/Down history cycling should only trigger when the caret is at the start/end boundary (or the input is empty).\n\nPreviously useInputHandlers intercepted arrows whenever inputBuf was empty, which still stole Up/Down from normal multiline editing. textInput now publishes caret position through inputSelectionStore even with no active selection, and useInputHandlers gates history/queue cycling on those boundaries.
This commit is contained in:
@@ -288,15 +288,27 @@ export function useInputHandlers(ctx: InputHandlerContext): InputHandlerResult {
|
||||
}
|
||||
|
||||
if (key.upArrow && !cState.inputBuf.length) {
|
||||
cycleQueue(1) || cycleHistory(-1)
|
||||
const inputSel = getInputSelection()
|
||||
const atStart = !cState.input || (!!inputSel && inputSel.start === 0 && inputSel.end === 0)
|
||||
|
||||
return
|
||||
if (atStart) {
|
||||
cycleQueue(1) || cycleHistory(-1)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (key.downArrow && !cState.inputBuf.length) {
|
||||
cycleQueue(-1) || cycleHistory(1)
|
||||
const inputSel = getInputSelection()
|
||||
const atEnd =
|
||||
!cState.input ||
|
||||
(!!inputSel && inputSel.start === cState.input.length && inputSel.end === cState.input.length)
|
||||
|
||||
return
|
||||
if (atEnd || cState.historyIdx !== null) {
|
||||
cycleQueue(-1) || cycleHistory(1)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (isAction(key, ch, 'c')) {
|
||||
|
||||
@@ -400,22 +400,20 @@ export function TextInput({
|
||||
return
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
setInputSelection({
|
||||
clear: () => {
|
||||
setInputSelection({
|
||||
clear: () => {
|
||||
if (selRef.current) {
|
||||
selRef.current = null
|
||||
setSel(null)
|
||||
},
|
||||
end: selected.end,
|
||||
start: selected.start,
|
||||
value: vRef.current
|
||||
})
|
||||
} else {
|
||||
setInputSelection(null)
|
||||
}
|
||||
}
|
||||
},
|
||||
end: selected?.end ?? curRef.current,
|
||||
start: selected?.start ?? curRef.current,
|
||||
value: vRef.current
|
||||
})
|
||||
|
||||
return () => setInputSelection(null)
|
||||
}, [focus, selected])
|
||||
}, [cur, focus, selected])
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
|
||||
Reference in New Issue
Block a user