Skip to content

Commit b5f41b9

Browse files
committed
Let workspaceContains trigger use rg --quiet (fixes microsoft#35236)
1 parent 49e570e commit b5f41b9

7 files changed

Lines changed: 104 additions & 4 deletions

File tree

src/vs/platform/search/common/search.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ export interface ICommonQueryOptions {
4444
filePattern?: string; // file search only
4545
fileEncoding?: string;
4646
maxResults?: number;
47+
/**
48+
* If true no results will be returned. Instead `limitHit` will indicate if at least one result exists or not.
49+
*
50+
* Currently does not work with queries including a 'siblings clause'.
51+
*/
52+
exists?: boolean;
4753
sortByScore?: boolean;
4854
cacheKey?: string;
4955
useRipgrep?: boolean;

src/vs/workbench/node/extensionHostMain.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,13 @@ export class ExtensionHostMain {
232232
const query: ISearchQuery = {
233233
folderQueries,
234234
type: QueryType.File,
235-
maxResults: 1,
235+
exists: true,
236236
includePattern: includes,
237237
useRipgrep
238238
};
239239

240240
let result = await this._diskSearch.search(query);
241-
if (result.results.length > 0) {
241+
if (result.limitHit) {
242242
// a file was found matching one of the glob patterns
243243
return (
244244
this._extensionService.activateById(extensionId, true)

src/vs/workbench/services/search/node/fileSearch.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export class FileWalker {
5353
private normalizedFilePatternLowercase: string;
5454
private includePattern: glob.ParsedExpression;
5555
private maxResults: number;
56+
private exists: boolean;
5657
private maxFilesize: number;
5758
private isLimitHit: boolean;
5859
private resultCount: number;
@@ -77,6 +78,7 @@ export class FileWalker {
7778
this.filePattern = config.filePattern;
7879
this.includePattern = config.includePattern && glob.parse(config.includePattern);
7980
this.maxResults = config.maxResults || null;
81+
this.exists = config.exists;
8082
this.maxFilesize = config.maxFilesize || null;
8183
this.walkedPaths = Object.create(null);
8284
this.resultCount = 0;
@@ -234,6 +236,7 @@ export class FileWalker {
234236
return;
235237
}
236238
if (this.isLimitHit) {
239+
done();
237240
return;
238241
}
239242

@@ -392,9 +395,12 @@ export class FileWalker {
392395

393396
cmd.on('close', (code: number) => {
394397
// ripgrep returns code=1 when no results are found
395-
if (code !== 0 && ((isRipgrep && stderr.length) || !isRipgrep)) {
398+
if (code !== 0 && (!isRipgrep || code !== 1)) {
396399
done(new Error(`command failed with error code ${code}: ${this.decodeData(stderr, encoding)}`));
397400
} else {
401+
if (isRipgrep && this.exists && code === 0) {
402+
this.isLimitHit = true;
403+
}
398404
done(null, '', true);
399405
}
400406
});
@@ -657,7 +663,7 @@ export class FileWalker {
657663
if (this.isFilePatternMatch(candidate.relativePath) && (!this.includePattern || this.includePattern(candidate.relativePath, candidate.basename))) {
658664
this.resultCount++;
659665

660-
if (this.maxResults && this.resultCount > this.maxResults) {
666+
if (this.exists || (this.maxResults && this.resultCount > this.maxResults)) {
661667
this.isLimitHit = true;
662668
}
663669

src/vs/workbench/services/search/node/ripgrepFileSearch.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ function getRgArgs(config: IRawSearch, folderQuery: IFolderSearch, includePatter
4444
// Follow symlinks
4545
args.push('--follow');
4646

47+
if (config.exists) {
48+
args.push('--quiet');
49+
}
50+
4751
// Folder to search
4852
args.push('--');
4953

src/vs/workbench/services/search/node/search.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export interface IRawSearch {
2525
includePattern?: IExpression;
2626
contentPattern?: IPatternInfo;
2727
maxResults?: number;
28+
exists?: boolean;
2829
sortByScore?: boolean;
2930
cacheKey?: string;
3031
maxFilesize?: number;

src/vs/workbench/services/search/node/searchService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ export class DiskSearch implements ISearchResultProvider {
266266
excludePattern: query.excludePattern,
267267
includePattern: query.includePattern,
268268
maxResults: query.maxResults,
269+
exists: query.exists,
269270
sortByScore: query.sortByScore,
270271
cacheKey: query.cacheKey,
271272
useRipgrep: query.useRipgrep,

src/vs/workbench/services/search/test/node/search.test.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,88 @@ suite('FileSearchEngine', () => {
8484
});
8585
});
8686

87+
test('Files: exists', function (done: () => void) {
88+
let engine = new FileSearchEngine({
89+
folderQueries: ROOT_FOLDER_QUERY,
90+
includePattern: { '**/file.txt': true },
91+
exists: true
92+
});
93+
94+
let count = 0;
95+
engine.search((result) => {
96+
if (result) {
97+
count++;
98+
}
99+
}, () => { }, (error, complete) => {
100+
assert.ok(!error);
101+
assert.equal(count, 0);
102+
assert.ok(complete.limitHit);
103+
done();
104+
});
105+
});
106+
107+
test('Files: not exists', function (done: () => void) {
108+
let engine = new FileSearchEngine({
109+
folderQueries: ROOT_FOLDER_QUERY,
110+
includePattern: { '**/nofile.txt': true },
111+
exists: true
112+
});
113+
114+
let count = 0;
115+
engine.search((result) => {
116+
if (result) {
117+
count++;
118+
}
119+
}, () => { }, (error, complete) => {
120+
assert.ok(!error);
121+
assert.equal(count, 0);
122+
assert.ok(!complete.limitHit);
123+
done();
124+
});
125+
});
126+
127+
test('Files: exists without Ripgrep', function (done: () => void) {
128+
let engine = new FileSearchEngine({
129+
folderQueries: ROOT_FOLDER_QUERY,
130+
includePattern: { '**/file.txt': true },
131+
exists: true,
132+
useRipgrep: false
133+
});
134+
135+
let count = 0;
136+
engine.search((result) => {
137+
if (result) {
138+
count++;
139+
}
140+
}, () => { }, (error, complete) => {
141+
assert.ok(!error);
142+
assert.equal(count, 0);
143+
assert.ok(complete.limitHit);
144+
done();
145+
});
146+
});
147+
148+
test('Files: not exists without Ripgrep', function (done: () => void) {
149+
let engine = new FileSearchEngine({
150+
folderQueries: ROOT_FOLDER_QUERY,
151+
includePattern: { '**/nofile.txt': true },
152+
exists: true,
153+
useRipgrep: false
154+
});
155+
156+
let count = 0;
157+
engine.search((result) => {
158+
if (result) {
159+
count++;
160+
}
161+
}, () => { }, (error, complete) => {
162+
assert.ok(!error);
163+
assert.equal(count, 0);
164+
assert.ok(!complete.limitHit);
165+
done();
166+
});
167+
});
168+
87169
test('Files: examples/com*', function (done: () => void) {
88170
let engine = new FileSearchEngine({
89171
folderQueries: ROOT_FOLDER_QUERY,

0 commit comments

Comments
 (0)