@codingame/monaco-vscode-search-service-override 3.2.3 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/package.json +2 -2
  2. package/search.js +4 -4
  3. package/external/rollup-plugin-styles/dist/runtime/inject-css.js +0 -3
  4. package/external/tslib/tslib.es6.js +0 -11
  5. package/override/vs/platform/dialogs/common/dialogs.js +0 -8
  6. package/vscode/src/vs/workbench/contrib/search/browser/anythingQuickAccess.js +0 -776
  7. package/vscode/src/vs/workbench/contrib/search/browser/media/anythingQuickAccess.css.js +0 -6
  8. package/vscode/src/vs/workbench/contrib/search/browser/media/searchview.css.js +0 -6
  9. package/vscode/src/vs/workbench/contrib/search/browser/patternInputWidget.js +0 -231
  10. package/vscode/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.js +0 -342
  11. package/vscode/src/vs/workbench/contrib/search/browser/replaceContributions.js +0 -8
  12. package/vscode/src/vs/workbench/contrib/search/browser/replaceService.js +0 -232
  13. package/vscode/src/vs/workbench/contrib/search/browser/search.contribution.js +0 -621
  14. package/vscode/src/vs/workbench/contrib/search/browser/searchActionsCopy.js +0 -209
  15. package/vscode/src/vs/workbench/contrib/search/browser/searchActionsNav.js +0 -511
  16. package/vscode/src/vs/workbench/contrib/search/browser/searchActionsRemoveReplace.js +0 -374
  17. package/vscode/src/vs/workbench/contrib/search/browser/searchActionsSymbol.js +0 -43
  18. package/vscode/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.js +0 -44
  19. package/vscode/src/vs/workbench/contrib/search/browser/searchActionsTopBar.js +0 -323
  20. package/vscode/src/vs/workbench/contrib/search/browser/searchFindInput.js +0 -47
  21. package/vscode/src/vs/workbench/contrib/search/browser/searchIcons.js +0 -96
  22. package/vscode/src/vs/workbench/contrib/search/browser/searchMessage.js +0 -66
  23. package/vscode/src/vs/workbench/contrib/search/browser/searchResultsView.js +0 -434
  24. package/vscode/src/vs/workbench/contrib/search/browser/searchView.js +0 -2096
  25. package/vscode/src/vs/workbench/contrib/search/browser/searchWidget.js +0 -667
  26. package/vscode/src/vs/workbench/contrib/search/browser/symbolsQuickAccess.js +0 -234
  27. package/vscode/src/vs/workbench/contrib/search/common/cacheState.js +0 -87
  28. package/vscode/src/vs/workbench/contrib/searchEditor/browser/media/searchEditor.css.js +0 -6
  29. package/vscode/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.js +0 -586
  30. package/vscode/src/vs/workbench/contrib/searchEditor/browser/searchEditor.js +0 -736
  31. package/vscode/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.js +0 -189
  32. package/vscode/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.js +0 -320
  33. package/vscode/src/vs/workbench/contrib/searchEditor/browser/searchEditorModel.js +0 -138
  34. package/vscode/src/vs/workbench/contrib/searchEditor/browser/searchEditorSerialization.js +0 -293
  35. package/vscode/src/vs/workbench/services/search/common/searchService.js +0 -372
