fix(tui): preserve reference file mention urls
This commit is contained in:
@@ -12,6 +12,7 @@ import fuzzysort from "fuzzysort"
|
||||
import path from "path"
|
||||
import { createEffect, createMemo, createResource, createSignal, onCleanup, onMount, type Accessor } from "solid-js"
|
||||
import * as Locale from "@/util/locale"
|
||||
import { ConfigReference } from "@/config/reference"
|
||||
import {
|
||||
createPromptHistory,
|
||||
isExitCommand,
|
||||
@@ -283,6 +284,19 @@ export function createPromptState(input: PromptInput): PromptState {
|
||||
},
|
||||
}))
|
||||
})
|
||||
const referenceNames = createMemo(() =>
|
||||
input
|
||||
.agents()
|
||||
.filter((item) => item.options.reference !== undefined)
|
||||
.map((item) => item.name)
|
||||
.toSorted((a, b) => b.length - a.length),
|
||||
)
|
||||
const referenceFilePath = (value: string) => {
|
||||
for (const name of referenceNames()) {
|
||||
if (value.startsWith(`${name}:/`)) return { name, path: value.slice(name.length + 2).replace(/\\/g, "/") }
|
||||
if (value.startsWith(`${name}/`)) return { name, path: value.slice(name.length + 1).replace(/\\/g, "/") }
|
||||
}
|
||||
}
|
||||
const resources = createMemo<Auto[]>(() => {
|
||||
return input.resources().map((item) => ({
|
||||
kind: "mention",
|
||||
@@ -331,7 +345,10 @@ export function createPromptState(input: PromptInput): PromptState {
|
||||
return a.localeCompare(b)
|
||||
})
|
||||
.map((item): Auto => {
|
||||
const url = pathToFileURL(path.resolve(input.directory, item))
|
||||
const reference = referenceFilePath(item)
|
||||
const url = reference
|
||||
? new URL(ConfigReference.fileUrl(reference.name, reference.path))
|
||||
: pathToFileURL(path.resolve(input.directory, item))
|
||||
let filename = item
|
||||
if (next.line && !item.endsWith("/")) {
|
||||
filename = `${item}#${next.line.start}${next.line.end ? `-${next.line.end}` : ""}`
|
||||
@@ -366,7 +383,9 @@ export function createPromptState(input: PromptInput): PromptState {
|
||||
},
|
||||
{ initialValue: [] as Auto[] },
|
||||
)
|
||||
const mentionOptions = createMemo(() => [...agents(), ...files(), ...resources()])
|
||||
const mentionOptions = createMemo(() =>
|
||||
referenceFilePath(removeLineRange(query())) ? files() : [...agents(), ...files(), ...resources()],
|
||||
)
|
||||
const slashOptions = createMemo<SlashOption[]>(() => {
|
||||
const builtins = [
|
||||
{ kind: "slash", name: "new", display: "/new", description: "start a new session" } satisfies SlashOption,
|
||||
|
||||
@@ -18,6 +18,7 @@ import { Locale } from "@/util/locale"
|
||||
import type { PromptInfo } from "./history"
|
||||
import { useFrecency } from "./frecency"
|
||||
import { useBindings } from "../../keymap"
|
||||
import { ConfigReference } from "@/config/reference"
|
||||
|
||||
function removeLineRange(input: string) {
|
||||
const hashIndex = input.lastIndexOf("#")
|
||||
@@ -225,8 +226,10 @@ export function Autocomplete(props: {
|
||||
|
||||
function createFilePart(item: string, lineRange?: { startLine: number; endLine?: number }) {
|
||||
const baseDir = (sync.path.directory || process.cwd()).replace(/\/+$/, "")
|
||||
const fullPath = path.isAbsolute(item) ? item : path.join(baseDir, item)
|
||||
const urlObj = pathToFileURL(fullPath)
|
||||
const reference = ConfigReference.parseFilePath(item, sync.data.config.reference)
|
||||
const urlObj = reference
|
||||
? new URL(ConfigReference.fileUrl(reference.name, reference.path))
|
||||
: pathToFileURL(path.isAbsolute(item) ? item : path.join(baseDir, item))
|
||||
const filename =
|
||||
lineRange && !item.endsWith("/")
|
||||
? `${item}#${lineRange.startLine}${lineRange.endLine ? `-${lineRange.endLine}` : ""}`
|
||||
@@ -261,6 +264,9 @@ export function Autocomplete(props: {
|
||||
}
|
||||
|
||||
function normalizeMentionPath(filePath: string) {
|
||||
const reference = ConfigReference.parseFilePath(filePath, sync.data.config.reference)
|
||||
if (reference) return ConfigReference.formatFilePath(reference.name, reference.path)
|
||||
|
||||
const baseDir = sync.path.directory || process.cwd()
|
||||
const absolute = path.resolve(filePath)
|
||||
const relative = path.relative(baseDir, absolute)
|
||||
@@ -430,11 +436,15 @@ export function Autocomplete(props: {
|
||||
const filesValue = files()
|
||||
const agentsValue = agents()
|
||||
const commandsValue = commands()
|
||||
const searchValue = search()
|
||||
const reference = ConfigReference.parseFilePath(removeLineRange(searchValue), sync.data.config.reference)
|
||||
|
||||
const mixed: AutocompleteOption[] =
|
||||
store.visible === "@" ? [...agentsValue, ...(filesValue || []), ...mcpResources()] : [...commandsValue]
|
||||
|
||||
const searchValue = search()
|
||||
store.visible === "@"
|
||||
? reference
|
||||
? filesValue || []
|
||||
: [...agentsValue, ...(filesValue || []), ...mcpResources()]
|
||||
: [...commandsValue]
|
||||
|
||||
if (!searchValue) {
|
||||
return mixed
|
||||
@@ -506,7 +516,7 @@ export function Autocomplete(props: {
|
||||
const currentCursorOffset = input.cursorOffset
|
||||
|
||||
const displayText = selected.display.trimEnd()
|
||||
const path = displayText.startsWith("@") ? displayText.slice(1) : displayText
|
||||
const path = selected.path ?? (displayText.startsWith("@") ? displayText.slice(1) : displayText)
|
||||
|
||||
input.cursorOffset = store.index
|
||||
const startCursor = input.logicalCursor
|
||||
|
||||
Reference in New Issue
Block a user