Skip to content

Commit

Permalink
use rust for langauge server
Browse files Browse the repository at this point in the history
  • Loading branch information
CppCXY committed Jan 7, 2025
1 parent b481f2f commit e76dc35
Show file tree
Hide file tree
Showing 8 changed files with 579 additions and 508 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ jobs:
strategy:
matrix:
include:
- {target: win32-x64, file: EmmyLua.LanguageServer-win32-x64.zip}
- {target: linux-x64, file: EmmyLua.LanguageServer-linux-x64.tar.gz}
- {target: darwin-x64, file: EmmyLua.LanguageServer-darwin-x64.zip}
- {target: darwin-arm64, file: EmmyLua.LanguageServer-darwin-arm64.zip}
- {target: win32-x64, file: emmylua_ls-win32-x64.zip}
- {target: win32-ia32, file: emmylua_ls-win32-ia32.zip}
- {target: win32-arm64, file: emmylua_ls-win32-arm64.zip}
- {target: linux-x64, file: emmylua_ls-linux-x64-glibc.2.17.tar.gz}
- {target: linux-arm64, file: emmylua_ls-linux-aarch64-glibc.2.17.tar.gz}
- {target: darwin-x64, file: emmylua_ls-darwin-x64.zip}
- {target: darwin-arm64, file: emmylua_ls-darwin-arm64.zip}

runs-on: ubuntu-latest

Expand Down
4 changes: 2 additions & 2 deletions build/config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
exports.default = {
emmyDebuggerVersion: '1.8.2',
emmyDebuggerUrl: 'https://github.com/EmmyLua/EmmyLuaDebugger/releases/download',
newLanguageServerVersion: "0.7.1",
newLanguageServerUrl: "https://github.com/CppCXY/EmmyLuaAnalyzer/releases/download"
newLanguageServerVersion: "0.1.5",
newLanguageServerUrl: "https://github.com/CppCXY/emmylua-analyzer-rust/releases/download"
}
17 changes: 2 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -272,22 +272,9 @@
"type": "string",
"default": "#FF6699"
},
"emmylua.colors.upvalue": {
"type": "string",
"default": "#a8c023"
},
"emmylua.colors.local": {
"type": "array",
"items": {
"type": "string"
},
"description": "Local variable colors",
"default": [
"#66CCFF",
"#ADD8E6",
"#FFA07A",
"#90EE90"
]
"type": "string",
"default": "#66CCFF"
}
}
},
Expand Down
118 changes: 51 additions & 67 deletions src/annotator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import * as vscode from 'vscode';
import { AnnotatorType } from './lspExt';
import { LanguageClient } from 'vscode-languageclient/node';
Expand All @@ -7,57 +6,60 @@ import * as notifications from "./lspExt";

let D_PARAM: vscode.TextEditorDecorationType;
let D_GLOBAL: vscode.TextEditorDecorationType;
let D_LOCALS: vscode.TextEditorDecorationType[];
let D_UPVALUE: vscode.TextEditorDecorationType;
let D_LOCAL: vscode.TextEditorDecorationType;
let D_MUT_LOCAL: vscode.TextEditorDecorationType;
let D_MUT_PARAM: vscode.TextEditorDecorationType;

