fix(tui): scope file autocomplete to session (#33458)

This commit is contained in:
Dax 2026-06-22 20:31:36 -04:00 committed by GitHub
commit ef2357915e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 70 additions and 49 deletions

View file

@ -13,6 +13,7 @@ import { useData } from "../../context/data"
import { getScrollAcceleration } from "../../util/scroll"
import { useTuiPaths } from "../../context/runtime"
import { useTuiConfig } from "../../config"
import { useLocation } from "../../context/location"
import { useTheme, selectedForeground } from "../../context/theme"
import { SplitBorder } from "../../ui/border"
import { useTerminalDimensions } from "@opentui/solid"
@ -21,6 +22,7 @@ import type { PromptInfo } from "../../prompt/history"
import { useFrecency } from "../../prompt/frecency"
import { useBindings, useCommandSlashes, useOpencodeModeStack } from "../../keymap"
import { displayCharAt, mentionTriggerIndex } from "../../prompt/display"
import type { FileSystemEntry } from "@opencode-ai/sdk/v2"
function removeLineRange(input: string) {
const hashIndex = input.lastIndexOf("#")
@ -94,6 +96,7 @@ export function Autocomplete(props: {
const frecency = useFrecency()
const tuiConfig = useTuiConfig()
const paths = useTuiPaths()
const location = useLocation()
const [store, setStore] = createStore({
index: 0,
selected: 0,
@ -236,16 +239,18 @@ export function Autocomplete(props: {
}
}
function createFilePart(item: string, lineRange?: { startLine: number; endLine?: number }) {
const baseDir = (sync.path.directory || paths.cwd).replace(/\/+$/, "")
const fullPath = path.isAbsolute(item) ? item : path.join(baseDir, item)
const urlObj = pathToFileURL(fullPath)
function createFilePart(
item: FileSystemEntry,
filePath: string,
lineRange?: { startLine: number; endLine?: number },
) {
const urlObj = pathToFileURL(filePath)
const filename =
lineRange && !item.endsWith("/")
? `${item}#${lineRange.startLine}${lineRange.endLine ? `-${lineRange.endLine}` : ""}`
: item
lineRange && item.type !== "directory"
? `${item.path}#${lineRange.startLine}${lineRange.endLine ? `-${lineRange.endLine}` : ""}`
: item.path
if (lineRange && !item.endsWith("/")) {
if (lineRange && item.type !== "directory") {
urlObj.searchParams.set("start", String(lineRange.startLine))
if (lineRange.endLine !== undefined) {
urlObj.searchParams.set("end", String(lineRange.endLine))
@ -254,10 +259,9 @@ export function Autocomplete(props: {
return {
filename,
url: urlObj.href,
part: {
type: "file" as const,
mime: "text/plain",
mime: item.mime,
filename,
url: urlObj.href,
source: {
@ -267,7 +271,7 @@ export function Autocomplete(props: {
end: 0,
value: "",
},
path: item,
path: item.path,
},
},
}
@ -284,7 +288,7 @@ export function Autocomplete(props: {
})
function normalizeMentionPath(filePath: string) {
const baseDir = sync.path.directory || paths.cwd
const baseDir = location()?.directory || sync.path.directory || paths.cwd
const absolute = path.resolve(filePath)
const relative = path.relative(baseDir, absolute)
@ -301,7 +305,11 @@ export function Autocomplete(props: {
startLine: input.lineStart,
endLine: input.lineEnd > input.lineStart ? input.lineEnd : undefined,
}
const { filename, part } = createFilePart(item, lineRange)
const { filename, part } = createFilePart(
{ path: item, type: "file", mime: "text/plain" },
input.filePath,
lineRange,
)
const index = store.visible === "@" ? store.index : props.input().cursorOffset
setStore("visible", false)
@ -310,17 +318,20 @@ export function Autocomplete(props: {
}
const [files] = createResource(
() => search(),
async (query) => {
() => ({ query: search(), location: location() }),
async (input) => {
if (!store.visible || store.visible === "/") return []
if (referenceMatch()) return []
const { lineRange, baseQuery } = extractLineRange(query ?? "")
const { lineRange, baseQuery } = extractLineRange(input.query ?? "")
// Get files from SDK
const result = await sdk.client.v2.fs.find({
query: baseQuery,
limit: "20",
location: { workspace: project.workspace.current() },
location: {
directory: input.location?.directory,
workspace: input.location?.workspaceID ?? project.workspace.current(),
},
})
const options: AutocompleteOption[] = []
@ -331,7 +342,11 @@ export function Autocomplete(props: {
const width = props.anchor().width - 4
options.push(
...result.data.data.map((item): AutocompleteOption => {
const { filename, url, part } = createFilePart(item.path, lineRange)
const { filename, part } = createFilePart(
item,
path.join(result.data.location.directory, item.path),
lineRange,
)
return {
display: Locale.truncateMiddle(filename, width),
value: filename,