@@ -12,6 +12,42 @@ import { useTerminalDimensions } from "@opentui/solid"
1212import { Locale } from "@/util/locale"
1313import type { PromptInfo } from "./history"
1414
15+ function removeLineRange ( input : string ) {
16+ const colonIndex = input . lastIndexOf ( ":" )
17+ return colonIndex !== - 1 ? input . substring ( 0 , colonIndex ) : input
18+ }
19+
20+ function extractLineRange ( input : string ) {
21+ const colonIndex = input . lastIndexOf ( ":" )
22+ if ( colonIndex === - 1 ) {
23+ return { baseQuery : input }
24+ }
25+
26+ const baseName = input . substring ( 0 , colonIndex )
27+ const linePart = input . substring ( colonIndex + 1 )
28+ const lineMatch = linePart . match ( / ^ ( \d + ) (?: - ( \d + ) ) ? $ / )
29+
30+ if ( ! lineMatch ) {
31+ return { baseQuery : baseName }
32+ }
33+
34+ const startLine = Number ( lineMatch [ 1 ] )
35+ const endLine = lineMatch [ 2 ] ? Number ( lineMatch [ 2 ] ) : undefined
36+
37+ if ( endLine !== undefined && startLine > endLine ) {
38+ return { baseQuery : baseName }
39+ }
40+
41+ return {
42+ lineRange : {
43+ baseName,
44+ startLine,
45+ endLine,
46+ } ,
47+ baseQuery : baseName ,
48+ }
49+ }
50+
1551export type AutocompleteRef = {
1652 onInput : ( value : string ) => void
1753 onKeyDown : ( e : KeyEvent ) => void
@@ -142,9 +178,11 @@ export function Autocomplete(props: {
142178 async ( query ) => {
143179 if ( ! store . visible || store . visible === "/" ) return [ ]
144180
181+ const { lineRange, baseQuery } = extractLineRange ( query ?? "" )
182+
145183 // Get files from SDK
146184 const result = await sdk . client . find . files ( {
147- query : query ?? "" ,
185+ query : baseQuery ,
148186 } )
149187
150188 const options : AutocompleteOption [ ] = [ ]
@@ -153,15 +191,27 @@ export function Autocomplete(props: {
153191 if ( ! result . error && result . data ) {
154192 const width = props . anchor ( ) . width - 4
155193 options . push (
156- ...result . data . map (
157- ( item ) : AutocompleteOption => ( {
158- display : Locale . truncateMiddle ( item , width ) ,
194+ ...result . data . map ( ( item ) : AutocompleteOption => {
195+ let url = `file://${ process . cwd ( ) } /${ item } `
196+ let filename = item
197+ if ( lineRange && ! item . endsWith ( "/" ) ) {
198+ filename = `${ item } :${ lineRange . startLine } ${ lineRange . endLine ? `-${ lineRange . endLine } ` : "" } `
199+ const urlObj = new URL ( url )
200+ urlObj . searchParams . set ( "start" , String ( lineRange . startLine ) )
201+ if ( lineRange . endLine !== undefined ) {
202+ urlObj . searchParams . set ( "end" , String ( lineRange . endLine ) )
203+ }
204+ url = urlObj . toString ( )
205+ }
206+
207+ return {
208+ display : Locale . truncateMiddle ( filename , width ) ,
159209 onSelect : ( ) => {
160- insertPart ( item , {
210+ insertPart ( filename , {
161211 type : "file" ,
162212 mime : "text/plain" ,
163- filename : item ,
164- url : `file:// ${ process . cwd ( ) } / ${ item } ` ,
213+ filename,
214+ url,
165215 source : {
166216 type : "file" ,
167217 text : {
@@ -173,8 +223,8 @@ export function Autocomplete(props: {
173223 } ,
174224 } )
175225 } ,
176- } ) ,
177- ) ,
226+ }
227+ } ) ,
178228 )
179229 }
180230
@@ -383,8 +433,8 @@ export function Autocomplete(props: {
383433 return prev
384434 }
385435
386- const result = fuzzysort . go ( currentFilter , mixed , {
387- keys : [ ( obj ) => obj . display . trimEnd ( ) , "description" , ( obj ) => obj . aliases ?. join ( " " ) ?? "" ] ,
436+ const result = fuzzysort . go ( removeLineRange ( currentFilter ) , mixed , {
437+ keys : [ ( obj ) => removeLineRange ( obj . display . trimEnd ( ) ) , "description" , ( obj ) => obj . aliases ?. join ( " " ) ?? "" ] ,
388438 limit : 10 ,
389439 scoreFn : ( objResults ) => {
390440 const displayResult = objResults [ 0 ]
0 commit comments