Skip to content

Commit b77192b

Browse files
author
Jackson Kearl
committed
1 parent 50e742c commit b77192b

5 files changed

Lines changed: 45 additions & 31 deletions

File tree

src/vs/workbench/contrib/search/browser/searchView.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
3434
import { TreeResourceNavigator, WorkbenchObjectTree, getSelectionKeyboardEvent } from 'vs/platform/list/browser/listService';
3535
import { INotificationService } from 'vs/platform/notification/common/notification';
3636
import { IProgressService, IProgressStep, IProgress } from 'vs/platform/progress/common/progress';
37-
import { IPatternInfo, ISearchComplete, ISearchConfiguration, ISearchConfigurationProperties, ITextQuery, VIEW_ID, SearchSortOrder } from 'vs/workbench/services/search/common/search';
37+
import { IPatternInfo, ISearchComplete, ISearchConfiguration, ISearchConfigurationProperties, ITextQuery, VIEW_ID, SearchSortOrder, SearchCompletionExitCode } from 'vs/workbench/services/search/common/search';
3838
import { ISearchHistoryService, ISearchHistoryValues } from 'vs/workbench/contrib/search/common/searchHistoryService';
3939
import { diffInserted, diffInsertedOutline, diffRemoved, diffRemovedOutline, editorFindMatchHighlight, editorFindMatchHighlightBorder, listActiveSelectionForeground, foreground } from 'vs/platform/theme/common/colorRegistry';
4040
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
@@ -1348,7 +1348,7 @@ export class SearchView extends ViewPane {
13481348
this.inputPatternIncludes.onSearchSubmit();
13491349
});
13501350

1351-
this.viewModel.cancelSearch();
1351+
this.viewModel.cancelSearch(true);
13521352

