Skip to content

Commit

Permalink
Add integration for Swift-MesonLSP
Browse files Browse the repository at this point in the history
Co-Authored-By: Tristan Partin <tristan@partin.io>
  • Loading branch information
JCWasmx86 and tristan957 committed Sep 28, 2023
1 parent 6212905 commit 8bd8c7c
Show file tree
Hide file tree
Showing 9 changed files with 619 additions and 72 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
- Add syntax highlight for `meson.options` files.
- Fix listing tests in the Test Explorer on activation
- Add support to run executables that are not installed (eg: examples)
- Add integration with
[Swift-MesonLSP](https://github.com/JCWasmx86/Swift-MesonLSP). vscode-meson
will automatically download it on Windows, Linux and MacOS. Linux users can
follow the [docs](https://github.com/JCWasmx86/Swift-MesonLSP/tree/main/Docs)
if they want to have updates delivered using their package manager.

## 1.10.0

Expand Down
41 changes: 40 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@
{
"command": "mesonbuild.benchmark",
"title": "Meson: Run Benchmarks"
},
{
"command": "mesonbuild.restartLanguageServer",
"title": "Meson: Restart Language Server"
}
],
"configuration": {
Expand Down Expand Up @@ -187,6 +191,35 @@
]
},
"description": "Give an object that's merged into the debug configuration provider"
},
"mesonbuild.languageServer": {
"type": "string",
"default": "Swift-MesonLSP",
"enum": [
"Swift-MesonLSP",
null
],
"description": "Select which language server to use"
},
"mesonbuild.languageServerPath": {
"type": "string",
"description": "Binary name or path to language server",
"default": ""
},
"mesonbuild.downloadLanguageServer": {
"type": "string",
"default": "ask",
"enum": [
true,
false,
"ask"
],
"enumDescriptions": [
"Download the language server",
"Do not download the language server",
"Ask every time to download the language server"
],
"description": "Have VSCode download the language server automatically (MacOS/Windows only for Swift-MesonLSP)"
}
}
},
Expand Down Expand Up @@ -338,14 +371,20 @@
"watch": "tsc -watch -p ./"
},
"devDependencies": {
"@types/adm-zip": "^0.5.1",
"@types/node": "^16.11.7",
"@types/vscode": "^1.1.59",
"@types/which": "^3.0.0",
"husky": "^8.0.3",
"lint-staged": "^14.0.1",
"prettier": "^3.0.3",
"typescript": "^4.4.4"
},
"dependencies": {},
"dependencies": {
"adm-zip": "0.5.10",
"vscode-languageclient": "8.0.2",
"which": "4.0.0"
},
"prettier": {
"proseWrap": "always"
}
Expand Down
73 changes: 63 additions & 10 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import {
useCompileCommands,
clearCache,
checkMesonIsConfigured,
getOutputChannel,
} from "./utils";
import { DebugConfigurationProvider } from "./configprovider";
import { testDebugHandler, testRunHandler, rebuildTests } from "./tests";
import { activateLinters } from "./linters";
import { activateFormatters } from "./formatters";
import { TaskQuickPickItem } from "./types";
import { SettingsKey, TaskQuickPickItem } from "./types";
import { createLanguageServerClient } from "./lsp/common";

