Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export function Autocomplete(props: {
index: 0,
selected: 0,
visible: false as AutocompleteRef["visible"],
input: "keyboard" as "keyboard" | "mouse",
})

const [positionTick, setPositionTick] = createSignal(0)
Expand Down Expand Up @@ -128,6 +129,14 @@ export function Autocomplete(props: {
return props.input().getTextRange(store.index + 1, props.input().cursorOffset)
})

// When the filter changes due to how TUI works, the mousemove might still be triggered
// via a synthetic event as the layout moves underneath the cursor. This is a workaround to make sure the input mode remains keyboard so
// that the mouseover event doesn't trigger when filtering.
createEffect(() => {
filter();
setStore("input", "keyboard")
})

function insertPart(text: string, part: PromptInfo["parts"][number]) {
const input = props.input()
const currentCursorOffset = input.cursorOffset
Expand Down Expand Up @@ -525,11 +534,13 @@ export function Autocomplete(props: {
const isNavDown = name === "down" || (ctrlOnly && name === "n")

if (isNavUp) {
setStore("input", "keyboard")
move(-1)
e.preventDefault()
return
}
if (isNavDown) {
setStore("input", "keyboard")
move(1)
e.preventDefault()
return
Expand Down Expand Up @@ -612,7 +623,17 @@ export function Autocomplete(props: {
paddingRight={1}
backgroundColor={index === store.selected ? theme.primary : undefined}
flexDirection="row"
onMouseOver={() => moveTo(index)}
onMouseMove={() => {
setStore("input", "mouse")
}}
onMouseOver={() => {
if (store.input !== "mouse") return
moveTo(index)
}}
onMouseDown={() => {
setStore("input", "mouse")
moveTo(index)
}}
onMouseUp={() => select()}
>
<text fg={index === store.selected ? selectedForeground(theme) : theme.text} flexShrink={0}>
Expand Down
21 changes: 21 additions & 0 deletions packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
const [store, setStore] = createStore({
selected: 0,
filter: "",
input: "keyboard" as "keyboard" | "mouse",
})

createEffect(
Expand Down Expand Up @@ -83,6 +84,14 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
return result
})

// When the filter changes due to how TUI works, the mousemove might still be triggered
// via a synthetic event as the layout moves underneath the cursor. This is a workaround to make sure the input mode remains keyboard
// that the mouseover event doesn't trigger when filtering.
createEffect(() => {
filtered();
setStore("input", "keyboard")
})

const grouped = createMemo(() => {
const result = pipe(
filtered(),
Expand Down Expand Up @@ -157,12 +166,15 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {

const keybind = useKeybind()
useKeyboard((evt) => {
setStore("input", "keyboard")

if (evt.name === "up" || (evt.ctrl && evt.name === "p")) move(-1)
if (evt.name === "down" || (evt.ctrl && evt.name === "n")) move(1)
if (evt.name === "pageup") move(-10)
if (evt.name === "pagedown") move(10)
if (evt.name === "home") moveTo(0)
if (evt.name === "end") moveTo(flat().length - 1)

if (evt.name === "return") {
const option = selected()
if (option) {
Expand Down Expand Up @@ -259,11 +271,20 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
<box
id={JSON.stringify(option.value)}
flexDirection="row"
onMouseMove={() => {
setStore("input", "mouse")
}}
onMouseUp={() => {
option.onSelect?.(dialog)
props.onSelect?.(option)
}}
onMouseOver={() => {
if (store.input !== "mouse") return
const index = flat().findIndex((x) => isDeepEqual(x.value, option.value))
if (index === -1) return
moveTo(index)
}}
onMouseDown={() => {
const index = flat().findIndex((x) => isDeepEqual(x.value, option.value))
if (index === -1) return
moveTo(index)
Expand Down