coc-vscode-loader 1.1.1 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -6
- package/assets/tui-preview.png +0 -0
- package/converter/src/cli.ts +28 -0
- package/converter/src/convert.ts +501 -0
- package/converter/src/presets.ts +57 -0
- package/converter/src/scanner.ts +136 -0
- package/converter/src/transforms/class-to-factory.ts +54 -0
- package/converter/src/transforms/enum-offset.ts +49 -0
- package/converter/src/transforms/import-mapping.ts +47 -0
- package/converter/src/transforms/language-client.ts +48 -0
- package/converter/src/transforms/provider-register.ts +55 -0
- package/converter/src/types.ts +8 -0
- package/lib/index.js +536 -103
- package/package.json +7 -1
- package/converter/README.md +0 -134
- package/converter/package-lock.json +0 -693
- package/converter/pnpm-lock.yaml +0 -419
package/lib/index.js
CHANGED
|
@@ -5,6 +5,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
9
|
+
try {
|
|
10
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
|
+
} catch (e) {
|
|
12
|
+
throw mod = 0, e;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
8
15
|
var __export = (target, all) => {
|
|
9
16
|
for (var name in all)
|
|
10
17
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -27,21 +34,105 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
34
|
));
|
|
28
35
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
36
|
|
|
37
|
+
// package.json
|
|
38
|
+
var require_package = __commonJS({
|
|
39
|
+
"package.json"(exports2, module2) {
|
|
40
|
+
module2.exports = {
|
|
41
|
+
name: "coc-vscode-loader",
|
|
42
|
+
version: "1.1.4",
|
|
43
|
+
description: "Run VS Code extensions seamlessly in coc.nvim",
|
|
44
|
+
main: "lib/index.js",
|
|
45
|
+
keywords: [
|
|
46
|
+
"coc.nvim",
|
|
47
|
+
"vscode",
|
|
48
|
+
"neovim",
|
|
49
|
+
"lsp",
|
|
50
|
+
"plugin-loader",
|
|
51
|
+
"vim"
|
|
52
|
+
],
|
|
53
|
+
repository: {
|
|
54
|
+
type: "git",
|
|
55
|
+
url: "git+https://github.com/coc-plugin/coc-vscode-loader.git"
|
|
56
|
+
},
|
|
57
|
+
bugs: {
|
|
58
|
+
url: "https://github.com/coc-plugin/coc-vscode-loader/issues"
|
|
59
|
+
},
|
|
60
|
+
homepage: "https://www.npmjs.com/package/coc-vscode-loader",
|
|
61
|
+
files: [
|
|
62
|
+
"lib/",
|
|
63
|
+
"converter/src/",
|
|
64
|
+
"converter/package.json",
|
|
65
|
+
"assets/"
|
|
66
|
+
],
|
|
67
|
+
license: "MIT",
|
|
68
|
+
engines: {
|
|
69
|
+
coc: ">= 0.0.80"
|
|
70
|
+
},
|
|
71
|
+
scripts: {
|
|
72
|
+
"bundle-converter": "rm -rf converter && cp -r ../converter ./converter && cd converter && npm install --legacy-peer-deps",
|
|
73
|
+
build: "npm run bundle-converter && node esbuild.mjs",
|
|
74
|
+
prepare: "node esbuild.mjs"
|
|
75
|
+
},
|
|
76
|
+
devDependencies: {
|
|
77
|
+
"coc.nvim": "^0.0.83-next.18",
|
|
78
|
+
esbuild: "^0.28.1",
|
|
79
|
+
typescript: "^6.0.3"
|
|
80
|
+
},
|
|
81
|
+
activationEvents: [
|
|
82
|
+
"onCommand:loader.open",
|
|
83
|
+
"onCommand:loader.install",
|
|
84
|
+
"onCommand:loader.uninstall",
|
|
85
|
+
"onCommand:loader.update",
|
|
86
|
+
"onCommand:loader.uninstallAll",
|
|
87
|
+
"onCommand:loader.updateRegistry",
|
|
88
|
+
"onCommand:loader._dispatch"
|
|
89
|
+
],
|
|
90
|
+
contributes: {
|
|
91
|
+
commands: [
|
|
92
|
+
{ command: "loader.open", title: "Open VS Code extension loader" },
|
|
93
|
+
{ command: "loader.install", title: "Install a VS Code extension" },
|
|
94
|
+
{ command: "loader.uninstall", title: "Uninstall a package" },
|
|
95
|
+
{ command: "loader.update", title: "Update a package" },
|
|
96
|
+
{ command: "loader.uninstallAll", title: "Uninstall all packages" },
|
|
97
|
+
{ command: "loader.updateRegistry", title: "Update package registry" },
|
|
98
|
+
{ command: "loader._dispatch", title: "" }
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
30
105
|
// src/index.ts
|
|
31
106
|
var index_exports = {};
|
|
32
107
|
__export(index_exports, {
|
|
33
108
|
activate: () => activate
|
|
34
109
|
});
|
|
35
110
|
module.exports = __toCommonJS(index_exports);
|
|
36
|
-
var
|
|
111
|
+
var import_coc3 = require("coc.nvim");
|
|
37
112
|
|
|
38
113
|
// src/registry.ts
|
|
39
114
|
var path = __toESM(require("path"));
|
|
40
115
|
var fs = __toESM(require("fs"));
|
|
41
116
|
var os = __toESM(require("os"));
|
|
117
|
+
function pluginVersion() {
|
|
118
|
+
try {
|
|
119
|
+
return require_package().version;
|
|
120
|
+
} catch {
|
|
121
|
+
return "0.0.0";
|
|
122
|
+
}
|
|
123
|
+
}
|
|
42
124
|
var REMOTE_REGISTRY_URL = "https://raw.githubusercontent.com/coc-plugin/coc-vscode-registry/main/registry.json";
|
|
43
125
|
var CACHE_PATH = path.join(os.homedir(), ".config", "coc", "converter-cache", "registry.json");
|
|
44
126
|
var cached = null;
|
|
127
|
+
function getLocalRegistryPath() {
|
|
128
|
+
try {
|
|
129
|
+
const pluginDir2 = path.dirname(fs.realpathSync(__dirname));
|
|
130
|
+
const local = path.join(pluginDir2, "..", "coc-vscode-registry", "registry.json");
|
|
131
|
+
if (fs.existsSync(local)) return local;
|
|
132
|
+
} catch {
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
45
136
|
function loadCache() {
|
|
46
137
|
try {
|
|
47
138
|
if (fs.existsSync(CACHE_PATH)) {
|
|
@@ -52,6 +143,16 @@ function loadCache() {
|
|
|
52
143
|
return null;
|
|
53
144
|
}
|
|
54
145
|
async function updateRegistry() {
|
|
146
|
+
const localPath = process.env.COC_REGISTRY_PATH || getLocalRegistryPath();
|
|
147
|
+
if (localPath) {
|
|
148
|
+
if (!fs.existsSync(localPath)) throw new Error(`Local registry not found: ${localPath}`);
|
|
149
|
+
const data2 = JSON.parse(fs.readFileSync(localPath, "utf-8"));
|
|
150
|
+
if (!Array.isArray(data2)) throw new Error("Invalid registry format");
|
|
151
|
+
fs.mkdirSync(path.dirname(CACHE_PATH), { recursive: true });
|
|
152
|
+
fs.writeFileSync(CACHE_PATH, JSON.stringify(data2, null, 2));
|
|
153
|
+
cached = data2;
|
|
154
|
+
return data2.length;
|
|
155
|
+
}
|
|
55
156
|
const res = await fetch(REMOTE_REGISTRY_URL);
|
|
56
157
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
57
158
|
const data = await res.json();
|
|
@@ -61,10 +162,21 @@ async function updateRegistry() {
|
|
|
61
162
|
cached = data;
|
|
62
163
|
return data.length;
|
|
63
164
|
}
|
|
165
|
+
function satisfiesVersion(required) {
|
|
166
|
+
const a = pluginVersion().replace(/-.*$/, "").split(".").map(Number);
|
|
167
|
+
const b = required.replace(/-.*$/, "").split(".").map(Number);
|
|
168
|
+
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
|
169
|
+
const va = a[i] || 0, vb = b[i] || 0;
|
|
170
|
+
if (va > vb) return true;
|
|
171
|
+
if (va < vb) return false;
|
|
172
|
+
}
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
64
175
|
function getAllPackages() {
|
|
65
|
-
if (cached)
|
|
66
|
-
|
|
67
|
-
|
|
176
|
+
if (!cached) {
|
|
177
|
+
cached = loadCache() || [];
|
|
178
|
+
}
|
|
179
|
+
return cached.filter((p) => !p.minPluginVersion || satisfiesVersion(p.minPluginVersion));
|
|
68
180
|
}
|
|
69
181
|
function getPackage(name) {
|
|
70
182
|
return getAllPackages().find((p) => p.name === name);
|
|
@@ -102,10 +214,11 @@ function createInitialState() {
|
|
|
102
214
|
commitDate,
|
|
103
215
|
progressLog: [],
|
|
104
216
|
expanded: false,
|
|
105
|
-
logExpanded: false
|
|
217
|
+
logExpanded: false,
|
|
218
|
+
marked: false
|
|
106
219
|
};
|
|
107
220
|
});
|
|
108
|
-
return { packages, searchQuery: "", showHelp: false, activePill: null, dirty: false, viewFilter: "all" };
|
|
221
|
+
return { packages, searchQuery: "", showHelp: false, activePill: null, dirty: false, viewFilter: "all", sortBy: "default" };
|
|
109
222
|
}
|
|
110
223
|
var StateManager = class {
|
|
111
224
|
constructor(initial) {
|
|
@@ -144,8 +257,11 @@ var StateManager = class {
|
|
|
144
257
|
}
|
|
145
258
|
pkg.status = status;
|
|
146
259
|
if (extra?.progress !== void 0) pkg.progress = extra.progress;
|
|
147
|
-
if (extra?.logEntry !== void 0)
|
|
148
|
-
|
|
260
|
+
if (extra?.logEntry !== void 0) {
|
|
261
|
+
pkg.progressLog.push(extra.logEntry);
|
|
262
|
+
} else if (extra?.progress !== void 0) {
|
|
263
|
+
pkg.progressLog.push(extra.progress);
|
|
264
|
+
}
|
|
149
265
|
if (extra?.error !== void 0) pkg.error = extra.error;
|
|
150
266
|
if (status === "installed" || status === "not-installed") {
|
|
151
267
|
pkg.progress = void 0;
|
|
@@ -175,6 +291,21 @@ var StateManager = class {
|
|
|
175
291
|
s.viewFilter = filter;
|
|
176
292
|
});
|
|
177
293
|
}
|
|
294
|
+
cycleViewFilter() {
|
|
295
|
+
this.mutate((s) => {
|
|
296
|
+
s.viewFilter = s.viewFilter === "all" ? "installed" : s.viewFilter === "installed" ? "not-installed" : "all";
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
setSortBy(sortBy) {
|
|
300
|
+
this.mutate((s) => {
|
|
301
|
+
s.sortBy = sortBy;
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
cycleSortBy() {
|
|
305
|
+
this.mutate((s) => {
|
|
306
|
+
s.sortBy = s.sortBy === "default" ? "name" : s.sortBy === "name" ? "status" : s.sortBy === "status" ? "type" : "default";
|
|
307
|
+
});
|
|
308
|
+
}
|
|
178
309
|
setStatusMessage(msg) {
|
|
179
310
|
this.mutate((s) => {
|
|
180
311
|
s.statusMessage = msg;
|
|
@@ -203,14 +334,39 @@ var StateManager = class {
|
|
|
203
334
|
pkgs = pkgs.filter((p) => p.status === "installed");
|
|
204
335
|
}
|
|
205
336
|
const q = this.state.searchQuery.toLowerCase();
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
337
|
+
if (q) {
|
|
338
|
+
pkgs = pkgs.filter(
|
|
339
|
+
(p) => p.info.name.toLowerCase().includes(q) || p.info.displayName.toLowerCase().includes(q) || p.info.description.toLowerCase().includes(q)
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
const sortBy = this.state.sortBy;
|
|
343
|
+
if (sortBy === "name") {
|
|
344
|
+
pkgs = [...pkgs].sort((a, b) => a.info.name.localeCompare(b.info.name));
|
|
345
|
+
} else if (sortBy === "status") {
|
|
346
|
+
const order = { installed: 0, installing: 1, updating: 2, uninstalling: 3, failed: 4, "not-installed": 5 };
|
|
347
|
+
pkgs = [...pkgs].sort((a, b) => (order[a.status] ?? 9) - (order[b.status] ?? 9));
|
|
348
|
+
} else if (sortBy === "type") {
|
|
349
|
+
pkgs = [...pkgs].sort((a, b) => a.info.type.localeCompare(b.info.type));
|
|
350
|
+
}
|
|
351
|
+
return pkgs;
|
|
210
352
|
}
|
|
211
353
|
getPackage(name) {
|
|
212
354
|
return this.state.packages.find((p) => p.info.name === name);
|
|
213
355
|
}
|
|
356
|
+
toggleMark(name) {
|
|
357
|
+
this.mutate((s) => {
|
|
358
|
+
const pkg = s.packages.find((p) => p.info.name === name);
|
|
359
|
+
if (pkg) pkg.marked = !pkg.marked;
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
clearMarks() {
|
|
363
|
+
this.mutate((s) => {
|
|
364
|
+
for (const p of s.packages) p.marked = false;
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
getMarkedNames() {
|
|
368
|
+
return this.state.packages.filter((p) => p.marked).map((p) => p.info.name);
|
|
369
|
+
}
|
|
214
370
|
refreshPackages() {
|
|
215
371
|
this.mutate((s) => {
|
|
216
372
|
const updated = getAllPackages();
|
|
@@ -226,7 +382,8 @@ var StateManager = class {
|
|
|
226
382
|
status: isInstalled(info.name) ? "installed" : "not-installed",
|
|
227
383
|
progressLog: [],
|
|
228
384
|
expanded: false,
|
|
229
|
-
logExpanded: false
|
|
385
|
+
logExpanded: false,
|
|
386
|
+
marked: false
|
|
230
387
|
};
|
|
231
388
|
});
|
|
232
389
|
});
|
|
@@ -234,10 +391,11 @@ var StateManager = class {
|
|
|
234
391
|
};
|
|
235
392
|
|
|
236
393
|
// src/tui.ts
|
|
237
|
-
var
|
|
394
|
+
var import_coc2 = require("coc.nvim");
|
|
238
395
|
|
|
239
396
|
// src/pipeline.ts
|
|
240
397
|
var import_child_process = require("child_process");
|
|
398
|
+
var import_coc = require("coc.nvim");
|
|
241
399
|
var path3 = __toESM(require("path"));
|
|
242
400
|
var fs3 = __toESM(require("fs"));
|
|
243
401
|
var os3 = __toESM(require("os"));
|
|
@@ -256,12 +414,9 @@ function pluginDir(name) {
|
|
|
256
414
|
}
|
|
257
415
|
function converterCliPath() {
|
|
258
416
|
const base = path3.resolve(__dirname, "..");
|
|
259
|
-
const cwd = process.cwd();
|
|
260
417
|
const candidates = [
|
|
261
418
|
path3.join(base, "converter", "src", "cli.ts"),
|
|
262
|
-
path3.join(base, "..", "converter", "src", "cli.ts")
|
|
263
|
-
path3.join(cwd, "converter", "src", "cli.ts"),
|
|
264
|
-
path3.join(cwd, "..", "converter", "src", "cli.ts")
|
|
419
|
+
path3.join(base, "..", "converter", "src", "cli.ts")
|
|
265
420
|
];
|
|
266
421
|
for (const p of candidates) {
|
|
267
422
|
if (fs3.existsSync(p)) return p;
|
|
@@ -270,37 +425,48 @@ function converterCliPath() {
|
|
|
270
425
|
"converter CLI not found. Please set $COC_CONVERTER_PATH to the converter/ directory, or ensure it is at the same level as coc-converter/"
|
|
271
426
|
);
|
|
272
427
|
}
|
|
428
|
+
var CMD_TIMEOUT = 3e5;
|
|
273
429
|
async function run(cmd, args, cwd, onLine) {
|
|
274
430
|
return new Promise((resolve2, reject) => {
|
|
275
431
|
const child = (0, import_child_process.spawn)(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"], shell: true });
|
|
276
|
-
const
|
|
432
|
+
const timer = setTimeout(() => {
|
|
433
|
+
child.kill("SIGTERM");
|
|
434
|
+
reject(new Error(`Timed out after ${CMD_TIMEOUT / 1e3}s: ${cmd} ${args.join(" ")}`));
|
|
435
|
+
}, CMD_TIMEOUT);
|
|
277
436
|
const handler = (data) => {
|
|
278
437
|
const text = data.toString();
|
|
279
|
-
|
|
280
|
-
onLine(text);
|
|
438
|
+
onLine?.(text);
|
|
281
439
|
};
|
|
282
440
|
child.stdout.on("data", handler);
|
|
283
441
|
child.stderr.on("data", handler);
|
|
442
|
+
let stderrBuf = "";
|
|
443
|
+
child.stderr.on("data", (d) => {
|
|
444
|
+
stderrBuf += d.toString();
|
|
445
|
+
});
|
|
284
446
|
child.on("close", (code) => {
|
|
447
|
+
clearTimeout(timer);
|
|
285
448
|
if (code === 0) resolve2();
|
|
286
|
-
else reject(new Error(`${cmd} ${args.join(" ")} exited with code ${code}
|
|
449
|
+
else reject(new Error(`${cmd} ${args.join(" ")} exited with code ${code}
|
|
450
|
+
${stderrBuf.trim()}`));
|
|
451
|
+
});
|
|
452
|
+
child.on("error", (e) => {
|
|
453
|
+
clearTimeout(timer);
|
|
454
|
+
reject(e);
|
|
287
455
|
});
|
|
288
|
-
child.on("error", reject);
|
|
289
456
|
});
|
|
290
457
|
}
|
|
291
458
|
async function downloadSource(info, name, onProgress) {
|
|
292
459
|
const srcDir = sourceDir(name);
|
|
293
460
|
const cache = cacheDir(name);
|
|
294
461
|
const repoUrl = `https://github.com/${info.source.repo}.git`;
|
|
462
|
+
const log = (chunk) => onProgress(1, 5, chunk.trim(), "");
|
|
295
463
|
if (fs3.existsSync(srcDir)) {
|
|
296
464
|
onProgress(1, 5, "Updating source...", `git -C ${srcDir} pull`);
|
|
297
|
-
await run("git", ["-C", srcDir, "pull"], cache,
|
|
298
|
-
});
|
|
465
|
+
await run("git", ["-C", srcDir, "pull"], cache, log);
|
|
299
466
|
} else {
|
|
300
467
|
onProgress(1, 5, "Cloning repository...", `git clone --depth=1 ${repoUrl}`);
|
|
301
468
|
fs3.mkdirSync(cache, { recursive: true });
|
|
302
|
-
await run("git", ["clone", "--depth=1", repoUrl, srcDir], cache,
|
|
303
|
-
});
|
|
469
|
+
await run("git", ["clone", "--depth=1", repoUrl, srcDir], cache, log);
|
|
304
470
|
}
|
|
305
471
|
return info.source.subdir ? path3.join(srcDir, info.source.subdir) : srcDir;
|
|
306
472
|
}
|
|
@@ -309,51 +475,165 @@ async function convertSource(inputDir, name, onProgress) {
|
|
|
309
475
|
if (fs3.existsSync(build)) fs3.rmSync(build, { recursive: true });
|
|
310
476
|
const cli = converterCliPath();
|
|
311
477
|
onProgress(2, 5, "Converting...", `converter convert ${inputDir} -o ${build}`);
|
|
312
|
-
|
|
313
|
-
|
|
478
|
+
const log = (chunk) => onProgress(2, 5, chunk.trim(), "");
|
|
479
|
+
await run("npx", ["tsx", cli, "convert", inputDir, "-o", build], cacheDir(name), log);
|
|
314
480
|
}
|
|
315
481
|
async function buildPackage(name, inputDir, info, onProgress) {
|
|
316
482
|
const build = buildDir(name);
|
|
483
|
+
const npmLog = (chunk) => onProgress(3, 5, chunk.trim(), "");
|
|
317
484
|
onProgress(3, 5, "Installing dependencies...", "npm install --legacy-peer-deps");
|
|
318
|
-
await run("npm", ["install", "--legacy-peer-deps"], build,
|
|
319
|
-
});
|
|
485
|
+
await run("npm", ["install", "--legacy-peer-deps"], build, npmLog);
|
|
320
486
|
onProgress(3, 5, "Running postinstall...", "npm run postinstall");
|
|
321
|
-
await run("npm", ["run", "postinstall", "--if-present"], build, () => {
|
|
322
|
-
}).catch(() => {
|
|
487
|
+
await run("npm", ["run", "postinstall", "--if-present"], build, npmLog).catch(() => {
|
|
323
488
|
});
|
|
489
|
+
if (info.pipPackages?.length) {
|
|
490
|
+
const pipLog = (chunk) => onProgress(3, 5, chunk.trim(), "");
|
|
491
|
+
const pythonPaths = [
|
|
492
|
+
"/opt/homebrew/bin/python3",
|
|
493
|
+
"/usr/local/bin/python3",
|
|
494
|
+
"/usr/bin/python3",
|
|
495
|
+
"python3"
|
|
496
|
+
];
|
|
497
|
+
let pythonBin = "";
|
|
498
|
+
for (const p of pythonPaths) {
|
|
499
|
+
if (p === "python3") {
|
|
500
|
+
try {
|
|
501
|
+
await run("python3", ["--version"], build);
|
|
502
|
+
pythonBin = "python3";
|
|
503
|
+
break;
|
|
504
|
+
} catch {
|
|
505
|
+
continue;
|
|
506
|
+
}
|
|
507
|
+
} else if (fs3.existsSync(p)) {
|
|
508
|
+
pythonBin = p;
|
|
509
|
+
break;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
if (!pythonBin) throw new Error("python3 not found, cannot install pip packages: " + info.pipPackages.join(", "));
|
|
513
|
+
const pipArgs = ["-m", "pip", "install"];
|
|
514
|
+
if (process.platform === "linux" || process.platform === "darwin") {
|
|
515
|
+
try {
|
|
516
|
+
const verOut = await runWithOutput(pythonBin, ["--version"], build);
|
|
517
|
+
const m = verOut.match(/^Python\s+(\d+)\.(\d+)/);
|
|
518
|
+
if (m) {
|
|
519
|
+
const pyMajor = parseInt(m[1]), pyMinor = parseInt(m[2]);
|
|
520
|
+
if (pyMajor > 3 || pyMajor === 3 && pyMinor >= 11) pipArgs.push("--break-system-packages");
|
|
521
|
+
}
|
|
522
|
+
} catch {
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
onProgress(3, 5, "Installing pip packages...", `${pythonBin} -m pip install ${info.pipPackages.join(" ")}`);
|
|
526
|
+
await run(pythonBin, pipArgs.concat(...info.pipPackages), build, pipLog);
|
|
527
|
+
}
|
|
324
528
|
const serverDir = path3.join(inputDir, "server");
|
|
325
529
|
if (fs3.existsSync(serverDir) && fs3.existsSync(path3.join(serverDir, "package.json"))) {
|
|
326
530
|
onProgress(3, 5, "Installing server dependencies...", `npm install in ${serverDir}`);
|
|
327
|
-
await run("npm", ["install", "--legacy-peer-deps"], serverDir,
|
|
328
|
-
});
|
|
531
|
+
await run("npm", ["install", "--legacy-peer-deps"], serverDir, npmLog);
|
|
329
532
|
const destServer = path3.join(build, "server");
|
|
330
533
|
if (fs3.existsSync(destServer)) fs3.rmSync(destServer, { recursive: true });
|
|
331
534
|
fs3.cpSync(serverDir, destServer, { recursive: true });
|
|
332
535
|
}
|
|
333
536
|
onProgress(4, 5, "Building...", "node esbuild.mjs");
|
|
334
|
-
|
|
335
|
-
|
|
537
|
+
const buildLog = (chunk) => onProgress(4, 5, chunk.trim(), "");
|
|
538
|
+
await run("node", ["esbuild.mjs"], build, buildLog);
|
|
336
539
|
if (info.serverBinary) {
|
|
337
540
|
const sb = info.serverBinary;
|
|
338
541
|
onProgress(4, 5, "Downloading language server...", `fetching ${sb.repo}`);
|
|
339
542
|
try {
|
|
340
|
-
const
|
|
341
|
-
|
|
543
|
+
const tagRes = await fetch(`https://api.github.com/repos/${sb.repo}/releases/latest`);
|
|
544
|
+
if (!tagRes.ok) throw new Error(`GitHub API: HTTP ${tagRes.status}`);
|
|
545
|
+
const tagData = await tagRes.json();
|
|
546
|
+
const tag = tagData.tag_name;
|
|
547
|
+
const version = tag.replace(/^v/, "");
|
|
548
|
+
const archMap = {
|
|
549
|
+
arm64: "aarch64",
|
|
550
|
+
x64: "x86_64"
|
|
551
|
+
};
|
|
552
|
+
const platformMap = {
|
|
553
|
+
darwin: "apple-darwin",
|
|
554
|
+
linux: "unknown-linux-gnu",
|
|
555
|
+
win32: "pc-windows-msvc"
|
|
556
|
+
};
|
|
342
557
|
const arch2 = os3.arch() === "arm64" ? "arm64" : "x64";
|
|
343
558
|
const platform = process.platform === "win32" ? "win32" : process.platform === "darwin" ? "darwin" : "linux";
|
|
344
|
-
const
|
|
345
|
-
const
|
|
559
|
+
const rawArch = archMap[arch2] || arch2;
|
|
560
|
+
const rustTarget = `${rawArch}-${platformMap[platform] || platform}`;
|
|
561
|
+
const filename = sb.asset.replace(/\{\{version}}/g, version).replace(/\{\{platform}}/g, platform).replace(/\{\{arch}}/g, arch2).replace(/\{\{raw-arch}}/g, rawArch).replace(/\{\{rust-target}}/g, rustTarget);
|
|
562
|
+
const url = `https://github.com/${sb.repo}/releases/download/${tag}/${filename}`;
|
|
346
563
|
onProgress(4, 5, "Downloading...", `curl ${filename}`);
|
|
347
|
-
await run("curl", ["
|
|
348
|
-
|
|
349
|
-
onProgress(4, 5, "Extracting...", `tar xzf ${filename}`);
|
|
564
|
+
await run("curl", ["-#SL", url, "-o", path3.join(build, filename)], build);
|
|
565
|
+
onProgress(4, 5, "Extracting...", filename);
|
|
350
566
|
const serverDir2 = path3.join(build, "server");
|
|
351
567
|
fs3.mkdirSync(serverDir2, { recursive: true });
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
568
|
+
if (filename.endsWith(".zip")) {
|
|
569
|
+
await run("unzip", ["-o", filename, "-d", serverDir2], build);
|
|
570
|
+
} else if (filename.endsWith(".gz") && !filename.endsWith(".tar.gz")) {
|
|
571
|
+
const outName = filename.replace(/\.gz$/, "");
|
|
572
|
+
await run("gunzip", [filename], build);
|
|
573
|
+
fs3.renameSync(path3.join(build, outName), path3.join(serverDir2, outName));
|
|
574
|
+
} else {
|
|
575
|
+
await run("tar", ["xzf", filename, "-C", serverDir2], build);
|
|
576
|
+
}
|
|
577
|
+
try {
|
|
578
|
+
fs3.readdirSync(serverDir2).forEach((f) => {
|
|
579
|
+
fs3.chmodSync(path3.join(serverDir2, f), 493);
|
|
580
|
+
});
|
|
581
|
+
} catch {
|
|
582
|
+
}
|
|
583
|
+
if (sb.binaryPath || filename.match(/\.(zip|gz)$/)) {
|
|
584
|
+
const archivePath = path3.join(build, filename);
|
|
585
|
+
if (fs3.existsSync(archivePath)) fs3.rmSync(archivePath);
|
|
586
|
+
}
|
|
587
|
+
const indexPath = path3.join(build, "lib", "index.js");
|
|
588
|
+
if (fs3.existsSync(indexPath)) {
|
|
589
|
+
const binPath = (sb.binaryPath || sb.asset.split(/-?\{\{/)[0]).replace(/\{\{version}}/g, version).replace(/\{\{platform}}/g, platform).replace(/\{\{arch}}/g, arch2).replace(/\{\{raw-arch}}/g, rawArch).replace(/\{\{rust-target}}/g, rustTarget);
|
|
590
|
+
let code = fs3.readFileSync(indexPath, "utf-8");
|
|
591
|
+
const svrArgs = sb.args?.length ? JSON.stringify(sb.args) : "[]";
|
|
592
|
+
code = code.replace(
|
|
593
|
+
/\{ module:\s*serverModule,\s*transport:\s*\w+\.TransportKind\.\w+\s*\}/,
|
|
594
|
+
`{ command: serverModule, args: ${svrArgs} }`
|
|
595
|
+
);
|
|
596
|
+
const serverPath = `require('path').join(__dirname, '..', 'server', '${binPath}')`;
|
|
597
|
+
code = code.replace(
|
|
598
|
+
/try\s*\{[^}]*?require\.resolve\([^)]+\)\s*;?\s*\}\s*catch\s*\{\s*\}/g,
|
|
599
|
+
`try { serverModule = ${serverPath} } catch {}`
|
|
600
|
+
);
|
|
601
|
+
code = code.replace(
|
|
602
|
+
/let\s+serverModule\s*=\s*config\.get\([^)]+\)\s*;?\s*/g,
|
|
603
|
+
`let serverModule = ${serverPath};`
|
|
604
|
+
);
|
|
605
|
+
fs3.writeFileSync(indexPath, code);
|
|
606
|
+
}
|
|
607
|
+
} catch (e) {
|
|
608
|
+
onProgress(4, 5, `Warning: serverBinary setup failed (${e.message})`, "install server binary manually");
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
const docSelPath = path3.join(build, "lib", "index.js");
|
|
612
|
+
if (fs3.existsSync(docSelPath)) {
|
|
613
|
+
let code = fs3.readFileSync(docSelPath, "utf-8");
|
|
614
|
+
const langSelector = info.languages.map((l) => `{ scheme: "file", language: "${l}" }`).join(", ");
|
|
615
|
+
code = code.replace(
|
|
616
|
+
/documentSelector:\s*\[\s*\{[^}]*?language:\s*['"][^'"]*['"][^}]*\}\s*\]/,
|
|
617
|
+
`documentSelector: [${langSelector}]`
|
|
618
|
+
);
|
|
619
|
+
code = code.replace(
|
|
620
|
+
/client\.start\(\);/g,
|
|
621
|
+
"client.start().catch(() => {/* init may complete async */});"
|
|
622
|
+
);
|
|
623
|
+
fs3.writeFileSync(docSelPath, code);
|
|
624
|
+
}
|
|
625
|
+
const pkgPath = path3.join(build, "package.json");
|
|
626
|
+
if (fs3.existsSync(pkgPath)) {
|
|
627
|
+
try {
|
|
628
|
+
const pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
|
|
629
|
+
const events = pkg.activationEvents || [];
|
|
630
|
+
const langEvents = info.languages.map((l) => `onLanguage:${l}`);
|
|
631
|
+
const newEvents = events.filter((e) => !e.startsWith("onLanguage:")).concat(langEvents);
|
|
632
|
+
if (newEvents.length > 0 && JSON.stringify(newEvents) !== JSON.stringify(events)) {
|
|
633
|
+
pkg.activationEvents = newEvents;
|
|
634
|
+
fs3.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
635
|
+
}
|
|
355
636
|
} catch {
|
|
356
|
-
onProgress(4, 5, "Warning: server download failed", "install server binary manually");
|
|
357
637
|
}
|
|
358
638
|
}
|
|
359
639
|
}
|
|
@@ -369,6 +649,7 @@ async function installToCoc(name, onProgress) {
|
|
|
369
649
|
fs3.cpSync(src, dest, { recursive: true });
|
|
370
650
|
const pkgPath = extensionsPkgPath();
|
|
371
651
|
const pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
|
|
652
|
+
pkg.dependencies = pkg.dependencies || {};
|
|
372
653
|
const depName = `coc-${name}`;
|
|
373
654
|
if (!pkg.dependencies[depName]) {
|
|
374
655
|
pkg.dependencies[depName] = `file:${dest}`;
|
|
@@ -379,10 +660,10 @@ async function installToCoc(name, onProgress) {
|
|
|
379
660
|
function metaPath(name) {
|
|
380
661
|
return path3.join(cacheDir(name), "meta.json");
|
|
381
662
|
}
|
|
382
|
-
function saveMeta(name) {
|
|
663
|
+
async function saveMeta(name) {
|
|
383
664
|
const srcDir = sourceDir(name);
|
|
384
665
|
try {
|
|
385
|
-
const log =
|
|
666
|
+
const log = await runWithOutput("git", ["-C", srcDir, "log", "-1", "--format=%h|%s|%ar"], srcDir);
|
|
386
667
|
const [commit, msg, date] = log.split("|");
|
|
387
668
|
fs3.writeFileSync(metaPath(name), JSON.stringify({ commit, msg, date, updatedAt: Date.now() }, null, 2));
|
|
388
669
|
} catch {
|
|
@@ -408,9 +689,10 @@ async function installPackage(state, name) {
|
|
|
408
689
|
await convertSource(input, name, prog);
|
|
409
690
|
await buildPackage(name, input, info, prog);
|
|
410
691
|
await installToCoc(name, prog);
|
|
411
|
-
saveMeta(name);
|
|
692
|
+
await saveMeta(name);
|
|
412
693
|
state.setDirty();
|
|
413
694
|
state.setPackageStatus(name, "installed");
|
|
695
|
+
import_coc.window.showInformationMessage(`coc-${name} installed`);
|
|
414
696
|
try {
|
|
415
697
|
const meta = JSON.parse(fs3.readFileSync(metaPath(name), "utf-8"));
|
|
416
698
|
if (meta.commit) {
|
|
@@ -440,6 +722,7 @@ async function uninstallPackage(state, name) {
|
|
|
440
722
|
state.setPackageStatus(name, "uninstalling", { progress: "[2/3] Removing from package.json..." });
|
|
441
723
|
const pkgPath = extensionsPkgPath();
|
|
442
724
|
const pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
|
|
725
|
+
pkg.dependencies = pkg.dependencies || {};
|
|
443
726
|
const depName = `coc-${name}`;
|
|
444
727
|
if (pkg.dependencies[depName]) {
|
|
445
728
|
delete pkg.dependencies[depName];
|
|
@@ -453,6 +736,7 @@ async function uninstallPackage(state, name) {
|
|
|
453
736
|
}
|
|
454
737
|
state.setPackageStatus(name, "not-installed");
|
|
455
738
|
state.setDirty();
|
|
739
|
+
import_coc.window.showInformationMessage(`coc-${name} uninstalled`);
|
|
456
740
|
} catch (e) {
|
|
457
741
|
state.setPackageStatus(name, "failed", { error: e.message });
|
|
458
742
|
}
|
|
@@ -477,9 +761,10 @@ async function updatePackage(state, name) {
|
|
|
477
761
|
await convertSource(input, name, prog);
|
|
478
762
|
await buildPackage(name, input, info, prog);
|
|
479
763
|
await installToCoc(name, prog);
|
|
480
|
-
saveMeta(name);
|
|
764
|
+
await saveMeta(name);
|
|
481
765
|
state.setDirty();
|
|
482
766
|
state.setPackageStatus(name, "installed");
|
|
767
|
+
import_coc.window.showInformationMessage(`coc-${name} installed`);
|
|
483
768
|
try {
|
|
484
769
|
const meta = JSON.parse(fs3.readFileSync(metaPath(name), "utf-8"));
|
|
485
770
|
if (meta.commit) {
|
|
@@ -502,6 +787,10 @@ async function updatePackage(state, name) {
|
|
|
502
787
|
async function runWithOutput(cmd, args, cwd) {
|
|
503
788
|
return new Promise((resolve2, reject) => {
|
|
504
789
|
const child = (0, import_child_process.spawn)(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"], shell: true });
|
|
790
|
+
const timer = setTimeout(() => {
|
|
791
|
+
child.kill("SIGTERM");
|
|
792
|
+
reject(new Error(`Timed out after ${CMD_TIMEOUT / 1e3}s: ${cmd} ${args.join(" ")}`));
|
|
793
|
+
}, CMD_TIMEOUT);
|
|
505
794
|
let out = "";
|
|
506
795
|
child.stdout.on("data", (d) => {
|
|
507
796
|
out += d.toString();
|
|
@@ -509,10 +798,27 @@ async function runWithOutput(cmd, args, cwd) {
|
|
|
509
798
|
child.stderr.on("data", (d) => {
|
|
510
799
|
out += d.toString();
|
|
511
800
|
});
|
|
512
|
-
child.on("close", (code) =>
|
|
513
|
-
|
|
801
|
+
child.on("close", (code) => {
|
|
802
|
+
clearTimeout(timer);
|
|
803
|
+
code === 0 ? resolve2(out.trim()) : reject(new Error(`exit ${code}`));
|
|
804
|
+
});
|
|
805
|
+
child.on("error", (e) => {
|
|
806
|
+
clearTimeout(timer);
|
|
807
|
+
reject(e);
|
|
808
|
+
});
|
|
514
809
|
});
|
|
515
810
|
}
|
|
811
|
+
async function runConcurrent(items, fn, concurrency = 3) {
|
|
812
|
+
const pool = /* @__PURE__ */ new Set();
|
|
813
|
+
for (const item of items) {
|
|
814
|
+
const p = fn(item).finally(() => pool.delete(p));
|
|
815
|
+
pool.add(p);
|
|
816
|
+
if (pool.size >= concurrency) {
|
|
817
|
+
await Promise.race(pool);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
await Promise.all(pool);
|
|
821
|
+
}
|
|
516
822
|
async function checkUpdates(state) {
|
|
517
823
|
const s = state.getState();
|
|
518
824
|
const results = {};
|
|
@@ -612,8 +918,16 @@ var LineBuffer = class {
|
|
|
612
918
|
};
|
|
613
919
|
|
|
614
920
|
// src/tui.ts
|
|
921
|
+
var VERSION = (() => {
|
|
922
|
+
try {
|
|
923
|
+
const pkg = JSON.parse(require("fs").readFileSync(require("path").join(__dirname, "..", "package.json"), "utf-8"));
|
|
924
|
+
return pkg.version;
|
|
925
|
+
} catch {
|
|
926
|
+
return "0.0.0";
|
|
927
|
+
}
|
|
928
|
+
})();
|
|
615
929
|
var HELP_TEXT = [
|
|
616
|
-
|
|
930
|
+
` coc-loader v${VERSION} \u2014 VS Code extension \u2192 coc.nvim plugin converter`,
|
|
617
931
|
"",
|
|
618
932
|
" Keymaps:",
|
|
619
933
|
" i Install package under cursor",
|
|
@@ -621,10 +935,18 @@ var HELP_TEXT = [
|
|
|
621
935
|
" U Update all installed packages",
|
|
622
936
|
" C Check for updates from remote",
|
|
623
937
|
" X Uninstall package under cursor",
|
|
938
|
+
" R Reinstall package under cursor",
|
|
624
939
|
" Z Uninstall all installed packages (with confirm)",
|
|
940
|
+
" D Clean up orphaned packages",
|
|
941
|
+
" x Toggle mark",
|
|
942
|
+
" f Cycle filter: all \u2192 installed \u2192 not-installed",
|
|
943
|
+
" s Cycle sort: default \u2192 name \u2192 status \u2192 type",
|
|
944
|
+
" gg Jump to first package",
|
|
945
|
+
" G Jump to last package",
|
|
625
946
|
" <Enter> Toggle expand/collapse details",
|
|
626
947
|
" / Search filter",
|
|
627
|
-
" q
|
|
948
|
+
" q Close window",
|
|
949
|
+
" <Esc> Help\u2192Search\u2192Marks\u2192Busy guard\u2192Close",
|
|
628
950
|
"",
|
|
629
951
|
" " + "\u2500".repeat(40),
|
|
630
952
|
"",
|
|
@@ -652,13 +974,21 @@ var TUI = class {
|
|
|
652
974
|
i: "i",
|
|
653
975
|
u: "u",
|
|
654
976
|
X: "X",
|
|
655
|
-
|
|
977
|
+
R: "R",
|
|
978
|
+
cr: "<CR>",
|
|
979
|
+
f: "f",
|
|
980
|
+
s: "s",
|
|
981
|
+
x: "x",
|
|
982
|
+
D: "D",
|
|
983
|
+
gg: "gg",
|
|
984
|
+
G: "G"
|
|
656
985
|
};
|
|
657
986
|
this.rendering = false;
|
|
987
|
+
this.pendingRender = false;
|
|
658
988
|
this.state = state;
|
|
659
989
|
}
|
|
660
990
|
async open() {
|
|
661
|
-
const nvim =
|
|
991
|
+
const nvim = import_coc2.workspace.nvim;
|
|
662
992
|
this.ns = await nvim.createNamespace("coc-loader");
|
|
663
993
|
await nvim.command("highlight default link CocConverterTitle Title");
|
|
664
994
|
await nvim.command("highlight default link CocConverterPill Visual");
|
|
@@ -700,10 +1030,11 @@ var TUI = class {
|
|
|
700
1030
|
await nvim.call("nvim_win_set_option", [this.winid, "spell", false]);
|
|
701
1031
|
await nvim.call("nvim_win_set_option", [this.winid, "foldenable", false]);
|
|
702
1032
|
this.unsubscribe = this.state.subscribe(() => {
|
|
703
|
-
this.render()
|
|
1033
|
+
this.render().catch(() => {
|
|
1034
|
+
});
|
|
704
1035
|
});
|
|
705
1036
|
this.disposables.push(
|
|
706
|
-
|
|
1037
|
+
import_coc2.workspace.registerAutocmd({
|
|
707
1038
|
event: "WinEnter",
|
|
708
1039
|
request: true,
|
|
709
1040
|
callback: async () => {
|
|
@@ -727,10 +1058,14 @@ var TUI = class {
|
|
|
727
1058
|
`);
|
|
728
1059
|
}
|
|
729
1060
|
await this.setupKeymaps();
|
|
1061
|
+
updateRegistry().then(() => this.state.refreshPackages()).catch(() => {
|
|
1062
|
+
this.state.setStatusMessage("Failed to fetch remote registry (offline?)");
|
|
1063
|
+
setTimeout(() => this.state.setStatusMessage(), 5e3);
|
|
1064
|
+
});
|
|
730
1065
|
await this.render();
|
|
731
1066
|
}
|
|
732
1067
|
async getCursorLine0() {
|
|
733
|
-
const nvim =
|
|
1068
|
+
const nvim = import_coc2.workspace.nvim;
|
|
734
1069
|
const cursor = await nvim.call("nvim_win_get_cursor", [this.winid]);
|
|
735
1070
|
return cursor[0] - 1;
|
|
736
1071
|
}
|
|
@@ -760,6 +1095,16 @@ var TUI = class {
|
|
|
760
1095
|
this.state.setSearchQuery("");
|
|
761
1096
|
return;
|
|
762
1097
|
}
|
|
1098
|
+
const hasMarks = s.packages.some((p) => p.marked);
|
|
1099
|
+
if (hasMarks) {
|
|
1100
|
+
this.state.clearMarks();
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
const busy = s.packages.some((p) => ["installing", "updating", "uninstalling"].includes(p.status));
|
|
1104
|
+
if (busy) {
|
|
1105
|
+
import_coc2.window.showInformationMessage("Operation in progress, wait for it to finish");
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
763
1108
|
this.close();
|
|
764
1109
|
return;
|
|
765
1110
|
}
|
|
@@ -769,26 +1114,62 @@ var TUI = class {
|
|
|
769
1114
|
}
|
|
770
1115
|
if (id === "slash") {
|
|
771
1116
|
try {
|
|
772
|
-
const q = await
|
|
1117
|
+
const q = await import_coc2.workspace.nvim.call("input", ["Search: ", ""]);
|
|
773
1118
|
if (q) this.state.setSearchQuery(q);
|
|
774
1119
|
} catch {
|
|
775
1120
|
}
|
|
776
1121
|
return;
|
|
777
1122
|
}
|
|
1123
|
+
if (id === "f") {
|
|
1124
|
+
this.state.cycleViewFilter();
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
if (id === "s") {
|
|
1128
|
+
this.state.cycleSortBy();
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1131
|
+
if (id === "gg") {
|
|
1132
|
+
const firstLine = Math.min(...this.pkgLineMap.keys());
|
|
1133
|
+
if (isFinite(firstLine)) {
|
|
1134
|
+
await import_coc2.workspace.nvim.call("nvim_win_set_cursor", [this.winid, [firstLine + 1, 0]]);
|
|
1135
|
+
}
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
if (id === "G") {
|
|
1139
|
+
const lastLine = Math.max(...this.pkgLineMap.keys());
|
|
1140
|
+
if (isFinite(lastLine)) {
|
|
1141
|
+
await import_coc2.workspace.nvim.call("nvim_win_set_cursor", [this.winid, [lastLine + 1, 0]]);
|
|
1142
|
+
}
|
|
1143
|
+
return;
|
|
1144
|
+
}
|
|
1145
|
+
if (id === "D") {
|
|
1146
|
+
const installed = s.packages.filter((p) => p.status === "installed");
|
|
1147
|
+
const removed = installed.filter((p) => !getPackage(p.info.name));
|
|
1148
|
+
if (removed.length === 0) {
|
|
1149
|
+
import_coc2.window.showInformationMessage("No orphaned packages found");
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
1152
|
+
const ok = await import_coc2.window.showPrompt(`Uninstall ${removed.length} orphaned package(s)?`);
|
|
1153
|
+
if (ok) {
|
|
1154
|
+
for (const p of removed) await uninstallPackage(this.state, p.info.name);
|
|
1155
|
+
}
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
778
1158
|
if (id === "U") {
|
|
779
1159
|
const installed = s.packages.filter((p) => p.status === "installed");
|
|
780
1160
|
if (installed.length === 0) return;
|
|
781
1161
|
this.state.setActivePill("U");
|
|
782
|
-
|
|
1162
|
+
const names = installed.map((p) => p.info.name);
|
|
1163
|
+
await runConcurrent(names, (name) => updatePackage(this.state, name));
|
|
783
1164
|
this.state.setActivePill(null);
|
|
784
1165
|
return;
|
|
785
1166
|
}
|
|
786
1167
|
if (id === "Z") {
|
|
787
1168
|
const installed = s.packages.filter((p) => p.status === "installed");
|
|
788
1169
|
if (installed.length === 0) return;
|
|
789
|
-
const ok = await
|
|
1170
|
+
const ok = await import_coc2.window.showPrompt(`Uninstall all ${installed.length} packages?`);
|
|
790
1171
|
if (ok) {
|
|
791
|
-
for (const pkg of installed) uninstallPackage(this.state, pkg.info.name);
|
|
1172
|
+
for (const pkg of installed) await uninstallPackage(this.state, pkg.info.name);
|
|
792
1173
|
}
|
|
793
1174
|
return;
|
|
794
1175
|
}
|
|
@@ -802,6 +1183,10 @@ var TUI = class {
|
|
|
802
1183
|
if (!pkgName) return;
|
|
803
1184
|
const entry = this.state.getPackage(pkgName);
|
|
804
1185
|
if (!entry) return;
|
|
1186
|
+
if (id === "x") {
|
|
1187
|
+
this.state.toggleMark(pkgName);
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
805
1190
|
if (id === "i" && entry.status === "not-installed") {
|
|
806
1191
|
await installPackage(this.state, pkgName);
|
|
807
1192
|
return;
|
|
@@ -814,6 +1199,11 @@ var TUI = class {
|
|
|
814
1199
|
uninstallPackage(this.state, pkgName);
|
|
815
1200
|
return;
|
|
816
1201
|
}
|
|
1202
|
+
if (id === "R" && entry.status === "installed") {
|
|
1203
|
+
await uninstallPackage(this.state, pkgName);
|
|
1204
|
+
await installPackage(this.state, pkgName);
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
817
1207
|
if (id === "cr") {
|
|
818
1208
|
if (this.logLineSet.has(line0)) {
|
|
819
1209
|
this.state.toggleLog(pkgName);
|
|
@@ -824,7 +1214,7 @@ var TUI = class {
|
|
|
824
1214
|
}
|
|
825
1215
|
}
|
|
826
1216
|
async setupKeymaps() {
|
|
827
|
-
const buf =
|
|
1217
|
+
const buf = import_coc2.workspace.nvim.createBuffer(this.bufnr);
|
|
828
1218
|
const entries = [
|
|
829
1219
|
["q", "q"],
|
|
830
1220
|
["<Esc>", "esc"],
|
|
@@ -838,7 +1228,13 @@ var TUI = class {
|
|
|
838
1228
|
["H", "H"],
|
|
839
1229
|
["u", "u"],
|
|
840
1230
|
["X", "X"],
|
|
841
|
-
["
|
|
1231
|
+
["R", "R"],
|
|
1232
|
+
["f", "f"],
|
|
1233
|
+
["s", "s"],
|
|
1234
|
+
["x", "x"],
|
|
1235
|
+
["D", "D"],
|
|
1236
|
+
["gg", "gg"],
|
|
1237
|
+
["G", "G"],
|
|
842
1238
|
["<CR>", "cr"]
|
|
843
1239
|
];
|
|
844
1240
|
for (const [vimKey, id] of entries) {
|
|
@@ -857,20 +1253,25 @@ var TUI = class {
|
|
|
857
1253
|
this.disposables = [];
|
|
858
1254
|
if (this.winid) {
|
|
859
1255
|
try {
|
|
860
|
-
await
|
|
1256
|
+
await import_coc2.workspace.nvim.call("nvim_win_close", [this.winid, true]);
|
|
861
1257
|
} catch {
|
|
862
1258
|
}
|
|
863
1259
|
this.winid = 0;
|
|
864
1260
|
}
|
|
865
1261
|
if (needRestart) {
|
|
866
|
-
|
|
1262
|
+
import_coc2.workspace.nvim.command("CocRestart", true);
|
|
867
1263
|
}
|
|
868
1264
|
}
|
|
869
1265
|
async render() {
|
|
870
|
-
if (!this.winid
|
|
1266
|
+
if (!this.winid) return;
|
|
1267
|
+
if (this.rendering) {
|
|
1268
|
+
this.pendingRender = true;
|
|
1269
|
+
return;
|
|
1270
|
+
}
|
|
871
1271
|
this.rendering = true;
|
|
1272
|
+
this.pendingRender = false;
|
|
872
1273
|
try {
|
|
873
|
-
const nvim =
|
|
1274
|
+
const nvim = import_coc2.workspace.nvim;
|
|
874
1275
|
const state = this.state.getState();
|
|
875
1276
|
const filtered = this.state.getFilteredPackages();
|
|
876
1277
|
const result = state.showHelp ? this.renderHelp() : this.renderPackageList(state, filtered);
|
|
@@ -891,12 +1292,13 @@ var TUI = class {
|
|
|
891
1292
|
this.logLineSet = result.logLines;
|
|
892
1293
|
} finally {
|
|
893
1294
|
this.rendering = false;
|
|
1295
|
+
if (this.pendingRender) this.render();
|
|
894
1296
|
}
|
|
895
1297
|
}
|
|
896
1298
|
renderHelp() {
|
|
897
1299
|
const header = [
|
|
898
1300
|
"",
|
|
899
|
-
|
|
1301
|
+
` coc-loader v${VERSION}`,
|
|
900
1302
|
" press ? help | / search | q quit",
|
|
901
1303
|
" " + "\u2500".repeat(50),
|
|
902
1304
|
""
|
|
@@ -938,7 +1340,13 @@ var TUI = class {
|
|
|
938
1340
|
buf.highlight(/\([IU?C]\)/g, "CocConverterKey");
|
|
939
1341
|
buf.nl();
|
|
940
1342
|
buf.nl();
|
|
1343
|
+
const filterLabel = state.viewFilter === "all" ? "All" : state.viewFilter === "installed" ? "Installed" : "Available";
|
|
1344
|
+
const sortLabel = state.sortBy === "default" ? "Default" : state.sortBy === "name" ? "Name" : state.sortBy === "status" ? "Status" : "Type";
|
|
941
1345
|
buf.append(`Total: ${filtered.length} packages`, "CocConverterTotal");
|
|
1346
|
+
buf.append(` | `);
|
|
1347
|
+
buf.append(`F:${filterLabel}(f)`, "CocConverterPill");
|
|
1348
|
+
buf.append(` `);
|
|
1349
|
+
buf.append(`S:${sortLabel}(s)`, "CocConverterPill");
|
|
942
1350
|
if (state.statusMessage) {
|
|
943
1351
|
buf.append(" \xB7 ");
|
|
944
1352
|
buf.append(state.statusMessage, "Comment");
|
|
@@ -961,6 +1369,10 @@ var TUI = class {
|
|
|
961
1369
|
if (filtered.length === 0 && state.searchQuery) {
|
|
962
1370
|
buf.nl("no matching packages");
|
|
963
1371
|
}
|
|
1372
|
+
buf.nl();
|
|
1373
|
+
buf.append(" " + "\u2500".repeat(50), "Comment");
|
|
1374
|
+
buf.nl();
|
|
1375
|
+
buf.append(` ${filtered.length} packages \xB7 ${filterLabel} \xB7 ${sortLabel} order`, "Comment");
|
|
964
1376
|
const result = buf.render(2);
|
|
965
1377
|
return { lines: result.lines, pkgLineMap, logLines: logSet, highlights: result.highlights };
|
|
966
1378
|
}
|
|
@@ -969,7 +1381,12 @@ var TUI = class {
|
|
|
969
1381
|
const iconHl = entry.status === "installed" ? "CocConverterInstalled" : entry.status === "failed" ? "ErrorMsg" : "CocConverterAvailable";
|
|
970
1382
|
const pkgLine = buf.currentLine();
|
|
971
1383
|
pkgLineMap.set(pkgLine, entry.info.name);
|
|
972
|
-
|
|
1384
|
+
if (entry.marked) {
|
|
1385
|
+
buf.append("\u25B8", "CocConverterKey");
|
|
1386
|
+
buf.append(" ");
|
|
1387
|
+
} else {
|
|
1388
|
+
buf.append(" ");
|
|
1389
|
+
}
|
|
973
1390
|
buf.append(icon, iconHl);
|
|
974
1391
|
buf.append(" ");
|
|
975
1392
|
buf.append(entry.info.displayName);
|
|
@@ -989,15 +1406,17 @@ var TUI = class {
|
|
|
989
1406
|
}
|
|
990
1407
|
if (entry.expanded) {
|
|
991
1408
|
buf.nl();
|
|
992
|
-
|
|
1409
|
+
const extras = [
|
|
993
1410
|
entry.info.description,
|
|
994
1411
|
`type ${entry.info.type}`,
|
|
995
1412
|
entry.commit ? `commit ${entry.commit}` : null,
|
|
996
1413
|
`source ${sourceStr(entry.info.source)}`,
|
|
997
1414
|
`languages ${entry.info.languages.join(", ")}`,
|
|
998
1415
|
`categories ${entry.info.categories.join(", ")}`,
|
|
999
|
-
`homepage ${entry.info.url}
|
|
1000
|
-
|
|
1416
|
+
`homepage ${entry.info.url}`,
|
|
1417
|
+
entry.info.serverBinary ? `server ${entry.info.serverBinary.repo} (binary release)` : null
|
|
1418
|
+
];
|
|
1419
|
+
for (const text of extras.filter(Boolean)) {
|
|
1001
1420
|
const ln = buf.currentLine();
|
|
1002
1421
|
buf.nl(` ${text}`);
|
|
1003
1422
|
pkgLineMap.set(ln, entry.info.name);
|
|
@@ -1033,9 +1452,6 @@ var TUI = class {
|
|
|
1033
1452
|
}
|
|
1034
1453
|
buf.nl();
|
|
1035
1454
|
}
|
|
1036
|
-
hl(line, hlGroup, colStart, colEnd) {
|
|
1037
|
-
this.hlLines.push({ line, hlGroup, colStart, colEnd });
|
|
1038
|
-
}
|
|
1039
1455
|
isOpen() {
|
|
1040
1456
|
return this.winid !== 0;
|
|
1041
1457
|
}
|
|
@@ -1051,7 +1467,7 @@ var currentTUI = null;
|
|
|
1051
1467
|
async function activate(context) {
|
|
1052
1468
|
const state = new StateManager(createInitialState());
|
|
1053
1469
|
context.subscriptions.push(
|
|
1054
|
-
|
|
1470
|
+
import_coc3.commands.registerCommand("loader.open", async () => {
|
|
1055
1471
|
if (currentTUI && currentTUI.isOpen()) {
|
|
1056
1472
|
await currentTUI.close();
|
|
1057
1473
|
}
|
|
@@ -1060,94 +1476,111 @@ async function activate(context) {
|
|
|
1060
1476
|
})
|
|
1061
1477
|
);
|
|
1062
1478
|
context.subscriptions.push(
|
|
1063
|
-
|
|
1479
|
+
import_coc3.commands.registerCommand("loader.install", async (name) => {
|
|
1064
1480
|
if (!name) {
|
|
1065
|
-
name = await
|
|
1481
|
+
name = await import_coc3.workspace.nvim.call("input", ["Plugin name: ", ""]);
|
|
1066
1482
|
if (!name) return;
|
|
1067
1483
|
}
|
|
1068
1484
|
const pkg = state.getPackage(name);
|
|
1069
1485
|
if (!pkg) {
|
|
1070
|
-
|
|
1486
|
+
import_coc3.window.showInformationMessage(`Unknown package: ${name}`);
|
|
1071
1487
|
return;
|
|
1072
1488
|
}
|
|
1073
1489
|
if (pkg.status === "installed") {
|
|
1074
|
-
|
|
1490
|
+
import_coc3.window.showInformationMessage(`${name} is already installed`);
|
|
1075
1491
|
return;
|
|
1076
1492
|
}
|
|
1077
1493
|
await installPackage(state, name);
|
|
1078
1494
|
})
|
|
1079
1495
|
);
|
|
1080
1496
|
context.subscriptions.push(
|
|
1081
|
-
|
|
1497
|
+
import_coc3.commands.registerCommand("loader.uninstall", async (name) => {
|
|
1082
1498
|
if (!name) {
|
|
1083
|
-
name = await
|
|
1499
|
+
name = await import_coc3.workspace.nvim.call("input", ["Plugin name: ", ""]);
|
|
1084
1500
|
if (!name) return;
|
|
1085
1501
|
}
|
|
1086
1502
|
const pkg = state.getPackage(name);
|
|
1087
1503
|
if (!pkg) {
|
|
1088
|
-
|
|
1504
|
+
import_coc3.window.showInformationMessage(`Unknown package: ${name}`);
|
|
1089
1505
|
return;
|
|
1090
1506
|
}
|
|
1091
1507
|
if (pkg.status !== "installed") {
|
|
1092
|
-
|
|
1508
|
+
import_coc3.window.showInformationMessage(`${name} is not installed`);
|
|
1093
1509
|
return;
|
|
1094
1510
|
}
|
|
1095
1511
|
uninstallPackage(state, name);
|
|
1096
1512
|
})
|
|
1097
1513
|
);
|
|
1098
1514
|
context.subscriptions.push(
|
|
1099
|
-
|
|
1515
|
+
import_coc3.commands.registerCommand("loader.update", async (name) => {
|
|
1100
1516
|
if (!name) {
|
|
1101
|
-
name = await
|
|
1517
|
+
name = await import_coc3.workspace.nvim.call("input", ["Plugin name: ", ""]);
|
|
1102
1518
|
if (!name) return;
|
|
1103
1519
|
}
|
|
1104
1520
|
const pkg = state.getPackage(name);
|
|
1105
1521
|
if (!pkg) {
|
|
1106
|
-
|
|
1522
|
+
import_coc3.window.showInformationMessage(`Unknown package: ${name}`);
|
|
1107
1523
|
return;
|
|
1108
1524
|
}
|
|
1109
1525
|
if (pkg.status !== "installed") {
|
|
1110
|
-
|
|
1526
|
+
import_coc3.window.showInformationMessage(`${name} is not installed`);
|
|
1111
1527
|
return;
|
|
1112
1528
|
}
|
|
1113
1529
|
await updatePackage(state, name);
|
|
1114
1530
|
})
|
|
1115
1531
|
);
|
|
1116
1532
|
context.subscriptions.push(
|
|
1117
|
-
|
|
1533
|
+
import_coc3.commands.registerCommand("loader.uninstallAll", async () => {
|
|
1118
1534
|
const installed = state.getState().packages.filter((p) => p.status === "installed");
|
|
1119
1535
|
if (installed.length === 0) {
|
|
1120
|
-
|
|
1536
|
+
import_coc3.window.showInformationMessage("No packages installed");
|
|
1121
1537
|
return;
|
|
1122
1538
|
}
|
|
1123
|
-
const ok = await
|
|
1539
|
+
const ok = await import_coc3.window.showPrompt(`Uninstall all ${installed.length} packages?`);
|
|
1124
1540
|
if (ok) {
|
|
1125
1541
|
for (const pkg of installed) {
|
|
1126
|
-
uninstallPackage(state, pkg.info.name);
|
|
1542
|
+
await uninstallPackage(state, pkg.info.name);
|
|
1127
1543
|
}
|
|
1128
1544
|
}
|
|
1129
1545
|
})
|
|
1130
1546
|
);
|
|
1131
1547
|
context.subscriptions.push(
|
|
1132
|
-
|
|
1548
|
+
import_coc3.commands.registerCommand("loader.reinstall", async (name) => {
|
|
1549
|
+
if (!name) {
|
|
1550
|
+
name = await import_coc3.workspace.nvim.call("input", ["Plugin name: ", ""]);
|
|
1551
|
+
if (!name) return;
|
|
1552
|
+
}
|
|
1553
|
+
const pkg = state.getPackage(name);
|
|
1554
|
+
if (!pkg) {
|
|
1555
|
+
import_coc3.window.showInformationMessage(`Unknown package: ${name}`);
|
|
1556
|
+
return;
|
|
1557
|
+
}
|
|
1558
|
+
if (pkg.status !== "installed") {
|
|
1559
|
+
import_coc3.window.showInformationMessage(`${name} is not installed`);
|
|
1560
|
+
return;
|
|
1561
|
+
}
|
|
1562
|
+
await uninstallPackage(state, name);
|
|
1563
|
+
await installPackage(state, name);
|
|
1564
|
+
})
|
|
1565
|
+
);
|
|
1566
|
+
context.subscriptions.push(
|
|
1567
|
+
import_coc3.commands.registerCommand("loader.updateRegistry", async () => {
|
|
1133
1568
|
try {
|
|
1134
1569
|
const count = await updateRegistry();
|
|
1135
|
-
|
|
1570
|
+
import_coc3.window.showInformationMessage(`Registry updated: ${count} packages available. Restart coc to apply.`);
|
|
1136
1571
|
} catch (e) {
|
|
1137
|
-
|
|
1572
|
+
import_coc3.window.showErrorMessage(`Registry update failed: ${e.message}`);
|
|
1138
1573
|
}
|
|
1139
1574
|
})
|
|
1140
1575
|
);
|
|
1141
1576
|
context.subscriptions.push(
|
|
1142
|
-
|
|
1577
|
+
import_coc3.commands.registerCommand("loader._dispatch", async (key) => {
|
|
1143
1578
|
if (currentTUI) {
|
|
1144
1579
|
await currentTUI.handleKey(key);
|
|
1145
1580
|
}
|
|
1146
1581
|
})
|
|
1147
1582
|
);
|
|
1148
|
-
|
|
1149
|
-
});
|
|
1150
|
-
import_coc2.window.showInformationMessage("coc-loader activated! Use :CocCommand loader.open");
|
|
1583
|
+
import_coc3.window.showInformationMessage("coc-loader activated! Use :CocCommand loader.open");
|
|
1151
1584
|
}
|
|
1152
1585
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1153
1586
|
0 && (module.exports = {
|