@@ -307,7 +307,10 @@ export class CommandHandler {
307307 showStatsNotification ( finalContexts . length , totalLines , stats , modeLabel ) ;
308308 }
309309
310- async handleCollectAll ( ) : Promise < void > {
310+ async handleCollectAll (
311+ uri : vscode . Uri ,
312+ selectedFiles ?: vscode . Uri [ ] ,
313+ ) : Promise < void > {
311314 return vscode . window . withProgress (
312315 {
313316 location : vscode . ProgressLocation . Notification ,
@@ -317,40 +320,82 @@ export class CommandHandler {
317320 async ( progress , token ) => {
318321 try {
319322 this . output . clear ( ) ;
320- this . output . log ( "Starting full workspace collection..." ) ;
323+ this . output . log ( "Starting full collection..." ) ;
321324
322- const workspaceFolder = vscode . workspace . workspaceFolders ?. [ 0 ] ;
323- if ( ! workspaceFolder ) {
325+ const workspaceRoot = getWorkspaceRoot ( ) ;
326+ if ( ! workspaceRoot ) {
324327 const message = "No workspace folder open" ;
325328 this . output . error ( message ) ;
326329 vscode . window . showErrorMessage ( message ) ;
327330 return ;
328331 }
329332
330- if ( token . isCancellationRequested ) {
331- return ;
333+ const targetFolders : string [ ] = [ ] ;
334+
335+ if ( selectedFiles ?. length ) {
336+ for ( const selectedUri of selectedFiles ) {
337+ const fsPath = selectedUri . fsPath ;
338+ if ( fs . existsSync ( fsPath ) ) {
339+ const stat = fs . statSync ( fsPath ) ;
340+ if ( stat . isDirectory ( ) ) {
341+ targetFolders . push ( fsPath ) ;
342+ } else if ( stat . isFile ( ) ) {
343+ targetFolders . push ( path . dirname ( fsPath ) ) ;
344+ }
345+ }
346+ }
347+ } else if ( uri ) {
348+ const fsPath = uri . fsPath ;
349+ if ( fs . existsSync ( fsPath ) ) {
350+ const stat = fs . statSync ( fsPath ) ;
351+ if ( stat . isDirectory ( ) ) {
352+ targetFolders . push ( fsPath ) ;
353+ } else if ( stat . isFile ( ) ) {
354+ targetFolders . push ( path . dirname ( fsPath ) ) ;
355+ }
356+ }
332357 }
333358
334- const contexts = await this . contextCollector . collectAllFiles (
335- workspaceFolder . uri . fsPath ,
336- ( ) => ! token . isCancellationRequested ,
337- ) ;
359+ if ( targetFolders . length === 0 ) {
360+ targetFolders . push ( workspaceRoot ) ;
361+ }
362+
363+ const uniqueFolders = [ ...new Set ( targetFolders ) ] ;
364+ this . output . log ( `Collecting from ${ uniqueFolders . length } folder(s)` ) ;
365+
366+ const allContexts : FileContext [ ] = [ ] ;
367+
368+ for ( const folder of uniqueFolders ) {
369+ if ( token . isCancellationRequested ) {
370+ return ;
371+ }
372+
373+ const contexts = await this . contextCollector . collectAllFiles (
374+ folder ,
375+ ( ) => ! token . isCancellationRequested ,
376+ ) ;
377+ allContexts . push ( ...contexts ) ;
378+ }
338379
339380 if ( token . isCancellationRequested ) {
340381 return ;
341382 }
342383
343- const totalLines = contexts . reduce (
384+ const uniqueContexts = Array . from (
385+ new Map ( allContexts . map ( ( ctx ) => [ ctx . path , ctx ] ) ) . values ( ) ,
386+ ) ;
387+
388+ const totalLines = uniqueContexts . reduce (
344389 ( sum , ctx ) => sum + ctx . content . split ( "\n" ) . length ,
345390 0 ,
346391 ) ;
347- const stats = getFileTypeStats ( contexts ) ;
348- const output = formatContexts ( contexts ) ;
392+ const stats = getFileTypeStats ( uniqueContexts ) ;
393+ const output = formatContexts ( uniqueContexts ) ;
349394 await vscode . env . clipboard . writeText ( output ) ;
350395
351- const successMessage = `Copied ${ contexts . length } files (${ totalLines } lines)` ;
396+ const successMessage = `Copied ${ uniqueContexts . length } files (${ totalLines } lines)` ;
352397 this . output . log ( `✓ ${ successMessage } ` ) ;
353- showStatsNotification ( contexts . length , totalLines , stats ) ;
398+ showStatsNotification ( uniqueContexts . length , totalLines , stats ) ;
354399 } catch ( error ) {
355400 const errorMessage = `Error: ${ error } ` ;
356401 this . output . error ( errorMessage , error ) ;
0 commit comments