@theia/search-in-workspace 1.67.0-next.56 → 1.67.0-next.59

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 (77) hide show
  1. package/lib/browser/components/search-in-workspace-input.d.ts +40 -0
  2. package/lib/browser/components/search-in-workspace-input.d.ts.map +1 -0
  3. package/lib/browser/components/search-in-workspace-input.js +124 -0
  4. package/lib/browser/components/search-in-workspace-input.js.map +1 -0
  5. package/lib/browser/components/search-in-workspace-textarea.d.ts +40 -0
  6. package/lib/browser/components/search-in-workspace-textarea.d.ts.map +1 -0
  7. package/lib/browser/components/search-in-workspace-textarea.js +136 -0
  8. package/lib/browser/components/search-in-workspace-textarea.js.map +1 -0
  9. package/lib/browser/search-in-workspace-context-key-service.d.ts +24 -0
  10. package/lib/browser/search-in-workspace-context-key-service.d.ts.map +1 -0
  11. package/lib/browser/search-in-workspace-context-key-service.js +83 -0
  12. package/lib/browser/search-in-workspace-context-key-service.js.map +1 -0
  13. package/lib/browser/search-in-workspace-factory.d.ts +11 -0
  14. package/lib/browser/search-in-workspace-factory.d.ts.map +1 -0
  15. package/lib/browser/search-in-workspace-factory.js +61 -0
  16. package/lib/browser/search-in-workspace-factory.js.map +1 -0
  17. package/lib/browser/search-in-workspace-frontend-contribution.d.ts +58 -0
  18. package/lib/browser/search-in-workspace-frontend-contribution.d.ts.map +1 -0
  19. package/lib/browser/search-in-workspace-frontend-contribution.js +509 -0
  20. package/lib/browser/search-in-workspace-frontend-contribution.js.map +1 -0
  21. package/lib/browser/search-in-workspace-frontend-module.d.ts +7 -0
  22. package/lib/browser/search-in-workspace-frontend-module.d.ts.map +1 -0
  23. package/lib/browser/search-in-workspace-frontend-module.js +73 -0
  24. package/lib/browser/search-in-workspace-frontend-module.js.map +1 -0
  25. package/lib/browser/search-in-workspace-label-provider.d.ts +10 -0
  26. package/lib/browser/search-in-workspace-label-provider.d.ts.map +1 -0
  27. package/lib/browser/search-in-workspace-label-provider.js +50 -0
  28. package/lib/browser/search-in-workspace-label-provider.js.map +1 -0
  29. package/lib/browser/search-in-workspace-result-tree-widget.d.ts +262 -0
  30. package/lib/browser/search-in-workspace-result-tree-widget.d.ts.map +1 -0
  31. package/lib/browser/search-in-workspace-result-tree-widget.js +1164 -0
  32. package/lib/browser/search-in-workspace-result-tree-widget.js.map +1 -0
  33. package/lib/browser/search-in-workspace-service.d.ts +36 -0
  34. package/lib/browser/search-in-workspace-service.d.ts.map +1 -0
  35. package/lib/browser/search-in-workspace-service.js +151 -0
  36. package/lib/browser/search-in-workspace-service.js.map +1 -0
  37. package/lib/browser/search-in-workspace-widget.d.ts +123 -0
  38. package/lib/browser/search-in-workspace-widget.d.ts.map +1 -0
  39. package/lib/browser/search-in-workspace-widget.js +624 -0
  40. package/lib/browser/search-in-workspace-widget.js.map +1 -0
  41. package/lib/browser/search-layout-migrations.d.ts +6 -0
  42. package/lib/browser/search-layout-migrations.d.ts.map +1 -0
  43. package/lib/browser/search-layout-migrations.js +60 -0
  44. package/lib/browser/search-layout-migrations.js.map +1 -0
  45. package/lib/browser-only/browser-only-search-in-workspace-service.d.ts +5 -0
  46. package/lib/browser-only/browser-only-search-in-workspace-service.d.ts.map +1 -0
  47. package/lib/browser-only/browser-only-search-in-workspace-service.js +40 -0
  48. package/lib/browser-only/browser-only-search-in-workspace-service.js.map +1 -0
  49. package/lib/browser-only/browser-search-in-workspace-server.d.ts +80 -0
  50. package/lib/browser-only/browser-search-in-workspace-server.d.ts.map +1 -0
  51. package/lib/browser-only/browser-search-in-workspace-server.js +378 -0
  52. package/lib/browser-only/browser-search-in-workspace-server.js.map +1 -0
  53. package/lib/browser-only/search-in-workspace-frontend-only-module.d.ts +4 -0
  54. package/lib/browser-only/search-in-workspace-frontend-only-module.d.ts.map +1 -0
  55. package/lib/browser-only/search-in-workspace-frontend-only-module.js +37 -0
  56. package/lib/browser-only/search-in-workspace-frontend-only-module.js.map +1 -0
  57. package/lib/common/search-in-workspace-interface.d.ts +117 -0
  58. package/lib/common/search-in-workspace-interface.d.ts.map +1 -0
  59. package/lib/common/search-in-workspace-interface.js +36 -0
  60. package/lib/common/search-in-workspace-interface.js.map +1 -0
  61. package/lib/common/search-in-workspace-preferences.d.ts +19 -0
  62. package/lib/common/search-in-workspace-preferences.d.ts.map +1 -0
  63. package/lib/common/search-in-workspace-preferences.js +89 -0
  64. package/lib/common/search-in-workspace-preferences.js.map +1 -0
  65. package/lib/node/ripgrep-search-in-workspace-server.d.ts +95 -0
  66. package/lib/node/ripgrep-search-in-workspace-server.d.ts.map +1 -0
  67. package/lib/node/ripgrep-search-in-workspace-server.js +420 -0
  68. package/lib/node/ripgrep-search-in-workspace-server.js.map +1 -0
  69. package/lib/node/ripgrep-search-in-workspace-server.slow-spec.d.ts +2 -0
  70. package/lib/node/ripgrep-search-in-workspace-server.slow-spec.d.ts.map +1 -0
  71. package/lib/node/ripgrep-search-in-workspace-server.slow-spec.js +900 -0
  72. package/lib/node/ripgrep-search-in-workspace-server.slow-spec.js.map +1 -0
  73. package/lib/node/search-in-workspace-backend-module.d.ts +4 -0
  74. package/lib/node/search-in-workspace-backend-module.d.ts.map +1 -0
  75. package/lib/node/search-in-workspace-backend-module.js +35 -0
  76. package/lib/node/search-in-workspace-backend-module.js.map +1 -0
  77. package/package.json +8 -8
