@@ -6,10 +6,11 @@ import Fuse, { type IFuseOptions } from "fuse.js";
66import { useDraftStore } from "../stores/draftStore" ;
77import type { CommandSuggestionItem , FileSuggestionItem } from "../types" ;
88
9- const FILE_LIMIT = 5 ;
9+ const FILE_DISPLAY_LIMIT = 25 ;
10+ const FILE_FETCH_LIMIT = 100 ;
1011const COMMAND_LIMIT = 5 ;
1112
12- const FUSE_OPTIONS : IFuseOptions < AvailableCommand > = {
13+ const COMMAND_FUSE_OPTIONS : IFuseOptions < AvailableCommand > = {
1314 keys : [
1415 { name : "name" , weight : 0.7 } ,
1516 { name : "description" , weight : 0.3 } ,
@@ -18,6 +19,20 @@ const FUSE_OPTIONS: IFuseOptions<AvailableCommand> = {
1819 includeScore : true ,
1920} ;
2021
22+ interface FileItem {
23+ path : string ;
24+ name : string ;
25+ }
26+
27+ const FILE_FUSE_OPTIONS : IFuseOptions < FileItem > = {
28+ keys : [
29+ { name : "name" , weight : 0.7 } ,
30+ { name : "path" , weight : 0.3 } ,
31+ ] ,
32+ threshold : 0.4 ,
33+ includeScore : true ,
34+ } ;
35+
2136function searchCommands (
2237 commands : AvailableCommand [ ] ,
2338 query : string ,
@@ -26,7 +41,7 @@ function searchCommands(
2641 return commands . slice ( 0 , COMMAND_LIMIT ) ;
2742 }
2843
29- const fuse = new Fuse ( commands , FUSE_OPTIONS ) ;
44+ const fuse = new Fuse ( commands , COMMAND_FUSE_OPTIONS ) ;
3045 const results = fuse . search ( query , { limit : COMMAND_LIMIT * 2 } ) ;
3146
3247 const lowerQuery = query . toLowerCase ( ) ;
@@ -42,6 +57,27 @@ function searchCommands(
4257 return results . slice ( 0 , COMMAND_LIMIT ) . map ( ( result ) => result . item ) ;
4358}
4459
60+ function searchFiles ( files : FileItem [ ] , query : string ) : FileItem [ ] {
61+ if ( ! query . trim ( ) ) {
62+ return files . slice ( 0 , FILE_DISPLAY_LIMIT ) ;
63+ }
64+
65+ const fuse = new Fuse ( files , FILE_FUSE_OPTIONS ) ;
66+ const results = fuse . search ( query , { limit : FILE_DISPLAY_LIMIT * 2 } ) ;
67+
68+ const lowerQuery = query . toLowerCase ( ) ;
69+ results . sort ( ( a , b ) => {
70+ const aStartsWithQuery = a . item . name . toLowerCase ( ) . startsWith ( lowerQuery ) ;
71+ const bStartsWithQuery = b . item . name . toLowerCase ( ) . startsWith ( lowerQuery ) ;
72+
73+ if ( aStartsWithQuery && ! bStartsWithQuery ) return - 1 ;
74+ if ( ! aStartsWithQuery && bStartsWithQuery ) return 1 ;
75+ return ( a . score ?? 0 ) - ( b . score ?? 0 ) ;
76+ } ) ;
77+
78+ return results . slice ( 0 , FILE_DISPLAY_LIMIT ) . map ( ( result ) => result . item ) ;
79+ }
80+
4581export async function getFileSuggestions (
4682 sessionId : string ,
4783 query : string ,
@@ -55,19 +91,26 @@ export async function getFileSuggestions(
5591 const results = await trpcVanilla . fs . listRepoFiles . query ( {
5692 repoPath,
5793 query,
58- limit : FILE_LIMIT ,
94+ limit : FILE_FETCH_LIMIT ,
5995 } ) ;
6096
61- return results
97+ const files : FileItem [ ] = results
6298 . filter (
6399 ( file : MentionItem ) : file is MentionItem & { path : string } =>
64100 ! ! file . path ,
65101 )
66102 . map ( ( file ) => ( {
67- id : file . path ,
68- label : file . path ,
69103 path : file . path ,
104+ name : file . path . split ( "/" ) . pop ( ) ?? file . path ,
70105 } ) ) ;
106+
107+ const matched = searchFiles ( files , query ) ;
108+
109+ return matched . map ( ( file ) => ( {
110+ id : file . path ,
111+ label : file . path ,
112+ path : file . path ,
113+ } ) ) ;
71114}
72115
73116export function getCommandSuggestions (
0 commit comments