diff --git a/.gitignore b/.gitignore index d6f9bac..c59a64f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -/out -/node_modules +out +node_modules package-lock.json /testproj .vscode diff --git a/coc-meson/.npmignore b/coc-meson/.npmignore new file mode 100644 index 0000000..6875b6f --- /dev/null +++ b/coc-meson/.npmignore @@ -0,0 +1,3 @@ +/* +!/out/ +*.map diff --git a/coc-meson/README.md b/coc-meson/README.md new file mode 100644 index 0000000..6c0b198 --- /dev/null +++ b/coc-meson/README.md @@ -0,0 +1,26 @@ +# Meson for Visual Studio Code + +Ported from [vscode-meson](https://github.com/deribaucourt/vscode-meson). + +Because some APIs of [vscode](github.com/microsoft/vscode) are missing in +[coc.nvim](https://github.com/neoclide/coc.nvim), disable some features +temporarily: + +- tasks: miss `vscode.task` + +## Install + +- [coc-marketplace](https://github.com/fannheyward/coc-marketplace) +- [npm](https://www.npmjs.com/package/coc-meson) +- vim: + +```vim +" command line +CocInstall coc-meson +" or add the following code to your vimrc +let g:coc_global_extensions = ['coc-meson', 'other coc-plugins'] +``` + +## Usage + +Refer [vscode-meson](https://github.com/deribaucourt/vscode-meson). diff --git a/coc-meson/package.json b/coc-meson/package.json new file mode 100644 index 0000000..92e622f --- /dev/null +++ b/coc-meson/package.json @@ -0,0 +1,567 @@ +{ + "name": "coc-meson", + "displayName": "Meson", + "description": "Meson language support for Visual Studio Code", + "icon": "graphics/icon.png", + "version": "1.22.0", + "license": "Apache-2.0", + "publisher": "mesonbuild", + "author": { + "name": "The Meson Project" + }, + "contributors": [ + { + "name": "Ali Sabil" + }, + { + "name": "Nathan Graule", + "email": "solarliner@gmail.com", + "url": "https://solarliner.me" + }, + { + "name": "Dylan Baker", + "email": "dylan@pnwbakers.com", + "url": "https://recursiveascent.blogspot.com/" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/mesonbuild/vscode-meson.git" + }, + "bugs": { + "url": "https://github.com/mesonbuild/vscode-meson/issues" + }, + "homepage": "https://github.com/mesonbuild/vscode-meson/blob/master/README.md", + "engines": { + "coc": "^0.0.82" + }, + "categories": [ + "Programming Languages" + ], + "activationEvents": [ + "onLanguage:meson", + "onDebugDynamicConfigurations", + "onDebugDynamicConfigurations:cppdbg", + "onDebugDynamicConfigurations:lldb" + ], + "main": "./out/extension.js", + "contributes": { + "commands": [ + { + "command": "mesonbuild.openBuildFile", + "title": "Open meson.build", + "icon": "$(preferences-open-settings)" + }, + { + "command": "mesonbuild.reconfigure", + "title": "Meson: Reconfigure", + "icon": { + "dark": "res/meson_32.svg", + "light": "res/meson_32.svg" + } + }, + { + "command": "mesonbuild.clean", + "title": "Meson: Clean" + }, + { + "command": "mesonbuild.build", + "title": "Meson: Build" + }, + { + "command": "mesonbuild.test", + "title": "Meson: Run Unit Tests" + }, + { + "command": "mesonbuild.run", + "title": "Meson: Run Executable" + }, + { + "command": "mesonbuild.install", + "title": "Meson: Install" + }, + { + "command": "mesonbuild.benchmark", + "title": "Meson: Run Benchmarks" + }, + { + "command": "mesonbuild.restartLanguageServer", + "title": "Meson: Restart Language Server" + }, + { + "command": "mesonbuild.selectRootDir", + "title": "Meson: Select Project Root Directory" + } + ], + "configuration": { + "title": "Meson build configuration", + "properties": { + "mesonbuild.selectRootDir": { + "type": "boolean", + "default": true, + "description": "Ask to select a Meson project root directory when more than one project is detected." + }, + "mesonbuild.configureOnOpen": { + "type": [ + "boolean", + "string" + ], + "default": "ask", + "enum": [ + true, + false, + "ask" + ], + "enumDescriptions": [ + "Automatically configure on open", + "Never configure on open", + "Ask every time" + ], + "description": "Have VS Code run Meson configure on opening a folder." + }, + "mesonbuild.buildFolder": { + "type": "string", + "default": "builddir", + "description": "Specify in which folder Meson configures and builds the project. Changing this value will reload the VS Code window." + }, + "mesonbuild.configureOptions": { + "type": "array", + "default": [], + "description": "Specify the list of options used for setup." + }, + "mesonbuild.configureEnvironment": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "default": {}, + "description": "Specify the list of additional environment variables used for setup." + }, + "mesonbuild.setupOptions": { + "type": "array", + "default": [], + "description": "Specify the list of options used for setup. Can be used to specify a cross file (use --cross-file=FILE).", + "deprecationMessage": "--cross-file and --native-file should be in configureOptions too." + }, + "mesonbuild.testOptions": { + "type": "array", + "default": [], + "description": "Specify the list of options used for running tests." + }, + "mesonbuild.testEnvironment": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "default": {}, + "description": "Specify the list of additional environment variables used for running tests." + }, + "mesonbuild.benchmarkOptions": { + "type": "array", + "default": [ + "--verbose" + ], + "description": "Specify the list of options used for running benchmarks. --benchmark is implicit." + }, + "mesonbuild.mesonPath": { + "type": "string", + "default": "meson", + "description": "Specify the meson executable to use" + }, + "mesonbuild.muonPath": { + "type": "string", + "default": "muon", + "description": "Specify the muon executable to use" + }, + "mesonbuild.linting.enabled": { + "type": "boolean", + "default": true, + "description": "Globally enable/disable linting" + }, + "mesonbuild.linter.muon.enabled": { + "type": "boolean", + "default": false, + "description": "Enable muon linter" + }, + "mesonbuild.formatting.enabled": { + "type": "boolean", + "default": false, + "description": "Globally enable/disable formatting" + }, + "mesonbuild.formatting.provider": { + "type": "string", + "default": "muon", + "enum": [ + "muon" + ], + "description": "Select which formatting provider to use" + }, + "mesonbuild.formatting.muonConfig": { + "type": "string", + "default": null, + "description": "Path to muon formatter config.ini" + }, + "mesonbuild.debugOptions": { + "type": "object", + "default": { + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + }, + "description": "Give an object that's merged into the debug configuration provider" + }, + "mesonbuild.languageServer": { + "type": [ + "string", + "null" + ], + "default": "mesonlsp", + "enum": [ + "Swift-MesonLSP", + "mesonlsp", + null + ], + "description": "Select which language server to use. Swift-MesonLSP is a legacy alias for mesonlsp." + }, + "mesonbuild.languageServerPath": { + "type": "string", + "description": "Binary name or path to language server", + "default": "mesonlsp" + }, + "mesonbuild.downloadLanguageServer": { + "type": [ + "boolean", + "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)" + }, + "mesonbuild.modifySettings": { + "type": [ + "boolean", + "array" + ], + "items": { + "enum": [ + "ms-vscode.cpptools", + "rust-lang.rust-analyzer" + ] + }, + "default": true, + "markdownDescription": "Automatically setup other extensions to use files generated by Meson. Set it to `false` if for example `.vscode/settings.json` is committed into git and should not be modified. It can also be an array of extension IDs of the following:\n- [`ms-vscode.cpptools`](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)\n- [`rust-lang.rust-analyzer`](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)." + }, + "mesonbuild.mesonlsp.others.defaultFormattingConfig": { + "type": [ + "null", + "string" + ], + "default": null, + "description": "Default muon config to use for formatting" + }, + "mesonbuild.mesonlsp.others.ignoreDiagnosticsFromSubprojects": { + "type": [ + "boolean", + "array" + ], + "default": false, + "description": "Ignore diagnostics from either all subprojects (if true) or from selected subprojects (if the value is an array)" + }, + "mesonbuild.mesonlsp.others.disableInlayHints": { + "type": "boolean", + "default": false, + "description": "Disable inlay hints" + }, + "mesonbuild.mesonlsp.others.removeDefaultTypesInInlayHints": { + "type": "boolean", + "default": false, + "description": "Reduce clutter in inlay hints by removing any|dict(any)|list(any)" + }, + "mesonbuild.mesonlsp.others.disablePosargInlayHints": { + "type": "boolean", + "default": false, + "description": "Disable inlay hints for arguments" + }, + "mesonbuild.mesonlsp.others.useCustomParser": { + "type": "boolean", + "default": true, + "description": "If true, a custom faster parser is used with better diagnostics, set to `false` it will fall back to the tree-sitter based parser" + }, + "mesonbuild.mesonlsp.others.muonPath": { + "type": "string", + "default": null, + "description": "Set path to muon that will be used for formatting" + }, + "mesonbuild.mesonlsp.linting.disableNameLinting": { + "type": "boolean", + "default": false, + "description": "Disable checking variable names for snake_case" + }, + "mesonbuild.mesonlsp.linting.disableAllIdLinting": { + "type": "boolean", + "default": false, + "description": "Shortcut for all other `mesonbuild.mesonlsp.linting.disableXXXIdLinting` options" + }, + "mesonbuild.mesonlsp.linting.disableCompilerIdLinting": { + "type": "boolean", + "default": false, + "description": "Disable checking whether a string literal is a known id, if comparing it with the result of `compiler.get_id()`" + }, + "mesonbuild.mesonlsp.linting.disableCompilerArgumentIdLinting": { + "type": "boolean", + "default": false, + "description": "Disable checking whether a string literal is a known id, if comparing it with the result of `compiler.get_argument_syntax()`" + }, + "mesonbuild.mesonlsp.linting.disableLinkerIdLinting": { + "type": "boolean", + "default": false, + "description": "Disable checking whether a string literal is a known id, if comparing it with the result of `compiler.get_linker_id()`" + }, + "mesonbuild.mesonlsp.linting.disableCpuFamilyLinting": { + "type": "boolean", + "default": false, + "description": "Disable checking whether a string literal is a known CPU family, if comparing it with the result of `XXX_machine.cpu_family()`" + }, + "mesonbuild.mesonlsp.linting.disableOsFamilyLinting": { + "type": "boolean", + "default": false, + "description": "Disable checking whether a string literal is a known system, if comparing it with the result of `XXX_machine.system()`" + }, + "mesonbuild.mesonlsp.linting.disableUnusedVariableCheck": { + "type": "boolean", + "default": false, + "description": "Disable checking whether a variable is unused" + }, + "mesonbuild.mesonlsp.linting.disableArgTypeChecking": { + "type": "boolean", + "default": false, + "description": "Disable checking whether the types of arguments passed to a method or function are correct" + } + } + }, + "taskDefinitions": [ + { + "type": "meson", + "required": [ + "mode" + ], + "properties": { + "target": { + "type": "string", + "description": "The Meson target. The full name, including path and type, is mandatory (e.g. relative/path/to/targetname:shared_library)", + "default": "all", + "dependencies": { + "mode": { + "enum": [ + "build", + "test" + ] + } + } + }, + "filename": { + "type": "string", + "description": "Filename to run as part of the target", + "dependencies": { + "mode": { + "enum": [ + "run" + ] + } + } + }, + "mode": { + "type": "string", + "description": "Specify the kind of task to perform", + "enum": [ + "build", + "run", + "test", + "reconfigure", + "clean", + "install" + ], + "default": "build" + } + } + } + ], + "languages": [ + { + "id": "meson", + "aliases": [ + "Meson", + "meson", + "mesonbuild" + ], + "filenames": [ + "meson.build", + "meson_options.txt", + "meson.options" + ], + "configuration": "./language-configuration.json", + "icon": { + "dark": "res/meson_32.svg", + "light": "res/meson_32.svg" + } + }, + { + "id": "ini", + "filenamePatterns": [ + "**/subprojects/*.wrap" + ], + "aliases": [ + "Meson Wrap" + ] + } + ], + "grammars": [ + { + "language": "meson", + "scopeName": "source.meson", + "path": "./syntaxes/meson.tmLanguage.json" + } + ], + "snippets": [ + { + "language": "meson", + "path": "./snippets/meson.json" + } + ], + "viewsContainers": { + "activitybar": [ + { + "id": "meson-sidebar", + "title": "Meson", + "icon": "res/meson_32.svg" + } + ] + }, + "views": { + "meson-sidebar": [ + { + "id": "meson-project", + "name": "Current project", + "when": "mesonbuild.hasProject" + } + ] + }, + "menus": { + "view/item/context": [ + { + "command": "mesonbuild.openBuildFile", + "when": "view == meson-project && viewItem == meson-target", + "group": "inline" + } + ], + "view/title": [ + { + "command": "mesonbuild.reconfigure", + "when": "view == meson-project", + "group": "navigation" + } + ], + "commandPalette": [ + { + "command": "mesonbuild.openBuildFile", + "when": "false" + }, + { + "command": "mesonbuild.reconfigure", + "when": "mesonbuild.hasProject" + }, + { + "command": "mesonbuild.clean", + "when": "mesonbuild.hasProject" + }, + { + "command": "mesonbuild.build", + "when": "mesonbuild.hasProject" + }, + { + "command": "mesonbuild.test", + "when": "mesonbuild.hasProject" + }, + { + "command": "mesonbuild.run", + "when": "mesonbuild.hasProject" + }, + { + "command": "mesonbuild.install", + "when": "mesonbuild.hasProject" + }, + { + "command": "mesonbuild.benchmark", + "when": "mesonbuild.hasProject" + }, + { + "command": "mesonbuild.restartLanguageServer", + "when": "mesonbuild.hasProject" + }, + { + "command": "mesonbuild.selectRootDir", + "when": "mesonbuild.hasMultipleProjects" + } + ] + }, + "problemMatchers": [ + { + "name": "meson-gcc", + "source": "gcc", + "owner": "meson", + "fileLocation": [ + "autoDetect", + "${workspaceFolder}/${config:mesonbuild.buildFolder}" + ], + "pattern": { + "regexp": "^(.*?):(\\d+):(\\d*):?\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "message": 5 + } + } + ] + }, + "scripts": { + "patch": "scripts/patch.sh ../src/**.ts", + "compile": "tsc -p ./", + "prepack": "npm run patch && npm run compile", + "markdownlint:check": "markdownlint-cli2 **.md", + "prettier:check": "prettier --check **.md **.ts **.yml **.json", + "vscode:prepublish": "npm run compile", + "watch": "tsc -watch -p ./" + }, + "devDependencies": { + "@types/adm-zip": "^0.5.1", + "@types/node": "^16.11.7", + "@types/which": "^3.0.0", + "coc.nvim": "^0.0.83-next.18", + "husky": "^8.0.3", + "lint-staged": "^14.0.1", + "markdownlint-cli2": "^0.10.0", + "prettier": "^3.0.3", + "typescript": "^5.2.2" + }, + "dependencies": { + "adm-zip": "^0.5.10", + "which": "^4.0.0" + }, + "prettier": { + "proseWrap": "always" + } +} diff --git a/coc-meson/scripts/patch.pl b/coc-meson/scripts/patch.pl new file mode 100755 index 0000000..5363953 --- /dev/null +++ b/coc-meson/scripts/patch.pl @@ -0,0 +1,2 @@ +#!/usr/bin/env -S perl -p +s=//#==; diff --git a/coc-meson/scripts/patch.sh b/coc-meson/scripts/patch.sh new file mode 100755 index 0000000..4197d23 --- /dev/null +++ b/coc-meson/scripts/patch.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -e +cd "$(dirname "$(dirname "$(readlink -f "$0")")")" + +for file; do + scripts/patch.pl "$file" | cpp -DHAVE_COC_NVIM -xassembler-with-cpp -nostdinc -P -C -o"${file#*/}" +done diff --git a/coc-meson/src/.gitignore b/coc-meson/src/.gitignore new file mode 100644 index 0000000..a68d087 --- /dev/null +++ b/coc-meson/src/.gitignore @@ -0,0 +1,2 @@ +/* +!/.gitignore diff --git a/coc-meson/tsconfig.json b/coc-meson/tsconfig.json new file mode 100644 index 0000000..d4e2f2f --- /dev/null +++ b/coc-meson/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../tsconfig", + "compilerOptions": { + "outDir": "out", + "rootDir": "src", + "strict": false, + "allowSyntheticDefaultImports": true, + }, + "exclude": [ + "src/cpptoolsconfigprovider.ts", + "src/debug/index.ts", + "src/tasks.ts", + "src/tests.ts", + "src/treeview/*" + ] +} diff --git a/src/dialogs.ts b/src/dialogs.ts index 5aecc06..1fef5f8 100644 --- a/src/dialogs.ts +++ b/src/dialogs.ts @@ -1,4 +1,8 @@ +//# #if HAVE_VSCODE import * as vscode from "vscode"; +//# #elif HAVE_COC_NVIM +//# import * as vscode from "coc.nvim"; +//# #endif import * as path from "path"; import { extensionConfiguration, extensionConfigurationSet } from "./utils"; import { SettingsKey } from "./types"; @@ -112,7 +116,9 @@ export async function selectRootDir(rootDirs: string[]): Promise 1); + //# #endif if (!rootDir) return; const sourceDir = rootDir; const buildDir = getBuildDirectory(sourceDir); workspaceState.update("mesonbuild.buildDir", buildDir); workspaceState.update("mesonbuild.sourceDir", sourceDir); + //# #if HAVE_VSCODE cpptools = new CpptoolsProvider(buildDir); registerCppToolsProvider(ctx, cpptools); @@ -234,6 +243,7 @@ export async function activate(ctx: vscode.ExtensionContext) { } else { await rebuildTests(controller); } + //# #endif const server = extensionConfiguration(SettingsKey.languageServer); let client = await createLanguageServerClient(server, await askShouldDownloadLanguageServer(), ctx); @@ -278,6 +288,7 @@ export async function activate(ctx: vscode.ExtensionContext) { }), ); + //# #if HAVE_VSCODE async function pickTask(mode: string) { const picker = vscode.window.createQuickPick(); picker.busy = true; @@ -321,4 +332,5 @@ export async function activate(ctx: vscode.ExtensionContext) { runTask(taskItem.task); } } + //# #endif } diff --git a/src/formatters.ts b/src/formatters.ts index 1087de8..1b24a37 100644 --- a/src/formatters.ts +++ b/src/formatters.ts @@ -1,4 +1,8 @@ +//# #if HAVE_VSCODE import * as vscode from "vscode"; +//# #elif HAVE_COC_NVIM +//# import * as vscode from "coc.nvim"; +//# #endif import { extensionConfiguration, getOutputChannel } from "./utils"; import { ToolCheckFunc, Tool } from "./types"; import * as muon from "./tools/muon"; @@ -34,7 +38,11 @@ async function reloadFormatters(sourceRoot: string, context: vscode.ExtensionCon return disposables; } + //# #if HAVE_VSCODE const sub = vscode.languages.registerDocumentFormattingEditProvider("meson", { + //# #elif HAVE_COC_NVIM + //# const sub = vscode.languages.registerDocumentFormatProvider(["meson"], { + //# #endif async provideDocumentFormattingEdits(document: vscode.TextDocument): Promise { return await props.format(checkResult.tool, sourceRoot, document); }, diff --git a/src/linters.ts b/src/linters.ts index 5df7a29..3442fc6 100644 --- a/src/linters.ts +++ b/src/linters.ts @@ -1,4 +1,8 @@ +//# #if HAVE_VSCODE import * as vscode from "vscode"; +//# #elif HAVE_COC_NVIM +//# import * as vscode from "coc.nvim"; +//# #endif import { extensionConfiguration, getOutputChannel } from "./utils"; import { ExtensionConfiguration, LinterConfiguration, ToolCheckFunc, Tool } from "./types"; import * as muon from "./tools/muon"; @@ -28,7 +32,16 @@ async function reloadLinters( return disposables; } - let enabledLinters: ((document: vscode.TextDocument) => Promise)[] = []; + let enabledLinters: ((document: + //# #if HAVE_VSCODE + vscode.TextDocument + //# #elif HAVE_COC_NVIM + //# { + //# version: number + //# uri: string + //# } + //# #endif + ) => Promise)[] = []; let name: keyof typeof linters; for (name in linters) { @@ -49,10 +62,21 @@ async function reloadLinters( enabledLinters.push(linter); } - const lintAll = (document: vscode.TextDocument) => { + const lintAll = (document: + //# #if HAVE_VSCODE + vscode.TextDocument + //# #elif HAVE_COC_NVIM + //# { + //# version: number + //# uri: string + //# } + //# #endif + ) => { + //# #if HAVE_VSCODE if (document.languageId != "meson") { return; } + //# #endif Promise.all(enabledLinters.map((l) => l(document))).then((values) => { diagnostics.set(document.uri, values.flat()); @@ -60,7 +84,11 @@ async function reloadLinters( }; const subscriptions = [ + //# #if HAVE_VSCODE vscode.workspace.onDidChangeTextDocument((c) => lintAll(c.document)), + //# #elif HAVE_COC_NVIM + //# vscode.workspace.onDidChangeTextDocument((c) => lintAll(c.textDocument)), + //# #endif vscode.window.onDidChangeActiveTextEditor((e) => { if (e) { lintAll(e.document); diff --git a/src/lsp/common.ts b/src/lsp/common.ts index 0ee66f3..8102e28 100644 --- a/src/lsp/common.ts +++ b/src/lsp/common.ts @@ -1,8 +1,13 @@ +//# #if HAVE_VSCODE import * as vscode from "vscode"; +import { Uri } from "vscode"; +//# #elif HAVE_COC_NVIM +//# import * as vscode from "coc.nvim"; +//# import { Uri } from "coc.nvim"; +//# #endif import { LanguageServerClient } from "."; import { LanguageServer } from "../types"; import { MesonLSPLanguageClient } from "./mesonlsp"; -import { Uri } from "vscode"; export function serverToClass(server: LanguageServer): any { switch (server) { @@ -38,9 +43,11 @@ export async function createLanguageServerClient( "This language server supports your systen, but provides no artifacts for automatic setup", ...Object.values(Options), ); + //# #if HAVE_VSCODE if (response == Options.open) { vscode.env.openExternal(Uri.parse(klass.setupURL)); } + //# #endif return null; } if (download) { diff --git a/src/lsp/index.ts b/src/lsp/index.ts index 60ccb83..7894950 100644 --- a/src/lsp/index.ts +++ b/src/lsp/index.ts @@ -5,16 +5,21 @@ import * as crypto from "crypto"; import * as fs from "fs"; import * as os from "os"; import * as path from "path"; -import * as vscode from "vscode"; import { - DidChangeConfigurationNotification, - DidChangeConfigurationParams, Executable, LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, + //# #if HAVE_VSCODE + DidChangeConfigurationNotification, + DidChangeConfigurationParams, } from "vscode-languageclient/node"; +import * as vscode from "vscode"; +//# #elif HAVE_COC_NVIM +//# } from "coc.nvim"; +//# import * as vscode from "coc.nvim"; +//# #endif import * as storage from "../storage"; import { LanguageServer } from "../types"; import { serverToClass } from "./common"; @@ -50,8 +55,13 @@ export abstract class LanguageServerClient { } private static cachedLanguageServer(server: LanguageServer, context: vscode.ExtensionContext): vscode.Uri | null { + //# #if HAVE_VSCODE const uri = vscode.Uri.joinPath( storage.uri(storage.Location.LSP, context), + //# #elif HAVE_COC_NVIM + //# const uri = vscode.Uri.parse( + //# storage.uri(storage.Location.LSP, context).toString() + + //# #endif `${server}${os.platform() === "win32" ? ".exe" : ""}`, ); @@ -214,10 +224,12 @@ export abstract class LanguageServerClient { async reloadConfig(): Promise { const config = vscode.workspace.getConfiguration(`mesonbuild.${this.server}`); + //# #if HAVE_VSCODE const params: DidChangeConfigurationParams = { settings: config, }; await this.ls!.sendNotification(DidChangeConfigurationNotification.type, params); + //# #endif } async update(context: vscode.ExtensionContext): Promise { diff --git a/src/lsp/mesonlsp.ts b/src/lsp/mesonlsp.ts index 6ebbe9d..d534493 100644 --- a/src/lsp/mesonlsp.ts +++ b/src/lsp/mesonlsp.ts @@ -1,7 +1,11 @@ import * as os from "os"; +//# #if HAVE_VSCODE import * as vscode from "vscode"; - import { Executable } from "vscode-languageclient/node"; +//# #elif HAVE_COC_NVIM +//# import * as vscode from "coc.nvim"; +//# import { Executable } from "coc.nvim"; +//# #endif import { LanguageServerClient } from "../lsp"; export class MesonLSPLanguageClient extends LanguageServerClient { diff --git a/src/storage.ts b/src/storage.ts index e81164d..3ef656e 100644 --- a/src/storage.ts +++ b/src/storage.ts @@ -1,9 +1,18 @@ +//# #if HAVE_VSCODE import * as vscode from "vscode"; +//# #elif HAVE_COC_NVIM +//# import * as vscode from "coc.nvim"; +//# import { resolve } from "path"; +//# #endif export enum Location { LSP = "lsp", } export function uri(location: Location, context: vscode.ExtensionContext): vscode.Uri { + //# #if HAVE_VSCODE return vscode.Uri.joinPath(context.globalStorageUri, location); + //# #elif HAVE_COC_NVIM + //# return vscode.Uri.file(resolve(context.storagePath, location)); + //# #endif } diff --git a/src/tools/muon.ts b/src/tools/muon.ts index 619401b..aa17afa 100644 --- a/src/tools/muon.ts +++ b/src/tools/muon.ts @@ -1,4 +1,8 @@ +//# #if HAVE_VSCODE import * as vscode from "vscode"; +//# #elif HAVE_COC_NVIM +//# import * as vscode from "coc.nvim"; +//# #endif import { ExecResult, exec, execFeed, extensionConfiguration, getOutputChannel } from "../utils"; import { Tool, ToolCheckResult } from "../types"; import { Version, type VersionArray } from "../version"; @@ -6,7 +10,11 @@ import { Version, type VersionArray } from "../version"; export async function lint(muon: Tool, root: string, document: vscode.TextDocument): Promise { const { stdout, stderr } = await execFeed( muon.path, +//# #if HAVE_VSCODE ["analyze", "-l", "-O", document.uri.fsPath], +//# #elif HAVE_COC_NVIM +//# ["analyze", "-l", "-O", vscode.Uri.parse(document.uri).fsPath], +//# #endif { cwd: root }, document.getText(), ); @@ -31,11 +39,19 @@ export async function lint(muon: Tool, root: string, document: vscode.TextDocume const col = Number(parts[2]); const fullmsg = parts.slice(3).join(":").trim(); +//# #if HAVE_VSCODE if (file != document.uri.fsPath) { +//# #elif HAVE_COC_NVIM +//# if (file != vscode.Uri.parse(document.uri).fsPath) { +//# #endif return; } +//# #if HAVE_VSCODE const range = new vscode.Range(line_no - 1, col, line_no - 1, col); +//# #elif HAVE_COC_NVIM +//# const range = /* new */vscode.Range.create(line_no - 1, col, line_no - 1, col); +//# #endif let severity: vscode.DiagnosticSeverity = vscode.DiagnosticSeverity.Error; if (fullmsg.startsWith("warn")) { @@ -44,14 +60,22 @@ export async function lint(muon: Tool, root: string, document: vscode.TextDocume const msg = fullmsg.slice(fullmsg.indexOf(" ") + 1); +//# #if HAVE_VSCODE const diagnostic = new vscode.Diagnostic(range, msg, severity); +//# #elif HAVE_COC_NVIM +//# const diagnostic = /* new */vscode.Diagnostic.create(range, msg, severity); +//# #endif diagnostics.push(diagnostic); }); return diagnostics; } +//# #if HAVE_VSCODE export async function format(muon: Tool, root: string, document: vscode.TextDocument): Promise { +//# #elif HAVE_COC_NVIM +//# export async function format(muon: Tool, root: string, document: vscode.LinesTextDocument): Promise { +//# #endif const originalDocumentText = document.getText(); let args = ["fmt"]; @@ -74,12 +98,20 @@ export async function format(muon: Tool, root: string, document: vscode.TextDocu return []; } +//# #if HAVE_VSCODE const documentRange = new vscode.Range( +//# #elif HAVE_COC_NVIM +//# const documentRange = /* new */vscode.Range.create( +//# #endif document.lineAt(0).range.start, document.lineAt(document.lineCount - 1).rangeIncludingLineBreak.end, ); +//# #if HAVE_VSCODE return [new vscode.TextEdit(documentRange, stdout)]; +//# #elif HAVE_COC_NVIM +//# return [/* new */vscode.TextEdit.replace(documentRange, stdout)]; +//# #endif } export async function check(): Promise { diff --git a/src/types.ts b/src/types.ts index d13dcb0..533ed16 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,8 @@ +//# #if HAVE_VSCODE import * as vscode from "vscode"; +//# #elif HAVE_COC_NVIM +//# import * as vscode from "coc.nvim"; +//# #endif import type { Version } from "./version"; type Dict = { [x: string]: T }; diff --git a/src/utils.ts b/src/utils.ts index 18aa4ef..cb9619c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,13 @@ import * as fs from "fs"; import * as path from "path"; import * as cp from "child_process"; +//# #if HAVE_VSCODE import * as vscode from "vscode"; +//# #elif HAVE_COC_NVIM +//# import * as vscode from "coc.nvim"; +//# import { readdir } from 'fs/promises'; +//# #define Thenable Promise +//# #endif import * as which from "which"; import { createHash, BinaryLike } from "crypto"; @@ -181,19 +187,34 @@ export function checkMesonIsConfigured(buildDir: string) { export async function mesonRootDirs(): Promise { let rootDirs: string[] = []; let pending: vscode.Uri[] = []; + //# #if HAVE_VSCODE vscode.workspace.workspaceFolders!.forEach((i) => pending.push(i.uri)); + //# #elif HAVE_COC_NVIM + //# vscode.workspace.workspaceFolders!.forEach((i) => pending.push(vscode.Uri.parse(i.uri))); + //# let type = true; + //# #endif while (true) { const d = pending.pop(); if (!d) break; let hasMesonFile: boolean = false; let subdirs: vscode.Uri[] = []; + //# #if HAVE_VSCODE for (const [name, type] of await vscode.workspace.fs.readDirectory(d)) { if (type & vscode.FileType.File && name == "meson.build") { + //# #elif HAVE_COC_NVIM + //# for (const name/* , type */ of await readdir(d.fsPath)) { + //# if (type/* & vscode.FileType.File */ && name == "meson.build") { + //# #endif rootDirs.push(d.fsPath); hasMesonFile = true; break; + //# #if HAVE_VSCODE } else if (type & vscode.FileType.Directory) { subdirs.push(vscode.Uri.joinPath(d, name)); + //# #elif HAVE_COC_NVIM + //# } else if (type/* & vscode.FileType.Directory */) { + //# subdirs.push(vscode.Uri.file(path.resolve(d.fsPath, name))); + //# #endif } } if (!hasMesonFile) {