Skip to content
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

Add support for locating a bundled version of air #166

Merged
merged 8 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions .zed/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
// For a full list of overridable settings, and general information on folder-specific settings,
// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
{
"TypeScript": {
"remove_trailing_whitespace_on_save": true,
"formatter": "prettier",
"code_actions_on_format": {
"source.fixAll.eslint": true
},
"format_on_save": {
"external": {
"command": "prettier",
"arguments": ["--stdin-filepath", "{buffer_path}"]
"languages": {
"TypeScript": {
"remove_trailing_whitespace_on_save": true,
"formatter": "prettier",
"code_actions_on_format": {
"source.fixAll.eslint": true
},
"format_on_save": {
"external": {
"command": "prettier",
"arguments": ["--stdin-filepath", "{buffer_path}"]
}
}
}
},
Expand Down
5 changes: 0 additions & 5 deletions editors/code/.editorconfig

This file was deleted.

5 changes: 5 additions & 0 deletions editors/code/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"useTabs": true,
"tabWidth": 4,
"trailingComma": "all"
}
1 change: 1 addition & 0 deletions editors/code/.vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ out/**
node_modules/**
src/**
.gitignore
.prettierrc
.yarnrc
webpack.config.js
vsc-extension-quickstart.md
Expand Down
84 changes: 67 additions & 17 deletions editors/code/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion editors/code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,20 @@
"markdownDescription": "Whether settings from air.toml files should be propagated to the client (the IDE).",
"scope": "application",
"type": "boolean"
},
"air.executableLocation": {
"default": "bundled",
"markdownDescription": "Location of the `air` executable to start the language server with.",
"enum": [
"bundled",
"environment"
],
"enumDescriptions": [
"Always use the bundled `air` executable.",
"Look for an `air` executable on the `PATH`, falling back to the bundled version."
],
"scope": "window",
"type": "string"
}
}
},
Expand Down Expand Up @@ -129,20 +143,25 @@
},
"dependencies": {
"@types/p-queue": "^3.1.0",
"fs-extra": "^11.1.1",
"p-queue": "npm:@esm2cjs/p-queue@^7.3.0",
"adm-zip": "^0.5.16",
"vscode-languageclient": "^9.0.1"
"vscode-languageclient": "^9.0.1",
"which": "^4.0.0"
},
"devDependencies": {
"@types/adm-zip": "^0.5.6",
"@types/fs-extra": "^11.0.4",
"@types/mocha": "^10.0.9",
"@types/node": "20.x",
"@types/vscode": "^1.90.0",
"@types/which": "^3.0.4",
"@typescript-eslint/eslint-plugin": "^8.10.0",
"@typescript-eslint/parser": "^8.7.0",
"@vscode/test-cli": "^0.0.10",
"@vscode/test-electron": "^2.4.1",
"eslint": "^9.13.0",
"prettier": "^3.4.2",
"ts-loader": "^9.5.1",
"typescript": "^5.6.3",
"webpack": "^5.95.0",
Expand Down
36 changes: 36 additions & 0 deletions editors/code/src/binary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as vscode from "vscode";
import which from "which";
import * as output from "./output";
import { AIR_BINARY_NAME, BUNDLED_AIR_EXECUTABLE } from "./constants";

export type ExecutableLocation = "environment" | "bundled";

export async function resolveAirBinaryPath(
executableLocation: ExecutableLocation,
): Promise<string> {
if (!vscode.workspace.isTrusted) {
output.log(
`Workspace is not trusted, using bundled executable: ${BUNDLED_AIR_EXECUTABLE}`,
);
return BUNDLED_AIR_EXECUTABLE;
}

if (executableLocation === "bundled") {
// User requested the `"bundled"` air binary
output.log(
`Using bundled executable as requested by \`air.executableLocation\`: ${BUNDLED_AIR_EXECUTABLE}`,
);
return BUNDLED_AIR_EXECUTABLE;
} else {
// User requested `"environment"`, so check the `PATH` first
const environmentPath = await which(AIR_BINARY_NAME, { nothrow: true });

if (environmentPath) {
output.log(`Using environment executable: ${environmentPath}`);
return environmentPath;
} else {
output.log(`Using bundled executable: ${BUNDLED_AIR_EXECUTABLE}`);
return BUNDLED_AIR_EXECUTABLE;
}
}
}
28 changes: 28 additions & 0 deletions editors/code/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as path from "path";

const folderName = path.basename(__dirname);

/**
* Path to the root directory of this extension.
* https://github.com/microsoft/vscode-python-tools-extension-template/blob/main/src/common/constants.ts
*/
export const EXTENSION_ROOT_DIR =
DavisVaughan marked this conversation as resolved.
Show resolved Hide resolved
folderName === "common"
? path.dirname(path.dirname(__dirname))
: path.dirname(__dirname);

/**
* Name of the `air` binary based on the current platform.
*/
export const AIR_BINARY_NAME = process.platform === "win32" ? "air.exe" : "air";

/**
* Path to the `air` executable that is bundled with the extension.
* The GitHub Action is in charge of placing the executable here.
*/
export const BUNDLED_AIR_EXECUTABLE = path.join(
EXTENSION_ROOT_DIR,
"bundled",
"bin",
AIR_BINARY_NAME,
);
21 changes: 17 additions & 4 deletions editors/code/src/lsp.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import * as vscode from "vscode";
import * as lc from "vscode-languageclient/node";
import { default as PQueue } from "p-queue";
import { getInitializationOptions } from "./settings";
import { getInitializationOptions, getWorkspaceSettings } from "./settings";
import { FileSettingsState } from "./notification/sync-file-settings";
import { Middleware, ResponseError } from "vscode-languageclient/node";
import { SYNC_FILE_SETTINGS } from "./notification/sync-file-settings";
import { registerLogger } from "./output";
import { resolveAirBinaryPath } from "./binary";
import { getRootWorkspaceFolder } from "./workspace";

// All session management operations are put on a queue. They can't run
// concurrently and either result in a started or stopped state. Starting when
Expand All @@ -29,7 +32,7 @@ export class Lsp {

constructor(context: vscode.ExtensionContext) {
this.channel = vscode.window.createOutputChannel("Air Language Server");
context.subscriptions.push(this.channel);
context.subscriptions.push(this.channel, registerLogger(this.channel));
this.stateQueue = new PQueue({ concurrency: 1 });
this.fileSettings = new FileSettingsState(context);
}
Expand Down Expand Up @@ -59,10 +62,17 @@ export class Lsp {
return;
}

const workspaceFolder = await getRootWorkspaceFolder();

const workspaceSettings = getWorkspaceSettings("air", workspaceFolder);
const initializationOptions = getInitializationOptions("air");

const command = await resolveAirBinaryPath(
workspaceSettings.executableLocation,
);

let serverOptions: lc.ServerOptions = {
command: "air",
command: command,
args: ["language-server"],
};

Expand Down Expand Up @@ -94,7 +104,10 @@ export class Lsp {

const config = vscode.workspace.getConfiguration(
undefined,
{ uri, languageId },
{
uri,
languageId,
},
);
items[i] = config.get(item.section);
}
Expand Down
Loading
Loading