@@ -10,7 +10,7 @@ import { prepareQuery, IPreparedQuery, compareItemsByScore, scoreItem, ScorerCac
1010import { IFileQueryBuilderOptions , QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder' ;
1111import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation' ;
1212import { getOutOfWorkspaceEditorResources , extractRangeFromFilter , IWorkbenchSearchConfiguration } from 'vs/workbench/contrib/search/common/search' ;
13- import { ISearchService } from 'vs/workbench/services/search/common/search' ;
13+ import { ISearchService , ISearchComplete } from 'vs/workbench/services/search/common/search' ;
1414import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace' ;
1515import { untildify } from 'vs/base/common/labels' ;
1616import { IRemotePathService } from 'vs/workbench/services/path/common/remotePathService' ;
@@ -48,6 +48,7 @@ import { once } from 'vs/base/common/functional';
4848import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService' ;
4949import { getCodeEditor } from 'vs/editor/browser/editorBrowser' ;
5050import { withNullAsUndefined } from 'vs/base/common/types' ;
51+ import { stripCodicons } from 'vs/base/common/codicons' ;
5152
5253interface IAnythingQuickPickItem extends IPickerQuickAccessItem {
5354 resource : URI | undefined ;
@@ -367,17 +368,26 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
367368 // Perform filtering
368369 const filteredAnythingPicks : IAnythingQuickPickItem [ ] = [ ] ;
369370 for ( const anythingPick of sortedAnythingPicks ) {
370- const { score, labelMatch, descriptionMatch } = scoreItem ( anythingPick , query , true , quickPickItemScorerAccessor , this . pickState . scorerCache ) ;
371- if ( ! score ) {
372- continue ; // exclude files/symbols not matching query
371+
372+ // Always preserve any existing highlights (e.g. from workspace symbols)
373+ if ( anythingPick . highlights ) {
374+ filteredAnythingPicks . push ( anythingPick ) ;
373375 }
374376
375- anythingPick . highlights = {
376- label : labelMatch ,
377- description : descriptionMatch
378- } ;
377+ // Otherwise, do the scoring and matching here
378+ else {
379+ const { score, labelMatch, descriptionMatch } = scoreItem ( anythingPick , query , true , quickPickItemScorerAccessor , this . pickState . scorerCache ) ;
380+ if ( ! score ) {
381+ continue ;
382+ }
383+
384+ anythingPick . highlights = {
385+ label : labelMatch ,
386+ description : descriptionMatch
387+ } ;
379388
380- filteredAnythingPicks . push ( anythingPick ) ;
389+ filteredAnythingPicks . push ( anythingPick ) ;
390+ }
381391 }
382392
383393 return filteredAnythingPicks ;
@@ -498,15 +508,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
498508 const [ fileSearchResults , relativePathFileResults ] = await Promise . all ( [
499509
500510 // File search: this is a search over all files of the workspace using the provided pattern
501- this . searchService . fileSearch (
502- this . fileQueryBuilder . file (
503- this . contextService . getWorkspace ( ) . folders ,
504- this . getFileQueryOptions ( {
505- query,
506- cacheKey : this . pickState . fileQueryCache ?. cacheKey ,
507- maxResults : AnythingQuickAccessProvider . MAX_RESULTS
508- } )
509- ) , token ) ,
511+ this . getFileSearchResults ( query , token ) ,
510512
511513 // Relative path search: we also want to consider results that match files inside the workspace
512514 // by looking for relative paths that the user typed as query. This allows to return even excluded
@@ -521,7 +523,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
521523
522524 // Return quickly if no relative results are present
523525 if ( ! relativePathFileResults ) {
524- return fileSearchResults . results . map ( result => result . resource ) ;
526+ return fileSearchResults ;
525527 }
526528
527529 // Otherwise, make sure to filter relative path results from
@@ -532,12 +534,12 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
532534 }
533535
534536 return [
535- ...fileSearchResults . results . filter ( result => ! relativePathFileResultsMap . has ( result . resource ) ) . map ( result => result . resource ) ,
537+ ...fileSearchResults . filter ( result => ! relativePathFileResultsMap . has ( result ) ) ,
536538 ...relativePathFileResults
537539 ] ;
538540 }
539541
540- private getFileQueryOptions ( input : { query ? : IPreparedQuery , cacheKey ?: string , maxResults ?: number } ) : IFileQueryBuilderOptions {
542+ private async getFileSearchResults ( query : IPreparedQuery , token : CancellationToken ) : Promise < URI [ ] > {
541543
542544 // filePattern for search depends on the number of queries in input:
543545 // - with multiple: only take the first one and let the filter later drop non-matching results
@@ -547,18 +549,61 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
547549 // search results for "someFile" and not both that would normally not match.
548550 //
549551 let filePattern = '' ;
550- if ( input . query ) {
551- if ( input . query . values && input . query . values . length > 1 ) {
552- filePattern = input . query . values [ 0 ] . original ;
553- } else {
554- filePattern = input . query . original ;
552+ if ( query . values && query . values . length > 1 ) {
553+ filePattern = query . values [ 0 ] . original ;
554+ } else {
555+ filePattern = query . original ;
556+ }
557+
558+ const fileSearchResults = await this . doGetFileSearchResults ( filePattern , token ) ;
559+ if ( token . isCancellationRequested ) {
560+ return [ ] ;
561+ }
562+
563+ // If we detect that the search limit has been hit and we have a query
564+ // that was composed of multiple inputs where we only took the first part
565+ // we run another search with the full original query included to make
566+ // sure we are including all possible results that could match.
567+ if ( fileSearchResults . limitHit && query . values && query . values . length > 1 ) {
568+ const additionalFileSearchResults = await this . doGetFileSearchResults ( query . original , token ) ;
569+ if ( token . isCancellationRequested ) {
570+ return [ ] ;
571+ }
572+
573+ // Remember which result we already covered
574+ const existingFileSearchResultsMap = new ResourceMap < boolean > ( ) ;
575+ for ( const fileSearchResult of fileSearchResults . results ) {
576+ existingFileSearchResultsMap . set ( fileSearchResult . resource , true ) ;
577+ }
578+
579+ // Add all additional results to the original set for inclusion
580+ for ( const additionalFileSearchResult of additionalFileSearchResults . results ) {
581+ if ( ! existingFileSearchResultsMap . has ( additionalFileSearchResult . resource ) ) {
582+ fileSearchResults . results . push ( additionalFileSearchResult ) ;
583+ }
555584 }
556585 }
557586
587+ return fileSearchResults . results . map ( result => result . resource ) ;
588+ }
589+
590+ private doGetFileSearchResults ( filePattern : string , token : CancellationToken ) : Promise < ISearchComplete > {
591+ return this . searchService . fileSearch (
592+ this . fileQueryBuilder . file (
593+ this . contextService . getWorkspace ( ) . folders ,
594+ this . getFileQueryOptions ( {
595+ filePattern,
596+ cacheKey : this . pickState . fileQueryCache ?. cacheKey ,
597+ maxResults : AnythingQuickAccessProvider . MAX_RESULTS
598+ } )
599+ ) , token ) ;
600+ }
601+
602+ private getFileQueryOptions ( input : { filePattern ?: string , cacheKey ?: string , maxResults ?: number } ) : IFileQueryBuilderOptions {
558603 return {
559604 _reason : 'openFileHandler' , // used for telemetry - do not change
560605 extraFileResources : this . instantiationService . invokeFunction ( getOutOfWorkspaceEditorResources ) ,
561- filePattern,
606+ filePattern : input . filePattern || '' ,
562607 cacheKey : input . cacheKey ,
563608 maxResults : input . maxResults || 0 ,
564609 sortByScore : true
@@ -570,7 +615,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
570615 return ;
571616 }
572617
573- const detildifiedQuery = untildify ( query . value , ( await this . remotePathService . userHome ) . path ) ;
618+ const detildifiedQuery = untildify ( query . original , ( await this . remotePathService . userHome ) . path ) ;
574619 if ( token . isCancellationRequested ) {
575620 return ;
576621 }
@@ -609,7 +654,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
609654
610655 // Convert relative paths to absolute paths over all folders of the workspace
611656 // and return them as results if the absolute paths exist
612- const isAbsolutePathQuery = ( await this . remotePathService . path ) . isAbsolute ( query . value ) ;
657+ const isAbsolutePathQuery = ( await this . remotePathService . path ) . isAbsolute ( query . original ) ;
613658 if ( ! isAbsolutePathQuery ) {
614659 const resources : URI [ ] = [ ] ;
615660 for ( const folder of this . contextService . getWorkspace ( ) . folders ) {
@@ -618,7 +663,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
618663 }
619664
620665 const resource = toLocalResource (
621- folder . toResource ( query . value ) ,
666+ folder . toResource ( query . original ) ,
622667 this . environmentService . configuration . remoteAuthority
623668 ) ;
624669
@@ -654,25 +699,11 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
654699 return [ ] ;
655700 }
656701
657- // symbolPattern for search depends on the number of queries in input:
658- // - with multiple: only take the first one and let the filter later drop non-matching results
659- // - with single: just take the original in full
660- //
661- // This enables to e.g. search for "someFile someFolder" by only returning
662- // symbol results for "someFile" and not both that would normally not match.
663- //
664- let symbolPattern = '' ;
665- if ( query . values && query . values . length > 1 ) {
666- symbolPattern = query . values [ 0 ] . original ;
667- } else {
668- symbolPattern = query . original ;
669- }
670-
671702 // Delegate to the existing symbols quick access
672703 // but skip local results and also do not score
673- return this . workspaceSymbolsQuickAccess . getSymbolPicks ( symbolPattern , {
704+ return this . workspaceSymbolsQuickAccess . getSymbolPicks ( query . original , {
674705 skipLocal : true ,
675- skipScoring : true ,
706+ skipSorting : true ,
676707 delay : AnythingQuickAccessProvider . TYPING_SEARCH_DELAY
677708 } , token ) ;
678709 }
@@ -740,7 +771,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
740771 }
741772
742773 // Ask provider for editor symbols
743- const editorSymbolPicks = ( await this . editorSymbolsQuickAccess . getSymbolPicks ( model , filter , disposables , token ) ) ;
774+ const editorSymbolPicks = ( await this . editorSymbolsQuickAccess . getSymbolPicks ( model , filter , { extraContainerLabel : stripCodicons ( activeGlobalPick . label ) } , disposables , token ) ) ;
744775 if ( token . isCancellationRequested ) {
745776 return [ ] ;
746777 }
@@ -756,7 +787,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
756787 return {
757788 ...editorSymbolPick ,
758789 resource : activeGlobalResource ,
759- description : editorSymbolPick . description ? ` ${ activeGlobalPick . label } • ${ editorSymbolPick . description } ` : activeGlobalPick . label ,
790+ description : editorSymbolPick . description ,
760791 trigger : ( buttonIndex , keyMods ) => {
761792 this . openAnything ( activeGlobalResource , { keyMods, range : editorSymbolPick . range ?. selection , forceOpenSideBySide : true } ) ;
762793
0 commit comments