@@ -24,13 +24,16 @@ type Entry = {
2424 path ?: string
2525}
2626
27- export function DialogSelectFile ( ) {
27+ type DialogSelectFileMode = "all" | "files"
28+
29+ export function DialogSelectFile ( props : { mode ?: DialogSelectFileMode } ) {
2830 const command = useCommand ( )
2931 const language = useLanguage ( )
3032 const layout = useLayout ( )
3133 const file = useFile ( )
3234 const dialog = useDialog ( )
3335 const params = useParams ( )
36+ const filesOnly = ( ) => props . mode === "files"
3437 const sessionKey = createMemo ( ( ) => `${ params . dir } ${ params . id ? "/" + params . id : "" } ` )
3538 const tabs = createMemo ( ( ) => layout . tabs ( sessionKey ) )
3639 const view = createMemo ( ( ) => layout . view ( sessionKey ) )
@@ -46,11 +49,12 @@ export function DialogSelectFile() {
4649 ]
4750 const limit = 5
4851
49- const allowed = createMemo ( ( ) =>
50- command . options . filter (
52+ const allowed = createMemo ( ( ) => {
53+ if ( filesOnly ( ) ) return [ ]
54+ return command . options . filter (
5155 ( option ) => ! option . disabled && ! option . id . startsWith ( "suggested." ) && option . id !== "file.open" ,
52- ) ,
53- )
56+ )
57+ } )
5458
5559 const commandItem = ( option : CommandOption ) : Entry => ( {
5660 id : "command:" + option . id ,
@@ -99,10 +103,50 @@ export function DialogSelectFile() {
99103 return items . slice ( 0 , limit )
100104 } )
101105
102- const items = async ( filter : string ) => {
103- const query = filter . trim ( )
106+ const root = createMemo ( ( ) => {
107+ const nodes = file . tree . children ( "" )
108+ const paths = nodes
109+ . filter ( ( node ) => node . type === "file" )
110+ . map ( ( node ) => node . path )
111+ . sort ( ( a , b ) => a . localeCompare ( b ) )
112+ return paths . slice ( 0 , limit ) . map ( fileItem )
113+ } )
114+
115+ const unique = ( items : Entry [ ] ) => {
116+ const seen = new Set < string > ( )
117+ const out : Entry [ ] = [ ]
118+ for ( const item of items ) {
119+ if ( seen . has ( item . id ) ) continue
120+ seen . add ( item . id )
121+ out . push ( item )
122+ }
123+ return out
124+ }
125+
126+ const items = async ( text : string ) => {
127+ const query = text . trim ( )
104128 setGrouped ( query . length > 0 )
129+
130+ if ( ! query && filesOnly ( ) ) {
131+ const loaded = file . tree . state ( "" ) ?. loaded
132+ const pending = loaded ? Promise . resolve ( ) : file . tree . list ( "" )
133+ const next = unique ( [ ...recent ( ) , ...root ( ) ] )
134+
135+ if ( loaded || next . length > 0 ) {
136+ void pending
137+ return next
138+ }
139+
140+ await pending
141+ return unique ( [ ...recent ( ) , ...root ( ) ] )
142+ }
143+
105144 if ( ! query ) return [ ...picks ( ) , ...recent ( ) ]
145+
146+ if ( filesOnly ( ) ) {
147+ const files = await file . searchFiles ( query )
148+ return files . map ( fileItem )
149+ }
106150 const files = await file . searchFiles ( query )
107151 const entries = files . map ( fileItem )
108152 return [ ...list ( ) , ...entries ]
@@ -146,7 +190,9 @@ export function DialogSelectFile() {
146190 < Dialog class = "pt-3 pb-0 !max-h-[480px]" transition >
147191 < List
148192 search = { {
149- placeholder : language . t ( "palette.search.placeholder" ) ,
193+ placeholder : filesOnly ( )
194+ ? language . t ( "session.header.searchFiles" )
195+ : language . t ( "palette.search.placeholder" ) ,
150196 autofocus : true ,
151197 hideIcon : true ,
152198 class : "pl-3 pr-2 !mb-0" ,
0 commit comments