export let extensionPath: string;
let explorer: MesonProjectExplorer;
Expand All @@ -34,9 +36,6 @@ export async function activate(ctx: vscode.ExtensionContext) {
const root = vscode.workspace.workspaceFolders[0].uri.fsPath;
const buildDir = workspaceRelative(extensionConfiguration("buildFolder"));

activateLinters(root, ctx);
activateFormatters(ctx);

explorer = new MesonProjectExplorer(ctx, root, buildDir);

ctx.subscriptions.push(
Expand Down Expand Up @@ -176,8 +175,7 @@ export async function activate(ctx: vscode.ExtensionContext) {
);

if (!checkMesonIsConfigured(buildDir)) {
const configureOnOpenKey = "configureOnOpen";
let configureOnOpen = extensionConfiguration(configureOnOpenKey);
let configureOnOpen = extensionConfiguration(SettingsKey.configureOnOpen);
if (configureOnOpen === "ask") {
enum Options {
yes = "Yes",
Expand All @@ -196,25 +194,80 @@ export async function activate(ctx: vscode.ExtensionContext) {
break;

case Options.never:
extensionConfigurationSet(configureOnOpenKey, false, vscode.ConfigurationTarget.Workspace);
extensionConfigurationSet(SettingsKey.configureOnOpen, false, vscode.ConfigurationTarget.Workspace);
break;

case Options.yes:
configureOnOpen = true;
break;

case Options.always:
extensionConfigurationSet(configureOnOpenKey, true, vscode.ConfigurationTarget.Workspace);
extensionConfigurationSet(SettingsKey.configureOnOpen, true, vscode.ConfigurationTarget.Workspace);
configureOnOpen = true;
break;
}
}
}

if (configureOnOpen === true) {
runFirstTask("reconfigure");
const downloadLanguageServer = extensionConfiguration(SettingsKey.downloadLanguageServer);
const server = extensionConfiguration(SettingsKey.languageServer);
const shouldDownload = async (downloadLanguageServer: boolean | "ask"): Promise<boolean> => {
if (typeof downloadLanguageServer === "boolean") return downloadLanguageServer;

enum Options {
yes = "Yes",
no = "Not this time",
never = "Never",
}

const response = await vscode.window.showInformationMessage(
"Should the extension try to download the language server?",
...Object.values(Options),
);

switch (response) {
case Options.yes:
extensionConfigurationSet(SettingsKey.downloadLanguageServer, true, vscode.ConfigurationTarget.Global);
return true;

case Options.never:
extensionConfigurationSet(SettingsKey.downloadLanguageServer, false, vscode.ConfigurationTarget.Global);
return false;

case Options.no:
extensionConfigurationSet(SettingsKey.downloadLanguageServer, "ask", vscode.ConfigurationTarget.Global);
return false;
}

return false;
};

let client = await createLanguageServerClient(server, await shouldDownload(downloadLanguageServer), ctx);
if (client !== null && server == "Swift-MesonLSP") {
ctx.subscriptions.push(client);
client.start();

getOutputChannel().appendLine("Not enabling the muon linter/formatter because Swift-MesonLSP is active.");
} else {
activateLinters(root, ctx);
activateFormatters(ctx);
}

ctx.subscriptions.push(
vscode.commands.registerCommand("mesonbuild.restartLanguageServer", async () => {
if (client === null) {
client = await createLanguageServerClient(server, await shouldDownload(downloadLanguageServer), ctx);
if (client !== null) {
ctx.subscriptions.push(client);
client.start();
// TODO: The output line from above about not enabling muon would be good to have here.
}
} else {
client.restart();
}
}),
);

async function pickTask(mode: string) {
const picker = vscode.window.createQuickPick<TaskQuickPickItem>();
picker.busy = true;
Expand Down
58 changes: 58 additions & 0 deletions src/lsp/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as vscode from "vscode";
import { LanguageServerClient } from ".";
import { LanguageServer } from "../types";
import { SwiftMesonLspLanguageClient } from "./swift-mesonlsp";
import { Uri } from "vscode";

export async function createLanguageServerClient(
server: LanguageServer,
download: boolean,
context: vscode.ExtensionContext,
): Promise<LanguageServerClient | null> {
const serverToClass = (server: LanguageServer) => {
switch (server) {
case "Swift-MesonLSP":
return SwiftMesonLspLanguageClient;
default:
return null;
}
};

const klass = serverToClass(server);
if (klass == null) {
return null;
}
if (!klass.supportsSystem()) {
vscode.window.showErrorMessage("The configured language server does not support the current system.");
return null;
}

let languageServerPath = LanguageServerClient.resolveLanguageServerPath(server, context);
if (languageServerPath === null) {
if (klass.artifact() == null) {
enum Options {
open = "Open documentation in browser",
}
const response = await vscode.window.showErrorMessage(
"This language server supports your systen, but provides no artifacts for automatic setup",
...Object.values(Options),
);
if (response == Options.open) {
vscode.env.openExternal(Uri.parse(klass.setupURL));
}
return null;
}
if (download) {
languageServerPath = await klass.download(server, klass.version, context);
if (languageServerPath === null) {
vscode.window.showErrorMessage("Failed to download the language server.");
return null;
}
} else {
vscode.window.showErrorMessage("Failed to find a language server on the system.");
return null;
}
}

return new klass(languageServerPath, context);
}
Loading

0 comments on commit 8bd8c7c

Please sign in to comment.