@@ -0,0 +1,624 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2018 TypeFox and others.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ var SearchInWorkspaceWidget_1;
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.SearchInWorkspaceWidget = void 0;
20
+ const tslib_1 = require("tslib");
21
+ const browser_1 = require("@theia/core/lib/browser");
22
+ const inversify_1 = require("@theia/core/shared/inversify");
23
+ const search_in_workspace_result_tree_widget_1 = require("./search-in-workspace-result-tree-widget");
24
+ const React = require("@theia/core/shared/react");
25
+ const client_1 = require("@theia/core/shared/react-dom/client");
26
+ const common_1 = require("@theia/core/lib/common");
27
+ const browser_2 = require("@theia/workspace/lib/browser");
28
+ const search_in_workspace_context_key_service_1 = require("./search-in-workspace-context-key-service");
29
+ const progress_bar_factory_1 = require("@theia/core/lib/browser/progress-bar-factory");
30
+ const browser_3 = require("@theia/editor/lib/browser");
31
+ const search_in_workspace_preferences_1 = require("../common/search-in-workspace-preferences");
32
+ const search_in_workspace_input_1 = require("./components/search-in-workspace-input");
33
+ const search_in_workspace_textarea_1 = require("./components/search-in-workspace-textarea");
34
+ const nls_1 = require("@theia/core/lib/common/nls");
35
+ const promise_util_1 = require("@theia/core/lib/common/promise-util");
36
+ let SearchInWorkspaceWidget = SearchInWorkspaceWidget_1 = class SearchInWorkspaceWidget extends browser_1.BaseWidget {
37
+ constructor() {
38
+ super(...arguments);
39
+ this.showSearchDetails = false;
40
+ this._hasResults = false;
41
+ this.resultNumber = 0;
42
+ this.searchFieldContainerIsFocused = false;
43
+ this.searchTerm = '';
44
+ this.replaceTerm = '';
45
+ this.searchRef = React.createRef();
46
+ this.replaceRef = React.createRef();
47
+ this.includeRef = React.createRef();
48
+ this.excludeRef = React.createRef();
49
+ this.refsAreSet = new promise_util_1.Deferred();
50
+ this._showReplaceField = false;
51
+ this.onDidUpdateEmitter = new common_1.Emitter();
52
+ this.onDidUpdate = this.onDidUpdateEmitter.event;
53
+ this.focusSearchFieldContainer = () => this.doFocusSearchFieldContainer();
54
+ this.blurSearchFieldContainer = () => this.doBlurSearchFieldContainer();
55
+ this.search = (e) => {
56
+ e.persist();
57
+ const searchOnType = this.searchInWorkspacePreferences['search.searchOnType'];
58
+ if (searchOnType) {
59
+ const delay = this.searchInWorkspacePreferences['search.searchOnTypeDebouncePeriod'] || 0;
60
+ window.clearTimeout(this._searchTimeout);
61
+ this._searchTimeout = window.setTimeout(() => this.doSearch(e), delay);
62
+ }
63
+ };
64
+ this.onKeyDownSearch = (e) => {
65
+ var _a;
66
+ if (browser_1.Key.ENTER.keyCode === ((_a = browser_1.KeyCode.createKeyCode(e.nativeEvent).key) === null || _a === void 0 ? void 0 : _a.keyCode)) {
67
+ this.performSearch();
68
+ }
69
+ };
70
+ this.handleFocusSearchInputBox = (event) => {
71
+ event.target.placeholder = SearchInWorkspaceWidget_1.LABEL + nls_1.nls.localizeByDefault(' ({0} for history)', '⇅');
72
+ this.contextKeyService.setSearchInputBoxFocus(true);
73
+ };
74
+ this.handleBlurSearchInputBox = (event) => {
75
+ event.target.placeholder = SearchInWorkspaceWidget_1.LABEL;
76
+ this.contextKeyService.setSearchInputBoxFocus(false);
77
+ };
78
+ this.updateReplaceTerm = (e) => this.doUpdateReplaceTerm(e);
79
+ this.handleFocusReplaceInputBox = (event) => {
80
+ event.target.placeholder = nls_1.nls.localizeByDefault('Replace') + nls_1.nls.localizeByDefault(' ({0} for history)', '⇅');
81
+ this.contextKeyService.setReplaceInputBoxFocus(true);
82
+ };
83
+ this.handleBlurReplaceInputBox = (event) => {
84
+ event.target.placeholder = nls_1.nls.localizeByDefault('Replace');
85
+ this.contextKeyService.setReplaceInputBoxFocus(false);
86
+ };
87
+ this.handleFocusIncludesInputBox = () => this.contextKeyService.setPatternIncludesInputBoxFocus(true);
88
+ this.handleBlurIncludesInputBox = () => this.contextKeyService.setPatternIncludesInputBoxFocus(false);
89
+ this.handleFocusExcludesInputBox = () => this.contextKeyService.setPatternExcludesInputBoxFocus(true);
90
+ this.handleBlurExcludesInputBox = () => this.contextKeyService.setPatternExcludesInputBoxFocus(false);
91
+ }
92
+ get hasResults() {
93
+ return this._hasResults;
94
+ }
95
+ set hasResults(hasResults) {
96
+ this.contextKeyService.hasSearchResult.set(hasResults);
97
+ this._hasResults = hasResults;
98
+ }
99
+ get showReplaceField() {
100
+ return this._showReplaceField;
101
+ }
102
+ set showReplaceField(showReplaceField) {
103
+ this.contextKeyService.replaceActive.set(showReplaceField);
104
+ this._showReplaceField = showReplaceField;
105
+ }
106
+ init() {
107
+ this.id = SearchInWorkspaceWidget_1.ID;
108
+ this.title.label = SearchInWorkspaceWidget_1.LABEL;
109
+ this.title.caption = SearchInWorkspaceWidget_1.LABEL;
110
+ this.title.iconClass = (0, browser_1.codicon)('search');
111
+ this.title.closable = true;
112
+ this.contentNode = document.createElement('div');
113
+ this.contentNode.classList.add('t-siw-search-container');
114
+ this.searchFormContainer = document.createElement('div');
115
+ this.searchFormContainer.classList.add('searchHeader');
116
+ this.contentNode.appendChild(this.searchFormContainer);
117
+ this.searchFormContainerRoot = (0, client_1.createRoot)(this.searchFormContainer);
118
+ this.node.tabIndex = 0;
119
+ this.node.appendChild(this.contentNode);
120
+ this.matchCaseState = {
121
+ className: (0, browser_1.codicon)('case-sensitive'),
122
+ enabled: false,
123
+ title: nls_1.nls.localizeByDefault('Match Case')
124
+ };
125
+ this.wholeWordState = {
126
+ className: (0, browser_1.codicon)('whole-word'),
127
+ enabled: false,
128
+ title: nls_1.nls.localizeByDefault('Match Whole Word')
129
+ };
130
+ this.regExpState = {
131
+ className: (0, browser_1.codicon)('regex'),
132
+ enabled: false,
133
+ title: nls_1.nls.localizeByDefault('Use Regular Expression')
134
+ };
135
+ this.includeIgnoredState = {
136
+ className: (0, browser_1.codicon)('eye'),
137
+ enabled: false,
138
+ title: nls_1.nls.localize('theia/search-in-workspace/includeIgnoredFiles', 'Include Ignored Files')
139
+ };
140
+ this.searchInWorkspaceOptions = {
141
+ matchCase: false,
142
+ matchWholeWord: false,
143
+ useRegExp: false,
144
+ multiline: false,
145
+ includeIgnored: false,
146
+ include: [],
147
+ exclude: [],
148
+ maxResults: 2000
149
+ };
150
+ this.toDispose.push(this.resultTreeWidget.onChange(r => {
151
+ this.hasResults = r.size > 0;
152
+ this.resultNumber = 0;
153
+ const results = Array.from(r.values());
154
+ results.forEach(rootFolder => rootFolder.children.forEach(file => this.resultNumber += file.children.length));
155
+ this.update();
156
+ }));
157
+ this.toDispose.push(this.resultTreeWidget.onFocusInput(b => {
158
+ this.focusInputField();
159
+ }));
160
+ this.toDispose.push(this.searchInWorkspacePreferences.onPreferenceChanged(e => {
161
+ if (e.preferenceName === 'search.smartCase') {
162
+ this.performSearch();
163
+ }
164
+ }));
165
+ this.toDispose.push(this.resultTreeWidget);
166
+ this.toDispose.push(this.resultTreeWidget.onExpansionChanged(() => {
167
+ this.onDidUpdateEmitter.fire();
168
+ }));
169
+ this.toDispose.push(this.progressBarFactory({ container: this.node, insertMode: 'prepend', locationId: 'search' }));
170
+ }
171
+ storeState() {
172
+ var _a, _b, _c, _d;
173
+ return {
174
+ matchCaseState: this.matchCaseState,
175
+ wholeWordState: this.wholeWordState,
176
+ regExpState: this.regExpState,
177
+ includeIgnoredState: this.includeIgnoredState,
178
+ showSearchDetails: this.showSearchDetails,
179
+ searchInWorkspaceOptions: this.searchInWorkspaceOptions,
180
+ searchTerm: this.searchTerm,
181
+ replaceTerm: this.replaceTerm,
182
+ showReplaceField: this.showReplaceField,
183
+ searchHistoryState: (_a = this.searchRef.current) === null || _a === void 0 ? void 0 : _a.state,
184
+ replaceHistoryState: (_b = this.replaceRef.current) === null || _b === void 0 ? void 0 : _b.state,
185
+ includeHistoryState: (_c = this.includeRef.current) === null || _c === void 0 ? void 0 : _c.state,
186
+ excludeHistoryState: (_d = this.excludeRef.current) === null || _d === void 0 ? void 0 : _d.state,
187
+ };
188
+ }
189
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
190
+ restoreState(oldState) {
191
+ var _a, _b, _c, _d;
192
+ this.matchCaseState = oldState.matchCaseState;
193
+ this.wholeWordState = oldState.wholeWordState;
194
+ this.regExpState = oldState.regExpState;
195
+ this.includeIgnoredState = oldState.includeIgnoredState;
196
+ // Override the title of the restored state, as we could have changed languages in between
197
+ this.matchCaseState.title = nls_1.nls.localizeByDefault('Match Case');
198
+ this.wholeWordState.title = nls_1.nls.localizeByDefault('Match Whole Word');
199
+ this.regExpState.title = nls_1.nls.localizeByDefault('Use Regular Expression');
200
+ this.includeIgnoredState.title = nls_1.nls.localize('theia/search-in-workspace/includeIgnoredFiles', 'Include Ignored Files');
201
+ this.showSearchDetails = oldState.showSearchDetails;
202
+ this.searchInWorkspaceOptions = oldState.searchInWorkspaceOptions;
203
+ this.searchTerm = oldState.searchTerm;
204
+ this.replaceTerm = oldState.replaceTerm;
205
+ this.showReplaceField = oldState.showReplaceField;
206
+ this.resultTreeWidget.replaceTerm = this.replaceTerm;
207
+ this.resultTreeWidget.showReplaceButtons = this.showReplaceField;
208
+ (_a = this.searchRef.current) === null || _a === void 0 ? void 0 : _a.setState(oldState.searchHistoryState);
209
+ (_b = this.replaceRef.current) === null || _b === void 0 ? void 0 : _b.setState(oldState.replaceHistoryState);
210
+ (_c = this.includeRef.current) === null || _c === void 0 ? void 0 : _c.setState(oldState.includeHistoryState);
211
+ (_d = this.excludeRef.current) === null || _d === void 0 ? void 0 : _d.setState(oldState.excludeHistoryState);
212
+ this.refresh();
213
+ }
214
+ findInFolder(uris) {
215
+ this.showSearchDetails = true;
216
+ const values = Array.from(new Set(uris.map(uri => `${uri}/**`)));
217
+ const value = values.join(', ');
218
+ this.searchInWorkspaceOptions.include = values;
219
+ if (this.includeRef.current) {
220
+ this.includeRef.current.value = value;
221
+ this.includeRef.current.addToHistory();
222
+ }
223
+ this.update();
224
+ }
225
+ /**
226
+ * Update the search term and input field.
227
+ * @param term the search term.
228
+ * @param showReplaceField controls if the replace field should be displayed.
229
+ */
230
+ updateSearchTerm(term, showReplaceField) {
231
+ this.searchTerm = term;
232
+ if (this.searchRef.current) {
233
+ this.searchRef.current.value = term;
234
+ this.searchRef.current.addToHistory();
235
+ }
236
+ if (showReplaceField) {
237
+ this.showReplaceField = true;
238
+ }
239
+ this.refresh();
240
+ }
241
+ hasResultList() {
242
+ return this.hasResults;
243
+ }
244
+ hasSearchTerm() {
245
+ return this.searchTerm !== '';
246
+ }
247
+ refresh() {
248
+ this.performSearch();
249
+ this.update();
250
+ }
251
+ getCancelIndicator() {
252
+ return this.resultTreeWidget.cancelIndicator;
253
+ }
254
+ collapseAll() {
255
+ this.resultTreeWidget.collapseAll();
256
+ this.update();
257
+ }
258
+ expandAll() {
259
+ this.resultTreeWidget.expandAll();
260
+ this.update();
261
+ }
262
+ areResultsCollapsed() {
263
+ return this.resultTreeWidget.areResultsCollapsed();
264
+ }
265
+ clear() {
266
+ this.searchTerm = '';
267
+ this.replaceTerm = '';
268
+ this.searchInWorkspaceOptions.include = [];
269
+ this.searchInWorkspaceOptions.exclude = [];
270
+ this.includeIgnoredState.enabled = false;
271
+ this.matchCaseState.enabled = false;
272
+ this.wholeWordState.enabled = false;
273
+ this.regExpState.enabled = false;
274
+ if (this.searchRef.current) {
275
+ this.searchRef.current.value = '';
276
+ }
277
+ if (this.replaceRef.current) {
278
+ this.replaceRef.current.value = '';
279
+ }
280
+ if (this.includeRef.current) {
281
+ this.includeRef.current.value = '';
282
+ }
283
+ if (this.excludeRef.current) {
284
+ this.excludeRef.current.value = '';
285
+ }
286
+ this.performSearch();
287
+ this.update();
288
+ }
289
+ onAfterAttach(msg) {
290
+ super.onAfterAttach(msg);
291
+ this.searchFormContainerRoot.render(React.createElement(React.Fragment, null,
292
+ this.renderSearchHeader(),
293
+ this.renderSearchInfo()));
294
+ browser_1.Widget.attach(this.resultTreeWidget, this.contentNode);
295
+ this.toDisposeOnDetach.push(common_1.Disposable.create(() => {
296
+ browser_1.Widget.detach(this.resultTreeWidget);
297
+ }));
298
+ }
299
+ onUpdateRequest(msg) {
300
+ super.onUpdateRequest(msg);
301
+ const searchInfo = this.renderSearchInfo();
302
+ if (searchInfo) {
303
+ this.searchFormContainerRoot.render(React.createElement(React.Fragment, null,
304
+ this.renderSearchHeader(),
305
+ searchInfo));
306
+ this.onDidUpdateEmitter.fire(undefined);
307
+ }
308
+ }
309
+ onResize(msg) {
310
+ var _a, _b;
311
+ super.onResize(msg);
312
+ (_a = this.searchRef.current) === null || _a === void 0 ? void 0 : _a.forceUpdate();
313
+ (_b = this.replaceRef.current) === null || _b === void 0 ? void 0 : _b.forceUpdate();
314
+ browser_1.MessageLoop.sendMessage(this.resultTreeWidget, browser_1.Widget.ResizeMessage.UnknownSize);
315
+ }
316
+ onAfterShow(msg) {
317
+ super.onAfterShow(msg);
318
+ this.focusInputField();
319
+ this.contextKeyService.searchViewletVisible.set(true);
320
+ }
321
+ onAfterHide(msg) {
322
+ super.onAfterHide(msg);
323
+ this.contextKeyService.searchViewletVisible.set(false);
324
+ }
325
+ onActivateRequest(msg) {
326
+ super.onActivateRequest(msg);
327
+ this.focusInputField();
328
+ }
329
+ async focusInputField() {
330
+ var _a;
331
+ // Wait until React rendering is sufficiently progressed before trying to focus the input field.
332
+ await this.refsAreSet.promise;
333
+ if ((_a = this.searchRef.current) === null || _a === void 0 ? void 0 : _a.textarea.current) {
334
+ this.searchRef.current.textarea.current.focus();
335
+ this.searchRef.current.textarea.current.select();
336
+ }
337
+ }
338
+ renderSearchHeader() {
339
+ const searchAndReplaceContainer = this.renderSearchAndReplace();
340
+ const searchDetails = this.renderSearchDetails();
341
+ return React.createElement("div", { ref: () => this.refsAreSet.resolve() },
342
+ searchAndReplaceContainer,
343
+ searchDetails);
344
+ }
345
+ renderSearchAndReplace() {
346
+ const toggleContainer = this.renderReplaceFieldToggle();
347
+ const searchField = this.renderSearchField();
348
+ const replaceField = this.renderReplaceField();
349
+ return React.createElement("div", { className: 'search-and-replace-container' },
350
+ toggleContainer,
351
+ React.createElement("div", { className: 'search-and-replace-fields' },
352
+ searchField,
353
+ replaceField));
354
+ }
355
+ renderReplaceFieldToggle() {
356
+ const toggle = React.createElement("span", { className: (0, browser_1.codicon)(this.showReplaceField ? 'chevron-down' : 'chevron-right') });
357
+ return React.createElement("div", { title: nls_1.nls.localizeByDefault('Toggle Replace'), className: 'replace-toggle', tabIndex: 0, onClick: e => {
358
+ const elArr = document.getElementsByClassName('replace-toggle');
359
+ if (elArr && elArr.length > 0) {
360
+ elArr[0].focus();
361
+ }
362
+ this.showReplaceField = !this.showReplaceField;
363
+ this.resultTreeWidget.showReplaceButtons = this.showReplaceField;
364
+ this.update();
365
+ } }, toggle);
366
+ }
367
+ renderNotification() {
368
+ if (this.workspaceService.tryGetRoots().length <= 0 && this.editorManager.all.length <= 0) {
369
+ return React.createElement("div", { className: 'search-notification show' },
370
+ React.createElement("div", null, nls_1.nls.localize('theia/search-in-workspace/noFolderSpecified', 'You have not opened or specified a folder. Only open files are currently searched.')));
371
+ }
372
+ return React.createElement("div", { className: `search-notification ${this.searchInWorkspaceOptions.maxResults && this.resultNumber >= this.searchInWorkspaceOptions.maxResults ? 'show' : ''}` },
373
+ React.createElement("div", null, nls_1.nls.localize('theia/search-in-workspace/resultSubset', 'This is only a subset of all results. Use a more specific search term to narrow down the result list.')));
374
+ }
375
+ doFocusSearchFieldContainer() {
376
+ this.searchFieldContainerIsFocused = true;
377
+ this.update();
378
+ }
379
+ doBlurSearchFieldContainer() {
380
+ this.searchFieldContainerIsFocused = false;
381
+ this.update();
382
+ }
383
+ doSearch(e) {
384
+ if (e.target) {
385
+ const searchValue = e.target.value;
386
+ if (this.searchTerm === searchValue) {
387
+ return;
388
+ }
389
+ else {
390
+ this.searchTerm = searchValue;
391
+ this.performSearch();
392
+ }
393
+ }
394
+ }
395
+ performSearch() {
396
+ const searchOptions = {
397
+ ...this.searchInWorkspaceOptions,
398
+ followSymlinks: this.shouldFollowSymlinks(),
399
+ matchCase: this.shouldMatchCase(),
400
+ multiline: this.searchTerm.includes('\n')
401
+ };
402
+ this.resultTreeWidget.search(this.searchTerm, searchOptions);
403
+ }
404
+ shouldFollowSymlinks() {
405
+ return this.searchInWorkspacePreferences['search.followSymlinks'];
406
+ }
407
+ /**
408
+ * Determine if search should be case sensitive.
409
+ */
410
+ shouldMatchCase() {
411
+ if (this.matchCaseState.enabled) {
412
+ return this.matchCaseState.enabled;
413
+ }
414
+ // search.smartCase makes siw search case-sensitive if the search term contains uppercase letter(s).
415
+ return (!!this.searchInWorkspacePreferences['search.smartCase']
416
+ && this.searchTerm !== this.searchTerm.toLowerCase());
417
+ }
418
+ renderSearchField() {
419
+ const input = React.createElement(search_in_workspace_textarea_1.SearchInWorkspaceTextArea, { id: 'search-input-field', className: 'theia-input', title: SearchInWorkspaceWidget_1.LABEL, placeholder: SearchInWorkspaceWidget_1.LABEL, defaultValue: this.searchTerm, autoComplete: 'off', onKeyUp: this.search, onKeyDown: this.onKeyDownSearch, onFocus: this.handleFocusSearchInputBox, onBlur: this.handleBlurSearchInputBox, ref: this.searchRef });
420
+ const notification = this.renderNotification();
421
+ const optionContainer = this.renderOptionContainer();
422
+ const tooMany = this.searchInWorkspaceOptions.maxResults && this.resultNumber >= this.searchInWorkspaceOptions.maxResults ? 'tooManyResults' : '';
423
+ const className = `search-field-container ${tooMany} ${this.searchFieldContainerIsFocused ? 'focused' : ''}`;
424
+ return React.createElement("div", { className: className },
425
+ React.createElement("div", { className: 'search-field', tabIndex: -1, onFocus: this.focusSearchFieldContainer, onBlur: this.blurSearchFieldContainer },
426
+ input,
427
+ optionContainer),
428
+ notification);
429
+ }
430
+ doUpdateReplaceTerm(e) {
431
+ var _a;
432
+ if (e.target) {
433
+ this.replaceTerm = e.target.value;
434
+ this.resultTreeWidget.replaceTerm = this.replaceTerm;
435
+ if (((_a = browser_1.KeyCode.createKeyCode(e.nativeEvent).key) === null || _a === void 0 ? void 0 : _a.keyCode) === browser_1.Key.ENTER.keyCode) {
436
+ this.performSearch();
437
+ }
438
+ this.update();
439
+ }
440
+ }
441
+ renderReplaceField() {
442
+ const replaceAllButtonContainer = this.renderReplaceAllButtonContainer();
443
+ const replace = nls_1.nls.localizeByDefault('Replace');
444
+ return React.createElement("div", { className: `replace-field${this.showReplaceField ? '' : ' hidden'}` },
445
+ React.createElement(search_in_workspace_textarea_1.SearchInWorkspaceTextArea, { id: 'replace-input-field', className: 'theia-input', title: replace, placeholder: replace, defaultValue: this.replaceTerm, autoComplete: 'off', onKeyUp: this.updateReplaceTerm, onFocus: this.handleFocusReplaceInputBox, onBlur: this.handleBlurReplaceInputBox, ref: this.replaceRef }),
446
+ replaceAllButtonContainer);
447
+ }
448
+ renderReplaceAllButtonContainer() {
449
+ // The `Replace All` button is enabled if there is a search term present with results.
450
+ const enabled = this.searchTerm !== '' && this.resultNumber > 0;
451
+ return React.createElement("div", { className: 'replace-all-button-container' },
452
+ React.createElement("span", { title: nls_1.nls.localizeByDefault('Replace All'), className: `${(0, browser_1.codicon)('replace-all', true)} ${enabled ? ' ' : ' disabled'}`, onClick: () => {
453
+ if (enabled) {
454
+ this.resultTreeWidget.replace(undefined);
455
+ }
456
+ } }));
457
+ }
458
+ renderOptionContainer() {
459
+ const matchCaseOption = this.renderOptionElement(this.matchCaseState);
460
+ const wholeWordOption = this.renderOptionElement(this.wholeWordState);
461
+ const regexOption = this.renderOptionElement(this.regExpState);
462
+ const includeIgnoredOption = this.renderOptionElement(this.includeIgnoredState);
463
+ return React.createElement("div", { className: 'option-buttons' },
464
+ matchCaseOption,
465
+ wholeWordOption,
466
+ regexOption,
467
+ includeIgnoredOption);
468
+ }
469
+ renderOptionElement(opt) {
470
+ return React.createElement("span", { className: `${opt.className} option action-label ${opt.enabled ? 'enabled' : ''}`, title: opt.title, onClick: () => this.handleOptionClick(opt) });
471
+ }
472
+ handleOptionClick(option) {
473
+ option.enabled = !option.enabled;
474
+ this.updateSearchOptions();
475
+ this.searchFieldContainerIsFocused = true;
476
+ this.performSearch();
477
+ this.update();
478
+ }
479
+ updateSearchOptions() {
480
+ this.searchInWorkspaceOptions.matchCase = this.matchCaseState.enabled;
481
+ this.searchInWorkspaceOptions.matchWholeWord = this.wholeWordState.enabled;
482
+ this.searchInWorkspaceOptions.useRegExp = this.regExpState.enabled;
483
+ this.searchInWorkspaceOptions.includeIgnored = this.includeIgnoredState.enabled;
484
+ }
485
+ renderSearchDetails() {
486
+ const expandButton = this.renderExpandGlobFieldsButton();
487
+ const globFieldContainer = this.renderGlobFieldContainer();
488
+ return React.createElement("div", { className: 'search-details' },
489
+ expandButton,
490
+ globFieldContainer);
491
+ }
492
+ renderGlobFieldContainer() {
493
+ const includeField = this.renderGlobField('include');
494
+ const excludeField = this.renderGlobField('exclude');
495
+ return React.createElement("div", { className: `glob-field-container${!this.showSearchDetails ? ' hidden' : ''}` },
496
+ includeField,
497
+ excludeField);
498
+ }
499
+ renderExpandGlobFieldsButton() {
500
+ return React.createElement("div", { className: 'button-container' },
501
+ React.createElement("span", { title: nls_1.nls.localizeByDefault('Toggle Search Details'), className: (0, browser_1.codicon)('ellipsis'), onClick: () => {
502
+ this.showSearchDetails = !this.showSearchDetails;
503
+ this.update();
504
+ } }));
505
+ }
506
+ renderGlobField(kind) {
507
+ const currentValue = this.searchInWorkspaceOptions[kind];
508
+ const value = currentValue && currentValue.join(', ') || '';
509
+ return React.createElement("div", { className: 'glob-field' },
510
+ React.createElement("div", { className: 'label' }, nls_1.nls.localizeByDefault('files to ' + kind)),
511
+ React.createElement(search_in_workspace_input_1.SearchInWorkspaceInput, { className: 'theia-input', type: 'text', size: 1, defaultValue: value, autoComplete: 'off', id: kind + '-glob-field', placeholder: kind === 'include'
512
+ ? nls_1.nls.localizeByDefault('e.g. *.ts, src/**/include')
513
+ : nls_1.nls.localizeByDefault('e.g. *.ts, src/**/exclude'), onKeyUp: e => {
514
+ var _a;
515
+ if (e.target) {
516
+ const targetValue = e.target.value || '';
517
+ let shouldSearch = browser_1.Key.ENTER.keyCode === ((_a = browser_1.KeyCode.createKeyCode(e.nativeEvent).key) === null || _a === void 0 ? void 0 : _a.keyCode);
518
+ const currentOptions = (this.searchInWorkspaceOptions[kind] || []).slice().map(s => s.trim()).sort();
519
+ const candidateOptions = this.splitOnComma(targetValue).map(s => s.trim()).sort();
520
+ const sameAs = (left, right) => {
521
+ if (left.length !== right.length) {
522
+ return false;
523
+ }
524
+ for (let i = 0; i < left.length; i++) {
525
+ if (left[i] !== right[i]) {
526
+ return false;
527
+ }
528
+ }
529
+ return true;
530
+ };
531
+ if (!sameAs(currentOptions, candidateOptions)) {
532
+ this.searchInWorkspaceOptions[kind] = this.splitOnComma(targetValue);
533
+ shouldSearch = true;
534
+ }
535
+ if (shouldSearch) {
536
+ this.performSearch();
537
+ }
538
+ }
539
+ }, onFocus: kind === 'include' ? this.handleFocusIncludesInputBox : this.handleFocusExcludesInputBox, onBlur: kind === 'include' ? this.handleBlurIncludesInputBox : this.handleBlurExcludesInputBox, ref: kind === 'include' ? this.includeRef : this.excludeRef }));
540
+ }
541
+ splitOnComma(patterns) {
542
+ return patterns.length > 0 ? patterns.split(',').map(s => s.trim()) : [];
543
+ }
544
+ renderSearchInfo() {
545
+ const message = this.getSearchResultMessage() || '';
546
+ return React.createElement("div", { className: 'search-info' }, message);
547
+ }
548
+ getSearchResultMessage() {
549
+ if (!this.searchTerm) {
550
+ return undefined;
551
+ }
552
+ if (this.resultNumber === 0) {
553
+ const isIncludesPresent = this.searchInWorkspaceOptions.include && this.searchInWorkspaceOptions.include.length > 0;
554
+ const isExcludesPresent = this.searchInWorkspaceOptions.exclude && this.searchInWorkspaceOptions.exclude.length > 0;
555
+ let message;
556
+ if (isIncludesPresent && isExcludesPresent) {
557
+ message = nls_1.nls.localizeByDefault("No results found in '{0}' excluding '{1}' - ", this.searchInWorkspaceOptions.include.toString(), this.searchInWorkspaceOptions.exclude.toString());
558
+ }
559
+ else if (isIncludesPresent) {
560
+ message = nls_1.nls.localizeByDefault("No results found in '{0}' - ", this.searchInWorkspaceOptions.include.toString());
561
+ }
562
+ else if (isExcludesPresent) {
563
+ message = nls_1.nls.localizeByDefault("No results found excluding '{0}' - ", this.searchInWorkspaceOptions.exclude.toString());
564
+ }
565
+ else {
566
+ message = nls_1.nls.localizeByDefault('No results found') + ' - ';
567
+ }
568
+ // We have to trim here as vscode will always add a trailing " - " string
569
+ return message.substring(0, message.length - 2).trim();
570
+ }
571
+ else {
572
+ if (this.resultNumber === 1 && this.resultTreeWidget.fileNumber === 1) {
573
+ return nls_1.nls.localizeByDefault('{0} result in {1} file', this.resultNumber.toString(), this.resultTreeWidget.fileNumber.toString());
574
+ }
575
+ else if (this.resultTreeWidget.fileNumber === 1) {
576
+ return nls_1.nls.localizeByDefault('{0} results in {1} file', this.resultNumber.toString(), this.resultTreeWidget.fileNumber.toString());
577
+ }
578
+ else if (this.resultTreeWidget.fileNumber > 0) {
579
+ return nls_1.nls.localizeByDefault('{0} results in {1} files', this.resultNumber.toString(), this.resultTreeWidget.fileNumber.toString());
580
+ }
581
+ else {
582
+ // if fileNumber === 0, return undefined so that `onUpdateRequest()` would not re-render component
583
+ return undefined;
584
+ }
585
+ }
586
+ }
587
+ };
588
+ exports.SearchInWorkspaceWidget = SearchInWorkspaceWidget;
589
+ SearchInWorkspaceWidget.ID = 'search-in-workspace';
590
+ SearchInWorkspaceWidget.LABEL = nls_1.nls.localizeByDefault('Search');
591
+ tslib_1.__decorate([
592
+ (0, inversify_1.inject)(search_in_workspace_result_tree_widget_1.SearchInWorkspaceResultTreeWidget),
593
+ tslib_1.__metadata("design:type", search_in_workspace_result_tree_widget_1.SearchInWorkspaceResultTreeWidget)
594
+ ], SearchInWorkspaceWidget.prototype, "resultTreeWidget", void 0);
595
+ tslib_1.__decorate([
596
+ (0, inversify_1.inject)(browser_2.WorkspaceService),
597
+ tslib_1.__metadata("design:type", browser_2.WorkspaceService)
598
+ ], SearchInWorkspaceWidget.prototype, "workspaceService", void 0);
599
+ tslib_1.__decorate([
600
+ (0, inversify_1.inject)(search_in_workspace_context_key_service_1.SearchInWorkspaceContextKeyService),
601
+ tslib_1.__metadata("design:type", search_in_workspace_context_key_service_1.SearchInWorkspaceContextKeyService)
602
+ ], SearchInWorkspaceWidget.prototype, "contextKeyService", void 0);
603
+ tslib_1.__decorate([
604
+ (0, inversify_1.inject)(progress_bar_factory_1.ProgressBarFactory),
605
+ tslib_1.__metadata("design:type", Function)
606
+ ], SearchInWorkspaceWidget.prototype, "progressBarFactory", void 0);
607
+ tslib_1.__decorate([
608
+ (0, inversify_1.inject)(browser_3.EditorManager),
609
+ tslib_1.__metadata("design:type", browser_3.EditorManager)
610
+ ], SearchInWorkspaceWidget.prototype, "editorManager", void 0);
611
+ tslib_1.__decorate([
612
+ (0, inversify_1.inject)(search_in_workspace_preferences_1.SearchInWorkspacePreferences),
613
+ tslib_1.__metadata("design:type", Object)
614
+ ], SearchInWorkspaceWidget.prototype, "searchInWorkspacePreferences", void 0);
615
+ tslib_1.__decorate([
616
+ (0, inversify_1.postConstruct)(),
617
+ tslib_1.__metadata("design:type", Function),
618
+ tslib_1.__metadata("design:paramtypes", []),
619
+ tslib_1.__metadata("design:returntype", void 0)
620
+ ], SearchInWorkspaceWidget.prototype, "init", null);
621
+ exports.SearchInWorkspaceWidget = SearchInWorkspaceWidget = SearchInWorkspaceWidget_1 = tslib_1.__decorate([
622
+ (0, inversify_1.injectable)()
623
+ ], SearchInWorkspaceWidget);
624
+ //# sourceMappingURL=search-in-workspace-widget.js.map