@@ -11,6 +11,42 @@ import { useCommandDialog } from "@tui/component/dialog-command"
1111import { Locale } from "@/util/locale"
1212import type { PromptInfo } from "./history"
1313
14+ function removeLineRange ( input : string ) {
15+ const colonIndex = input . lastIndexOf ( ":" )
16+ return colonIndex !== - 1 ? input . substring ( 0 , colonIndex ) : input
17+ }
18+
19+ function extractLineRange ( input : string ) {
20+ const colonIndex = input . lastIndexOf ( ":" )
21+ if ( colonIndex === - 1 ) {
22+ return { baseQuery : input }
23+ }
24+
25+ const baseName = input . substring ( 0 , colonIndex )
26+ const linePart = input . substring ( colonIndex + 1 )
27+ const lineMatch = linePart . match ( / ^ ( \d + ) (?: - ( \d + ) ) ? $ / )
28+
29+ if ( ! lineMatch ) {
30+ return { baseQuery : baseName }
31+ }
32+
33+ const startLine = Number ( lineMatch [ 1 ] )
34+ const endLine = lineMatch [ 2 ] ? Number ( lineMatch [ 2 ] ) : undefined
35+
36+ if ( endLine !== undefined && startLine > endLine ) {
37+ return { baseQuery : baseName }
38+ }
39+
40+ return {
41+ lineRange : {
42+ baseName,
43+ startLine,
44+ endLine,
45+ } ,
46+ baseQuery : baseName ,
47+ }
48+ }
49+
1450export type AutocompleteRef = {
1551 onInput : ( value : string ) => void
1652 onKeyDown : ( e : KeyEvent ) => void
@@ -115,10 +151,12 @@ export function Autocomplete(props: {
115151 async ( query ) => {
116152 if ( ! store . visible || store . visible === "/" ) return [ ]
117153
154+ const { lineRange, baseQuery } = extractLineRange ( query ?? "" )
155+
118156 // Get files from SDK
119157 const result = await sdk . client . find . files ( {
120158 query : {
121- query : query ?? "" ,
159+ query : baseQuery ,
122160 } ,
123161 } )
124162
@@ -128,15 +166,27 @@ export function Autocomplete(props: {
128166 if ( ! result . error && result . data ) {
129167 const width = store . position . width - 4
130168 options . push (
131- ...result . data . map (
132- ( item ) : AutocompleteOption => ( {
133- display : Locale . truncateMiddle ( item , width ) ,
169+ ...result . data . map ( ( item ) : AutocompleteOption => {
170+ let url = `file://${ process . cwd ( ) } /${ item } `
171+ let filename = item
172+ if ( lineRange && ! item . endsWith ( "/" ) ) {
173+ filename = `${ item } :${ lineRange . startLine } ${ lineRange . endLine ? `-${ lineRange . endLine } ` : "" } `
174+ const urlObj = new URL ( url )
175+ urlObj . searchParams . set ( "start" , String ( lineRange . startLine ) )
176+ if ( lineRange . endLine !== undefined ) {
177+ urlObj . searchParams . set ( "end" , String ( lineRange . endLine ) )
178+ }
179+ url = urlObj . toString ( )
180+ }
181+
182+ return {
183+ display : Locale . truncateMiddle ( filename , width ) ,
134184 onSelect : ( ) => {
135- insertPart ( item , {
185+ insertPart ( filename , {
136186 type : "file" ,
137187 mime : "text/plain" ,
138- filename : item ,
139- url : `file:// ${ process . cwd ( ) } / ${ item } ` ,
188+ filename,
189+ url,
140190 source : {
141191 type : "file" ,
142192 text : {
@@ -148,8 +198,8 @@ export function Autocomplete(props: {
148198 } ,
149199 } )
150200 } ,
151- } ) ,
152- ) ,
201+ }
202+ } ) ,
153203 )
154204 }
155205
@@ -331,8 +381,8 @@ export function Autocomplete(props: {
331381 ) . filter ( ( x ) => x . disabled !== true )
332382 const currentFilter = filter ( )
333383 if ( ! currentFilter ) return mixed . slice ( 0 , 10 )
334- const result = fuzzysort . go ( currentFilter , mixed , {
335- keys : [ ( obj ) => obj . display . trimEnd ( ) , "description" , ( obj ) => obj . aliases ?. join ( " " ) ?? "" ] ,
384+ const result = fuzzysort . go ( removeLineRange ( currentFilter ) , mixed , {
385+ keys : [ ( obj ) => removeLineRange ( obj . display . trimEnd ( ) ) , "description" , ( obj ) => obj . aliases ?. join ( " " ) ?? "" ] ,
336386 limit : 10 ,
337387 } )
338388 return result . map ( ( arr ) => arr . obj )
0 commit comments