Просмотр исходного кода

tui: autocomplete: expand directory on Tab, select on Enter (#6975)

Signed-off-by: yuguorui <[email protected]>
Guorui Yu 1 месяц назад
Родитель
Сommit
5a38a6f248
1 измененных файлов с 35 добавлено и 1 удалено
  1. 35 1
      packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx

+ 35 - 1
packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx

@@ -55,6 +55,7 @@ export type AutocompleteOption = {
   aliases?: string[]
   disabled?: boolean
   description?: string
+  isDirectory?: boolean
   onSelect?: () => void
 }
 
@@ -200,8 +201,10 @@ export function Autocomplete(props: {
               url = urlObj.toString()
             }
 
+            const isDir = item.endsWith("/")
             return {
               display: Locale.truncateMiddle(filename, width),
+              isDirectory: isDir,
               onSelect: () => {
                 insertPart(filename, {
                   type: "file",
@@ -511,6 +514,27 @@ export function Autocomplete(props: {
     selected.onSelect?.()
   }
 
+  function expandDirectory() {
+    const selected = options()[store.selected]
+    if (!selected) return
+
+    const input = props.input()
+    const currentCursorOffset = input.cursorOffset
+
+    const displayText = selected.display.trimEnd()
+    const path = displayText.startsWith("@") ? displayText.slice(1) : displayText
+
+    input.cursorOffset = store.index
+    const startCursor = input.logicalCursor
+    input.cursorOffset = currentCursorOffset
+    const endCursor = input.logicalCursor
+
+    input.deleteRange(startCursor.row, startCursor.col, endCursor.row, endCursor.col)
+    input.insertText("@" + path)
+
+    setStore("selected", 0)
+  }
+
   function show(mode: "@" | "/") {
     command.keybinds(false)
     setStore({
@@ -575,11 +599,21 @@ export function Autocomplete(props: {
             e.preventDefault()
             return
           }
-          if (name === "return" || name === "tab") {
+          if (name === "return") {
             select()
             e.preventDefault()
             return
           }
+          if (name === "tab") {
+            const selected = options()[store.selected]
+            if (selected?.isDirectory) {
+              expandDirectory()
+            } else {
+              select()
+            }
+            e.preventDefault()
+            return
+          }
         }
         if (!store.visible) {
           if (e.name === "@") {