function createDecoration(key: string | undefined, config: vscode.DecorationRenderOptions = {}): vscode.TextEditorDecorationType {
if (key == undefined) {
return vscode.window.createTextEditorDecorationType(config);
}
function createDecoration(key: string): vscode.TextEditorDecorationType {
let config: vscode.DecorationRenderOptions = {}
let color = vscode.workspace.getConfiguration("emmylua").get(key);
if (typeof (color) === 'string') {
config.light = { color: color };
config.dark = { color: color };
config.light = { color };
config.dark = { color };
}
return vscode.window.createTextEditorDecorationType(config);
}

function createDecorations(key: string, config: vscode.DecorationRenderOptions = {}): vscode.TextEditorDecorationType[] {
let colors = vscode.workspace.getConfiguration("emmylua").get(key);
if (colors instanceof Array) {
return colors.map(color => vscode.window.createTextEditorDecorationType({
light: { color: color },
dark: { color: color }
}));
function createDecorationUnderline(key: string): vscode.TextEditorDecorationType {
let config: vscode.DecorationRenderOptions = {}
let color = vscode.workspace.getConfiguration("emmylua").get(key);
if (typeof (color) === 'string') {
config.light = {
color,
textDecoration: `underline;text-decoration-color:${color};`
};
config.dark = {
color,
textDecoration: `underline;text-decoration-color:${color};`
};
} else {
config.light = {
textDecoration: `underline;`
};
config.dark = {
textDecoration: `underline;`
};
}
return [];
return vscode.window.createTextEditorDecorationType(config);
}

function disposeDecorations(...decorations: (vscode.TextEditorDecorationType | undefined)[]) {
decorations.forEach(d => d && d.dispose());
}

function updateDecorations() {
// 各种方式更新时之前的decoration没有dispose导致重复渲染
if (D_PARAM) {
D_PARAM.dispose();
D_GLOBAL.dispose();
D_LOCALS.forEach(d => d.dispose());
D_UPVALUE.dispose();
disposeDecorations(D_PARAM, D_GLOBAL, D_LOCAL, D_MUT_LOCAL, D_MUT_PARAM);
}

D_PARAM = createDecoration("colors.parameter");
D_GLOBAL = createDecoration("colors.global");
D_LOCALS = createDecorations("colors.local");

let upvalueColor = vscode.workspace.getConfiguration("emmylua").get("colors.upvalue");
if (upvalueColor && upvalueColor != "") {
D_UPVALUE = createDecoration(undefined, {
textDecoration: `underline;text-decoration-color:${upvalueColor};`
});
}
else {
D_UPVALUE = createDecoration(undefined);
}
D_LOCAL = createDecoration("colors.local");
D_MUT_LOCAL = createDecorationUnderline("colors.local");
D_MUT_PARAM = createDecorationUnderline("colors.parameter");
}

export function onDidChangeConfiguration(client: LanguageClient) {
export function onDidChangeConfiguration() {
updateDecorations();
}

Expand All @@ -78,62 +80,44 @@ function requestAnnotatorsImpl(editor: vscode.TextEditor, client: LanguageClient
let params: notifications.AnnotatorParams = { uri: editor.document.uri.toString() };
client.sendRequest<notifications.IAnnotator[]>("emmy/annotator", params).then(list => {
let map: Map<AnnotatorType, vscode.Range[]> = new Map();
map.set(AnnotatorType.Param, []);
map.set(AnnotatorType.ReadOnlyParam, []);
map.set(AnnotatorType.Global, []);
map.set(AnnotatorType.Upvalue, []);

let local_maps = new Map<number, vscode.Range[]>();
for (let i = 0; i < D_LOCALS.length; i++) {
local_maps.set(i, []);
}
map.set(AnnotatorType.ReadOnlyLocal, []);
map.set(AnnotatorType.MutLocal, []);
map.set(AnnotatorType.MutParam, []);

if (!list) {
return;
}

let local_index = 0;

list.forEach(annotation => {
if (annotation.type !== AnnotatorType.Local) {
let ranges = map.get(annotation.type);
if (ranges) {
ranges.push(...annotation.ranges);
}
} else if (D_LOCALS.length > 0) {
let ranges = local_maps.get(local_index);
if (!ranges) {
ranges = [];
local_maps.set(local_index, ranges);
}
let ranges = map.get(annotation.type);
if (ranges) {
ranges.push(...annotation.ranges);
local_index++;
if (local_index >= D_LOCALS.length) {
local_index = 0;
}
}
});
map.forEach((v, k) => {
updateAnnotators(editor, k, v);
});

local_maps.forEach((v, i) => {
if (i < D_LOCALS.length) {
editor.setDecorations(D_LOCALS[i], v);
}
});
});
}

function updateAnnotators(editor: vscode.TextEditor, type: AnnotatorType, ranges: vscode.Range[]) {
switch (type) {
case AnnotatorType.Param:
case AnnotatorType.ReadOnlyParam:
editor.setDecorations(D_PARAM, ranges);
break;
case AnnotatorType.Global:
editor.setDecorations(D_GLOBAL, ranges);
break;
case AnnotatorType.Upvalue:
editor.setDecorations(D_UPVALUE, ranges);
case AnnotatorType.ReadOnlyLocal:
editor.setDecorations(D_LOCAL, ranges);
break;
case AnnotatorType.MutLocal:
editor.setDecorations(D_MUT_LOCAL, ranges);
break;
case AnnotatorType.MutParam:
editor.setDecorations(D_MUT_PARAM, ranges);
break;
}
}
91 changes: 37 additions & 54 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { InlineDebugAdapterFactory } from './debugger/DebugFactory'
import * as os from 'os';
import * as fs from 'fs';
import { IServerLocation, IServerPosition } from './lspExt';
import { onDidChangeConfiguration } from './annotator';

export let ctx: EmmyContext;
let activeEditor: vscode.TextEditor;
Expand All @@ -34,6 +35,13 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(onDidChangeActiveTextEditor, null, context.subscriptions));
context.subscriptions.push(vscode.commands.registerCommand("emmy.insertEmmyDebugCode", insertEmmyDebugCode));
context.subscriptions.push(vscode.languages.setLanguageConfiguration("lua", new LuaLanguageConfiguration()));
context.subscriptions.push(
vscode.workspace.onDidChangeConfiguration(e => {
if (e.affectsConfiguration("emmylua")) {
onDidChangeConfiguration()
}
})
);
startServer();
registerDebuggers();
return {
Expand Down Expand Up @@ -97,17 +105,26 @@ async function startServer() {
});
}

const serverPaths: { [key: string]: { [key: string]: string } } = {
win32: {
arm64: 'emmylua_ls-win32-arm64',
x64: 'emmylua_ls-win32-x64',
ia32: 'emmylua_ls-win32-ia32'
},
linux: {
arm64: 'emmylua_ls-linux-aarch64-glibc.2.17',
x64: 'emmylua_ls-linux-x64-glibc.2.17'
},
darwin: {
arm64: 'emmylua_ls-darwin-arm64',
x64: 'emmylua_ls-darwin-x64'
}
};

async function doStartServer() {
const context = ctx.extensionContext;
const clientOptions: LanguageClientOptions = {
documentSelector: [{ scheme: 'file', language: ctx.LANGUAGE_ID }],
// synchronize: {
// configurationSection: ["emmylua", "files.associations"],
// fileEvents: [
// vscode.workspace.createFileSystemWatcher("**/*.lua"),
// vscode.workspace.createFileSystemWatcher("**/.editorconfig"),
// ]
// },
initializationOptions: {}
};

Expand All @@ -130,54 +147,20 @@ async function doStartServer() {
return Promise.resolve(result);
};
} else {
let platform: string = os.platform();
let platform = os.platform();
let arch = os.arch();
let executableName = platform === 'win32' ? 'emmylua_ls.exe' : 'emmylua_ls';

const serverDir = serverPaths[platform]?.[arch];
if (!serverDir) {
vscode.window.showErrorMessage(`Unsupported platform: ${platform} ${arch}`);
return;
}

const command = path.join(context.extensionPath, 'server', serverDir, executableName);

let command: string = "";
switch (platform) {
case "win32":
command = path.join(
context.extensionPath,
'server',
'emmylua_ls-win32-x64',
'emmylua_ls.exe'
)
break;
case "linux":
if (os.arch() === "arm64") {
command = path.join(
context.extensionPath,
'server',
'emmylua_ls-linux-arm64',
'emmylua_ls'
);
} else {
command = path.join(
context.extensionPath,
'server',
'emmylua_ls-linux-x64',
'emmylua_ls'
);
}
fs.chmodSync(command, '777');
break;
case "darwin":
if (os.arch() === "arm64") {
command = path.join(
context.extensionPath,
'server',
'emmylua_ls-darwin-arm64',
'emmylua_ls'
);
} else {
command = path.join(
context.extensionPath,
'server',
'emmylua_ls-darwin-x64',
'emmylua_ls'
);
}
fs.chmodSync(command, '777');
break;
if (platform !== 'win32') {
fs.chmodSync(command, '777');
}
serverOptions = {
command: command,
Expand Down
7 changes: 4 additions & 3 deletions src/lspExt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ export interface AnnotatorParams {
}

export enum AnnotatorType {
Param,
ReadOnlyParam,
Global,
Local,
Upvalue,
ReadOnlyLocal,
MutLocal,
MutParam,
}

export interface IAnnotator {
Expand Down
Loading

0 comments on commit e76dc35

Please sign in to comment.