Skip to content

Support different toolchains per folder #1478

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 29, 2025
Merged
17 changes: 3 additions & 14 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import { runTask } from "./commands/runTask";
import { TestKind } from "./TestExplorer/TestKind";
import { pickProcess } from "./commands/pickProcess";
import { openDocumentation } from "./commands/openDocumentation";
import showFolderSelectionQuickPick from "./utilities/folderQuickPick";
import restartLSPServer from "./commands/restartLSPServer";

/**
* References:
Expand Down Expand Up @@ -97,6 +97,7 @@ export enum Commands {
DEBUG_ALL_TESTS = "swift.debugAllTests",
COVER_ALL_TESTS = "swift.coverAllTests",
OPEN_MANIFEST = "swift.openManifest",
RESTART_LSP = "swift.restartLSPServer",
}

/**
Expand Down Expand Up @@ -147,19 +148,7 @@ export function register(ctx: WorkspaceContext): vscode.Disposable[] {
),
vscode.commands.registerCommand(Commands.RUN_PLUGIN_TASK, () => runPluginTask()),
vscode.commands.registerCommand(Commands.RUN_TASK, name => runTask(ctx, name)),
vscode.commands.registerCommand("swift.restartLSPServer", async () => {
const folder =
ctx.currentFolder ??
(await showFolderSelectionQuickPick(
ctx,
"Select a folder to restart the LSP server for"
));
if (!folder) {
return;
}
const languageClientManager = ctx.languageClientManager.get(folder);
await languageClientManager.restart();
}),
vscode.commands.registerCommand(Commands.RESTART_LSP, () => restartLSPServer(ctx)),
vscode.commands.registerCommand("swift.reindexProject", () => reindexProject(ctx)),
vscode.commands.registerCommand("swift.insertFunctionComment", () =>
insertFunctionComment(ctx)
Expand Down
5 changes: 1 addition & 4 deletions src/commands/dependencies/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,12 @@ import { FolderContext } from "../../FolderContext";
import { createSwiftTask, SwiftTaskProvider } from "../../tasks/SwiftTaskProvider";
import { WorkspaceContext } from "../../WorkspaceContext";
import { executeTaskWithUI, updateAfterError } from "../utilities";
import showFolderSelectionQuickPick from "../../utilities/folderQuickPick";

/**
* Executes a {@link vscode.Task task} to resolve this package's dependencies.
*/
export async function resolveDependencies(ctx: WorkspaceContext) {
const current =
ctx.currentFolder ??
(await showFolderSelectionQuickPick(ctx, "Select a folder to resolve dependencies for"));
const current = ctx.currentFolder;
if (!current) {
return false;
}
Expand Down
59 changes: 59 additions & 0 deletions src/commands/restartLSPServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the VS Code Swift open source project
//
// Copyright (c) 2025 the VS Code Swift project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of VS Code Swift project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import * as vscode from "vscode";
import { WorkspaceContext } from "../WorkspaceContext";
import { FolderContext } from "../FolderContext";

export default async function restartLSPServer(ctx: WorkspaceContext) {
const toolchainLookup = ctx.folders.reduce(
(acc, folder) => {
acc[folder.swiftVersion.toString()] = acc[folder.swiftVersion.toString()] ?? [];
acc[folder.swiftVersion.toString()].push({
folder,
fullToolchainName: folder.toolchain.swiftVersionString,
});
return acc;
},
{} as Record<string, { folder: FolderContext; fullToolchainName: string }[]>
);

const toolchains: vscode.QuickPickItem[] = Object.keys(toolchainLookup).map(key => ({
label: key,
description: toolchainLookup[key][0].fullToolchainName,
detail: toolchainLookup[key].map(({ folder }) => folder.name).join(", "),
}));

// Skip picking a toolchain if there is only one option to pick
if (toolchains.length === 1) {
return restartLSP(ctx, toolchains[0].label);
}

const selected = await vscode.window.showQuickPick(toolchains, {
title: "Restart LSP server",
placeHolder: "Select a sourcekit-lsp instance to restart",
canPickMany: false,
});

if (!selected) {
return undefined;
}

return restartLSP(ctx, selected.label);
}

async function restartLSP(ctx: WorkspaceContext, version: string) {
const languageClientManager = ctx.languageClientManager.getByVersion(version);
await languageClientManager.restart();
}
11 changes: 10 additions & 1 deletion src/sourcekit-lsp/LanguageClientToolchainCoordinator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,16 @@ export class LanguageClientToolchainCoordinator implements vscode.Disposable {
* @returns
*/
public get(folder: FolderContext): LanguageClientManager {
const client = this.clients.get(folder.swiftVersion.toString());
return this.getByVersion(folder.swiftVersion.toString());
}

/**
* Returns the LanguageClientManager for the supplied toolchain version.
* @param folder
* @returns
*/
public getByVersion(version: string): LanguageClientManager {
const client = this.clients.get(version);
if (!client) {
throw new Error(
"LanguageClientManager has not yet been created. This is a bug, please file an issue at https://github.com/swiftlang/vscode-swift/issues"
Expand Down
38 changes: 0 additions & 38 deletions src/utilities/folderQuickPick.ts

This file was deleted.