2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { asArray, coalesce } from '../../../../base/common/arrays.js';
7
>
import { CancellationToken } from '../../../../base/common/cancellation.js';
8
>
import { URI } from '../../../../base/common/uri.js';
9
>
import { IProgress } from '../../../../platform/progress/common/progress.js';
10
>
import { DEFAULT_TEXT_SEARCH_PREVIEW_OPTIONS } from './search.js';
11
>
import { Range, FileSearchProvider2, FileSearchProviderOptions, ProviderResult, TextSearchComplete2, TextSearchContext2, TextSearchMatch2, TextSearchProvider2, TextSearchProviderOptions, TextSearchQuery2, TextSearchResult2, TextSearchCompleteMessage } from './searchExtTypes.js';
12
>
13
>
// old types that are retained for backward compatibility
14
>
// TODO: delete this when search apis are adopted by all first-party extensions
15
>
16
>
/**
17
>
* A relative pattern is a helper to construct glob patterns that are matched
18
>
* relatively to a base path. The base path can either be an absolute file path
19
>
* or a [workspace folder](#WorkspaceFolder).
20
>
*/
21
>
export interface RelativePattern {
22
>
23
>
/**
24
>
* A base file path to which this pattern will be matched against relatively.
25
>
*/
26
>
base: string;
27
>
28
>
/**
29
>
* A file glob pattern like `*.{ts,js}` that will be matched on file paths
30
>
* relative to the base path.
31
>
*
32
>
* Example: Given a base of `/home/work/folder` and a file path of `/home/work/folder/index.js`,
33
>
* the file glob pattern will match on `index.js`.
34
>
*/
35
>
pattern: string;
36
>
}
37
>
38
>
/**
39
>
* A file glob pattern to match file paths against. This can either be a glob pattern string
40
>
* (like `** /*.{ts,js}` without space before / or `*.{ts,js}`) or a [relative pattern](#RelativePattern).
41
>
*
42
>
* Glob patterns can have the following syntax:
43
>
* * `*` to match zero or more characters in a path segment
44
>
* * `?` to match on one character in a path segment
45
>
* * `**` to match any number of path segments, including none
46
>
* * `{}` to group conditions (e.g. `** /*.{ts,js}` without space before / matches all TypeScript and JavaScript files)
47
>
* * `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
48
>
* * `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
49
>
*
50
>
* Note: a backslash (`\`) is not valid within a glob pattern. If you have an existing file
51
>
* path to match against, consider to use the [relative pattern](#RelativePattern) support
52
>
* that takes care of converting any backslash into slash. Otherwise, make sure to convert
53
>
* any backslash to slash when creating the glob pattern.
54
>
*/
55
>
export type GlobPattern = string | RelativePattern;
56
>
57
>
/**
58
>
* The parameters of a query for text search.
59
>
*/
60
>
export interface TextSearchQuery {
61
>
/**
62
>
* The text pattern to search for.
63
>
*/
64
>
pattern: string;
65
>
66
>
/**
67
>
* Whether or not `pattern` should match multiple lines of text.
68
>
*/
69
>
isMultiline?: boolean;
70
>
71
>
/**
72
>
* Whether or not `pattern` should be interpreted as a regular expression.
73
>
*/
74
>
isRegExp?: boolean;
75
>
76
>
/**
77
>
* Whether or not the search should be case-sensitive.
78
>
*/
79
>
isCaseSensitive?: boolean;
80
>
81
>
/**
82
>
* Whether or not to search for whole word matches only.
83
>
*/
84
>
isWordMatch?: boolean;
85
>
}
86
>
87
>
/**
88
>
* A file glob pattern to match file paths against.
89
>
* TODO@roblou - merge this with the GlobPattern docs/definition in vscode.d.ts.
90
>
* @see [GlobPattern](#GlobPattern)
91
>
*/
92
>
export type GlobString = string;
93
>
94
>
/**
95
>
* Options common to file and text search
96
>
*/
97
>
export interface SearchOptions {
98
>
/**
99
>
* The root folder to search within.
100
>
*/
101
>
folder: URI;
102
>
103
>
/**
104
>
* Files that match an `includes` glob pattern should be included in the search.
105
>
*/
106
>
includes: GlobString[];
107
>
108
>
/**
109
>
* Files that match an `excludes` glob pattern should be excluded from the search.
110
>
*/
111
>
excludes: GlobString[];
112
>
113
>
/**
114
>
* Whether external files that exclude files, like .gitignore, should be respected.
115
>
* See the vscode setting `"search.useIgnoreFiles"`.
116
>
*/
117
>
useIgnoreFiles: boolean;
118
>
119
>
/**
120
>
* Whether symlinks should be followed while searching.
121
>
* See the vscode setting `"search.followSymlinks"`.
122
>
*/
123
>
followSymlinks: boolean;
124
>
125
>
/**
126
>
* Whether global files that exclude files, like .gitignore, should be respected.
127
>
* See the vscode setting `"search.useGlobalIgnoreFiles"`.
128
>
*/
129
>
useGlobalIgnoreFiles: boolean;
130
>
131
>
/**
132
>
* Whether files in parent directories that exclude files, like .gitignore, should be respected.
133
>
* See the vscode setting `"search.useParentIgnoreFiles"`.
134
>
*/
135
>
useParentIgnoreFiles: boolean;
136
>
}
137
>
138
>
/**
139
>
* Options to specify the size of the result text preview.
140
>
* These options don't affect the size of the match itself, just the amount of preview text.
141
>
*/
142
>
export interface TextSearchPreviewOptions {
143
>
/**
144
>
* The maximum number of lines in the preview.
145
>
* Only search providers that support multiline search will ever return more than one line in the match.
146
>
*/
147
>
matchLines: number;
148
>
149
>
/**
150
>
* The maximum number of characters included per line.
151
>
*/
152
>
charsPerLine: number;
153
>
}
154
>
155
>
/**
156
>
* Options that apply to text search.
157
>
*/
158
>
export interface TextSearchOptions extends SearchOptions {
159
>
/**
160
>
* The maximum number of results to be returned.
161
>
*/
162
>
maxResults: number;
163
>
164
>
/**
165
>
* Options to specify the size of the result text preview.
166
>
*/
167
>
previewOptions?: TextSearchPreviewOptions;
168
>
169
>
/**
170
>
* Exclude files larger than `maxFileSize` in bytes.
171
>
*/
172
>
maxFileSize?: number;
173
>
174
>
/**
175
>
* Interpret files using this encoding.
176
>
* See the vscode setting `"files.encoding"`
177
>
*/
178
>
encoding?: string;
179
>
180
>
/**
181
>
* Number of lines of context to include before each match.
182
>
*/
183
>
beforeContext?: number;
184
>
185
>
/**
186
>
* Number of lines of context to include after each match.
187
>
*/
188
>
afterContext?: number;
189
>
}
190
>
/**
191
>
* Options that apply to AI text search.
192
>
*/
193
>
export interface AITextSearchOptions extends SearchOptions {
194
>
/**
195
>
* The maximum number of results to be returned.
196
>
*/
197
>
maxResults: number;
198
>
199
>
/**
200
>
* Options to specify the size of the result text preview.
201
>
*/
202
>
previewOptions?: TextSearchPreviewOptions;
203
>
204
>
/**
205
>
* Exclude files larger than `maxFileSize` in bytes.
206
>
*/
207
>
maxFileSize?: number;
208
>
209
>
/**
210
>
* Number of lines of context to include before each match.
211
>
*/
212
>
beforeContext?: number;
213
>
214
>
/**
215
>
* Number of lines of context to include after each match.
216
>
*/
217
>
afterContext?: number;
218
>
}
219
>
220
>
/**
221
>
* Information collected when text search is complete.
222
>
*/
223
>
export interface TextSearchComplete {
224
>
/**
225
>
* Whether the search hit the limit on the maximum number of search results.
226
>
* `maxResults` on [`TextSearchOptions`](#TextSearchOptions) specifies the max number of results.
227
>
* - If exactly that number of matches exist, this should be false.
228
>
* - If `maxResults` matches are returned and more exist, this should be true.
229
>
* - If search hits an internal limit which is less than `maxResults`, this should be true.
230
>
*/
231
>
limitHit?: boolean;
232
>
233
>
/**
234
>
* Additional information regarding the state of the completed search.
235
>
*
236
>
* Supports links in markdown syntax:
237
>
* - Click to [run a command](command:workbench.action.OpenQuickPick)
238
>
* - Click to [open a website](https://aka.ms)
239
>
*/
240
>
message?: TextSearchCompleteMessage | TextSearchCompleteMessage[];
241
>
}
242
>
243
>
/**
244
>
* The parameters of a query for file search.
245
>
*/
246
>
export interface FileSearchQuery {
247
>
/**
248
>
* The search pattern to match against file paths.
249
>
*/
250
>
pattern: string;
251
>
}
252
>
253
>
/**
254
>
* Options that apply to file search.
255
>
*/
256
>
export interface FileSearchOptions extends SearchOptions {
257
>
/**
258
>
* The maximum number of results to be returned.
259
>
*/
260
>
maxResults?: number;
261
>
262
>
/**
263
>
* A CancellationToken that represents the session for this search query. If the provider chooses to, this object can be used as the key for a cache,
264
>
* and searches with the same session object can search the same cache. When the token is cancelled, the session is complete and the cache can be cleared.
265
>
*/
266
>
session?: CancellationToken;
267
>
}
268
>
269
>
/**
270
>
* A preview of the text result.
271
>
*/
272
>
export interface TextSearchMatchPreview {
273
>
/**
274
>
* The matching lines of text, or a portion of the matching line that contains the match.
275
>
*/
276
>
text: string;
277
>
278
>
/**
279
>
* The Range within `text` corresponding to the text of the match.
280
>
* The number of matches must match the TextSearchMatch's range property.
281
>
*/
282
>
matches: Range | Range[];
283
>
}
284
>
285
>
/**
286
>
* A match from a text search
287
>
*/
288
>
export interface TextSearchMatch {
289
>
/**
290
>
* The uri for the matching document.
291
>
*/
292
>
uri: URI;
293
>
294
>
/**
295
>
* The range of the match within the document, or multiple ranges for multiple matches.
296
>
*/
297
>
ranges: Range | Range[];
298
>
299
>
/**
300
>
* A preview of the text match.
301
>
*/
302
>
preview: TextSearchMatchPreview;
303
>
}
304
>
305
>
/**
306
>
* Checks if the given object is of type TextSearchMatch.
307
>
* @param object The object to check.
308
>
* @returns True if the object is a TextSearchMatch, false otherwise.
309
>
*/
310
function isTextSearchMatch(object: any): object is TextSearchMatch {
311
return 'uri' in object && 'ranges' in object && 'preview' in object;
312
}
314
>
/**
315
>
* A line of context surrounding a TextSearchMatch.
316
>
*/
317
>
export interface TextSearchContext {
318
>
/**
319
>
* The uri for the matching document.
320
>
*/
321
>
uri: URI;
322
>
323
>
/**
324
>
* One line of text.
325
>
* previewOptions.charsPerLine applies to this
326
>
*/
327
>
text: string;
328
>
329
>
/**
330
>
* The line number of this line of context.
331
>
*/
332
>
lineNumber: number;
333
>
}
334
>
335
>
export type TextSearchResult = TextSearchMatch | TextSearchContext;
336
>
337
>
/**
338
>
* A FileSearchProvider provides search results for files in the given folder that match a query string. It can be invoked by quickaccess or other extensions.
339
>
*
340
>
* A FileSearchProvider is the more powerful of two ways to implement file search in VS Code. Use a FileSearchProvider if you wish to search within a folder for
341
>
* all files that match the user's query.
342
>
*
343
>
* The FileSearchProvider will be invoked on every keypress in quickaccess. When `workspace.findFiles` is called, it will be invoked with an empty query string,
344
>
* and in that case, every file in the folder should be returned.
345
>
*/
346
>
export interface FileSearchProvider {
347
>
/**
348
>
* Provide the set of files that match a certain file path pattern.
349
>
* @param query The parameters for this query.
350
>
* @param options A set of options to consider while searching files.
351
>
* @param progress A progress callback that must be invoked for all results.
352
>
* @param token A cancellation token.
353
>
*/
354
>
provideFileSearchResults(query: FileSearchQuery, options: FileSearchOptions, token: CancellationToken): ProviderResult<URI[]>;
355
>
}
356
>
357
>
/**
358
>
* A TextSearchProvider provides search results for text results inside files in the workspace.
359
>
*/
360
>
export interface TextSearchProvider {
361
>
/**
362
>
* Provide results that match the given text pattern.
363
>
* @param query The parameters for this query.
364
>
* @param options A set of options to consider while searching.
365
>
* @param progress A progress callback that must be invoked for all results.
366
>
* @param token A cancellation token.
367
>
*/
368
>
provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: IProgress<TextSearchResult>, token: CancellationToken): ProviderResult<TextSearchComplete>;
369
>
}
370
>
/**
371
>
* Options that can be set on a findTextInFiles search.
372
>
*/
373
>
export interface FindTextInFilesOptions {
374
>
/**
375
>
* A [glob pattern](#GlobPattern) that defines the files to search for. The glob pattern
376
>
* will be matched against the file paths of files relative to their workspace. Use a [relative pattern](#RelativePattern)
377
>
* to restrict the search results to a [workspace folder](#WorkspaceFolder).
378
>
*/
379
>
include?: GlobPattern;
380
>
381
>
/**
382
>
* A [glob pattern](#GlobPattern) that defines files and folders to exclude. The glob pattern
383
>
* will be matched against the file paths of resulting matches relative to their workspace. When `undefined` only default excludes will
384
>
* apply, when `null` no excludes will apply.
385
>
*/
386
>
exclude?: GlobPattern | null;
387
>
388
>
/**
389
>
* The maximum number of results to search for
390
>
*/
391
>
maxResults?: number;
392
>
393
>
/**
394
>
* Whether external files that exclude files, like .gitignore, should be respected.
395
>
* See the vscode setting `"search.useIgnoreFiles"`.
396
>
*/
397
>
useIgnoreFiles?: boolean;
398
>
399
>
/**
400
>
* Whether global files that exclude files, like .gitignore, should be respected.
401
>
* See the vscode setting `"search.useGlobalIgnoreFiles"`.
402
>
*/
403
>
useGlobalIgnoreFiles?: boolean;
404
>
405
>
/**
406
>
* Whether files in parent directories that exclude files, like .gitignore, should be respected.
407
>
* See the vscode setting `"search.useParentIgnoreFiles"`.
408
>
*/
409
>
useParentIgnoreFiles: boolean;
410
>
411
>
/**
412
>
* Whether symlinks should be followed while searching.
413
>
* See the vscode setting `"search.followSymlinks"`.
414
>
*/
415
>
followSymlinks?: boolean;
416
>
417
>
/**
418
>
* Interpret files using this encoding.
419
>
* See the vscode setting `"files.encoding"`
420
>
*/
421
>
encoding?: string;
422
>
423
>
/**
424
>
* Options to specify the size of the result text preview.
425
>
*/
426
>
previewOptions?: TextSearchPreviewOptions;
427
>
428
>
/**
429
>
* Number of lines of context to include before each match.
430
>
*/
431
>
beforeContext?: number;
432
>
433
>
/**
434
>
* Number of lines of context to include after each match.
435
>
*/
436
>
afterContext?: number;
437
>
}
438
>
439
function newToOldFileProviderOptions(options: FileSearchProviderOptions): FileSearchOptions[] {
440
return options.folderOptions.map(folderOption => ({