@@ -1,2096 +0,0 @@
1
- import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
- import { $ as $$1, hide, append, addDisposableListener, EventType, EventHelper, clearNode, show, getActiveWindow, getTotalHeight, Dimension, isAncestorOfActiveElement } from 'vscode/vscode/vs/base/browser/dom';
3
- import { StandardKeyboardEvent } from 'vscode/vscode/vs/base/browser/keyboardEvent';
4
- import { status } from 'vscode/vscode/vs/base/browser/ui/aria/aria';
5
- import { ObjectTreeElementCollapseState } from 'vscode/vscode/vs/base/browser/ui/tree/tree';
6
- import { Delayer, RunOnceScheduler } from 'vscode/vscode/vs/base/common/async';
7
- import { isCancellationError, onUnexpectedError } from 'vscode/vscode/vs/base/common/errors';
8
- import { Event } from 'vscode/vscode/vs/base/common/event';
9
- import { Iterable } from 'vscode/vscode/vs/base/common/iterator';
10
- import { DisposableStore, Disposable } from 'vscode/vscode/vs/base/common/lifecycle';
11
- import { isMacintosh, isNative } from 'vscode/vscode/vs/base/common/platform';
12
- import { escapeRegExpCharacters } from 'vscode/vscode/vs/base/common/strings';
13
- import { URI } from 'vscode/vscode/vs/base/common/uri';
14
- import { Schemas } from 'vscode/vscode/vs/base/common/network';
15
- import './media/searchview.css.js';
16
- import { isCodeEditor, getCodeEditor, isDiffEditor } from 'vscode/vscode/vs/editor/browser/editorBrowser';
17
- import { ICodeEditorService } from 'vscode/vscode/vs/editor/browser/services/codeEditorService';
18
- import { EmbeddedCodeEditorWidget } from 'vscode/vscode/vs/editor/browser/widget/embeddedCodeEditorWidget';
19
- import { Selection } from 'vscode/vscode/vs/editor/common/core/selection';
20
- import { CommonFindController } from 'vscode/vscode/vs/editor/contrib/find/browser/findController';
21
- import { MultiCursorSelectionController } from 'vscode/vscode/vs/editor/contrib/multicursor/browser/multicursor';
22
- import { localizeWithPath } from 'vscode/vscode/vs/nls';
23
- import { IAccessibilityService } from 'vscode/vscode/vs/platform/accessibility/common/accessibility';
24
- import { MenuId } from 'vscode/vscode/vs/platform/actions/common/actions';
25
- import { ICommandService } from 'vscode/vscode/vs/platform/commands/common/commands';
26
- import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration';
27
- import { IContextKeyService } from 'vscode/vscode/vs/platform/contextkey/common/contextkey';
28
- import { IContextViewService, IContextMenuService } from 'vscode/vscode/vs/platform/contextview/browser/contextView';
29
- import '../../../../../../../override/vs/platform/dialogs/common/dialogs.js';
30
- import { IFileService } from 'vscode/vscode/vs/platform/files/common/files';
31
- import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
32
- import { ServiceCollection } from 'vscode/vscode/vs/platform/instantiation/common/serviceCollection';
33
- import { IKeybindingService } from 'vscode/vscode/vs/platform/keybinding/common/keybinding';
34
- import { WorkbenchCompressibleObjectTree, getSelectionKeyboardEvent } from 'vscode/vscode/vs/platform/list/browser/listService';
35
- import { INotificationService } from 'vscode/vscode/vs/platform/notification/common/notification';
36
- import { withSelection, IOpenerService } from 'vscode/vscode/vs/platform/opener/common/opener';
37
- import { IProgressService } from 'vscode/vscode/vs/platform/progress/common/progress';
38
- import { IStorageService } from 'vscode/vscode/vs/platform/storage/common/storage';
39
- import { ITelemetryService } from 'vscode/vscode/vs/platform/telemetry/common/telemetry';
40
- import { defaultInputBoxStyles, defaultToggleStyles } from 'vscode/vscode/vs/platform/theme/browser/defaultStyles';
41
- import { IThemeService } from 'vscode/vscode/vs/platform/theme/common/themeService';
42
- import { ThemeIcon } from 'vscode/vscode/vs/base/common/themables';
43
- import { IWorkspaceContextService } from 'vscode/vscode/vs/platform/workspace/common/workspace';
44
- import { OpenFileFolderAction, OpenFolderAction } from 'vscode/vscode/vs/workbench/browser/actions/workspaceActions';
45
- import { ResourceListDnDHandler } from 'vscode/vscode/vs/workbench/browser/dnd';
46
- import { ResourceLabels } from 'vscode/vscode/vs/workbench/browser/labels';
47
- import { ViewPane } from 'vscode/vscode/vs/workbench/browser/parts/views/viewPane';
48
- import { Memento } from 'vscode/vscode/vs/workbench/common/memento';
49
- import { IViewDescriptorService } from 'vscode/vscode/vs/workbench/common/views';
50
- import { NotebookEditor } from 'vscode/vscode/vs/workbench/contrib/notebook/browser/notebookEditor';
51
- import { IncludePatternInputWidget, ExcludePatternInputWidget } from './patternInputWidget.js';
52
- import { appendKeyBindingLabel } from 'vscode/vscode/vs/workbench/contrib/search/browser/searchActionsBase';
53
- import { searchDetailsIcon } from './searchIcons.js';
54
- import { renderSearchMessage } from './searchMessage.js';
55
- import { SearchAccessibilityProvider, SearchDelegate, FolderMatchRenderer, FileMatchRenderer, MatchRenderer } from './searchResultsView.js';
56
- import { SearchWidget } from './searchWidget.js';
57
- import { SearchContext } from 'vscode/vscode/vs/workbench/contrib/search/common/constants';
58
- import { IReplaceService } from 'vscode/vscode/vs/workbench/contrib/search/browser/replace';
59
- import { SearchStateKey, SearchUIState, getOutOfWorkspaceEditorResources } from 'vscode/vscode/vs/workbench/contrib/search/common/search';
60
- import { SearchHistoryService, ISearchHistoryService } from 'vscode/vscode/vs/workbench/contrib/search/common/searchHistoryService';
61
- import { SearchModelLocation, searchMatchComparer, FileMatch, SearchResult, FolderMatch, Match, FolderMatchWithResource, MatchInNotebook, ISearchViewModelWorkbenchService } from 'vscode/vscode/vs/workbench/contrib/search/browser/searchModel';
62
- import { createEditorFromSearchResult } from '../../searchEditor/browser/searchEditorActions.js';
63
- import { SIDE_GROUP, ACTIVE_GROUP, IEditorService } from 'vscode/vscode/vs/workbench/services/editor/common/editorService';
64
- import { IPreferencesService } from 'vscode/vscode/vs/workbench/services/preferences/common/preferences';
65
- import { QueryBuilder } from 'vscode/vscode/vs/workbench/services/search/common/queryBuilder';
66
- import 'vscode/vscode/vs/workbench/services/search/common/search';
67
- import { ITextFileService } from 'vscode/vscode/vs/workbench/services/textfile/common/textfiles';
68
- import { INotebookService } from 'vscode/vscode/vs/workbench/contrib/notebook/common/notebookService';
69
- import { ILogService } from 'vscode/vscode/vs/platform/log/common/log';
70
- import { AccessibilitySignal, IAccessibilitySignalService } from 'vscode/vscode/vs/platform/accessibilitySignal/browser/accessibilitySignalService';
71
- import { TextSearchCompleteMessageType } from 'vscode/vscode/vs/workbench/services/search/common/searchExtTypes';
72
- import { IDialogService } from 'vscode/vscode/vs/platform/dialogs/common/dialogs';
73
-
74
- var SearchView_1;
75
- const $ = $$1;
76
- const SEARCH_CANCELLED_MESSAGE = ( localizeWithPath(
77
- 'vs/workbench/contrib/search/browser/searchView',
78
- 'searchCanceled',
79
- "Search was canceled before any results could be found - "
80
- ));
81
- const DEBOUNCE_DELAY = 75;
82
- let SearchView = class SearchView extends ViewPane {
83
- static { SearchView_1 = this; }
84
- static { this.ACTIONS_RIGHT_CLASS_NAME = 'actions-right'; }
85
- constructor(options, fileService, editorService, codeEditorService, progressService, notificationService, dialogService, commandService, contextViewService, instantiationService, viewDescriptorService, configurationService, contextService, searchViewModelWorkbenchService, contextKeyService, replaceService, textFileService, preferencesService, themeService, searchHistoryService, contextMenuService, accessibilityService, keybindingService, storageService, openerService, telemetryService, notebookService, logService, accessibilitySignalService) {
86
- super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService);
87
- this.fileService = fileService;
88
- this.editorService = editorService;
89
- this.codeEditorService = codeEditorService;
90
- this.progressService = progressService;
91
- this.notificationService = notificationService;
92
- this.dialogService = dialogService;
93
- this.commandService = commandService;
94
- this.contextViewService = contextViewService;
95
- this.contextService = contextService;
96
- this.searchViewModelWorkbenchService = searchViewModelWorkbenchService;
97
- this.replaceService = replaceService;
98
- this.textFileService = textFileService;
99
- this.preferencesService = preferencesService;
100
- this.searchHistoryService = searchHistoryService;
101
- this.accessibilityService = accessibilityService;
102
- this.storageService = storageService;
103
- this.notebookService = notebookService;
104
- this.logService = logService;
105
- this.accessibilitySignalService = accessibilitySignalService;
106
- this.isDisposed = false;
107
- this.lastFocusState = 'input';
108
- this.messageDisposables = ( new DisposableStore());
109
- this.changedWhileHidden = false;
110
- this.currentSearchQ = Promise.resolve();
111
- this.pauseSearching = false;
112
- this._visibleMatches = 0;
113
- this.container = $$1('.search-view');
114
- this.viewletVisible = SearchContext.SearchViewVisibleKey.bindTo(this.contextKeyService);
115
- this.firstMatchFocused = SearchContext.FirstMatchFocusKey.bindTo(this.contextKeyService);
116
- this.fileMatchOrMatchFocused = SearchContext.FileMatchOrMatchFocusKey.bindTo(this.contextKeyService);
117
- this.fileMatchOrFolderMatchFocus = SearchContext.FileMatchOrFolderMatchFocusKey.bindTo(this.contextKeyService);
118
- this.fileMatchOrFolderMatchWithResourceFocus = SearchContext.FileMatchOrFolderMatchWithResourceFocusKey.bindTo(this.contextKeyService);
119
- this.fileMatchFocused = SearchContext.FileFocusKey.bindTo(this.contextKeyService);
120
- this.folderMatchFocused = SearchContext.FolderFocusKey.bindTo(this.contextKeyService);
121
- this.folderMatchWithResourceFocused = SearchContext.ResourceFolderFocusKey.bindTo(this.contextKeyService);
122
- this.hasSearchResultsKey = SearchContext.HasSearchResults.bindTo(this.contextKeyService);
123
- this.matchFocused = SearchContext.MatchFocusKey.bindTo(this.contextKeyService);
124
- this.searchStateKey = SearchStateKey.bindTo(this.contextKeyService);
125
- this.hasSearchPatternKey = SearchContext.ViewHasSearchPatternKey.bindTo(this.contextKeyService);
126
- this.hasReplacePatternKey = SearchContext.ViewHasReplacePatternKey.bindTo(this.contextKeyService);
127
- this.hasFilePatternKey = SearchContext.ViewHasFilePatternKey.bindTo(this.contextKeyService);
128
- this.hasSomeCollapsibleResultKey = SearchContext.ViewHasSomeCollapsibleKey.bindTo(this.contextKeyService);
129
- this.treeViewKey = SearchContext.InTreeViewKey.bindTo(this.contextKeyService);
130
- this.contextKeyService = this._register(this.contextKeyService.createScoped(this.container));
131
- SearchContext.SearchViewFocusedKey.bindTo(this.contextKeyService).set(true);
132
- this.inputBoxFocused = SearchContext.InputBoxFocusedKey.bindTo(this.contextKeyService);
133
- this.inputPatternIncludesFocused = SearchContext.PatternIncludesFocusedKey.bindTo(this.contextKeyService);
134
- this.inputPatternExclusionsFocused = SearchContext.PatternExcludesFocusedKey.bindTo(this.contextKeyService);
135
- this.isEditableItem = SearchContext.IsEditableItemKey.bindTo(this.contextKeyService);
136
- this.instantiationService = this.instantiationService.createChild(( new ServiceCollection([IContextKeyService, this.contextKeyService])));
137
- this.configurationService.onDidChangeConfiguration(e => {
138
- if (e.affectsConfiguration('search.sortOrder')) {
139
- if (this.searchConfig.sortOrder === "modified" ) {
140
- this.removeFileStats();
141
- }
142
- this.refreshTree();
143
- }
144
- });
145
- this.viewModel = this._register(this.searchViewModelWorkbenchService.searchModel);
146
- this.queryBuilder = this.instantiationService.createInstance(QueryBuilder);
147
- this.memento = ( new Memento(this.id, storageService));
148
- this.viewletState = this.memento.getMemento(1 , 1 );
149
- this._register(this.fileService.onDidFilesChange(e => this.onFilesChanged(e)));
150
- this._register(this.textFileService.untitled.onWillDispose(model => this.onUntitledDidDispose(model.resource)));
151
- this._register(this.contextService.onDidChangeWorkbenchState(() => this.onDidChangeWorkbenchState()));
152
- this._register(this.searchHistoryService.onDidClearHistory(() => this.clearHistory()));
153
- this._register(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(e)));
154
- this.delayedRefresh = this._register(( new Delayer(250)));
155
- this.addToSearchHistoryDelayer = this._register(( new Delayer(2000)));
156
- this.toggleCollapseStateDelayer = this._register(( new Delayer(100)));
157
- this.triggerQueryDelayer = this._register(( new Delayer(0)));
158
- this.treeAccessibilityProvider = this.instantiationService.createInstance(SearchAccessibilityProvider, this);
159
- this.isTreeLayoutViewVisible = this.viewletState['view.treeLayout'] ?? ((this.searchConfig.defaultViewMode === "tree") );
160
- this._refreshResultsScheduler = this._register(( new RunOnceScheduler(this._updateResults.bind(this), 80)));
161
- this._register(this.storageService.onWillSaveState(() => {
162
- this._saveSearchHistoryService();
163
- }));
164
- this._register(this.storageService.onDidChangeValue(1 , SearchHistoryService.SEARCH_HISTORY_KEY, this._register(( new DisposableStore())))(() => {
165
- const restoredHistory = this.searchHistoryService.load();
166
- if (restoredHistory.include) {
167
- this.inputPatternIncludes.prependHistory(restoredHistory.include);
168
- }
169
- if (restoredHistory.exclude) {
170
- this.inputPatternExcludes.prependHistory(restoredHistory.exclude);
171
- }
172
- if (restoredHistory.search) {
173
- this.searchWidget.prependSearchHistory(restoredHistory.search);
174
- }
175
- if (restoredHistory.replace) {
176
- this.searchWidget.prependReplaceHistory(restoredHistory.replace);
177
- }
178
- }));
179
- }
180
- get isTreeLayoutViewVisible() {
181
- return this.treeViewKey.get() ?? false;
182
- }
183
- set isTreeLayoutViewVisible(visible) {
184
- this.treeViewKey.set(visible);
185
- }
186
- setTreeView(visible) {
187
- if (visible === this.isTreeLayoutViewVisible) {
188
- return;
189
- }
190
- this.isTreeLayoutViewVisible = visible;
191
- this.updateIndentStyles(this.themeService.getFileIconTheme());
192
- this.refreshTree();
193
- }
194
- get state() {
195
- return this.searchStateKey.get() ?? SearchUIState.Idle;
196
- }
197
- set state(v) {
198
- this.searchStateKey.set(v);
199
- }
200
- getContainer() {
201
- return this.container;
202
- }
203
- get searchResult() {
204
- return this.viewModel && this.viewModel.searchResult;
205
- }
206
- get model() {
207
- return this.viewModel;
208
- }
209
- onDidChangeWorkbenchState() {
210
- if (this.contextService.getWorkbenchState() !== 1 && this.searchWithoutFolderMessageElement) {
211
- hide(this.searchWithoutFolderMessageElement);
212
- }
213
- }
214
- refreshInputs() {
215
- this.pauseSearching = true;
216
- this.searchWidget.setValue(this.viewModel.searchResult.query?.contentPattern.pattern ?? '');
217
- this.searchWidget.setReplaceAllActionState(false);
218
- this.searchWidget.toggleReplace(true);
219
- this.inputPatternIncludes.setOnlySearchInOpenEditors(this.viewModel.searchResult.query?.onlyOpenEditors || false);
220
- this.inputPatternExcludes.setUseExcludesAndIgnoreFiles(!this.viewModel.searchResult.query?.userDisabledExcludesAndIgnoreFiles || true);
221
- this.searchIncludePattern.setValue('');
222
- this.searchExcludePattern.setValue('');
223
- this.pauseSearching = false;
224
- }
225
- async replaceSearchModel(searchModel, asyncResults) {
226
- let progressComplete;
227
- this.progressService.withProgress({ location: this.getProgressLocation(), delay: 0 }, _progress => {
228
- return ( new Promise(resolve => progressComplete = resolve));
229
- });
230
- const slowTimer = setTimeout(() => {
231
- this.state = SearchUIState.SlowSearch;
232
- }, 2000);
233
- this._refreshResultsScheduler.schedule();
234
- searchModel.location = SearchModelLocation.PANEL;
235
- searchModel.replaceActive = this.viewModel.isReplaceActive();
236
- searchModel.replaceString = this.searchWidget.getReplaceValue();
237
- this._onSearchResultChangedDisposable?.dispose();
238
- this._onSearchResultChangedDisposable = this._register(searchModel.onSearchResultChanged((event) => this.onSearchResultsChanged(event)));
239
- this.searchViewModelWorkbenchService.searchModel = searchModel;
240
- this.viewModel = searchModel;
241
- this.onSearchResultsChanged();
242
- this.refreshInputs();
243
- asyncResults.then((complete) => {
244
- clearTimeout(slowTimer);
245
- this.onSearchComplete(progressComplete, undefined, undefined, complete);
246
- }, (e) => {
247
- clearTimeout(slowTimer);
248
- this.onSearchError(e, progressComplete, undefined, undefined);
249
- });
250
- const collapseResults = this.searchConfig.collapseResults;
251
- if (collapseResults !== 'alwaysCollapse' && this.viewModel.searchResult.matches().length === 1) {
252
- const onlyMatch = this.viewModel.searchResult.matches()[0];
253
- if (onlyMatch.count() < 50) {
254
- this.tree.expand(onlyMatch);
255
- }
256
- }
257
- }
258
- renderBody(parent) {
259
- super.renderBody(parent);
260
- this.container = append(parent, $$1('.search-view'));
261
- this.searchWidgetsContainerElement = append(this.container, $('.search-widgets-container'));
262
- this.createSearchWidget(this.searchWidgetsContainerElement);
263
- const history = this.searchHistoryService.load();
264
- const filePatterns = this.viewletState['query.filePatterns'] || '';
265
- const patternExclusions = this.viewletState['query.folderExclusions'] || '';
266
- const patternExclusionsHistory = history.exclude || [];
267
- const patternIncludes = this.viewletState['query.folderIncludes'] || '';
268
- const patternIncludesHistory = history.include || [];
269
- const onlyOpenEditors = this.viewletState['query.onlyOpenEditors'] || false;
270
- const queryDetailsExpanded = this.viewletState['query.queryDetailsExpanded'] || '';
271
- const useExcludesAndIgnoreFiles = typeof this.viewletState['query.useExcludesAndIgnoreFiles'] === 'boolean' ?
272
- this.viewletState['query.useExcludesAndIgnoreFiles'] : true;
273
- this.queryDetails = append(this.searchWidgetsContainerElement, $('.query-details'));
274
- this.toggleQueryDetailsButton = append(this.queryDetails, $('.more' + ThemeIcon.asCSSSelector(searchDetailsIcon), { tabindex: 0, role: 'button', title: ( localizeWithPath(
275
- 'vs/workbench/contrib/search/browser/searchView',
276
- 'moreSearch',
277
- "Toggle Search Details"
278
- )) }));
279
- this._register(addDisposableListener(this.toggleQueryDetailsButton, EventType.CLICK, e => {
280
- EventHelper.stop(e);
281
- this.toggleQueryDetails(!this.accessibilityService.isScreenReaderOptimized());
282
- }));
283
- this._register(addDisposableListener(this.toggleQueryDetailsButton, EventType.KEY_UP, (e) => {
284
- const event = ( new StandardKeyboardEvent(e));
285
- if (event.equals(3 ) || event.equals(10 )) {
286
- EventHelper.stop(e);
287
- this.toggleQueryDetails(false);
288
- }
289
- }));
290
- this._register(addDisposableListener(this.toggleQueryDetailsButton, EventType.KEY_DOWN, (e) => {
291
- const event = ( new StandardKeyboardEvent(e));
292
- if (event.equals(1024 | 2 )) {
293
- if (this.searchWidget.isReplaceActive()) {
294
- this.searchWidget.focusReplaceAllAction();
295
- }
296
- else {
297
- this.searchWidget.isReplaceShown() ? this.searchWidget.replaceInput?.focusOnPreserve() : this.searchWidget.focusRegexAction();
298
- }
299
- EventHelper.stop(e);
300
- }
301
- }));
302
- const folderIncludesList = append(this.queryDetails, $('.file-types.includes'));
303
- const filesToIncludeTitle = ( localizeWithPath(
304
- 'vs/workbench/contrib/search/browser/searchView',
305
- 'searchScope.includes',
306
- "files to include"
307
- ));
308
- append(folderIncludesList, $('h4', undefined, filesToIncludeTitle));
309
- this.inputPatternIncludes = this._register(this.instantiationService.createInstance(IncludePatternInputWidget, folderIncludesList, this.contextViewService, {
310
- ariaLabel: filesToIncludeTitle,
311
- placeholder: ( localizeWithPath(
312
- 'vs/workbench/contrib/search/browser/searchView',
313
- 'placeholder.includes',
314
- "e.g. *.ts, src/**/include"
315
- )),
316
- showPlaceholderOnFocus: true,
317
- history: patternIncludesHistory,
318
- inputBoxStyles: defaultInputBoxStyles
319
- }));
320
- this.inputPatternIncludes.setValue(patternIncludes);
321
- this.inputPatternIncludes.setOnlySearchInOpenEditors(onlyOpenEditors);
322
- this._register(this.inputPatternIncludes.onCancel(() => this.cancelSearch(false)));
323
- this._register(this.inputPatternIncludes.onChangeSearchInEditorsBox(() => this.triggerQueryChange()));
324
- this.trackInputBox(this.inputPatternIncludes.inputFocusTracker, this.inputPatternIncludesFocused);
325
- const excludesList = append(this.queryDetails, $('.file-types.excludes'));
326
- const excludesTitle = ( localizeWithPath(
327
- 'vs/workbench/contrib/search/browser/searchView',
328
- 'searchScope.excludes',
329
- "files to exclude"
330
- ));
331
- append(excludesList, $('h4', undefined, excludesTitle));
332
- this.inputPatternExcludes = this._register(this.instantiationService.createInstance(ExcludePatternInputWidget, excludesList, this.contextViewService, {
333
- ariaLabel: excludesTitle,
334
- placeholder: ( localizeWithPath(
335
- 'vs/workbench/contrib/search/browser/searchView',
336
- 'placeholder.excludes',
337
- "e.g. *.ts, src/**/exclude"
338
- )),
339
- showPlaceholderOnFocus: true,
340
- history: patternExclusionsHistory,
341
- inputBoxStyles: defaultInputBoxStyles
342
- }));
343
- this.inputPatternExcludes.setValue(patternExclusions);
344
- this.inputPatternExcludes.setUseExcludesAndIgnoreFiles(useExcludesAndIgnoreFiles);
345
- this._register(this.inputPatternExcludes.onCancel(() => this.cancelSearch(false)));
346
- this._register(this.inputPatternExcludes.onChangeIgnoreBox(() => this.triggerQueryChange()));
347
- this.trackInputBox(this.inputPatternExcludes.inputFocusTracker, this.inputPatternExclusionsFocused);
348
- const updateHasFilePatternKey = () => this.hasFilePatternKey.set(this.inputPatternIncludes.getValue().length > 0 || this.inputPatternExcludes.getValue().length > 0);
349
- updateHasFilePatternKey();
350
- const onFilePatternSubmit = (triggeredOnType) => {
351
- this.triggerQueryChange({ triggeredOnType, delay: this.searchConfig.searchOnTypeDebouncePeriod });
352
- if (triggeredOnType) {
353
- updateHasFilePatternKey();
354
- }
355
- };
356
- this._register(this.inputPatternIncludes.onSubmit(onFilePatternSubmit));
357
- this._register(this.inputPatternExcludes.onSubmit(onFilePatternSubmit));
358
- this.messagesElement = append(this.container, $('.messages.text-search-provider-messages'));
359
- if (this.contextService.getWorkbenchState() === 1 ) {
360
- this.showSearchWithoutFolderMessage();
361
- }
362
- this.createSearchResultsView(this.container);
363
- if (filePatterns !== '' || patternExclusions !== '' || patternIncludes !== '' || queryDetailsExpanded !== '' || !useExcludesAndIgnoreFiles) {
364
- this.toggleQueryDetails(true, true, true);
365
- }
366
- this._onSearchResultChangedDisposable = this._register(this.viewModel.onSearchResultChanged((event) => this.onSearchResultsChanged(event)));
367
- this._register(this.onDidChangeBodyVisibility(visible => this.onVisibilityChanged(visible)));
368
- this.updateIndentStyles(this.themeService.getFileIconTheme());
369
- this._register(this.themeService.onDidFileIconThemeChange(this.updateIndentStyles, this));
370
- }
371
- updateIndentStyles(theme) {
372
- this.resultsElement.classList.toggle('hide-arrows', this.isTreeLayoutViewVisible && theme.hidesExplorerArrows);
373
- }
374
- onVisibilityChanged(visible) {
375
- this.viewletVisible.set(visible);
376
- if (visible) {
377
- if (this.changedWhileHidden) {
378
- this.refreshAndUpdateCount();
379
- this.changedWhileHidden = false;
380
- }
381
- }
382
- else {
383
- this.lastFocusState = 'input';
384
- }
385
- this.viewModel?.searchResult.toggleHighlights(visible);
386
- }
387
- get searchAndReplaceWidget() {
388
- return this.searchWidget;
389
- }
390
- get searchIncludePattern() {
391
- return this.inputPatternIncludes;
392
- }
393
- get searchExcludePattern() {
394
- return this.inputPatternExcludes;
395
- }
396
- createSearchWidget(container) {
397
- const contentPattern = this.viewletState['query.contentPattern'] || '';
398
- const replaceText = this.viewletState['query.replaceText'] || '';
399
- const isRegex = this.viewletState['query.regex'] === true;
400
- const isWholeWords = this.viewletState['query.wholeWords'] === true;
401
- const isCaseSensitive = this.viewletState['query.caseSensitive'] === true;
402
- const history = this.searchHistoryService.load();
403
- const searchHistory = history.search || this.viewletState['query.searchHistory'] || [];
404
- const replaceHistory = history.replace || this.viewletState['query.replaceHistory'] || [];
405
- const showReplace = typeof this.viewletState['view.showReplace'] === 'boolean' ? this.viewletState['view.showReplace'] : true;
406
- const preserveCase = this.viewletState['query.preserveCase'] === true;
407
- const isInNotebookMarkdownInput = this.viewletState['query.isInNotebookMarkdownInput'] ?? true;
408
- const isInNotebookMarkdownPreview = this.viewletState['query.isInNotebookMarkdownPreview'] ?? true;
409
- const isInNotebookCellInput = this.viewletState['query.isInNotebookCellInput'] ?? true;
410
- const isInNotebookCellOutput = this.viewletState['query.isInNotebookCellOutput'] ?? true;
411
- this.searchWidget = this._register(this.instantiationService.createInstance(SearchWidget, container, {
412
- value: contentPattern,
413
- replaceValue: replaceText,
414
- isRegex: isRegex,
415
- isCaseSensitive: isCaseSensitive,
416
- isWholeWords: isWholeWords,
417
- searchHistory: searchHistory,
418
- replaceHistory: replaceHistory,
419
- preserveCase: preserveCase,
420
- inputBoxStyles: defaultInputBoxStyles,
421
- toggleStyles: defaultToggleStyles,
422
- notebookOptions: {
423
- isInNotebookMarkdownInput,
424
- isInNotebookMarkdownPreview,
425
- isInNotebookCellInput,
426
- isInNotebookCellOutput,
427
- }
428
- }));
429
- if (!this.searchWidget.searchInput || !this.searchWidget.replaceInput) {
430
- this.logService.warn(`Cannot fully create search widget. Search or replace input undefined. SearchInput: ${this.searchWidget.searchInput}, ReplaceInput: ${this.searchWidget.replaceInput}`);
431
- return;
432
- }
433
- if (showReplace) {
434
- this.searchWidget.toggleReplace(true);
435
- }
436
- this._register(this.searchWidget.onSearchSubmit(options => this.triggerQueryChange(options)));
437
- this._register(this.searchWidget.onSearchCancel(({ focus }) => this.cancelSearch(focus)));
438
- this._register(this.searchWidget.searchInput.onDidOptionChange(() => this.triggerQueryChange()));
439
- this._register(this.searchWidget.getNotebookFilters().onDidChange(() => this.triggerQueryChange()));
440
- const updateHasPatternKey = () => this.hasSearchPatternKey.set(this.searchWidget.searchInput ? (this.searchWidget.searchInput.getValue().length > 0) : false);
441
- updateHasPatternKey();
442
- this._register(this.searchWidget.searchInput.onDidChange(() => updateHasPatternKey()));
443
- const updateHasReplacePatternKey = () => this.hasReplacePatternKey.set(this.searchWidget.getReplaceValue().length > 0);
444
- updateHasReplacePatternKey();
445
- this._register(this.searchWidget.replaceInput.inputBox.onDidChange(() => updateHasReplacePatternKey()));
446
- this._register(this.searchWidget.onDidHeightChange(() => this.reLayout()));
447
- this._register(this.searchWidget.onReplaceToggled(() => this.reLayout()));
448
- this._register(this.searchWidget.onReplaceStateChange((state) => {
449
- this.viewModel.replaceActive = state;
450
- this.refreshTree();
451
- }));
452
- this._register(this.searchWidget.onPreserveCaseChange((state) => {
453
- this.viewModel.preserveCase = state;
454
- this.refreshTree();
455
- }));
456
- this._register(this.searchWidget.onReplaceValueChanged(() => {
457
- this.viewModel.replaceString = this.searchWidget.getReplaceValue();
458
- this.delayedRefresh.trigger(() => this.refreshTree());
459
- }));
460
- this._register(this.searchWidget.onBlur(() => {
461
- this.toggleQueryDetailsButton.focus();
462
- }));
463
- this._register(this.searchWidget.onReplaceAll(() => this.replaceAll()));
464
- this.trackInputBox(this.searchWidget.searchInputFocusTracker);
465
- this.trackInputBox(this.searchWidget.replaceInputFocusTracker);
466
- }
467
- onConfigurationUpdated(event) {
468
- if (event && (event.affectsConfiguration('search.decorations.colors') || event.affectsConfiguration('search.decorations.badges'))) {
469
- this.refreshTree();
470
- }
471
- }
472
- trackInputBox(inputFocusTracker, contextKey) {
473
- if (!inputFocusTracker) {
474
- return;
475
- }
476
- this._register(inputFocusTracker.onDidFocus(() => {
477
- this.lastFocusState = 'input';
478
- this.inputBoxFocused.set(true);
479
- contextKey?.set(true);
480
- }));
481
- this._register(inputFocusTracker.onDidBlur(() => {
482
- this.inputBoxFocused.set(this.searchWidget.searchInputHasFocus()
483
- || this.searchWidget.replaceInputHasFocus()
484
- || this.inputPatternIncludes.inputHasFocus()
485
- || this.inputPatternExcludes.inputHasFocus());
486
- contextKey?.set(false);
487
- }));
488
- }
489
- onSearchResultsChanged(event) {
490
- if (this.isVisible()) {
491
- return this.refreshAndUpdateCount(event);
492
- }
493
- else {
494
- this.changedWhileHidden = true;
495
- }
496
- }
497
- refreshAndUpdateCount(event) {
498
- this.searchWidget.setReplaceAllActionState(!this.viewModel.searchResult.isEmpty());
499
- this.updateSearchResultCount(this.viewModel.searchResult.query.userDisabledExcludesAndIgnoreFiles, this.viewModel.searchResult.query?.onlyOpenEditors, event?.clearingAll);
500
- return this.refreshTree(event);
501
- }
502
- refreshTree(event) {
503
- const collapseResults = this.searchConfig.collapseResults;
504
- if (!event || event.added || event.removed) {
505
- if (this.searchConfig.sortOrder === "modified" ) {
506
- this.retrieveFileStats()
507
- .then(() => this.tree.setChildren(null, this.createResultIterator(collapseResults)));
508
- }
509
- else {
510
- this.tree.setChildren(null, this.createResultIterator(collapseResults));
511
- }
512
- }
513
- else {
514
- if (this.searchConfig.sortOrder === "countAscending" ||
515
- this.searchConfig.sortOrder === "countDescending" ) {
516
- this.tree.setChildren(null, this.createResultIterator(collapseResults));
517
- }
518
- else {
519
- event.elements.forEach(element => {
520
- this.tree.setChildren(element, this.createIterator(element, collapseResults));
521
- this.tree.rerender(element);
522
- });
523
- }
524
- }
525
- }
526
- createResultIterator(collapseResults) {
527
- const folderMatches = this.searchResult.folderMatches()
528
- .filter(fm => !fm.isEmpty())
529
- .sort(searchMatchComparer);
530
- if (folderMatches.length === 1) {
531
- return this.createFolderIterator(folderMatches[0], collapseResults, true);
532
- }
533
- return ( Iterable.map(folderMatches, folderMatch => {
534
- const children = this.createFolderIterator(folderMatch, collapseResults, true);
535
- return { element: folderMatch, children, incompressible: true };
536
- }));
537
- }
538
- createFolderIterator(folderMatch, collapseResults, childFolderIncompressible) {
539
- const sortOrder = this.searchConfig.sortOrder;
540
- const matchArray = this.isTreeLayoutViewVisible ? folderMatch.matches() : folderMatch.allDownstreamFileMatches();
541
- const matches = matchArray.sort((a, b) => searchMatchComparer(a, b, sortOrder));
542
- return ( Iterable.map(matches, match => {
543
- let children;
544
- if (match instanceof FileMatch) {
545
- children = this.createFileIterator(match);
546
- }
547
- else {
548
- children = this.createFolderIterator(match, collapseResults, false);
549
- }
550
- const collapsed = (collapseResults === 'alwaysCollapse' || (match.count() > 10 && collapseResults !== 'alwaysExpand')) ? ObjectTreeElementCollapseState.PreserveOrCollapsed : ObjectTreeElementCollapseState.PreserveOrExpanded;
551
- return { element: match, children, collapsed, incompressible: (match instanceof FileMatch) ? true : childFolderIncompressible };
552
- }));
553
- }
554
- createFileIterator(fileMatch) {
555
- const matches = fileMatch.matches().sort(searchMatchComparer);
556
- return ( Iterable.map(matches, r => ({ element: r, incompressible: true })));
557
- }
558
- createIterator(match, collapseResults) {
559
- return match instanceof SearchResult ? this.createResultIterator(collapseResults) :
560
- match instanceof FolderMatch ? this.createFolderIterator(match, collapseResults, false) :
561
- this.createFileIterator(match);
562
- }
563
- replaceAll() {
564
- if (this.viewModel.searchResult.count() === 0) {
565
- return;
566
- }
567
- const occurrences = this.viewModel.searchResult.count();
568
- const fileCount = this.viewModel.searchResult.fileCount();
569
- const replaceValue = this.searchWidget.getReplaceValue() || '';
570
- const afterReplaceAllMessage = this.buildAfterReplaceAllMessage(occurrences, fileCount, replaceValue);
571
- let progressComplete;
572
- let progressReporter;
573
- this.progressService.withProgress({ location: this.getProgressLocation(), delay: 100, total: occurrences }, p => {
574
- progressReporter = p;
575
- return ( new Promise(resolve => progressComplete = resolve));
576
- });
577
- const confirmation = {
578
- title: ( localizeWithPath(
579
- 'vs/workbench/contrib/search/browser/searchView',
580
- 'replaceAll.confirmation.title',
581
- "Replace All"
582
- )),
583
- message: this.buildReplaceAllConfirmationMessage(occurrences, fileCount, replaceValue),
584
- primaryButton: ( localizeWithPath(
585
- 'vs/workbench/contrib/search/browser/searchView',
586
- { key: 'replaceAll.confirm.button', comment: ['&& denotes a mnemonic'] },
587
- "&&Replace"
588
- ))
589
- };
590
- this.dialogService.confirm(confirmation).then(res => {
591
- if (res.confirmed) {
592
- this.searchWidget.setReplaceAllActionState(false);
593
- this.viewModel.searchResult.replaceAll(progressReporter).then(() => {
594
- progressComplete();
595
- const messageEl = this.clearMessage();
596
- append(messageEl, afterReplaceAllMessage);
597
- this.reLayout();
598
- }, (error) => {
599
- progressComplete();
600
- this.notificationService.error(error);
601
- });
602
- }
603
- else {
604
- progressComplete();
605
- }
606
- });
607
- }
608
- buildAfterReplaceAllMessage(occurrences, fileCount, replaceValue) {
609
- if (occurrences === 1) {
610
- if (fileCount === 1) {
611
- if (replaceValue) {
612
- return ( localizeWithPath(
613
- 'vs/workbench/contrib/search/browser/searchView',
614
- 'replaceAll.occurrence.file.message',
615
- "Replaced {0} occurrence across {1} file with '{2}'.",
616
- occurrences,
617
- fileCount,
618
- replaceValue
619
- ));
620
- }
621
- return ( localizeWithPath(
622
- 'vs/workbench/contrib/search/browser/searchView',
623
- 'removeAll.occurrence.file.message',
624
- "Replaced {0} occurrence across {1} file.",
625
- occurrences,
626
- fileCount
627
- ));
628
- }
629
- if (replaceValue) {
630
- return ( localizeWithPath(
631
- 'vs/workbench/contrib/search/browser/searchView',
632
- 'replaceAll.occurrence.files.message',
633
- "Replaced {0} occurrence across {1} files with '{2}'.",
634
- occurrences,
635
- fileCount,
636
- replaceValue
637
- ));
638
- }
639
- return ( localizeWithPath(
640
- 'vs/workbench/contrib/search/browser/searchView',
641
- 'removeAll.occurrence.files.message',
642
- "Replaced {0} occurrence across {1} files.",
643
- occurrences,
644
- fileCount
645
- ));
646
- }
647
- if (fileCount === 1) {
648
- if (replaceValue) {
649
- return ( localizeWithPath(
650
- 'vs/workbench/contrib/search/browser/searchView',
651
- 'replaceAll.occurrences.file.message',
652
- "Replaced {0} occurrences across {1} file with '{2}'.",
653
- occurrences,
654
- fileCount,
655
- replaceValue
656
- ));
657
- }
658
- return ( localizeWithPath(
659
- 'vs/workbench/contrib/search/browser/searchView',
660
- 'removeAll.occurrences.file.message',
661
- "Replaced {0} occurrences across {1} file.",
662
- occurrences,
663
- fileCount
664
- ));
665
- }
666
- if (replaceValue) {
667
- return ( localizeWithPath(
668
- 'vs/workbench/contrib/search/browser/searchView',
669
- 'replaceAll.occurrences.files.message',
670
- "Replaced {0} occurrences across {1} files with '{2}'.",
671
- occurrences,
672
- fileCount,
673
- replaceValue
674
- ));
675
- }
676
- return ( localizeWithPath(
677
- 'vs/workbench/contrib/search/browser/searchView',
678
- 'removeAll.occurrences.files.message',
679
- "Replaced {0} occurrences across {1} files.",
680
- occurrences,
681
- fileCount
682
- ));
683
- }
684
- buildReplaceAllConfirmationMessage(occurrences, fileCount, replaceValue) {
685
- if (occurrences === 1) {
686
- if (fileCount === 1) {
687
- if (replaceValue) {
688
- return ( localizeWithPath(
689
- 'vs/workbench/contrib/search/browser/searchView',
690
- 'removeAll.occurrence.file.confirmation.message',
691
- "Replace {0} occurrence across {1} file with '{2}'?",
692
- occurrences,
693
- fileCount,
694
- replaceValue
695
- ));
696
- }
697
- return ( localizeWithPath(
698
- 'vs/workbench/contrib/search/browser/searchView',
699
- 'replaceAll.occurrence.file.confirmation.message',
700
- "Replace {0} occurrence across {1} file?",
701
- occurrences,
702
- fileCount
703
- ));
704
- }
705
- if (replaceValue) {
706
- return ( localizeWithPath(
707
- 'vs/workbench/contrib/search/browser/searchView',
708
- 'removeAll.occurrence.files.confirmation.message',
709
- "Replace {0} occurrence across {1} files with '{2}'?",
710
- occurrences,
711
- fileCount,
712
- replaceValue
713
- ));
714
- }
715
- return ( localizeWithPath(
716
- 'vs/workbench/contrib/search/browser/searchView',
717
- 'replaceAll.occurrence.files.confirmation.message',
718
- "Replace {0} occurrence across {1} files?",
719
- occurrences,
720
- fileCount
721
- ));
722
- }
723
- if (fileCount === 1) {
724
- if (replaceValue) {
725
- return ( localizeWithPath(
726
- 'vs/workbench/contrib/search/browser/searchView',
727
- 'removeAll.occurrences.file.confirmation.message',
728
- "Replace {0} occurrences across {1} file with '{2}'?",
729
- occurrences,
730
- fileCount,
731
- replaceValue
732
- ));
733
- }
734
- return ( localizeWithPath(
735
- 'vs/workbench/contrib/search/browser/searchView',
736
- 'replaceAll.occurrences.file.confirmation.message',
737
- "Replace {0} occurrences across {1} file?",
738
- occurrences,
739
- fileCount
740
- ));
741
- }
742
- if (replaceValue) {
743
- return ( localizeWithPath(
744
- 'vs/workbench/contrib/search/browser/searchView',
745
- 'removeAll.occurrences.files.confirmation.message',
746
- "Replace {0} occurrences across {1} files with '{2}'?",
747
- occurrences,
748
- fileCount,
749
- replaceValue
750
- ));
751
- }
752
- return ( localizeWithPath(
753
- 'vs/workbench/contrib/search/browser/searchView',
754
- 'replaceAll.occurrences.files.confirmation.message',
755
- "Replace {0} occurrences across {1} files?",
756
- occurrences,
757
- fileCount
758
- ));
759
- }
760
- clearMessage() {
761
- this.searchWithoutFolderMessageElement = undefined;
762
- const wasHidden = this.messagesElement.style.display === 'none';
763
- clearNode(this.messagesElement);
764
- show(this.messagesElement);
765
- this.messageDisposables.clear();
766
- const newMessage = append(this.messagesElement, $('.message'));
767
- if (wasHidden) {
768
- this.reLayout();
769
- }
770
- return newMessage;
771
- }
772
- createSearchResultsView(container) {
773
- this.resultsElement = append(container, $('.results.show-file-icons.file-icon-themable-tree'));
774
- const delegate = this.instantiationService.createInstance(SearchDelegate);
775
- const identityProvider = {
776
- getId(element) {
777
- return element.id();
778
- }
779
- };
780
- this.treeLabels = this._register(this.instantiationService.createInstance(ResourceLabels, { onDidChangeVisibility: this.onDidChangeBodyVisibility }));
781
- this.tree = this._register(this.instantiationService.createInstance(WorkbenchCompressibleObjectTree, 'SearchView', this.resultsElement, delegate, [
782
- this._register(this.instantiationService.createInstance(FolderMatchRenderer, this, this.treeLabels)),
783
- this._register(this.instantiationService.createInstance(FileMatchRenderer, this, this.treeLabels)),
784
- this._register(this.instantiationService.createInstance(MatchRenderer, this)),
785
- ], {
786
- identityProvider,
787
- accessibilityProvider: this.treeAccessibilityProvider,
788
- dnd: this.instantiationService.createInstance(ResourceListDnDHandler, element => {
789
- if (element instanceof FileMatch) {
790
- return element.resource;
791
- }
792
- if (element instanceof Match) {
793
- return withSelection(element.parent().resource, element.range());
794
- }
795
- return null;
796
- }),
797
- multipleSelectionSupport: true,
798
- selectionNavigation: true,
799
- overrideStyles: {
800
- listBackground: this.getBackgroundColor()
801
- },
802
- paddingBottom: SearchDelegate.ITEM_HEIGHT
803
- }));
804
- this._register(this.tree.onContextMenu(e => this.onContextMenu(e)));
805
- const updateHasSomeCollapsible = () => this.toggleCollapseStateDelayer.trigger(() => this.hasSomeCollapsibleResultKey.set(this.hasSomeCollapsible()));
806
- updateHasSomeCollapsible();
807
- this._register(this.tree.onDidChangeCollapseState(() => updateHasSomeCollapsible()));
808
- this._register(this.tree.onDidChangeModel(() => updateHasSomeCollapsible()));
809
- this._register(Event.debounce(this.tree.onDidOpen, (last, event) => event, DEBOUNCE_DELAY, true)(options => {
810
- if (options.element instanceof Match) {
811
- const selectedMatch = options.element;
812
- this.currentSelectedFileMatch?.setSelectedMatch(null);
813
- this.currentSelectedFileMatch = selectedMatch.parent();
814
- this.currentSelectedFileMatch.setSelectedMatch(selectedMatch);
815
- this.onFocus(selectedMatch, options.editorOptions.preserveFocus, options.sideBySide, options.editorOptions.pinned);
816
- }
817
- }));
818
- this._register(Event.debounce(this.tree.onDidChangeFocus, (last, event) => event, DEBOUNCE_DELAY, true)(() => {
819
- const selection = this.tree.getSelection();
820
- const focus = this.tree.getFocus()[0];
821
- if (selection.length > 1 && focus instanceof Match) {
822
- this.onFocus(focus, true);
823
- }
824
- }));
825
- this._register(Event.any(this.tree.onDidFocus, this.tree.onDidChangeFocus)(() => {
826
- const focus = this.tree.getFocus()[0];
827
- if (this.tree.isDOMFocused()) {
828
- this.firstMatchFocused.set(this.tree.navigate().first() === focus);
829
- this.fileMatchOrMatchFocused.set(!!focus);
830
- this.fileMatchFocused.set(focus instanceof FileMatch);
831
- this.folderMatchFocused.set(focus instanceof FolderMatch);
832
- this.matchFocused.set(focus instanceof Match);
833
- this.fileMatchOrFolderMatchFocus.set(focus instanceof FileMatch || focus instanceof FolderMatch);
834
- this.fileMatchOrFolderMatchWithResourceFocus.set(focus instanceof FileMatch || focus instanceof FolderMatchWithResource);
835
- this.folderMatchWithResourceFocused.set(focus instanceof FolderMatchWithResource);
836
- this.lastFocusState = 'tree';
837
- }
838
- let editable = false;
839
- if (focus instanceof Match) {
840
- editable = (focus instanceof MatchInNotebook) ? !focus.isReadonly() : true;
841
- }
842
- else if (focus instanceof FileMatch) {
843
- editable = !focus.hasOnlyReadOnlyMatches();
844
- }
845
- else if (focus instanceof FolderMatch) {
846
- editable = !focus.hasOnlyReadOnlyMatches();
847
- }
848
- this.isEditableItem.set(editable);
849
- }));
850
- this._register(this.tree.onDidBlur(() => {
851
- this.firstMatchFocused.reset();
852
- this.fileMatchOrMatchFocused.reset();
853
- this.fileMatchFocused.reset();
854
- this.folderMatchFocused.reset();
855
- this.matchFocused.reset();
856
- this.fileMatchOrFolderMatchFocus.reset();
857
- this.fileMatchOrFolderMatchWithResourceFocus.reset();
858
- this.folderMatchWithResourceFocused.reset();
859
- this.isEditableItem.reset();
860
- }));
861
- }
862
- onContextMenu(e) {
863
- e.browserEvent.preventDefault();
864
- e.browserEvent.stopPropagation();
865
- this.contextMenuService.showContextMenu({
866
- menuId: MenuId.SearchContext,
867
- menuActionOptions: { shouldForwardArgs: true },
868
- contextKeyService: this.contextKeyService,
869
- getAnchor: () => e.anchor,
870
- getActionsContext: () => e.element,
871
- });
872
- }
873
- hasSomeCollapsible() {
874
- const viewer = this.getControl();
875
- const navigator = viewer.navigate();
876
- let node = navigator.first();
877
- do {
878
- if (!viewer.isCollapsed(node)) {
879
- return true;
880
- }
881
- } while (node = navigator.next());
882
- return false;
883
- }
884
- selectNextMatch() {
885
- if (!this.hasSearchResults()) {
886
- return;
887
- }
888
- const [selected] = this.tree.getSelection();
889
- if (selected && !(selected instanceof Match)) {
890
- if (this.tree.isCollapsed(selected)) {
891
- this.tree.expand(selected);
892
- }
893
- }
894
- const navigator = this.tree.navigate(selected);
895
- let next = navigator.next();
896
- if (!next) {
897
- next = navigator.first();
898
- }
899
- while (next && !(next instanceof Match)) {
900
- if (this.tree.isCollapsed(next)) {
901
- this.tree.expand(next);
902
- }
903
- next = navigator.next();
904
- }
905
- if (next) {
906
- if (next === selected) {
907
- this.tree.setFocus([]);
908
- }
909
- const event = getSelectionKeyboardEvent(undefined, false, false);
910
- this.tree.setFocus([next], event);
911
- this.tree.setSelection([next], event);
912
- this.tree.reveal(next);
913
- const ariaLabel = this.treeAccessibilityProvider.getAriaLabel(next);
914
- if (ariaLabel) {
915
- status(ariaLabel);
916
- }
917
- }
918
- }
919
- selectPreviousMatch() {
920
- if (!this.hasSearchResults()) {
921
- return;
922
- }
923
- const [selected] = this.tree.getSelection();
924
- let navigator = this.tree.navigate(selected);
925
- let prev = navigator.previous();
926
- while (!prev || (!(prev instanceof Match) && !this.tree.isCollapsed(prev))) {
927
- const nextPrev = prev ? navigator.previous() : navigator.last();
928
- if (!prev && !nextPrev) {
929
- return;
930
- }
931
- prev = nextPrev;
932
- }
933
- while (!(prev instanceof Match)) {
934
- const nextItem = navigator.next();
935
- this.tree.expand(prev);
936
- navigator = this.tree.navigate(nextItem);
937
- prev = nextItem ? navigator.previous() : navigator.last();
938
- }
939
- if (prev) {
940
- if (prev === selected) {
941
- this.tree.setFocus([]);
942
- }
943
- const event = getSelectionKeyboardEvent(undefined, false, false);
944
- this.tree.setFocus([prev], event);
945
- this.tree.setSelection([prev], event);
946
- this.tree.reveal(prev);
947
- const ariaLabel = this.treeAccessibilityProvider.getAriaLabel(prev);
948
- if (ariaLabel) {
949
- status(ariaLabel);
950
- }
951
- }
952
- }
953
- moveFocusToResults() {
954
- this.tree.domFocus();
955
- }
956
- focus() {
957
- super.focus();
958
- if (this.lastFocusState === 'input' || !this.hasSearchResults()) {
959
- const updatedText = this.searchConfig.seedOnFocus ? this.updateTextFromSelection({ allowSearchOnType: false }) : false;
960
- this.searchWidget.focus(undefined, undefined, updatedText);
961
- }
962
- else {
963
- this.tree.domFocus();
964
- }
965
- }
966
- updateTextFromFindWidgetOrSelection({ allowUnselectedWord = true, allowSearchOnType = true }) {
967
- let activeEditor = this.editorService.activeTextEditorControl;
968
- if (isCodeEditor(activeEditor) && !activeEditor?.hasTextFocus()) {
969
- const controller = CommonFindController.get(activeEditor);
970
- if (controller && controller.isFindInputFocused()) {
971
- return this.updateTextFromFindWidget(controller, { allowSearchOnType });
972
- }
973
- const editors = this.codeEditorService.listCodeEditors();
974
- activeEditor = editors.find(editor => editor instanceof EmbeddedCodeEditorWidget && editor.getParentEditor() === activeEditor && editor.hasTextFocus())
975
- ?? activeEditor;
976
- }
977
- return this.updateTextFromSelection({ allowUnselectedWord, allowSearchOnType }, activeEditor);
978
- }
979
- updateTextFromFindWidget(controller, { allowSearchOnType = true }) {
980
- if (!this.searchConfig.seedWithNearestWord && (getActiveWindow().getSelection()?.toString() ?? '') === '') {
981
- return false;
982
- }
983
- const searchString = controller.getState().searchString;
984
- if (searchString === '') {
985
- return false;
986
- }
987
- this.searchWidget.searchInput?.setCaseSensitive(controller.getState().matchCase);
988
- this.searchWidget.searchInput?.setWholeWords(controller.getState().wholeWord);
989
- this.searchWidget.searchInput?.setRegex(controller.getState().isRegex);
990
- this.updateText(searchString, allowSearchOnType);
991
- return true;
992
- }
993
- updateTextFromSelection({ allowUnselectedWord = true, allowSearchOnType = true }, editor) {
994
- const seedSearchStringFromSelection = this.configurationService.getValue('editor').find.seedSearchStringFromSelection;
995
- if (!seedSearchStringFromSelection || seedSearchStringFromSelection === 'never') {
996
- return false;
997
- }
998
- let selectedText = this.getSearchTextFromEditor(allowUnselectedWord, editor);
999
- if (selectedText === null) {
1000
- return false;
1001
- }
1002
- if (this.searchWidget.searchInput?.getRegex()) {
1003
- selectedText = escapeRegExpCharacters(selectedText);
1004
- }
1005
- this.updateText(selectedText, allowSearchOnType);
1006
- return true;
1007
- }
1008
- updateText(text, allowSearchOnType = true) {
1009
- if (allowSearchOnType && !this.viewModel.searchResult.isDirty) {
1010
- this.searchWidget.setValue(text);
1011
- }
1012
- else {
1013
- this.pauseSearching = true;
1014
- this.searchWidget.setValue(text);
1015
- this.pauseSearching = false;
1016
- }
1017
- }
1018
- focusNextInputBox() {
1019
- if (this.searchWidget.searchInputHasFocus()) {
1020
- if (this.searchWidget.isReplaceShown()) {
1021
- this.searchWidget.focus(true, true);
1022
- }
1023
- else {
1024
- this.moveFocusFromSearchOrReplace();
1025
- }
1026
- return;
1027
- }
1028
- if (this.searchWidget.replaceInputHasFocus()) {
1029
- this.moveFocusFromSearchOrReplace();
1030
- return;
1031
- }
1032
- if (this.inputPatternIncludes.inputHasFocus()) {
1033
- this.inputPatternExcludes.focus();
1034
- this.inputPatternExcludes.select();
1035
- return;
1036
- }
1037
- if (this.inputPatternExcludes.inputHasFocus()) {
1038
- this.selectTreeIfNotSelected();
1039
- return;
1040
- }
1041
- }
1042
- moveFocusFromSearchOrReplace() {
1043
- if (this.showsFileTypes()) {
1044
- this.toggleQueryDetails(true, this.showsFileTypes());
1045
- }
1046
- else {
1047
- this.selectTreeIfNotSelected();
1048
- }
1049
- }
1050
- focusPreviousInputBox() {
1051
- if (this.searchWidget.searchInputHasFocus()) {
1052
- return;
1053
- }
1054
- if (this.searchWidget.replaceInputHasFocus()) {
1055
- this.searchWidget.focus(true);
1056
- return;
1057
- }
1058
- if (this.inputPatternIncludes.inputHasFocus()) {
1059
- this.searchWidget.focus(true, true);
1060
- return;
1061
- }
1062
- if (this.inputPatternExcludes.inputHasFocus()) {
1063
- this.inputPatternIncludes.focus();
1064
- this.inputPatternIncludes.select();
1065
- return;
1066
- }
1067
- if (this.tree.isDOMFocused()) {
1068
- this.moveFocusFromResults();
1069
- return;
1070
- }
1071
- }
1072
- moveFocusFromResults() {
1073
- if (this.showsFileTypes()) {
1074
- this.toggleQueryDetails(true, true, false, true);
1075
- }
1076
- else {
1077
- this.searchWidget.focus(true, true);
1078
- }
1079
- }
1080
- reLayout() {
1081
- if (this.isDisposed || !this.size) {
1082
- return;
1083
- }
1084
- const actionsPosition = this.searchConfig.actionsPosition;
1085
- this.getContainer().classList.toggle(SearchView_1.ACTIONS_RIGHT_CLASS_NAME, actionsPosition === 'right');
1086
- this.searchWidget.setWidth(this.size.width - 28 );
1087
- this.inputPatternExcludes.setWidth(this.size.width - 28 );
1088
- this.inputPatternIncludes.setWidth(this.size.width - 28 );
1089
- const widgetHeight = getTotalHeight(this.searchWidgetsContainerElement);
1090
- const messagesHeight = getTotalHeight(this.messagesElement);
1091
- this.tree.layout(this.size.height - widgetHeight - messagesHeight, this.size.width - 28);
1092
- }
1093
- layoutBody(height, width) {
1094
- super.layoutBody(height, width);
1095
- this.size = new Dimension(width, height);
1096
- this.reLayout();
1097
- }
1098
- getControl() {
1099
- return this.tree;
1100
- }
1101
- allSearchFieldsClear() {
1102
- return this.searchWidget.getReplaceValue() === '' &&
1103
- (!this.searchWidget.searchInput || this.searchWidget.searchInput.getValue() === '');
1104
- }
1105
- allFilePatternFieldsClear() {
1106
- return this.searchExcludePattern.getValue() === '' &&
1107
- this.searchIncludePattern.getValue() === '';
1108
- }
1109
- hasSearchResults() {
1110
- return !this.viewModel.searchResult.isEmpty();
1111
- }
1112
- clearSearchResults(clearInput = true) {
1113
- this.viewModel.searchResult.clear();
1114
- this.showEmptyStage(true);
1115
- if (this.contextService.getWorkbenchState() === 1 ) {
1116
- this.showSearchWithoutFolderMessage();
1117
- }
1118
- if (clearInput) {
1119
- if (this.allSearchFieldsClear()) {
1120
- this.clearFilePatternFields();
1121
- }
1122
- this.searchWidget.clear();
1123
- }
1124
- this.viewModel.cancelSearch();
1125
- this.tree.ariaLabel = ( localizeWithPath(
1126
- 'vs/workbench/contrib/search/browser/searchView',
1127
- 'emptySearch',
1128
- "Empty Search"
1129
- ));
1130
- this.accessibilitySignalService.playSignal(AccessibilitySignal.clear);
1131
- this.reLayout();
1132
- }
1133
- clearFilePatternFields() {
1134
- this.searchExcludePattern.clear();
1135
- this.searchIncludePattern.clear();
1136
- }
1137
- cancelSearch(focus = true) {
1138
- if (this.viewModel.cancelSearch()) {
1139
- if (focus) {
1140
- this.searchWidget.focus();
1141
- }
1142
- return true;
1143
- }
1144
- return false;
1145
- }
1146
- selectTreeIfNotSelected() {
1147
- if (this.tree.getNode(null)) {
1148
- this.tree.domFocus();
1149
- const selection = this.tree.getSelection();
1150
- if (selection.length === 0) {
1151
- const event = getSelectionKeyboardEvent();
1152
- this.tree.focusNext(undefined, undefined, event);
1153
- this.tree.setSelection(this.tree.getFocus(), event);
1154
- }
1155
- }
1156
- }
1157
- getSearchTextFromEditor(allowUnselectedWord, editor) {
1158
- if (isAncestorOfActiveElement(this.getContainer())) {
1159
- return null;
1160
- }
1161
- editor = editor ?? this.editorService.activeTextEditorControl;
1162
- if (!editor) {
1163
- return null;
1164
- }
1165
- const allowUnselected = this.searchConfig.seedWithNearestWord && allowUnselectedWord;
1166
- return getSelectionTextFromEditor(allowUnselected, editor);
1167
- }
1168
- showsFileTypes() {
1169
- return this.queryDetails.classList.contains('more');
1170
- }
1171
- toggleCaseSensitive() {
1172
- this.searchWidget.searchInput?.setCaseSensitive(!this.searchWidget.searchInput.getCaseSensitive());
1173
- this.triggerQueryChange();
1174
- }
1175
- toggleWholeWords() {
1176
- this.searchWidget.searchInput?.setWholeWords(!this.searchWidget.searchInput.getWholeWords());
1177
- this.triggerQueryChange();
1178
- }
1179
- toggleRegex() {
1180
- this.searchWidget.searchInput?.setRegex(!this.searchWidget.searchInput.getRegex());
1181
- this.triggerQueryChange();
1182
- }
1183
- togglePreserveCase() {
1184
- this.searchWidget.replaceInput?.setPreserveCase(!this.searchWidget.replaceInput.getPreserveCase());
1185
- this.triggerQueryChange();
1186
- }
1187
- setSearchParameters(args = {}) {
1188
- if (typeof args.isCaseSensitive === 'boolean') {
1189
- this.searchWidget.searchInput?.setCaseSensitive(args.isCaseSensitive);
1190
- }
1191
- if (typeof args.matchWholeWord === 'boolean') {
1192
- this.searchWidget.searchInput?.setWholeWords(args.matchWholeWord);
1193
- }
1194
- if (typeof args.isRegex === 'boolean') {
1195
- this.searchWidget.searchInput?.setRegex(args.isRegex);
1196
- }
1197
- if (typeof args.filesToInclude === 'string') {
1198
- this.searchIncludePattern.setValue(String(args.filesToInclude));
1199
- }
1200
- if (typeof args.filesToExclude === 'string') {
1201
- this.searchExcludePattern.setValue(String(args.filesToExclude));
1202
- }
1203
- if (typeof args.query === 'string') {
1204
- this.searchWidget.searchInput?.setValue(args.query);
1205
- }
1206
- if (typeof args.replace === 'string') {
1207
- this.searchWidget.replaceInput?.setValue(args.replace);
1208
- }
1209
- else {
1210
- if (this.searchWidget.replaceInput && this.searchWidget.replaceInput.getValue() !== '') {
1211
- this.searchWidget.replaceInput.setValue('');
1212
- }
1213
- }
1214
- if (typeof args.triggerSearch === 'boolean' && args.triggerSearch) {
1215
- this.triggerQueryChange();
1216
- }
1217
- if (typeof args.preserveCase === 'boolean') {
1218
- this.searchWidget.replaceInput?.setPreserveCase(args.preserveCase);
1219
- }
1220
- if (typeof args.useExcludeSettingsAndIgnoreFiles === 'boolean') {
1221
- this.inputPatternExcludes.setUseExcludesAndIgnoreFiles(args.useExcludeSettingsAndIgnoreFiles);
1222
- }
1223
- if (typeof args.onlyOpenEditors === 'boolean') {
1224
- this.searchIncludePattern.setOnlySearchInOpenEditors(args.onlyOpenEditors);
1225
- }
1226
- }
1227
- toggleQueryDetails(moveFocus = true, show, skipLayout, reverse) {
1228
- const cls = 'more';
1229
- show = typeof show === 'undefined' ? !this.queryDetails.classList.contains(cls) : Boolean(show);
1230
- this.viewletState['query.queryDetailsExpanded'] = show;
1231
- skipLayout = Boolean(skipLayout);
1232
- if (show) {
1233
- this.toggleQueryDetailsButton.setAttribute('aria-expanded', 'true');
1234
- this.queryDetails.classList.add(cls);
1235
- if (moveFocus) {
1236
- if (reverse) {
1237
- this.inputPatternExcludes.focus();
1238
- this.inputPatternExcludes.select();
1239
- }
1240
- else {
1241
- this.inputPatternIncludes.focus();
1242
- this.inputPatternIncludes.select();
1243
- }
1244
- }
1245
- }
1246
- else {
1247
- this.toggleQueryDetailsButton.setAttribute('aria-expanded', 'false');
1248
- this.queryDetails.classList.remove(cls);
1249
- if (moveFocus) {
1250
- this.searchWidget.focus();
1251
- }
1252
- }
1253
- if (!skipLayout && this.size) {
1254
- this.reLayout();
1255
- }
1256
- }
1257
- searchInFolders(folderPaths = []) {
1258
- this._searchWithIncludeOrExclude(true, folderPaths);
1259
- }
1260
- searchOutsideOfFolders(folderPaths = []) {
1261
- this._searchWithIncludeOrExclude(false, folderPaths);
1262
- }
1263
- _searchWithIncludeOrExclude(include, folderPaths) {
1264
- if (!folderPaths.length || ( folderPaths.some(folderPath => folderPath === '.'))) {
1265
- this.inputPatternIncludes.setValue('');
1266
- this.searchWidget.focus();
1267
- return;
1268
- }
1269
- if (!this.showsFileTypes()) {
1270
- this.toggleQueryDetails(true, true);
1271
- }
1272
- (include ? this.inputPatternIncludes : this.inputPatternExcludes).setValue(folderPaths.join(', '));
1273
- this.searchWidget.focus(false);
1274
- }
1275
- triggerQueryChange(_options) {
1276
- const options = { preserveFocus: true, triggeredOnType: false, delay: 0, ..._options };
1277
- if (options.triggeredOnType && !this.searchConfig.searchOnType) {
1278
- return;
1279
- }
1280
- if (!this.pauseSearching) {
1281
- const delay = options.triggeredOnType ? options.delay : 0;
1282
- this.triggerQueryDelayer.trigger(() => {
1283
- this._onQueryChanged(options.preserveFocus, options.triggeredOnType);
1284
- }, delay);
1285
- }
1286
- }
1287
- _onQueryChanged(preserveFocus, triggeredOnType = false) {
1288
- if (!(this.searchWidget.searchInput?.inputBox.isInputValid())) {
1289
- return;
1290
- }
1291
- const isRegex = this.searchWidget.searchInput.getRegex();
1292
- const isInNotebookMarkdownInput = this.searchWidget.getNotebookFilters().markupInput;
1293
- const isInNotebookMarkdownPreview = this.searchWidget.getNotebookFilters().markupPreview;
1294
- const isInNotebookCellInput = this.searchWidget.getNotebookFilters().codeInput;
1295
- const isInNotebookCellOutput = this.searchWidget.getNotebookFilters().codeOutput;
1296
- const isWholeWords = this.searchWidget.searchInput.getWholeWords();
1297
- const isCaseSensitive = this.searchWidget.searchInput.getCaseSensitive();
1298
- const contentPattern = this.searchWidget.searchInput.getValue();
1299
- const excludePatternText = this.inputPatternExcludes.getValue().trim();
1300
- const includePatternText = this.inputPatternIncludes.getValue().trim();
1301
- const useExcludesAndIgnoreFiles = this.inputPatternExcludes.useExcludesAndIgnoreFiles();
1302
- const onlySearchInOpenEditors = this.inputPatternIncludes.onlySearchInOpenEditors();
1303
- if (contentPattern.length === 0) {
1304
- this.clearSearchResults(false);
1305
- this.clearMessage();
1306
- return;
1307
- }
1308
- const content = {
1309
- pattern: contentPattern,
1310
- isRegExp: isRegex,
1311
- isCaseSensitive: isCaseSensitive,
1312
- isWordMatch: isWholeWords,
1313
- notebookInfo: {
1314
- isInNotebookMarkdownInput,
1315
- isInNotebookMarkdownPreview,
1316
- isInNotebookCellInput,
1317
- isInNotebookCellOutput
1318
- }
1319
- };
1320
- const excludePattern = this.inputPatternExcludes.getValue();
1321
- const includePattern = this.inputPatternIncludes.getValue();
1322
- const charsPerLine = content.isRegExp ? 10000 : 1000;
1323
- const options = {
1324
- _reason: 'searchView',
1325
- extraFileResources: this.instantiationService.invokeFunction(getOutOfWorkspaceEditorResources),
1326
- maxResults: this.searchConfig.maxResults ?? undefined,
1327
- disregardIgnoreFiles: !useExcludesAndIgnoreFiles || undefined,
1328
- disregardExcludeSettings: !useExcludesAndIgnoreFiles || undefined,
1329
- onlyOpenEditors: onlySearchInOpenEditors,
1330
- excludePattern,
1331
- includePattern,
1332
- previewOptions: {
1333
- matchLines: 1,
1334
- charsPerLine
1335
- },
1336
- isSmartCase: this.searchConfig.smartCase,
1337
- expandPatterns: true
1338
- };
1339
- const folderResources = this.contextService.getWorkspace().folders;
1340
- const onQueryValidationError = (err) => {
1341
- this.searchWidget.searchInput?.showMessage({ content: err.message, type: 3 });
1342
- this.viewModel.searchResult.clear();
1343
- };
1344
- let query;
1345
- try {
1346
- query = this.queryBuilder.text(content, ( folderResources.map(folder => folder.uri)), options);
1347
- }
1348
- catch (err) {
1349
- onQueryValidationError(err);
1350
- return;
1351
- }
1352
- this.validateQuery(query).then(() => {
1353
- this.onQueryTriggered(query, options, excludePatternText, includePatternText, triggeredOnType);
1354
- if (!preserveFocus) {
1355
- this.searchWidget.focus(false, undefined, true);
1356
- }
1357
- }, onQueryValidationError);
1358
- }
1359
- validateQuery(query) {
1360
- const folderQueriesExistP = ( query.folderQueries.map(fq => {
1361
- return this.fileService.exists(fq.folder).catch(() => false);
1362
- }));
1363
- return Promise.all(folderQueriesExistP).then(existResults => {
1364
- const existingFolderQueries = query.folderQueries.filter((folderQuery, i) => existResults[i]);
1365
- if (!query.folderQueries.length || existingFolderQueries.length) {
1366
- query.folderQueries = existingFolderQueries;
1367
- }
1368
- else {
1369
- const nonExistantPath = query.folderQueries[0].folder.fsPath;
1370
- const searchPathNotFoundError = ( localizeWithPath(
1371
- 'vs/workbench/contrib/search/browser/searchView',
1372
- 'searchPathNotFoundError',
1373
- "Search path not found: {0}",
1374
- nonExistantPath
1375
- ));
1376
- return Promise.reject(( new Error(searchPathNotFoundError)));
1377
- }
1378
- return undefined;
1379
- });
1380
- }
1381
- onQueryTriggered(query, options, excludePatternText, includePatternText, triggeredOnType) {
1382
- this.addToSearchHistoryDelayer.trigger(() => {
1383
- this.searchWidget.searchInput?.onSearchSubmit();
1384
- this.inputPatternExcludes.onSearchSubmit();
1385
- this.inputPatternIncludes.onSearchSubmit();
1386
- });
1387
- this.viewModel.cancelSearch(true);
1388
- this.currentSearchQ = this.currentSearchQ
1389
- .then(() => this.doSearch(query, excludePatternText, includePatternText, triggeredOnType))
1390
- .then(() => undefined, () => undefined);
1391
- }
1392
- _updateResults() {
1393
- if (this.state === SearchUIState.Idle) {
1394
- return;
1395
- }
1396
- try {
1397
- const fileCount = this.viewModel.searchResult.fileCount();
1398
- if (this._visibleMatches !== fileCount) {
1399
- this._visibleMatches = fileCount;
1400
- this.refreshAndUpdateCount();
1401
- }
1402
- }
1403
- finally {
1404
- this._refreshResultsScheduler.schedule();
1405
- }
1406
- }
1407
- onSearchComplete(progressComplete, excludePatternText, includePatternText, completed) {
1408
- this.state = SearchUIState.Idle;
1409
- progressComplete();
1410
- this.onSearchResultsChanged();
1411
- const collapseResults = this.searchConfig.collapseResults;
1412
- if (collapseResults !== 'alwaysCollapse' && this.viewModel.searchResult.matches().length === 1) {
1413
- const onlyMatch = this.viewModel.searchResult.matches()[0];
1414
- if (onlyMatch.count() < 50) {
1415
- this.tree.expand(onlyMatch);
1416
- }
1417
- }
1418
- const hasResults = !this.viewModel.searchResult.isEmpty();
1419
- if (completed?.exit === 1 ) {
1420
- return;
1421
- }
1422
- if (!hasResults) {
1423
- const hasExcludes = !!excludePatternText;
1424
- const hasIncludes = !!includePatternText;
1425
- let message;
1426
- if (!completed) {
1427
- message = SEARCH_CANCELLED_MESSAGE;
1428
- }
1429
- else if (this.inputPatternIncludes.onlySearchInOpenEditors()) {
1430
- if (hasIncludes && hasExcludes) {
1431
- message = ( localizeWithPath(
1432
- 'vs/workbench/contrib/search/browser/searchView',
1433
- 'noOpenEditorResultsIncludesExcludes',
1434
- "No results found in open editors matching '{0}' excluding '{1}' - ",
1435
- includePatternText,
1436
- excludePatternText
1437
- ));
1438
- }
1439
- else if (hasIncludes) {
1440
- message = ( localizeWithPath(
1441
- 'vs/workbench/contrib/search/browser/searchView',
1442
- 'noOpenEditorResultsIncludes',
1443
- "No results found in open editors matching '{0}' - ",
1444
- includePatternText
1445
- ));
1446
- }
1447
- else if (hasExcludes) {
1448
- message = ( localizeWithPath(
1449
- 'vs/workbench/contrib/search/browser/searchView',
1450
- 'noOpenEditorResultsExcludes',
1451
- "No results found in open editors excluding '{0}' - ",
1452
- excludePatternText
1453
- ));
1454
- }
1455
- else {
1456
- message = ( localizeWithPath(
1457
- 'vs/workbench/contrib/search/browser/searchView',
1458
- 'noOpenEditorResultsFound',
1459
- "No results found in open editors. Review your settings for configured exclusions and check your gitignore files - "
1460
- ));
1461
- }
1462
- }
1463
- else {
1464
- if (hasIncludes && hasExcludes) {
1465
- message = ( localizeWithPath(
1466
- 'vs/workbench/contrib/search/browser/searchView',
1467
- 'noResultsIncludesExcludes',
1468
- "No results found in '{0}' excluding '{1}' - ",
1469
- includePatternText,
1470
- excludePatternText
1471
- ));
1472
- }
1473
- else if (hasIncludes) {
1474
- message = ( localizeWithPath(
1475
- 'vs/workbench/contrib/search/browser/searchView',
1476
- 'noResultsIncludes',
1477
- "No results found in '{0}' - ",
1478
- includePatternText
1479
- ));
1480
- }
1481
- else if (hasExcludes) {
1482
- message = ( localizeWithPath(
1483
- 'vs/workbench/contrib/search/browser/searchView',
1484
- 'noResultsExcludes',
1485
- "No results found excluding '{0}' - ",
1486
- excludePatternText
1487
- ));
1488
- }
1489
- else {
1490
- message = ( localizeWithPath(
1491
- 'vs/workbench/contrib/search/browser/searchView',
1492
- 'noResultsFound',
1493
- "No results found. Review your settings for configured exclusions and check your gitignore files - "
1494
- ));
1495
- }
1496
- }
1497
- status(message);
1498
- const messageEl = this.clearMessage();
1499
- append(messageEl, message);
1500
- if (!completed) {
1501
- const searchAgainButton = this.messageDisposables.add(( new SearchLinkButton(( localizeWithPath(
1502
- 'vs/workbench/contrib/search/browser/searchView',
1503
- 'rerunSearch.message',
1504
- "Search again"
1505
- )), () => this.triggerQueryChange({ preserveFocus: false }))));
1506
- append(messageEl, searchAgainButton.element);
1507
- }
1508
- else if (hasIncludes || hasExcludes) {
1509
- const searchAgainButton = this.messageDisposables.add(( new SearchLinkButton(( localizeWithPath(
1510
- 'vs/workbench/contrib/search/browser/searchView',
1511
- 'rerunSearchInAll.message',
1512
- "Search again in all files"
1513
- )), this.onSearchAgain.bind(this))));
1514
- append(messageEl, searchAgainButton.element);
1515
- }
1516
- else {
1517
- const openSettingsButton = this.messageDisposables.add(( new SearchLinkButton(( localizeWithPath(
1518
- 'vs/workbench/contrib/search/browser/searchView',
1519
- 'openSettings.message',
1520
- "Open Settings"
1521
- )), this.onOpenSettings.bind(this))));
1522
- append(messageEl, openSettingsButton.element);
1523
- }
1524
- if (completed) {
1525
- append(messageEl, $('span', undefined, ' - '));
1526
- const learnMoreButton = this.messageDisposables.add(( new SearchLinkButton(( localizeWithPath(
1527
- 'vs/workbench/contrib/search/browser/searchView',
1528
- 'openSettings.learnMore',
1529
- "Learn More"
1530
- )), this.onLearnMore.bind(this))));
1531
- append(messageEl, learnMoreButton.element);
1532
- }
1533
- if (this.contextService.getWorkbenchState() === 1 ) {
1534
- this.showSearchWithoutFolderMessage();
1535
- }
1536
- this.reLayout();
1537
- }
1538
- else {
1539
- this.viewModel.searchResult.toggleHighlights(this.isVisible());
1540
- status(( localizeWithPath(
1541
- 'vs/workbench/contrib/search/browser/searchView',
1542
- 'ariaSearchResultsStatus',
1543
- "Search returned {0} results in {1} files",
1544
- this.viewModel.searchResult.count(),
1545
- this.viewModel.searchResult.fileCount()
1546
- )));
1547
- }
1548
- if (completed && completed.limitHit) {
1549
- completed.messages.push({ type: TextSearchCompleteMessageType.Warning, text: ( localizeWithPath(
1550
- 'vs/workbench/contrib/search/browser/searchView',
1551
- 'searchMaxResultsWarning',
1552
- "The result set only contains a subset of all matches. Be more specific in your search to narrow down the results."
1553
- )) });
1554
- }
1555
- if (completed && completed.messages) {
1556
- for (const message of completed.messages) {
1557
- this.addMessage(message);
1558
- }
1559
- }
1560
- this.reLayout();
1561
- }
1562
- onSearchError(e, progressComplete, excludePatternText, includePatternText, completed) {
1563
- this.state = SearchUIState.Idle;
1564
- if (isCancellationError(e)) {
1565
- return this.onSearchComplete(progressComplete, excludePatternText, includePatternText, completed);
1566
- }
1567
- else {
1568
- progressComplete();
1569
- this.searchWidget.searchInput?.showMessage({ content: e.message, type: 3 });
1570
- this.viewModel.searchResult.clear();
1571
- return Promise.resolve();
1572
- }
1573
- }
1574
- doSearch(query, excludePatternText, includePatternText, triggeredOnType) {
1575
- let progressComplete;
1576
- this.progressService.withProgress({ location: this.getProgressLocation(), delay: triggeredOnType ? 300 : 0 }, _progress => {
1577
- return ( new Promise(resolve => progressComplete = resolve));
1578
- });
1579
- this.searchWidget.searchInput?.clearMessage();
1580
- this.state = SearchUIState.Searching;
1581
- this.showEmptyStage();
1582
- const slowTimer = setTimeout(() => {
1583
- this.state = SearchUIState.SlowSearch;
1584
- }, 2000);
1585
- this._visibleMatches = 0;
1586
- this._refreshResultsScheduler.schedule();
1587
- this.searchWidget.setReplaceAllActionState(false);
1588
- this.tree.setSelection([]);
1589
- this.tree.setFocus([]);
1590
- this.viewModel.replaceString = this.searchWidget.getReplaceValue();
1591
- const result = this.viewModel.search(query);
1592
- return result.asyncResults.then((complete) => {
1593
- clearTimeout(slowTimer);
1594
- this.onSearchComplete(progressComplete, excludePatternText, includePatternText, complete);
1595
- }, (e) => {
1596
- clearTimeout(slowTimer);
1597
- this.onSearchError(e, progressComplete, excludePatternText, includePatternText);
1598
- });
1599
- }
1600
- onOpenSettings(e) {
1601
- EventHelper.stop(e, false);
1602
- this.openSettings('@id:files.exclude,search.exclude,search.useParentIgnoreFiles,search.useGlobalIgnoreFiles,search.useIgnoreFiles');
1603
- }
1604
- openSettings(query) {
1605
- const options = { query };
1606
- return this.contextService.getWorkbenchState() !== 1 ?
1607
- this.preferencesService.openWorkspaceSettings(options) :
1608
- this.preferencesService.openUserSettings(options);
1609
- }
1610
- onLearnMore() {
1611
- this.openerService.open(( URI.parse('https://go.microsoft.com/fwlink/?linkid=853977')));
1612
- }
1613
- onSearchAgain() {
1614
- this.inputPatternExcludes.setValue('');
1615
- this.inputPatternIncludes.setValue('');
1616
- this.inputPatternIncludes.setOnlySearchInOpenEditors(false);
1617
- this.triggerQueryChange({ preserveFocus: false });
1618
- }
1619
- onEnableExcludes() {
1620
- this.toggleQueryDetails(false, true);
1621
- this.searchExcludePattern.setUseExcludesAndIgnoreFiles(true);
1622
- }
1623
- onDisableSearchInOpenEditors() {
1624
- this.toggleQueryDetails(false, true);
1625
- this.inputPatternIncludes.setOnlySearchInOpenEditors(false);
1626
- }
1627
- updateSearchResultCount(disregardExcludesAndIgnores, onlyOpenEditors, clear = false) {
1628
- const fileCount = this.viewModel.searchResult.fileCount();
1629
- this.hasSearchResultsKey.set(fileCount > 0);
1630
- const msgWasHidden = this.messagesElement.style.display === 'none';
1631
- const messageEl = this.clearMessage();
1632
- const resultMsg = clear ? '' : this.buildResultCountMessage(this.viewModel.searchResult.count(), fileCount);
1633
- this.tree.ariaLabel = resultMsg + ( localizeWithPath(
1634
- 'vs/workbench/contrib/search/browser/searchView',
1635
- 'forTerm',
1636
- " - Search: {0}",
1637
- this.searchResult.query?.contentPattern.pattern ?? ''
1638
- ));
1639
- append(messageEl, resultMsg);
1640
- if (fileCount > 0) {
1641
- if (disregardExcludesAndIgnores) {
1642
- const excludesDisabledMessage = ' - ' + ( localizeWithPath(
1643
- 'vs/workbench/contrib/search/browser/searchView',
1644
- 'useIgnoresAndExcludesDisabled',
1645
- "exclude settings and ignore files are disabled"
1646
- )) + ' ';
1647
- const enableExcludesButton = this.messageDisposables.add(( new SearchLinkButton(( localizeWithPath(
1648
- 'vs/workbench/contrib/search/browser/searchView',
1649
- 'excludes.enable',
1650
- "enable"
1651
- )), this.onEnableExcludes.bind(this), ( localizeWithPath(
1652
- 'vs/workbench/contrib/search/browser/searchView',
1653
- 'useExcludesAndIgnoreFilesDescription',
1654
- "Use Exclude Settings and Ignore Files"
1655
- )))));
1656
- append(messageEl, $('span', undefined, excludesDisabledMessage, '(', enableExcludesButton.element, ')'));
1657
- }
1658
- if (onlyOpenEditors) {
1659
- const searchingInOpenMessage = ' - ' + ( localizeWithPath(
1660
- 'vs/workbench/contrib/search/browser/searchView',
1661
- 'onlyOpenEditors',
1662
- "searching only in open files"
1663
- )) + ' ';
1664
- const disableOpenEditorsButton = this.messageDisposables.add(( new SearchLinkButton(( localizeWithPath(
1665
- 'vs/workbench/contrib/search/browser/searchView',
1666
- 'openEditors.disable',
1667
- "disable"
1668
- )), this.onDisableSearchInOpenEditors.bind(this), ( localizeWithPath(
1669
- 'vs/workbench/contrib/search/browser/searchView',
1670
- 'disableOpenEditors',
1671
- "Search in entire workspace"
1672
- )))));
1673
- append(messageEl, $('span', undefined, searchingInOpenMessage, '(', disableOpenEditorsButton.element, ')'));
1674
- }
1675
- append(messageEl, ' - ');
1676
- const openInEditorTooltip = appendKeyBindingLabel(( localizeWithPath(
1677
- 'vs/workbench/contrib/search/browser/searchView',
1678
- 'openInEditor.tooltip',
1679
- "Copy current search results to an editor"
1680
- )), this.keybindingService.lookupKeybinding("search.action.openInEditor" ));
1681
- const openInEditorButton = this.messageDisposables.add(( new SearchLinkButton(( localizeWithPath(
1682
- 'vs/workbench/contrib/search/browser/searchView',
1683
- 'openInEditor.message',
1684
- "Open in editor"
1685
- )), () => this.instantiationService.invokeFunction(createEditorFromSearchResult, this.searchResult, this.searchIncludePattern.getValue(), this.searchExcludePattern.getValue(), this.searchIncludePattern.onlySearchInOpenEditors()), openInEditorTooltip)));
1686
- append(messageEl, openInEditorButton.element);
1687
- this.reLayout();
1688
- }
1689
- else if (!msgWasHidden) {
1690
- hide(this.messagesElement);
1691
- }
1692
- }
1693
- addMessage(message) {
1694
- const messageBox = this.messagesElement.firstChild;
1695
- if (!messageBox) {
1696
- return;
1697
- }
1698
- append(messageBox, renderSearchMessage(message, this.instantiationService, this.notificationService, this.openerService, this.commandService, this.messageDisposables, () => this.triggerQueryChange()));
1699
- }
1700
- buildResultCountMessage(resultCount, fileCount) {
1701
- if (resultCount === 1 && fileCount === 1) {
1702
- return ( localizeWithPath(
1703
- 'vs/workbench/contrib/search/browser/searchView',
1704
- 'search.file.result',
1705
- "{0} result in {1} file",
1706
- resultCount,
1707
- fileCount
1708
- ));
1709
- }
1710
- else if (resultCount === 1) {
1711
- return ( localizeWithPath(
1712
- 'vs/workbench/contrib/search/browser/searchView',
1713
- 'search.files.result',
1714
- "{0} result in {1} files",
1715
- resultCount,
1716
- fileCount
1717
- ));
1718
- }
1719
- else if (fileCount === 1) {
1720
- return ( localizeWithPath(
1721
- 'vs/workbench/contrib/search/browser/searchView',
1722
- 'search.file.results',
1723
- "{0} results in {1} file",
1724
- resultCount,
1725
- fileCount
1726
- ));
1727
- }
1728
- else {
1729
- return ( localizeWithPath(
1730
- 'vs/workbench/contrib/search/browser/searchView',
1731
- 'search.files.results',
1732
- "{0} results in {1} files",
1733
- resultCount,
1734
- fileCount
1735
- ));
1736
- }
1737
- }
1738
- showSearchWithoutFolderMessage() {
1739
- this.searchWithoutFolderMessageElement = this.clearMessage();
1740
- const textEl = append(this.searchWithoutFolderMessageElement, $('p', undefined, ( localizeWithPath(
1741
- 'vs/workbench/contrib/search/browser/searchView',
1742
- 'searchWithoutFolder',
1743
- "You have not opened or specified a folder. Only open files are currently searched - "
1744
- ))));
1745
- const openFolderButton = this.messageDisposables.add(( new SearchLinkButton(( localizeWithPath(
1746
- 'vs/workbench/contrib/search/browser/searchView',
1747
- 'openFolder',
1748
- "Open Folder"
1749
- )), () => {
1750
- this.commandService.executeCommand(isMacintosh && isNative ? OpenFileFolderAction.ID : OpenFolderAction.ID).catch(err => onUnexpectedError(err));
1751
- })));
1752
- append(textEl, openFolderButton.element);
1753
- }
1754
- showEmptyStage(forceHideMessages = false) {
1755
- const showingCancelled = (this.messagesElement.firstChild?.textContent?.indexOf(SEARCH_CANCELLED_MESSAGE) ?? -1) > -1;
1756
- if (showingCancelled || forceHideMessages || !this.configurationService.getValue().search.searchOnType) {
1757
- hide(this.messagesElement);
1758
- }
1759
- show(this.resultsElement);
1760
- this.currentSelectedFileMatch = undefined;
1761
- }
1762
- shouldOpenInNotebookEditor(match, uri) {
1763
- return match instanceof MatchInNotebook || (uri.scheme !== Schemas.untitled && this.notebookService.getContributedNotebookTypes(uri).length > 0);
1764
- }
1765
- onFocus(lineMatch, preserveFocus, sideBySide, pinned) {
1766
- const useReplacePreview = this.configurationService.getValue().search.useReplacePreview;
1767
- const resource = lineMatch instanceof Match ? lineMatch.parent().resource : lineMatch.resource;
1768
- return (useReplacePreview && this.viewModel.isReplaceActive() && !!this.viewModel.replaceString && !(this.shouldOpenInNotebookEditor(lineMatch, resource))) ?
1769
- this.replaceService.openReplacePreview(lineMatch, preserveFocus, sideBySide, pinned) :
1770
- this.open(lineMatch, preserveFocus, sideBySide, pinned, resource);
1771
- }
1772
- async open(element, preserveFocus, sideBySide, pinned, resourceInput) {
1773
- const selection = getEditorSelectionFromMatch(element, this.viewModel);
1774
- const oldParentMatches = element instanceof Match ? element.parent().matches() : [];
1775
- const resource = resourceInput ?? (element instanceof Match ? element.parent().resource : element.resource);
1776
- let editor;
1777
- const options = {
1778
- preserveFocus,
1779
- pinned,
1780
- selection,
1781
- revealIfVisible: true,
1782
- };
1783
- try {
1784
- editor = await this.editorService.openEditor({
1785
- resource: resource,
1786
- options,
1787
- }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP);
1788
- const editorControl = editor?.getControl();
1789
- if (element instanceof Match && preserveFocus && isCodeEditor(editorControl)) {
1790
- this.viewModel.searchResult.rangeHighlightDecorations.highlightRange(editorControl.getModel(), element.range());
1791
- }
1792
- else {
1793
- this.viewModel.searchResult.rangeHighlightDecorations.removeHighlightRange();
1794
- }
1795
- }
1796
- catch (err) {
1797
- onUnexpectedError(err);
1798
- return;
1799
- }
1800
- if (editor instanceof NotebookEditor) {
1801
- const elemParent = element.parent();
1802
- if (element instanceof Match) {
1803
- if (element instanceof MatchInNotebook) {
1804
- element.parent().showMatch(element);
1805
- }
1806
- else {
1807
- const editorWidget = editor.getControl();
1808
- if (editorWidget) {
1809
- elemParent.bindNotebookEditorWidget(editorWidget);
1810
- await elemParent.updateMatchesForEditorWidget();
1811
- const matchIndex = oldParentMatches.findIndex(e => e.id() === element.id());
1812
- const matches = elemParent.matches();
1813
- const match = matchIndex >= matches.length ? matches[matches.length - 1] : matches[matchIndex];
1814
- if (match instanceof MatchInNotebook) {
1815
- elemParent.showMatch(match);
1816
- if (!this.tree.getFocus().includes(match) || !this.tree.getSelection().includes(match)) {
1817
- this.tree.setSelection([match], getSelectionKeyboardEvent());
1818
- this.tree.setFocus([match]);
1819
- }
1820
- }
1821
- }
1822
- }
1823
- }
1824
- }
1825
- }
1826
- openEditorWithMultiCursor(element) {
1827
- const resource = element instanceof Match ? element.parent().resource : element.resource;
1828
- return this.editorService.openEditor({
1829
- resource: resource,
1830
- options: {
1831
- preserveFocus: false,
1832
- pinned: true,
1833
- revealIfVisible: true
1834
- }
1835
- }).then(editor => {
1836
- if (editor) {
1837
- let fileMatch = null;
1838
- if (element instanceof FileMatch) {
1839
- fileMatch = element;
1840
- }
1841
- else if (element instanceof Match) {
1842
- fileMatch = element.parent();
1843
- }
1844
- if (fileMatch) {
1845
- const selections = ( fileMatch.matches().map(m => ( new Selection(
1846
- m.range().startLineNumber,
1847
- m.range().startColumn,
1848
- m.range().endLineNumber,
1849
- m.range().endColumn
1850
- ))));
1851
- const codeEditor = getCodeEditor(editor.getControl());
1852
- if (codeEditor) {
1853
- const multiCursorController = MultiCursorSelectionController.get(codeEditor);
1854
- multiCursorController?.selectAllUsingSelections(selections);
1855
- }
1856
- }
1857
- }
1858
- this.viewModel.searchResult.rangeHighlightDecorations.removeHighlightRange();
1859
- }, onUnexpectedError);
1860
- }
1861
- onUntitledDidDispose(resource) {
1862
- if (!this.viewModel) {
1863
- return;
1864
- }
1865
- const matches = this.viewModel.searchResult.matches();
1866
- for (let i = 0, len = matches.length; i < len; i++) {
1867
- if (( resource.toString()) === ( matches[i].resource.toString())) {
1868
- this.viewModel.searchResult.remove(matches[i]);
1869
- }
1870
- }
1871
- }
1872
- onFilesChanged(e) {
1873
- if (!this.viewModel || (this.searchConfig.sortOrder !== "modified" && !e.gotDeleted())) {
1874
- return;
1875
- }
1876
- const matches = this.viewModel.searchResult.matches();
1877
- if (e.gotDeleted()) {
1878
- const deletedMatches = matches.filter(m => e.contains(m.resource, 2 ));
1879
- this.viewModel.searchResult.remove(deletedMatches);
1880
- }
1881
- else {
1882
- const changedMatches = matches.filter(m => e.contains(m.resource));
1883
- if (changedMatches.length && this.searchConfig.sortOrder === "modified" ) {
1884
- this.updateFileStats(changedMatches).then(() => this.refreshTree());
1885
- }
1886
- }
1887
- }
1888
- get searchConfig() {
1889
- return this.configurationService.getValue('search');
1890
- }
1891
- clearHistory() {
1892
- this.searchWidget.clearHistory();
1893
- this.inputPatternExcludes.clearHistory();
1894
- this.inputPatternIncludes.clearHistory();
1895
- }
1896
- saveState() {
1897
- if (!this.searchWidget) {
1898
- return;
1899
- }
1900
- const patternExcludes = this.inputPatternExcludes?.getValue().trim() ?? '';
1901
- const patternIncludes = this.inputPatternIncludes?.getValue().trim() ?? '';
1902
- const onlyOpenEditors = this.inputPatternIncludes?.onlySearchInOpenEditors() ?? false;
1903
- const useExcludesAndIgnoreFiles = this.inputPatternExcludes?.useExcludesAndIgnoreFiles() ?? true;
1904
- const preserveCase = this.viewModel.preserveCase;
1905
- if (this.searchWidget.searchInput) {
1906
- const isRegex = this.searchWidget.searchInput.getRegex();
1907
- const isWholeWords = this.searchWidget.searchInput.getWholeWords();
1908
- const isCaseSensitive = this.searchWidget.searchInput.getCaseSensitive();
1909
- const contentPattern = this.searchWidget.searchInput.getValue();
1910
- const isInNotebookCellInput = this.searchWidget.getNotebookFilters().codeInput;
1911
- const isInNotebookCellOutput = this.searchWidget.getNotebookFilters().codeOutput;
1912
- const isInNotebookMarkdownInput = this.searchWidget.getNotebookFilters().markupInput;
1913
- const isInNotebookMarkdownPreview = this.searchWidget.getNotebookFilters().markupPreview;
1914
- this.viewletState['query.contentPattern'] = contentPattern;
1915
- this.viewletState['query.regex'] = isRegex;
1916
- this.viewletState['query.wholeWords'] = isWholeWords;
1917
- this.viewletState['query.caseSensitive'] = isCaseSensitive;
1918
- this.viewletState['query.isInNotebookMarkdownInput'] = isInNotebookMarkdownInput;
1919
- this.viewletState['query.isInNotebookMarkdownPreview'] = isInNotebookMarkdownPreview;
1920
- this.viewletState['query.isInNotebookCellInput'] = isInNotebookCellInput;
1921
- this.viewletState['query.isInNotebookCellOutput'] = isInNotebookCellOutput;
1922
- }
1923
- this.viewletState['query.folderExclusions'] = patternExcludes;
1924
- this.viewletState['query.folderIncludes'] = patternIncludes;
1925
- this.viewletState['query.useExcludesAndIgnoreFiles'] = useExcludesAndIgnoreFiles;
1926
- this.viewletState['query.preserveCase'] = preserveCase;
1927
- this.viewletState['query.onlyOpenEditors'] = onlyOpenEditors;
1928
- const isReplaceShown = this.searchAndReplaceWidget.isReplaceShown();
1929
- this.viewletState['view.showReplace'] = isReplaceShown;
1930
- this.viewletState['view.treeLayout'] = this.isTreeLayoutViewVisible;
1931
- this.viewletState['query.replaceText'] = isReplaceShown && this.searchWidget.getReplaceValue();
1932
- this._saveSearchHistoryService();
1933
- this.memento.saveMemento();
1934
- super.saveState();
1935
- }
1936
- _saveSearchHistoryService() {
1937
- if (this.searchWidget === undefined) {
1938
- return;
1939
- }
1940
- const history = Object.create(null);
1941
- const searchHistory = this.searchWidget.getSearchHistory();
1942
- if (searchHistory && searchHistory.length) {
1943
- history.search = searchHistory;
1944
- }
1945
- const replaceHistory = this.searchWidget.getReplaceHistory();
1946
- if (replaceHistory && replaceHistory.length) {
1947
- history.replace = replaceHistory;
1948
- }
1949
- const patternExcludesHistory = this.inputPatternExcludes.getHistory();
1950
- if (patternExcludesHistory && patternExcludesHistory.length) {
1951
- history.exclude = patternExcludesHistory;
1952
- }
1953
- const patternIncludesHistory = this.inputPatternIncludes.getHistory();
1954
- if (patternIncludesHistory && patternIncludesHistory.length) {
1955
- history.include = patternIncludesHistory;
1956
- }
1957
- this.searchHistoryService.save(history);
1958
- }
1959
- async retrieveFileStats() {
1960
- const files = ( this.searchResult.matches().filter(f => !f.fileStat).map(f => f.resolveFileStat(this.fileService)));
1961
- await Promise.all(files);
1962
- }
1963
- async updateFileStats(elements) {
1964
- const files = ( elements.map(f => f.resolveFileStat(this.fileService)));
1965
- await Promise.all(files);
1966
- }
1967
- removeFileStats() {
1968
- for (const fileMatch of this.searchResult.matches()) {
1969
- fileMatch.fileStat = undefined;
1970
- }
1971
- }
1972
- dispose() {
1973
- this.isDisposed = true;
1974
- this.saveState();
1975
- super.dispose();
1976
- }
1977
- };
1978
- SearchView = SearchView_1 = ( __decorate([
1979
- ( __param(1, IFileService)),
1980
- ( __param(2, IEditorService)),
1981
- ( __param(3, ICodeEditorService)),
1982
- ( __param(4, IProgressService)),
1983
- ( __param(5, INotificationService)),
1984
- ( __param(6, IDialogService)),
1985
- ( __param(7, ICommandService)),
1986
- ( __param(8, IContextViewService)),
1987
- ( __param(9, IInstantiationService)),
1988
- ( __param(10, IViewDescriptorService)),
1989
- ( __param(11, IConfigurationService)),
1990
- ( __param(12, IWorkspaceContextService)),
1991
- ( __param(13, ISearchViewModelWorkbenchService)),
1992
- ( __param(14, IContextKeyService)),
1993
- ( __param(15, IReplaceService)),
1994
- ( __param(16, ITextFileService)),
1995
- ( __param(17, IPreferencesService)),
1996
- ( __param(18, IThemeService)),
1997
- ( __param(19, ISearchHistoryService)),
1998
- ( __param(20, IContextMenuService)),
1999
- ( __param(21, IAccessibilityService)),
2000
- ( __param(22, IKeybindingService)),
2001
- ( __param(23, IStorageService)),
2002
- ( __param(24, IOpenerService)),
2003
- ( __param(25, ITelemetryService)),
2004
- ( __param(26, INotebookService)),
2005
- ( __param(27, ILogService)),
2006
- ( __param(28, IAccessibilitySignalService))
2007
- ], SearchView));
2008
- class SearchLinkButton extends Disposable {
2009
- constructor(label, handler, tooltip) {
2010
- super();
2011
- this.element = $('a.pointer', { tabindex: 0, title: tooltip }, label);
2012
- this.addEventHandlers(handler);
2013
- }
2014
- addEventHandlers(handler) {
2015
- const wrappedHandler = (e) => {
2016
- EventHelper.stop(e, false);
2017
- handler(e);
2018
- };
2019
- this._register(addDisposableListener(this.element, EventType.CLICK, wrappedHandler));
2020
- this._register(addDisposableListener(this.element, EventType.KEY_DOWN, e => {
2021
- const event = ( new StandardKeyboardEvent(e));
2022
- if (event.equals(10 ) || event.equals(3 )) {
2023
- wrappedHandler(e);
2024
- event.preventDefault();
2025
- event.stopPropagation();
2026
- }
2027
- }));
2028
- }
2029
- }
2030
- function getEditorSelectionFromMatch(element, viewModel) {
2031
- let match = null;
2032
- if (element instanceof Match) {
2033
- match = element;
2034
- }
2035
- if (element instanceof FileMatch && element.count() > 0) {
2036
- match = element.matches()[element.matches().length - 1];
2037
- }
2038
- if (match) {
2039
- const range = match.range();
2040
- if (viewModel.isReplaceActive() && !!viewModel.replaceString) {
2041
- const replaceString = match.replaceString;
2042
- return {
2043
- startLineNumber: range.startLineNumber,
2044
- startColumn: range.startColumn,
2045
- endLineNumber: range.startLineNumber,
2046
- endColumn: range.startColumn + replaceString.length
2047
- };
2048
- }
2049
- return range;
2050
- }
2051
- return undefined;
2052
- }
2053
- function getSelectionTextFromEditor(allowUnselectedWord, activeEditor) {
2054
- let editor = activeEditor;
2055
- if (isDiffEditor(editor)) {
2056
- if (editor.getOriginalEditor().hasTextFocus()) {
2057
- editor = editor.getOriginalEditor();
2058
- }
2059
- else {
2060
- editor = editor.getModifiedEditor();
2061
- }
2062
- }
2063
- if (!isCodeEditor(editor) || !editor.hasModel()) {
2064
- return null;
2065
- }
2066
- const range = editor.getSelection();
2067
- if (!range) {
2068
- return null;
2069
- }
2070
- if (range.isEmpty()) {
2071
- if (allowUnselectedWord) {
2072
- const wordAtPosition = editor.getModel().getWordAtPosition(range.getStartPosition());
2073
- return wordAtPosition?.word ?? null;
2074
- }
2075
- else {
2076
- return null;
2077
- }
2078
- }
2079
- let searchText = '';
2080
- for (let i = range.startLineNumber; i <= range.endLineNumber; i++) {
2081
- let lineText = editor.getModel().getLineContent(i);
2082
- if (i === range.endLineNumber) {
2083
- lineText = lineText.substring(0, range.endColumn - 1);
2084
- }
2085
- if (i === range.startLineNumber) {
2086
- lineText = lineText.substring(range.startColumn - 1);
2087
- }
2088
- if (i !== range.startLineNumber) {
2089
- lineText = '\n' + lineText;
2090
- }
2091
- searchText += lineText;
2092
- }
2093
- return searchText;
2094
- }
2095
-
2096
- export { SearchView, getEditorSelectionFromMatch, getSelectionTextFromEditor };