Skip to content

Commit 0ed41eb

Browse files
committed
Server-side search: use include/exclude specs (fix intersystems-community#1019)
1 parent f3a2b12 commit 0ed41eb

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

src/providers/FileSystemProvider/TextSearchProvider.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,43 @@ export class TextSearchProvider implements vscode.TextSearchProvider {
104104
} else {
105105
const sysStr = params.has("system") && params.get("system").length ? params.get("system") : "0";
106106
const genStr = params.has("generated") && params.get("generated").length ? params.get("generated") : "0";
107+
108+
let uri = options.folder;
109+
110+
if (!new URLSearchParams(uri.query).has("filter")) {
111+
// Unless isfs spec already includes a filter (which it rarely does), apply includes and excludes at the server side.
112+
// If include or exclude field is set to, say, A1B2M*.int there will be two consecutive options.[in|ex]cludes elements:
113+
// **/A1B2M*.int/**
114+
// **/A1B2M*.int
115+
//
116+
// Ignore first, and strip **/ prefix from second.
117+
// When 'Use Exclude Settings and Ignore Files' is enabled (which is typical) options.excludes will also contain entries from files.exclude and search.exclude settings.
118+
// This will result in additional server-side filtering which is probably superfluous but harmless (other than perhaps incurring a performance cost, probably small).
119+
const tidyFilters = (filters: string[]): string[] => {
120+
return filters
121+
.map((value, index, array) =>
122+
value.endsWith("/**") && index < array.length - 1 && array[index + 1] + "/**" === value
123+
? ""
124+
: value.startsWith("**/")
125+
? value.slice(3)
126+
: value
127+
)
128+
.filter((value) => value !== "");
129+
};
130+
const tidiedIncludes = tidyFilters(options.includes);
131+
const tidiedExcludes = tidyFilters(options.excludes);
132+
const filter = tidiedIncludes.join(",") + (tidiedExcludes.length === 0 ? "" : ",'" + tidiedExcludes.join(",'"));
133+
if (filter) {
134+
uri = options.folder.with({ query: `filter=${filter}` });
135+
}
136+
}
107137
searchPromise = api
108138
.actionSearch({
109139
query: query.pattern,
110140
regex: query.isRegExp,
111141
word: query.isWordMatch,
112142
case: query.isCaseSensitive,
113-
files: fileSpecFromURI(options.folder),
143+
files: fileSpecFromURI(uri),
114144
sys: sysStr === "1" || (sysStr === "0" && api.ns === "%SYS"),
115145
gen: genStr === "1",
116146
// If options.maxResults is null the search is supposed to return an unlimited number of results

0 commit comments

Comments
 (0)