13531353
this.currentSearchQ = this.currentSearchQ
13541354
.then(() => this.doSearch(query, excludePatternText, includePatternText, triggeredOnType))
@@ -1393,6 +1393,10 @@ export class SearchView extends ViewPane {
13931393
this.updateActions();
13941394
const hasResults = !this.viewModel.searchResult.isEmpty();
13951395

1396+
if (completed?.exit === SearchCompletionExitCode.NewSearchStarted) {
1397+
return;
1398+
}
1399+
13961400
if (completed && completed.limitHit) {
13971401
this.searchWidget.searchInput.showMessage({
13981402
content: nls.localize('searchMaxResultsWarning', "The result set only contains a subset of all matches. Please be more specific in your search to narrow down the results."),

src/vs/workbench/contrib/search/browser/searchWidget.ts

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,6 @@ export class SearchWidget extends Widget {
154154
private readonly _onDidToggleContext = new Emitter<void>();
155155
readonly onDidToggleContext: Event<void> = this._onDidToggleContext.event;
156156

157-
private temporarilySkipSearchOnChange = false;
158157
private showContextCheckbox!: Checkbox;
159158
private contextLinesInput!: InputBox;
160159

@@ -488,12 +487,10 @@ export class SearchWidget extends Widget {
488487
this.setReplaceAllActionState(false);
489488

490489
if (this.searchConfiguration.searchOnType) {
491-
if (!this.temporarilySkipSearchOnChange) {
492-
this._onSearchCancel.fire({ focus: false });
493-
if (this.searchInput.getRegex()) {
494-
try {
495-
const regex = new RegExp(this.searchInput.getValue(), 'ug');
496-
const matchienessHeuristic = `
490+
if (this.searchInput.getRegex()) {
491+
try {
492+
const regex = new RegExp(this.searchInput.getValue(), 'ug');
493+
const matchienessHeuristic = `
497494
~!@#$%^&*()_+
498495
\`1234567890-=
499496
qwertyuiop[]\\
@@ -503,18 +500,17 @@ export class SearchWidget extends Widget {
503500
zxcvbnm,./
504501
ZXCVBNM<>? `.match(regex)?.length ?? 0;
505502

506-
const delayMultiplier =
507-
matchienessHeuristic < 50 ? 1 :
508-
matchienessHeuristic < 100 ? 5 : // expressions like `.` or `\w`
509-
10; // only things matching empty string
510-
511-
this.submitSearch(true, this.searchConfiguration.searchOnTypeDebouncePeriod * delayMultiplier);
512-
} catch {
513-
// pass
514-
}
515-
} else {
516-
this.submitSearch(true, this.searchConfiguration.searchOnTypeDebouncePeriod);
503+
const delayMultiplier =
504+
matchienessHeuristic < 50 ? 1 :
505+
matchienessHeuristic < 100 ? 5 : // expressions like `.` or `\w`
506+
10; // only things matching empty string
507+
508+
this.submitSearch(true, this.searchConfiguration.searchOnTypeDebouncePeriod * delayMultiplier);
509+
} catch {
510+
// pass
517511
}
512+
} else {
513+
this.submitSearch(true, this.searchConfiguration.searchOnTypeDebouncePeriod);
518514
}
519515
}
520516
}

src/vs/workbench/contrib/search/common/searchModel.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { IModelService } from 'vs/editor/common/services/modelService';
2020
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
2121
import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress';
2222
import { ReplacePattern } from 'vs/workbench/services/search/common/replace';
23-
import { IFileMatch, IPatternInfo, ISearchComplete, ISearchProgressItem, ISearchConfigurationProperties, ISearchService, ITextQuery, ITextSearchPreviewOptions, ITextSearchMatch, ITextSearchStats, resultIsMatch, ISearchRange, OneLineRange, ITextSearchContext, ITextSearchResult, SearchSortOrder } from 'vs/workbench/services/search/common/search';
23+
import { IFileMatch, IPatternInfo, ISearchComplete, ISearchProgressItem, ISearchConfigurationProperties, ISearchService, ITextQuery, ITextSearchPreviewOptions, ITextSearchMatch, ITextSearchStats, resultIsMatch, ISearchRange, OneLineRange, ITextSearchContext, ITextSearchResult, SearchSortOrder, SearchCompletionExitCode } from 'vs/workbench/services/search/common/search';
2424
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
2525
import { overviewRulerFindMatchForeground, minimapFindMatch } from 'vs/platform/theme/common/colorRegistry';
2626
import { themeColorFromId } from 'vs/platform/theme/common/themeService';
@@ -968,6 +968,7 @@ export class SearchModel extends Disposable {
968968
readonly onReplaceTermChanged: Event<void> = this._onReplaceTermChanged.event;
969969

970970
private currentCancelTokenSource: CancellationTokenSource | null = null;
971+
private searchCancelledForNewSearch: boolean = false;
971972

972973
constructor(
973974
@ISearchService private readonly searchService: ISearchService,
@@ -1016,7 +1017,7 @@ export class SearchModel extends Disposable {
10161017
}
10171018

10181019
search(query: ITextQuery, onProgress?: (result: ISearchProgressItem) => void): Promise<ISearchComplete> {
1019-
this.cancelSearch();
1020+
this.cancelSearch(true);
10201021

10211022

10221023
this._searchQuery = query;
@@ -1114,7 +1115,12 @@ export class SearchModel extends Disposable {
11141115

11151116
private onSearchError(e: any, duration: number): void {
11161117
if (errors.isPromiseCanceledError(e)) {
1117-
this.onSearchCompleted(null, duration);
1118+
this.onSearchCompleted(
1119+
this.searchCancelledForNewSearch
1120+
? { exit: SearchCompletionExitCode.NewSearchStarted, results: [] }
1121+
: null,
1122+
duration);
1123+
this.searchCancelledForNewSearch = false;
11181124
}
11191125
}
11201126

@@ -1133,8 +1139,9 @@ export class SearchModel extends Disposable {
11331139
return this.configurationService.getValue<ISearchConfigurationProperties>('search');
11341140
}
11351141

1136-
cancelSearch(): boolean {
1142+
cancelSearch(cancelledForNewSearch = false): boolean {
11371143
if (this.currentCancelTokenSource) {
1144+
this.searchCancelledForNewSearch = cancelledForNewSearch;
11381145
this.currentCancelTokenSource.cancel();
11391146
return true;
11401147
}

src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export class SearchEditor extends BaseTextEditor {
7777
private searchHistoryDelayer: Delayer<void>;
7878
private messageDisposables: IDisposable[] = [];
7979
private container: HTMLElement;
80+
private searchModel: SearchModel;
8081

8182
constructor(
8283
@ITelemetryService telemetryService: ITelemetryService,
@@ -107,6 +108,8 @@ export class SearchEditor extends BaseTextEditor {
107108
this.inputFocusContextKey = InputBoxFocusedKey.bindTo(scopedContextKeyService);
108109
this.searchOperation = this._register(new LongRunningOperation(progressService));
109110
this.searchHistoryDelayer = new Delayer<void>(2000);
111+
112+
this.searchModel = this._register(this.instantiationService.createInstance(SearchModel));
110113
}
111114

112115
createEditor(parent: HTMLElement) {
@@ -326,6 +329,8 @@ export class SearchEditor extends BaseTextEditor {
326329
}
327330

328331
private async doRunSearch() {
332+
this.searchModel.cancelSearch(true);
333+
329334
const startInput = this.getInput();
330335

331336
this.searchHistoryDelayer.trigger(() => {
@@ -372,30 +377,26 @@ export class SearchEditor extends BaseTextEditor {
372377
catch (err) {
373378
return;
374379
}
375-
const searchModel = this.instantiationService.createInstance(SearchModel);
380+
376381
this.searchOperation.start(500);
377-
await searchModel.search(query).finally(() => this.searchOperation.stop());
382+
await this.searchModel.search(query).finally(() => this.searchOperation.stop());
378383
const input = this.getInput();
379384
if (!input ||
380385
input !== startInput ||
381386
JSON.stringify(config) !== JSON.stringify(this.readConfigFromWidget())) {
382-
383-
searchModel.dispose();
384387
return;
385388
}
386389

387390
const controller = ReferencesController.get(this.searchResultEditor);
388391
controller.closeWidget(false);
389392
const labelFormatter = (uri: URI): string => this.labelService.getUriLabel(uri, { relative: true });
390-
const results = serializeSearchResultForEditor(searchModel.searchResult, config.includes, config.excludes, config.contextLines, labelFormatter, false);
393+
const results = serializeSearchResultForEditor(this.searchModel.searchResult, config.includes, config.excludes, config.contextLines, labelFormatter, false);
391394
const { header, body } = await input.getModels();
392395
this.modelService.updateModel(body, results.text);
393396
header.setValue(serializeSearchConfiguration(config));
394397

395398
input.setDirty(input.resource.scheme !== 'search-editor');
396399
input.setMatchRanges(results.matchRanges);
397-
398-
searchModel.dispose();
399400
}
400401

401402
layout(dimension: DOM.Dimension) {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,12 @@ export interface ISearchCompleteStats {
198198

199199
export interface ISearchComplete extends ISearchCompleteStats {
200200
results: IFileMatch[];
201+
exit?: SearchCompletionExitCode
202+
}
203+
204+
export const enum SearchCompletionExitCode {
205+
Normal,
206+
NewSearchStarted
201207
}
202208

203209
export interface ITextSearchStats {

0 commit comments

Comments
 (0)