UNPKG

coc-basedpyright

Version:

Basedpyright(fork of Pyright) extension for coc.nvim

661 lines (651 loc) 25.1 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // node_modules/which/node_modules/isexe/dist/cjs/posix.js var require_posix = __commonJS({ "node_modules/which/node_modules/isexe/dist/cjs/posix.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.sync = exports2.isexe = void 0; var fs_1 = require("fs"); var promises_1 = require("fs/promises"); var isexe = async (path2, options = {}) => { const { ignoreErrors = false } = options; try { return checkStat(await (0, promises_1.stat)(path2), options); } catch (e) { const er = e; if (ignoreErrors || er.code === "EACCES") return false; throw er; } }; exports2.isexe = isexe; var sync = (path2, options = {}) => { const { ignoreErrors = false } = options; try { return checkStat((0, fs_1.statSync)(path2), options); } catch (e) { const er = e; if (ignoreErrors || er.code === "EACCES") return false; throw er; } }; exports2.sync = sync; var checkStat = (stat, options) => stat.isFile() && checkMode(stat, options); var checkMode = (stat, options) => { var _a, _b, _c; const myUid = options.uid ?? ((_a = process.getuid) == null ? void 0 : _a.call(process)); const myGroups = options.groups ?? ((_b = process.getgroups) == null ? void 0 : _b.call(process)) ?? []; const myGid = options.gid ?? ((_c = process.getgid) == null ? void 0 : _c.call(process)) ?? myGroups[0]; if (myUid === void 0 || myGid === void 0) { throw new Error("cannot get uid or gid"); } const groups = /* @__PURE__ */ new Set([myGid, ...myGroups]); const mod = stat.mode; const uid = stat.uid; const gid = stat.gid; const u = parseInt("100", 8); const g = parseInt("010", 8); const o = parseInt("001", 8); const ug = u | g; return !!(mod & o || mod & g && groups.has(gid) || mod & u && uid === myUid || mod & ug && myUid === 0); }; } }); // node_modules/which/node_modules/isexe/dist/cjs/win32.js var require_win32 = __commonJS({ "node_modules/which/node_modules/isexe/dist/cjs/win32.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.sync = exports2.isexe = void 0; var fs_1 = require("fs"); var promises_1 = require("fs/promises"); var isexe = async (path2, options = {}) => { const { ignoreErrors = false } = options; try { return checkStat(await (0, promises_1.stat)(path2), path2, options); } catch (e) { const er = e; if (ignoreErrors || er.code === "EACCES") return false; throw er; } }; exports2.isexe = isexe; var sync = (path2, options = {}) => { const { ignoreErrors = false } = options; try { return checkStat((0, fs_1.statSync)(path2), path2, options); } catch (e) { const er = e; if (ignoreErrors || er.code === "EACCES") return false; throw er; } }; exports2.sync = sync; var checkPathExt = (path2, options) => { const { pathExt = process.env.PATHEXT || "" } = options; const peSplit = pathExt.split(";"); if (peSplit.indexOf("") !== -1) { return true; } for (let i = 0; i < peSplit.length; i++) { const p = peSplit[i].toLowerCase(); const ext = path2.substring(path2.length - p.length).toLowerCase(); if (p && ext === p) { return true; } } return false; }; var checkStat = (stat, path2, options) => stat.isFile() && checkPathExt(path2, options); } }); // node_modules/which/node_modules/isexe/dist/cjs/options.js var require_options = __commonJS({ "node_modules/which/node_modules/isexe/dist/cjs/options.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); } }); // node_modules/which/node_modules/isexe/dist/cjs/index.js var require_cjs = __commonJS({ "node_modules/which/node_modules/isexe/dist/cjs/index.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); } : function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) { for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); } __setModuleDefault(result, mod); return result; }; var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p); }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.sync = exports2.isexe = exports2.posix = exports2.win32 = void 0; var posix = __importStar(require_posix()); exports2.posix = posix; var win32 = __importStar(require_win32()); exports2.win32 = win32; __exportStar(require_options(), exports2); var platform = process.env._ISEXE_TEST_PLATFORM_ || process.platform; var impl = platform === "win32" ? win32 : posix; exports2.isexe = impl.isexe; exports2.sync = impl.sync; } }); // node_modules/which/lib/index.js var require_lib = __commonJS({ "node_modules/which/lib/index.js"(exports2, module2) { var { isexe, sync: isexeSync } = require_cjs(); var { join: join2, delimiter, sep, posix } = require("path"); var isWindows = process.platform === "win32"; var rSlash = new RegExp(`[${posix.sep}${sep === posix.sep ? "" : sep}]`.replace(/(\\)/g, "\\$1")); var rRel = new RegExp(`^\\.${rSlash.source}`); var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" }); var getPathInfo = (cmd, { path: optPath = process.env.PATH, pathExt: optPathExt = process.env.PATHEXT, delimiter: optDelimiter = delimiter }) => { const pathEnv = cmd.match(rSlash) ? [""] : [ // windows always checks the cwd first ...isWindows ? [process.cwd()] : [], ...(optPath || /* istanbul ignore next: very unusual */ "").split(optDelimiter) ]; if (isWindows) { const pathExtExe = optPathExt || [".EXE", ".CMD", ".BAT", ".COM"].join(optDelimiter); const pathExt = pathExtExe.split(optDelimiter).flatMap((item) => [item, item.toLowerCase()]); if (cmd.includes(".") && pathExt[0] !== "") { pathExt.unshift(""); } return { pathEnv, pathExt, pathExtExe }; } return { pathEnv, pathExt: [""] }; }; var getPathPart = (raw, cmd) => { const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw; const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : ""; return prefix + join2(pathPart, cmd); }; var which2 = async (cmd, opt = {}) => { const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt); const found = []; for (const envPart of pathEnv) { const p = getPathPart(envPart, cmd); for (const ext of pathExt) { const withExt = p + ext; const is = await isexe(withExt, { pathExt: pathExtExe, ignoreErrors: true }); if (is) { if (!opt.all) { return withExt; } found.push(withExt); } } } if (opt.all && found.length) { return found; } if (opt.nothrow) { return null; } throw getNotFoundError(cmd); }; var whichSync = (cmd, opt = {}) => { const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt); const found = []; for (const pathEnvPart of pathEnv) { const p = getPathPart(pathEnvPart, cmd); for (const ext of pathExt) { const withExt = p + ext; const is = isexeSync(withExt, { pathExt: pathExtExe, ignoreErrors: true }); if (is) { if (!opt.all) { return withExt; } found.push(withExt); } } } if (opt.all && found.length) { return found; } if (opt.nothrow) { return null; } throw getNotFoundError(cmd); }; module2.exports = which2; which2.sync = whichSync; } }); // src/index.ts var src_exports = {}; __export(src_exports, { activate: () => activate }); module.exports = __toCommonJS(src_exports); var import_coc3 = require("coc.nvim"); var import_node_fs2 = require("node:fs"); var import_node_path2 = require("node:path"); // src/configSettings.ts var import_coc = require("coc.nvim"); var child_process = __toESM(require("node:child_process")); var import_node_fs = __toESM(require("node:fs")); var import_node_path = __toESM(require("node:path")); var import_which = __toESM(require_lib()); var _PythonSettings = class _PythonSettings { constructor() { this.disposables = []; this._pythonPath = ""; this.workspaceRoot = import_coc.workspace.root ? import_coc.workspace.root : __dirname; this.initialize(); } static getInstance() { const workspaceFolder = import_coc.workspace.workspaceFolders.length > 0 ? import_coc.workspace.workspaceFolders[0] : void 0; const workspaceFolderKey = workspaceFolder ? workspaceFolder.name : "unknown"; if (!_PythonSettings.pythonSettings.has(workspaceFolderKey)) { const settings = new _PythonSettings(); _PythonSettings.pythonSettings.set(workspaceFolderKey, settings); return settings; } return _PythonSettings.pythonSettings.get(workspaceFolderKey); } static dispose() { _PythonSettings.pythonSettings.forEach((item) => item.dispose()); _PythonSettings.pythonSettings.clear(); } dispose() { for (const disposable of this.disposables) { disposable.dispose(); } this.disposables = []; } resolvePythonFromVENV() { function pythonBinFromPath(p) { const fullPath = process.platform === "win32" ? import_node_path.default.join(p, "Scripts", "python.exe") : import_node_path.default.join(p, "bin", "python"); return import_node_fs.default.existsSync(fullPath) ? fullPath : void 0; } try { if (process.env.VIRTUAL_ENV && import_node_fs.default.existsSync(import_node_path.default.join(process.env.VIRTUAL_ENV, "pyvenv.cfg"))) { return pythonBinFromPath(process.env.VIRTUAL_ENV); } if (process.env.CONDA_PREFIX) { return pythonBinFromPath(process.env.CONDA_PREFIX); } let p = import_node_path.default.join(this.workspaceRoot, ".python-version"); if (import_node_fs.default.existsSync(p)) { if (!process.env.PYENV_VERSION) { process.env.PYENV_VERSION = import_node_fs.default.readFileSync(p).toString().trim().split("\n")[0]; } return; } p = import_node_path.default.join(this.workspaceRoot, "Pipfile"); if (import_node_fs.default.existsSync(p)) { return child_process.spawnSync("pipenv", ["--py"], { encoding: "utf8" }).stdout.trim(); } p = import_node_path.default.join(this.workspaceRoot, "poetry.lock"); if (import_node_fs.default.existsSync(p)) { const list = child_process.spawnSync("poetry", ["env", "list", "--full-path", "--no-ansi"], { encoding: "utf8", cwd: this.workspaceRoot }).stdout.trim(); let info = ""; for (const item of list.split("\n")) { if (item.includes("(Activated)")) { info = item.replace(/\(Activated\)/, "").trim(); break; } info = item; } if (info) { return pythonBinFromPath(info); } } p = import_node_path.default.join(this.workspaceRoot, ".pdm-python"); if (import_node_fs.default.existsSync(p)) { return child_process.spawnSync("pdm", ["info", "--python"], { encoding: "utf8" }).stdout.trim(); } const files = import_node_fs.default.readdirSync(this.workspaceRoot); for (const file of files) { const x = import_node_path.default.join(this.workspaceRoot, file); if (import_node_fs.default.existsSync(import_node_path.default.join(x, "pyvenv.cfg"))) { return pythonBinFromPath(x); } } } catch (e) { console.error(e); } } update(pythonSettings) { const vp = this.resolvePythonFromVENV(); this.pythonPath = vp ? vp : pythonSettings.get("pythonPath", "python"); } get pythonPath() { return this._pythonPath; } set pythonPath(value) { if (this._pythonPath === value) { return; } try { this._pythonPath = getPythonExecutable(value); } catch (ex) { this._pythonPath = value; } } initialize() { this.disposables.push( import_coc.workspace.onDidChangeConfiguration((event) => { if (event.affectsConfiguration("python")) { const currentConfig = import_coc.workspace.getConfiguration("python", import_coc.workspace.root); this.update(currentConfig); } }) ); const initialConfig = import_coc.workspace.getConfiguration("python", import_coc.workspace.root); if (initialConfig) { this.update(initialConfig); } } }; _PythonSettings.pythonSettings = /* @__PURE__ */ new Map(); var PythonSettings = _PythonSettings; function getPythonExecutable(val) { let pythonPath = import_coc.workspace.expand(val); if (pythonPath === "python" || pythonPath.indexOf(import_node_path.default.sep) === -1 || import_node_path.default.basename(pythonPath) === import_node_path.default.dirname(pythonPath)) { const bin = import_which.default.sync(pythonPath, { nothrow: true }); if (bin) { pythonPath = bin; } } if (isValidPythonPath(pythonPath)) { return pythonPath; } return pythonPath; } function isValidPythonPath(pythonPath) { try { return child_process.spawnSync(pythonPath, ["-c", "print(1234)"], { encoding: "utf8" }).stdout.startsWith("1234"); } catch (ex) { return false; } } // src/middleware.ts var import_coc2 = require("coc.nvim"); function toJSONObject(obj) { if (obj) { if (Array.isArray(obj)) { return obj.map(toJSONObject); } if (typeof obj === "object") { const res = /* @__PURE__ */ Object.create(null); for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { res[key] = toJSONObject(obj[key]); } } return res; } } return obj; } function configuration(params, token, next) { const pythonItem = params.items.find((x) => x.section === "python"); if (pythonItem) { const custom = () => { const config = toJSONObject(import_coc2.workspace.getConfiguration(pythonItem.section, pythonItem.scopeUri)); config.pythonPath = PythonSettings.getInstance().pythonPath; return [config]; }; return custom(); } const analysisItem = params.items.find((x) => x.section === "basedpyright.analysis"); if (analysisItem) { const custom = () => { const analysis = toJSONObject(import_coc2.workspace.getConfiguration(analysisItem.section, analysisItem.scopeUri)); analysis.stubPath = import_coc2.workspace.expand(analysis.stubPath); const inspect = import_coc2.workspace.getConfiguration("python.analysis").inspect("stubPath"); if (inspect && (inspect.globalValue === void 0 || inspect.workspaceValue === void 0 || inspect.workspaceFolderValue === void 0)) { analysis.stubPath = void 0; } const extraPaths = analysis.extraPaths; if (extraPaths == null ? void 0 : extraPaths.length) { analysis.extraPaths = extraPaths.map((p) => import_coc2.workspace.expand(p)); } const typeshedPaths = analysis.typeshedPaths; if (typeshedPaths == null ? void 0 : typeshedPaths.length) { analysis.typeshedPaths = typeshedPaths.map((p) => import_coc2.workspace.expand(p)); } return [analysis]; }; return custom(); } return next(params, token); } async function provideCompletionItem(document, position, context, token, next) { var _a; const result = await next(document, position, context, token); if (!result) return; const items = Array.isArray(result) ? result : result.items; for (const item of items) { item.sortText = item.sortText ? item.sortText.toLowerCase() : item.label.toLowerCase(); } const snippetSupport = import_coc2.workspace.getConfiguration("basedpyright").get("completion.snippetSupport"); if (snippetSupport) { for (const item of items) { if ((_a = item.data) == null ? void 0 : _a.funcParensDisabled) continue; if (item.kind === import_coc2.CompletionItemKind.Method || item.kind === import_coc2.CompletionItemKind.Function) { item.insertText = `${item.label}($1)$0`; item.insertTextFormat = import_coc2.InsertTextFormat.Snippet; } } } return Array.isArray(result) ? items : { items, isIncomplete: result.isIncomplete }; } async function resolveCompletionItem(item, token, next) { const result = await next(item, token); if (result && typeof result.documentation === "object" && "kind" in result.documentation && result.documentation.kind === "markdown") { result.documentation.value = result.documentation.value.replace(/&nbsp;/g, " "); } return result; } async function provideHover(document, position, token, next) { const hover = await next(document, position, token); if (hover && typeof hover.contents === "object" && "kind" in hover.contents && hover.contents.kind === "markdown") { hover.contents.value = hover.contents.value.replace(/&nbsp;/g, " "); } return hover; } async function provideSignatureHelp(document, position, context, token, next) { const help = await next(document, position, context, token); if (help == null ? void 0 : help.signatures.length) { for (const sign of help.signatures) { if (sign.documentation && typeof sign.documentation === "object" && sign.documentation.kind === "markdown") { sign.documentation.value = sign.documentation.value.replace(/&nbsp;/g, " "); } } } return help; } async function handleDiagnostics(uri, diagnostics, next) { next( uri, diagnostics.filter((d) => d.message !== '"__" is not accessed') ); } // src/index.ts var defaultHeapSize = 3072; var method = "workspace/executeCommand"; var documentSelector = [ { scheme: "file", language: "python" } ]; var PyrightExtensionFeature = class { dispose() { } initialize() { } fillClientCapabilities(capabilities) { capabilities.textDocument.signatureHelp.signatureInformation.activeParameterSupport = false; } }; async function activate(context) { const pyrightCfg = import_coc3.workspace.getConfiguration("basedpyright"); const isEnable = pyrightCfg.get("enable", true); if (!isEnable) return; const module2 = (0, import_node_path2.join)(context.extensionPath, "node_modules", "basedpyright", "langserver.index.js"); if (!(0, import_node_fs2.existsSync)(module2)) { import_coc3.window.showErrorMessage(`Basedpyright langserver doesn't exist, please reinstall coc-basedpyright`); return; } const runOptions = { execArgv: [`--max-old-space-size=${defaultHeapSize}`] }; const debugOptions = { execArgv: ["--nolazy", "--inspect=6600", `--max-old-space-size=${defaultHeapSize}`] }; const serverOptions = { run: { module: module2, transport: import_coc3.TransportKind.ipc, options: runOptions }, debug: { module: module2, transport: import_coc3.TransportKind.ipc, options: debugOptions } }; const outputChannel = import_coc3.window.createOutputChannel("Basedpyright"); const pythonSettings = PythonSettings.getInstance(); outputChannel.appendLine(`Workspace: ${import_coc3.workspace.root}`); outputChannel.appendLine(`Using python from ${pythonSettings.pythonPath} `); const clientOptions = { documentSelector, synchronize: { configurationSection: ["python", "pyright", "basedpyright"] }, outputChannel, middleware: { workspace: { configuration }, provideHover, provideSignatureHelp, provideCompletionItem, handleDiagnostics, resolveCompletionItem } }; const client = new import_coc3.LanguageClient( "basedpyright", "Basedpyright Server", serverOptions, clientOptions ); client.registerFeature(new PyrightExtensionFeature()); context.subscriptions.push(import_coc3.services.registerLanguageClient(client)); const textEditorCommands = ["basedpyright.organizeimports", "basedpyright.addoptionalforparam"]; for (const command2 of textEditorCommands) { context.subscriptions.push( import_coc3.commands.registerCommand(command2, async (offset) => { const doc = await import_coc3.workspace.document; const cmd = { command: command2, arguments: [doc.uri.toString(), offset] }; await client.sendRequest(method, cmd); }) ); } let command = "basedpyright.restartserver"; let disposable = import_coc3.commands.registerCommand(command, async () => { await client.sendRequest(method, { command }); }); context.subscriptions.push(disposable); command = "basedpyright.createtypestub"; disposable = import_coc3.commands.registerCommand(command, async (...args) => { if (!args.length) { import_coc3.window.showWarningMessage("Module name is missing"); return; } const doc = await import_coc3.workspace.document; const filePath = import_coc3.Uri.parse(doc.uri).fsPath; if (args[args.length - 1] !== filePath) { args.unshift(import_coc3.workspace.root); args.push(filePath); } const cmd = { command, arguments: args }; await client.sendRequest(method, cmd); }); context.subscriptions.push(disposable); disposable = import_coc3.commands.registerCommand("basedpyright.version", () => { const pyrightJSON = (0, import_node_path2.join)(context.extensionPath, "node_modules", "basedpyright", "package.json"); const pyrightPackage = JSON.parse((0, import_node_fs2.readFileSync)(pyrightJSON, "utf8")); const cocPyrightJSON = (0, import_node_path2.join)(context.extensionPath, "package.json"); const cocPyrightPackage = JSON.parse((0, import_node_fs2.readFileSync)(cocPyrightJSON, "utf8")); import_coc3.window.showInformationMessage( `coc-basedpyright ${cocPyrightPackage.version} with Basedpyright ${pyrightPackage.version}` ); }); context.subscriptions.push(disposable); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { activate });