coc-basedpyright
Version:
Basedpyright(fork of Pyright) extension for coc.nvim
661 lines (651 loc) • 25.1 kB
JavaScript
;
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 index_exports = {};
__export(index_exports, {
activate: () => activate
});
module.exports = __toCommonJS(index_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(/ /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(/ /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(/ /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
});