Skip to content

Commit f99bc17

Browse files
plemarquandMahdiBM
andauthored
Add "auto" mode to sourcekit-lsp backgroundIndexing setting (#1232)
* Add "auto" mode to sourcekit-lsp backgroundIndexing setting Now that backgroundIndexing is no longer experimental it can be enabled by default in Swift 6.1. This patch evolves the `sourcekit-lsp.backgroundIndexing` setting to be an enum with three possible values, `true`, `false` or `auto`. The `true` and `false` options function as they did previously. The new `auto` setting will enable background indexing on Swift >= 6.1. To enable background indexing on Swift 6.0 the user must still set this setting to `true`, as this feature is experimental in 6.0. Co-authored-by: Mahdi Bahrami <[email protected]>
1 parent 47eff44 commit f99bc17

File tree

4 files changed

+85
-12
lines changed

4 files changed

+85
-12
lines changed

package.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,9 +475,14 @@
475475
"order": 3
476476
},
477477
"swift.sourcekit-lsp.backgroundIndexing": {
478-
"type": "boolean",
479-
"default": false,
480-
"markdownDescription": "**Experimental**: Enable or disable background indexing. This option has no effect in Swift versions prior to 6.0.",
478+
"type": "string",
479+
"enum": [
480+
"on",
481+
"off",
482+
"auto"
483+
],
484+
"default": "auto",
485+
"markdownDescription": "Turns background indexing `on` or `off`. `auto` will enable background indexing if the Swift version is >= 6.1. This option has no effect in Swift versions prior to 6.0.",
481486
"order": 4
482487
},
483488
"swift.sourcekit-lsp.trace.server": {

src/configuration.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,17 @@ const configuration = {
242242
.get<boolean>("backgroundCompilation", false);
243243
},
244244
/** background indexing */
245-
get backgroundIndexing(): boolean {
246-
return vscode.workspace
245+
get backgroundIndexing(): "on" | "off" | "auto" {
246+
const value = vscode.workspace
247247
.getConfiguration("swift.sourcekit-lsp")
248-
.get("backgroundIndexing", false);
248+
.get("backgroundIndexing", "auto");
249+
250+
// Legacy versions of this setting were a boolean, convert to the new string version.
251+
if (typeof value === "boolean") {
252+
return value ? "on" : "off";
253+
} else {
254+
return value;
255+
}
249256
},
250257
/** focus on problems view whenever there is a build error */
251258
get actionAfterBuildError(): ActionAfterBuildError {

src/sourcekit-lsp/LanguageClientManager.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ export class LanguageClientManager {
129129
// that are not at the root of their workspace
130130
public subFolderWorkspaces: vscode.Uri[];
131131
private namedOutputChannels: Map<string, LSPOutputChannel> = new Map();
132+
private swiftVersion: Version;
133+
132134
/** Get the current state of the underlying LanguageClient */
133135
public get state(): langclient.State {
134136
if (!this.languageClient) {
@@ -142,9 +144,8 @@ export class LanguageClientManager {
142144
LanguageClientManager.indexingLogName,
143145
new LSPOutputChannel(LanguageClientManager.indexingLogName, false, true)
144146
);
145-
this.singleServerSupport = workspaceContext.swiftVersion.isGreaterThanOrEqual(
146-
new Version(5, 7, 0)
147-
);
147+
this.swiftVersion = workspaceContext.swiftVersion;
148+
this.singleServerSupport = this.swiftVersion.isGreaterThanOrEqual(new Version(5, 7, 0));
148149
this.subscriptions = [];
149150
this.subFolderWorkspaces = [];
150151
if (this.singleServerSupport) {
@@ -613,10 +614,18 @@ export class LanguageClientManager {
613614
},
614615
};
615616

616-
if (configuration.backgroundIndexing) {
617+
// Swift 6.0.0 and later supports background indexing.
618+
// In 6.0.0 it is experimental so only "true" enables it.
619+
// In 6.1.0 it is no longer experimental, and so "auto" or "true" enables it.
620+
if (
621+
this.swiftVersion.isGreaterThanOrEqual(new Version(6, 0, 0)) &&
622+
(configuration.backgroundIndexing === "on" ||
623+
(configuration.backgroundIndexing === "auto" &&
624+
this.swiftVersion.isGreaterThanOrEqual(new Version(6, 1, 0))))
625+
) {
617626
options = {
618627
...options,
619-
backgroundIndexing: configuration.backgroundIndexing,
628+
backgroundIndexing: true,
620629
backgroundPreparationMode: "enabled",
621630
};
622631
}

test/unit-tests/sourcekit-lsp/LanguageClientManager.test.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ suite("LanguageClientManager Suite", () => {
6565
let createFilesEmitter: AsyncEventEmitter<vscode.FileCreateEvent>;
6666
let deleteFilesEmitter: AsyncEventEmitter<vscode.FileDeleteEvent>;
6767

68+
const doesNotHave = (prop: any) =>
69+
match(function (actual) {
70+
if (typeof actual === "object") {
71+
return !(prop in actual);
72+
}
73+
return actual[prop] === undefined;
74+
}, "doesNotHave");
75+
6876
setup(async () => {
6977
// Mock pieces of the VSCode API
7078
mockedVSCodeWindow.activeTextEditor = undefined;
@@ -153,7 +161,7 @@ suite("LanguageClientManager Suite", () => {
153161
// LSP configuration defaults
154162
mockedConfig.path = "";
155163
mockedConfig.buildArguments = [];
156-
mockedConfig.backgroundIndexing = false;
164+
mockedConfig.backgroundIndexing = "off";
157165
mockedConfig.swiftEnvironmentVariables = {};
158166
mockedLspConfig.supportCFamily = "cpptools-inactive";
159167
mockedLspConfig.disable = false;
@@ -177,6 +185,50 @@ suite("LanguageClientManager Suite", () => {
177185
expect(languageClientMock.start).to.have.been.calledOnce;
178186
});
179187

188+
test("chooses the correct backgroundIndexing value is auto, swift version if 6.0.0", async () => {
189+
mockedWorkspace.swiftVersion = new Version(6, 0, 0);
190+
mockedConfig.backgroundIndexing = "auto";
191+
new LanguageClientManager(instance(mockedWorkspace));
192+
await waitForReturnedPromises(languageClientMock.start);
193+
194+
expect(mockedLangClientModule.LanguageClient).to.have.been.calledOnceWith(
195+
match.string,
196+
match.string,
197+
match.object,
198+
match.hasNested("initializationOptions", doesNotHave("backgroundIndexing"))
199+
);
200+
});
201+
202+
test("chooses the correct backgroundIndexing value is auto, swift version if 6.1.0", async () => {
203+
mockedWorkspace.swiftVersion = new Version(6, 1, 0);
204+
mockedConfig.backgroundIndexing = "auto";
205+
206+
new LanguageClientManager(instance(mockedWorkspace));
207+
await waitForReturnedPromises(languageClientMock.start);
208+
209+
expect(mockedLangClientModule.LanguageClient).to.have.been.calledOnceWith(
210+
match.string,
211+
match.string,
212+
match.object,
213+
match.hasNested("initializationOptions.backgroundIndexing", match.truthy)
214+
);
215+
});
216+
217+
test("chooses the correct backgroundIndexing value is true, swift version if 6.0.0", async () => {
218+
mockedWorkspace.swiftVersion = new Version(6, 0, 0);
219+
mockedConfig.backgroundIndexing = "on";
220+
221+
new LanguageClientManager(instance(mockedWorkspace));
222+
await waitForReturnedPromises(languageClientMock.start);
223+
224+
expect(mockedLangClientModule.LanguageClient).to.have.been.calledOnceWith(
225+
match.string,
226+
match.string,
227+
match.object,
228+
match.hasNested("initializationOptions.backgroundIndexing", match.truthy)
229+
);
230+
});
231+
180232
test("notifies SourceKit-LSP of WorkspaceFolder changes", async () => {
181233
const folder1 = mockObject<FolderContext>({
182234
isRootFolder: false,

0 commit comments

Comments
 (0)