|
@@ -11,6 +11,7 @@ import { useCommandDialog } from "@tui/component/dialog-command"
|
|
|
import { useTerminalDimensions } from "@opentui/solid"
|
|
import { useTerminalDimensions } from "@opentui/solid"
|
|
|
import { Locale } from "@/util/locale"
|
|
import { Locale } from "@/util/locale"
|
|
|
import type { PromptInfo } from "./history"
|
|
import type { PromptInfo } from "./history"
|
|
|
|
|
+import { useFrecency } from "./frecency"
|
|
|
|
|
|
|
|
function removeLineRange(input: string) {
|
|
function removeLineRange(input: string) {
|
|
|
const hashIndex = input.lastIndexOf("#")
|
|
const hashIndex = input.lastIndexOf("#")
|
|
@@ -57,6 +58,7 @@ export type AutocompleteOption = {
|
|
|
description?: string
|
|
description?: string
|
|
|
isDirectory?: boolean
|
|
isDirectory?: boolean
|
|
|
onSelect?: () => void
|
|
onSelect?: () => void
|
|
|
|
|
+ path?: string
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export function Autocomplete(props: {
|
|
export function Autocomplete(props: {
|
|
@@ -76,6 +78,7 @@ export function Autocomplete(props: {
|
|
|
const command = useCommandDialog()
|
|
const command = useCommandDialog()
|
|
|
const { theme } = useTheme()
|
|
const { theme } = useTheme()
|
|
|
const dimensions = useTerminalDimensions()
|
|
const dimensions = useTerminalDimensions()
|
|
|
|
|
+ const frecency = useFrecency()
|
|
|
|
|
|
|
|
const [store, setStore] = createStore({
|
|
const [store, setStore] = createStore({
|
|
|
index: 0,
|
|
index: 0,
|
|
@@ -168,6 +171,10 @@ export function Autocomplete(props: {
|
|
|
draft.parts.push(part)
|
|
draft.parts.push(part)
|
|
|
props.setExtmark(partIndex, extmarkId)
|
|
props.setExtmark(partIndex, extmarkId)
|
|
|
})
|
|
})
|
|
|
|
|
+
|
|
|
|
|
+ if (part.type === "file" && part.source && part.source.type === "file") {
|
|
|
|
|
+ frecency.updateFrecency(part.source.path)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const [files] = createResource(
|
|
const [files] = createResource(
|
|
@@ -186,9 +193,19 @@ export function Autocomplete(props: {
|
|
|
|
|
|
|
|
// Add file options
|
|
// Add file options
|
|
|
if (!result.error && result.data) {
|
|
if (!result.error && result.data) {
|
|
|
|
|
+ const sortedFiles = result.data.sort((a, b) => {
|
|
|
|
|
+ const aScore = frecency.getFrecency(a)
|
|
|
|
|
+ const bScore = frecency.getFrecency(b)
|
|
|
|
|
+ if (aScore !== bScore) return bScore - aScore
|
|
|
|
|
+ const aDepth = a.split("/").length
|
|
|
|
|
+ const bDepth = b.split("/").length
|
|
|
|
|
+ if (aDepth !== bDepth) return aDepth - bDepth
|
|
|
|
|
+ return a.localeCompare(b)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
const width = props.anchor().width - 4
|
|
const width = props.anchor().width - 4
|
|
|
options.push(
|
|
options.push(
|
|
|
- ...result.data.map((item): AutocompleteOption => {
|
|
|
|
|
|
|
+ ...sortedFiles.map((item): AutocompleteOption => {
|
|
|
let url = `file://${process.cwd()}/${item}`
|
|
let url = `file://${process.cwd()}/${item}`
|
|
|
let filename = item
|
|
let filename = item
|
|
|
if (lineRange && !item.endsWith("/")) {
|
|
if (lineRange && !item.endsWith("/")) {
|
|
@@ -205,6 +222,7 @@ export function Autocomplete(props: {
|
|
|
return {
|
|
return {
|
|
|
display: Locale.truncateMiddle(filename, width),
|
|
display: Locale.truncateMiddle(filename, width),
|
|
|
isDirectory: isDir,
|
|
isDirectory: isDir,
|
|
|
|
|
+ path: item,
|
|
|
onSelect: () => {
|
|
onSelect: () => {
|
|
|
insertPart(filename, {
|
|
insertPart(filename, {
|
|
|
type: "file",
|
|
type: "file",
|
|
@@ -471,10 +489,12 @@ export function Autocomplete(props: {
|
|
|
limit: 10,
|
|
limit: 10,
|
|
|
scoreFn: (objResults) => {
|
|
scoreFn: (objResults) => {
|
|
|
const displayResult = objResults[0]
|
|
const displayResult = objResults[0]
|
|
|
|
|
+ let score = objResults.score
|
|
|
if (displayResult && displayResult.target.startsWith(store.visible + currentFilter)) {
|
|
if (displayResult && displayResult.target.startsWith(store.visible + currentFilter)) {
|
|
|
- return objResults.score * 2
|
|
|
|
|
|
|
+ score *= 2
|
|
|
}
|
|
}
|
|
|
- return objResults.score
|
|
|
|
|
|
|
+ const frecencyScore = objResults.obj.path ? frecency.getFrecency(objResults.obj.path) : 0
|
|
|
|
|
+ return score * (1 + frecencyScore)
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
|
|
|
|