coc-vscode-loader 1.1.0 → 1.1.2
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 +20 -6
- package/assets/tui-preview.png +0 -0
- package/converter/package-lock.json +71 -245
- package/converter/package.json +4 -4
- package/converter/pnpm-lock.yaml +66 -170
- package/lib/index.js +589 -115
- package/package.json +3 -3
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,53 +34,99 @@ 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.2",
|
|
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
|
+
license: "MIT",
|
|
62
|
+
engines: {
|
|
63
|
+
coc: ">= 0.0.80"
|
|
64
|
+
},
|
|
65
|
+
scripts: {
|
|
66
|
+
"bundle-converter": "rm -rf converter && cp -r ../converter ./converter && cd converter && npm install --legacy-peer-deps",
|
|
67
|
+
build: "npm run bundle-converter && node esbuild.mjs",
|
|
68
|
+
prepare: "node esbuild.mjs"
|
|
69
|
+
},
|
|
70
|
+
devDependencies: {
|
|
71
|
+
"coc.nvim": "^0.0.83-next.18",
|
|
72
|
+
esbuild: "^0.28.1",
|
|
73
|
+
typescript: "^6.0.3"
|
|
74
|
+
},
|
|
75
|
+
activationEvents: [
|
|
76
|
+
"onCommand:loader.open",
|
|
77
|
+
"onCommand:loader.install",
|
|
78
|
+
"onCommand:loader.uninstall",
|
|
79
|
+
"onCommand:loader.update",
|
|
80
|
+
"onCommand:loader.uninstallAll",
|
|
81
|
+
"onCommand:loader.updateRegistry",
|
|
82
|
+
"onCommand:loader._dispatch"
|
|
83
|
+
],
|
|
84
|
+
contributes: {
|
|
85
|
+
commands: [
|
|
86
|
+
{ command: "loader.open", title: "Open VS Code extension loader" },
|
|
87
|
+
{ command: "loader.install", title: "Install a VS Code extension" },
|
|
88
|
+
{ command: "loader.uninstall", title: "Uninstall a package" },
|
|
89
|
+
{ command: "loader.update", title: "Update a package" },
|
|
90
|
+
{ command: "loader.uninstallAll", title: "Uninstall all packages" },
|
|
91
|
+
{ command: "loader.updateRegistry", title: "Update package registry" },
|
|
92
|
+
{ command: "loader._dispatch", title: "" }
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
30
99
|
// src/index.ts
|
|
31
100
|
var index_exports = {};
|
|
32
101
|
__export(index_exports, {
|
|
33
102
|
activate: () => activate
|
|
34
103
|
});
|
|
35
104
|
module.exports = __toCommonJS(index_exports);
|
|
36
|
-
var
|
|
105
|
+
var import_coc3 = require("coc.nvim");
|
|
37
106
|
|
|
38
107
|
// src/registry.ts
|
|
39
108
|
var path = __toESM(require("path"));
|
|
40
109
|
var fs = __toESM(require("fs"));
|
|
41
110
|
var os = __toESM(require("os"));
|
|
111
|
+
function pluginVersion() {
|
|
112
|
+
try {
|
|
113
|
+
return require_package().version;
|
|
114
|
+
} catch {
|
|
115
|
+
return "0.0.0";
|
|
116
|
+
}
|
|
117
|
+
}
|
|
42
118
|
var REMOTE_REGISTRY_URL = "https://raw.githubusercontent.com/coc-plugin/coc-vscode-registry/main/registry.json";
|
|
43
119
|
var CACHE_PATH = path.join(os.homedir(), ".config", "coc", "converter-cache", "registry.json");
|
|
44
|
-
var BUILTIN_REGISTRY = [
|
|
45
|
-
{
|
|
46
|
-
name: "volar",
|
|
47
|
-
displayName: "Volar (Vue)",
|
|
48
|
-
description: "Vue language support \u2014 template/script/style IntelliSense",
|
|
49
|
-
type: "ts-bridge",
|
|
50
|
-
source: { type: "github", repo: "vuejs/language-tools", subdir: "extensions/vscode" },
|
|
51
|
-
url: "https://github.com/vuejs/language-tools",
|
|
52
|
-
languages: ["vue"],
|
|
53
|
-
categories: ["LSP", "TypeScript"]
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
name: "prisma",
|
|
57
|
-
displayName: "Prisma",
|
|
58
|
-
description: "Prisma schema language support \u2014 syntax highlight, lint, format",
|
|
59
|
-
type: "pure-lsp",
|
|
60
|
-
source: { type: "github", repo: "prisma/language-tools", subdir: "packages/vscode" },
|
|
61
|
-
url: "https://github.com/prisma/language-tools",
|
|
62
|
-
languages: ["prisma"],
|
|
63
|
-
categories: ["LSP"]
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
name: "html-css-support",
|
|
67
|
-
displayName: "HTML CSS Support",
|
|
68
|
-
description: "CSS class name completion for HTML attributes",
|
|
69
|
-
type: "direct-api",
|
|
70
|
-
source: { type: "github", repo: "ecmel/vscode-html-css" },
|
|
71
|
-
url: "https://github.com/ecmel/vscode-html-css",
|
|
72
|
-
languages: ["html", "css"],
|
|
73
|
-
categories: ["Completion"]
|
|
74
|
-
}
|
|
75
|
-
];
|
|
76
120
|
var cached = null;
|
|
121
|
+
function getLocalRegistryPath() {
|
|
122
|
+
try {
|
|
123
|
+
const pluginDir2 = path.dirname(fs.realpathSync(__dirname));
|
|
124
|
+
const local = path.join(pluginDir2, "..", "coc-vscode-registry", "registry.json");
|
|
125
|
+
if (fs.existsSync(local)) return local;
|
|
126
|
+
} catch {
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
77
130
|
function loadCache() {
|
|
78
131
|
try {
|
|
79
132
|
if (fs.existsSync(CACHE_PATH)) {
|
|
@@ -84,6 +137,16 @@ function loadCache() {
|
|
|
84
137
|
return null;
|
|
85
138
|
}
|
|
86
139
|
async function updateRegistry() {
|
|
140
|
+
const localPath = process.env.COC_REGISTRY_PATH || getLocalRegistryPath();
|
|
141
|
+
if (localPath) {
|
|
142
|
+
if (!fs.existsSync(localPath)) throw new Error(`Local registry not found: ${localPath}`);
|
|
143
|
+
const data2 = JSON.parse(fs.readFileSync(localPath, "utf-8"));
|
|
144
|
+
if (!Array.isArray(data2)) throw new Error("Invalid registry format");
|
|
145
|
+
fs.mkdirSync(path.dirname(CACHE_PATH), { recursive: true });
|
|
146
|
+
fs.writeFileSync(CACHE_PATH, JSON.stringify(data2, null, 2));
|
|
147
|
+
cached = data2;
|
|
148
|
+
return data2.length;
|
|
149
|
+
}
|
|
87
150
|
const res = await fetch(REMOTE_REGISTRY_URL);
|
|
88
151
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
89
152
|
const data = await res.json();
|
|
@@ -93,10 +156,21 @@ async function updateRegistry() {
|
|
|
93
156
|
cached = data;
|
|
94
157
|
return data.length;
|
|
95
158
|
}
|
|
159
|
+
function satisfiesVersion(required) {
|
|
160
|
+
const a = pluginVersion().split(".").map(Number);
|
|
161
|
+
const b = required.split(".").map(Number);
|
|
162
|
+
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
|
163
|
+
const va = a[i] || 0, vb = b[i] || 0;
|
|
164
|
+
if (va > vb) return true;
|
|
165
|
+
if (va < vb) return false;
|
|
166
|
+
}
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
96
169
|
function getAllPackages() {
|
|
97
|
-
if (cached)
|
|
98
|
-
|
|
99
|
-
|
|
170
|
+
if (!cached) {
|
|
171
|
+
cached = loadCache() || [];
|
|
172
|
+
}
|
|
173
|
+
return cached.filter((p) => !p.minPluginVersion || satisfiesVersion(p.minPluginVersion));
|
|
100
174
|
}
|
|
101
175
|
function getPackage(name) {
|
|
102
176
|
return getAllPackages().find((p) => p.name === name);
|
|
@@ -113,12 +187,16 @@ function createInitialState() {
|
|
|
113
187
|
const packages = getAllPackages().map((info) => {
|
|
114
188
|
const installed = isInstalled(info.name);
|
|
115
189
|
let commit;
|
|
190
|
+
let commitMsg;
|
|
191
|
+
let commitDate;
|
|
116
192
|
if (installed) {
|
|
117
193
|
try {
|
|
118
194
|
const meta = JSON.parse(
|
|
119
195
|
fs2.readFileSync(path2.join(os2.homedir(), ".config", "coc", "converter-cache", info.name, "meta.json"), "utf-8")
|
|
120
196
|
);
|
|
121
197
|
commit = meta.commit || void 0;
|
|
198
|
+
commitMsg = meta.msg || void 0;
|
|
199
|
+
commitDate = meta.date || void 0;
|
|
122
200
|
} catch {
|
|
123
201
|
}
|
|
124
202
|
}
|
|
@@ -126,12 +204,15 @@ function createInitialState() {
|
|
|
126
204
|
info,
|
|
127
205
|
status: installed ? "installed" : "not-installed",
|
|
128
206
|
commit,
|
|
207
|
+
commitMsg,
|
|
208
|
+
commitDate,
|
|
129
209
|
progressLog: [],
|
|
130
210
|
expanded: false,
|
|
131
|
-
logExpanded: false
|
|
211
|
+
logExpanded: false,
|
|
212
|
+
marked: false
|
|
132
213
|
};
|
|
133
214
|
});
|
|
134
|
-
return { packages, searchQuery: "", showHelp: false, activePill: null, dirty: false, viewFilter: "all" };
|
|
215
|
+
return { packages, searchQuery: "", showHelp: false, activePill: null, dirty: false, viewFilter: "all", sortBy: "default" };
|
|
135
216
|
}
|
|
136
217
|
var StateManager = class {
|
|
137
218
|
constructor(initial) {
|
|
@@ -165,10 +246,16 @@ var StateManager = class {
|
|
|
165
246
|
this.mutate((s) => {
|
|
166
247
|
const pkg = s.packages.find((p) => p.info.name === name);
|
|
167
248
|
if (pkg) {
|
|
249
|
+
if (status === "installing" || status === "updating" || status === "uninstalling") {
|
|
250
|
+
pkg.progressLog = [];
|
|
251
|
+
}
|
|
168
252
|
pkg.status = status;
|
|
169
253
|
if (extra?.progress !== void 0) pkg.progress = extra.progress;
|
|
170
|
-
if (extra?.logEntry !== void 0)
|
|
171
|
-
|
|
254
|
+
if (extra?.logEntry !== void 0) {
|
|
255
|
+
pkg.progressLog.push(extra.logEntry);
|
|
256
|
+
} else if (extra?.progress !== void 0) {
|
|
257
|
+
pkg.progressLog.push(extra.progress);
|
|
258
|
+
}
|
|
172
259
|
if (extra?.error !== void 0) pkg.error = extra.error;
|
|
173
260
|
if (status === "installed" || status === "not-installed") {
|
|
174
261
|
pkg.progress = void 0;
|
|
@@ -198,6 +285,21 @@ var StateManager = class {
|
|
|
198
285
|
s.viewFilter = filter;
|
|
199
286
|
});
|
|
200
287
|
}
|
|
288
|
+
cycleViewFilter() {
|
|
289
|
+
this.mutate((s) => {
|
|
290
|
+
s.viewFilter = s.viewFilter === "all" ? "installed" : s.viewFilter === "installed" ? "not-installed" : "all";
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
setSortBy(sortBy) {
|
|
294
|
+
this.mutate((s) => {
|
|
295
|
+
s.sortBy = sortBy;
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
cycleSortBy() {
|
|
299
|
+
this.mutate((s) => {
|
|
300
|
+
s.sortBy = s.sortBy === "default" ? "name" : s.sortBy === "name" ? "status" : s.sortBy === "status" ? "type" : "default";
|
|
301
|
+
});
|
|
302
|
+
}
|
|
201
303
|
setStatusMessage(msg) {
|
|
202
304
|
this.mutate((s) => {
|
|
203
305
|
s.statusMessage = msg;
|
|
@@ -226,21 +328,68 @@ var StateManager = class {
|
|
|
226
328
|
pkgs = pkgs.filter((p) => p.status === "installed");
|
|
227
329
|
}
|
|
228
330
|
const q = this.state.searchQuery.toLowerCase();
|
|
229
|
-
if (
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
331
|
+
if (q) {
|
|
332
|
+
pkgs = pkgs.filter(
|
|
333
|
+
(p) => p.info.name.toLowerCase().includes(q) || p.info.displayName.toLowerCase().includes(q) || p.info.description.toLowerCase().includes(q)
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
const sortBy = this.state.sortBy;
|
|
337
|
+
if (sortBy === "name") {
|
|
338
|
+
pkgs = [...pkgs].sort((a, b) => a.info.name.localeCompare(b.info.name));
|
|
339
|
+
} else if (sortBy === "status") {
|
|
340
|
+
const order = { installed: 0, installing: 1, updating: 2, uninstalling: 3, failed: 4, "not-installed": 5 };
|
|
341
|
+
pkgs = [...pkgs].sort((a, b) => (order[a.status] ?? 9) - (order[b.status] ?? 9));
|
|
342
|
+
} else if (sortBy === "type") {
|
|
343
|
+
pkgs = [...pkgs].sort((a, b) => a.info.type.localeCompare(b.info.type));
|
|
344
|
+
}
|
|
345
|
+
return pkgs;
|
|
233
346
|
}
|
|
234
347
|
getPackage(name) {
|
|
235
348
|
return this.state.packages.find((p) => p.info.name === name);
|
|
236
349
|
}
|
|
350
|
+
toggleMark(name) {
|
|
351
|
+
this.mutate((s) => {
|
|
352
|
+
const pkg = s.packages.find((p) => p.info.name === name);
|
|
353
|
+
if (pkg) pkg.marked = !pkg.marked;
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
clearMarks() {
|
|
357
|
+
this.mutate((s) => {
|
|
358
|
+
for (const p of s.packages) p.marked = false;
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
getMarkedNames() {
|
|
362
|
+
return this.state.packages.filter((p) => p.marked).map((p) => p.info.name);
|
|
363
|
+
}
|
|
364
|
+
refreshPackages() {
|
|
365
|
+
this.mutate((s) => {
|
|
366
|
+
const updated = getAllPackages();
|
|
367
|
+
const oldMap = new Map(s.packages.map((p) => [p.info.name, p]));
|
|
368
|
+
s.packages = updated.map((info) => {
|
|
369
|
+
const old = oldMap.get(info.name);
|
|
370
|
+
if (old) {
|
|
371
|
+
old.info = info;
|
|
372
|
+
return old;
|
|
373
|
+
}
|
|
374
|
+
return {
|
|
375
|
+
info,
|
|
376
|
+
status: isInstalled(info.name) ? "installed" : "not-installed",
|
|
377
|
+
progressLog: [],
|
|
378
|
+
expanded: false,
|
|
379
|
+
logExpanded: false,
|
|
380
|
+
marked: false
|
|
381
|
+
};
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
}
|
|
237
385
|
};
|
|
238
386
|
|
|
239
387
|
// src/tui.ts
|
|
240
|
-
var
|
|
388
|
+
var import_coc2 = require("coc.nvim");
|
|
241
389
|
|
|
242
390
|
// src/pipeline.ts
|
|
243
391
|
var import_child_process = require("child_process");
|
|
392
|
+
var import_coc = require("coc.nvim");
|
|
244
393
|
var path3 = __toESM(require("path"));
|
|
245
394
|
var fs3 = __toESM(require("fs"));
|
|
246
395
|
var os3 = __toESM(require("os"));
|
|
@@ -259,12 +408,9 @@ function pluginDir(name) {
|
|
|
259
408
|
}
|
|
260
409
|
function converterCliPath() {
|
|
261
410
|
const base = path3.resolve(__dirname, "..");
|
|
262
|
-
const cwd = process.cwd();
|
|
263
411
|
const candidates = [
|
|
264
412
|
path3.join(base, "converter", "src", "cli.ts"),
|
|
265
|
-
path3.join(base, "..", "converter", "src", "cli.ts")
|
|
266
|
-
path3.join(cwd, "converter", "src", "cli.ts"),
|
|
267
|
-
path3.join(cwd, "..", "converter", "src", "cli.ts")
|
|
413
|
+
path3.join(base, "..", "converter", "src", "cli.ts")
|
|
268
414
|
];
|
|
269
415
|
for (const p of candidates) {
|
|
270
416
|
if (fs3.existsSync(p)) return p;
|
|
@@ -273,37 +419,43 @@ function converterCliPath() {
|
|
|
273
419
|
"converter CLI not found. Please set $COC_CONVERTER_PATH to the converter/ directory, or ensure it is at the same level as coc-converter/"
|
|
274
420
|
);
|
|
275
421
|
}
|
|
422
|
+
var CMD_TIMEOUT = 3e5;
|
|
276
423
|
async function run(cmd, args, cwd, onLine) {
|
|
277
424
|
return new Promise((resolve2, reject) => {
|
|
278
425
|
const child = (0, import_child_process.spawn)(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"], shell: true });
|
|
279
|
-
const
|
|
426
|
+
const timer = setTimeout(() => {
|
|
427
|
+
child.kill("SIGTERM");
|
|
428
|
+
reject(new Error(`Timed out after ${CMD_TIMEOUT / 1e3}s: ${cmd} ${args.join(" ")}`));
|
|
429
|
+
}, CMD_TIMEOUT);
|
|
280
430
|
const handler = (data) => {
|
|
281
431
|
const text = data.toString();
|
|
282
|
-
|
|
283
|
-
onLine(text);
|
|
432
|
+
onLine?.(text);
|
|
284
433
|
};
|
|
285
434
|
child.stdout.on("data", handler);
|
|
286
435
|
child.stderr.on("data", handler);
|
|
287
436
|
child.on("close", (code) => {
|
|
437
|
+
clearTimeout(timer);
|
|
288
438
|
if (code === 0) resolve2();
|
|
289
439
|
else reject(new Error(`${cmd} ${args.join(" ")} exited with code ${code}`));
|
|
290
440
|
});
|
|
291
|
-
child.on("error",
|
|
441
|
+
child.on("error", (e) => {
|
|
442
|
+
clearTimeout(timer);
|
|
443
|
+
reject(e);
|
|
444
|
+
});
|
|
292
445
|
});
|
|
293
446
|
}
|
|
294
447
|
async function downloadSource(info, name, onProgress) {
|
|
295
448
|
const srcDir = sourceDir(name);
|
|
296
449
|
const cache = cacheDir(name);
|
|
297
450
|
const repoUrl = `https://github.com/${info.source.repo}.git`;
|
|
451
|
+
const log = (chunk) => onProgress(1, 5, chunk.trim(), "");
|
|
298
452
|
if (fs3.existsSync(srcDir)) {
|
|
299
453
|
onProgress(1, 5, "Updating source...", `git -C ${srcDir} pull`);
|
|
300
|
-
await run("git", ["-C", srcDir, "pull"], cache,
|
|
301
|
-
});
|
|
454
|
+
await run("git", ["-C", srcDir, "pull"], cache, log);
|
|
302
455
|
} else {
|
|
303
456
|
onProgress(1, 5, "Cloning repository...", `git clone --depth=1 ${repoUrl}`);
|
|
304
457
|
fs3.mkdirSync(cache, { recursive: true });
|
|
305
|
-
await run("git", ["clone", "--depth=1", repoUrl, srcDir], cache,
|
|
306
|
-
});
|
|
458
|
+
await run("git", ["clone", "--depth=1", repoUrl, srcDir], cache, log);
|
|
307
459
|
}
|
|
308
460
|
return info.source.subdir ? path3.join(srcDir, info.source.subdir) : srcDir;
|
|
309
461
|
}
|
|
@@ -312,17 +464,154 @@ async function convertSource(inputDir, name, onProgress) {
|
|
|
312
464
|
if (fs3.existsSync(build)) fs3.rmSync(build, { recursive: true });
|
|
313
465
|
const cli = converterCliPath();
|
|
314
466
|
onProgress(2, 5, "Converting...", `converter convert ${inputDir} -o ${build}`);
|
|
315
|
-
|
|
316
|
-
|
|
467
|
+
const log = (chunk) => onProgress(2, 5, chunk.trim(), "");
|
|
468
|
+
await run("npx", ["tsx", cli, "convert", inputDir, "-o", build], cacheDir(name), log);
|
|
317
469
|
}
|
|
318
|
-
async function buildPackage(name, onProgress) {
|
|
470
|
+
async function buildPackage(name, inputDir, info, onProgress) {
|
|
319
471
|
const build = buildDir(name);
|
|
472
|
+
const npmLog = (chunk) => onProgress(3, 5, chunk.trim(), "");
|
|
320
473
|
onProgress(3, 5, "Installing dependencies...", "npm install --legacy-peer-deps");
|
|
321
|
-
await run("npm", ["install", "--legacy-peer-deps"], build,
|
|
474
|
+
await run("npm", ["install", "--legacy-peer-deps"], build, npmLog);
|
|
475
|
+
onProgress(3, 5, "Running postinstall...", "npm run postinstall");
|
|
476
|
+
await run("npm", ["run", "postinstall", "--if-present"], build, npmLog).catch(() => {
|
|
322
477
|
});
|
|
478
|
+
if (info.pipPackages?.length) {
|
|
479
|
+
const pipLog = (chunk) => onProgress(3, 5, chunk.trim(), "");
|
|
480
|
+
const pythonPaths = [
|
|
481
|
+
"/opt/homebrew/bin/python3",
|
|
482
|
+
"/usr/local/bin/python3",
|
|
483
|
+
"/usr/bin/python3",
|
|
484
|
+
"python3"
|
|
485
|
+
];
|
|
486
|
+
let pythonBin = "";
|
|
487
|
+
for (const p of pythonPaths) {
|
|
488
|
+
if (p === "python3") {
|
|
489
|
+
try {
|
|
490
|
+
await run("python3", ["--version"], build);
|
|
491
|
+
pythonBin = "python3";
|
|
492
|
+
break;
|
|
493
|
+
} catch {
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
496
|
+
} else if (fs3.existsSync(p)) {
|
|
497
|
+
pythonBin = p;
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (!pythonBin) throw new Error("python3 not found, cannot install pip packages: " + info.pipPackages.join(", "));
|
|
502
|
+
const pipArgs = ["-m", "pip", "install"];
|
|
503
|
+
if (process.platform === "linux") pipArgs.push("--break-system-packages");
|
|
504
|
+
onProgress(3, 5, "Installing pip packages...", `${pythonBin} -m pip install ${info.pipPackages.join(" ")}`);
|
|
505
|
+
await run(pythonBin, pipArgs.concat(...info.pipPackages), build, pipLog);
|
|
506
|
+
}
|
|
507
|
+
const serverDir = path3.join(inputDir, "server");
|
|
508
|
+
if (fs3.existsSync(serverDir) && fs3.existsSync(path3.join(serverDir, "package.json"))) {
|
|
509
|
+
onProgress(3, 5, "Installing server dependencies...", `npm install in ${serverDir}`);
|
|
510
|
+
await run("npm", ["install", "--legacy-peer-deps"], serverDir, npmLog);
|
|
511
|
+
const destServer = path3.join(build, "server");
|
|
512
|
+
if (fs3.existsSync(destServer)) fs3.rmSync(destServer, { recursive: true });
|
|
513
|
+
fs3.cpSync(serverDir, destServer, { recursive: true });
|
|
514
|
+
}
|
|
323
515
|
onProgress(4, 5, "Building...", "node esbuild.mjs");
|
|
324
|
-
|
|
325
|
-
|
|
516
|
+
const buildLog = (chunk) => onProgress(4, 5, chunk.trim(), "");
|
|
517
|
+
await run("node", ["esbuild.mjs"], build, buildLog);
|
|
518
|
+
if (info.serverBinary) {
|
|
519
|
+
const sb = info.serverBinary;
|
|
520
|
+
onProgress(4, 5, "Downloading language server...", `fetching ${sb.repo}`);
|
|
521
|
+
try {
|
|
522
|
+
const tagRes = await fetch(`https://api.github.com/repos/${sb.repo}/releases/latest`);
|
|
523
|
+
if (!tagRes.ok) throw new Error(`GitHub API: HTTP ${tagRes.status}`);
|
|
524
|
+
const tagData = await tagRes.json();
|
|
525
|
+
const tag = tagData.tag_name;
|
|
526
|
+
const version = tag.replace(/^v/, "");
|
|
527
|
+
const archMap = {
|
|
528
|
+
arm64: "aarch64",
|
|
529
|
+
x64: "x86_64"
|
|
530
|
+
};
|
|
531
|
+
const platformMap = {
|
|
532
|
+
darwin: "apple-darwin",
|
|
533
|
+
linux: "unknown-linux-gnu",
|
|
534
|
+
win32: "pc-windows-msvc"
|
|
535
|
+
};
|
|
536
|
+
const arch2 = os3.arch() === "arm64" ? "arm64" : "x64";
|
|
537
|
+
const platform = process.platform === "win32" ? "win32" : process.platform === "darwin" ? "darwin" : "linux";
|
|
538
|
+
const rawArch = archMap[arch2] || arch2;
|
|
539
|
+
const rustTarget = `${rawArch}-${platformMap[platform] || platform}`;
|
|
540
|
+
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);
|
|
541
|
+
const url = `https://github.com/${sb.repo}/releases/download/${tag}/${filename}`;
|
|
542
|
+
onProgress(4, 5, "Downloading...", `curl ${filename}`);
|
|
543
|
+
await run("curl", ["-#SL", url, "-o", path3.join(build, filename)], build);
|
|
544
|
+
onProgress(4, 5, "Extracting...", filename);
|
|
545
|
+
const serverDir2 = path3.join(build, "server");
|
|
546
|
+
fs3.mkdirSync(serverDir2, { recursive: true });
|
|
547
|
+
if (filename.endsWith(".zip")) {
|
|
548
|
+
await run("unzip", ["-o", filename, "-d", serverDir2], build);
|
|
549
|
+
} else if (filename.endsWith(".gz") && !filename.endsWith(".tar.gz")) {
|
|
550
|
+
const outName = filename.replace(/\.gz$/, "");
|
|
551
|
+
await run("gunzip", [filename], build);
|
|
552
|
+
fs3.renameSync(path3.join(build, outName), path3.join(serverDir2, outName));
|
|
553
|
+
} else {
|
|
554
|
+
await run("tar", ["xzf", filename, "-C", serverDir2], build);
|
|
555
|
+
}
|
|
556
|
+
try {
|
|
557
|
+
fs3.readdirSync(serverDir2).forEach((f) => {
|
|
558
|
+
fs3.chmodSync(path3.join(serverDir2, f), 493);
|
|
559
|
+
});
|
|
560
|
+
} catch {
|
|
561
|
+
}
|
|
562
|
+
if (sb.binaryPath || filename.match(/\.(zip|gz)$/)) {
|
|
563
|
+
const archivePath = path3.join(build, filename);
|
|
564
|
+
if (fs3.existsSync(archivePath)) fs3.rmSync(archivePath);
|
|
565
|
+
}
|
|
566
|
+
const indexPath = path3.join(build, "lib", "index.js");
|
|
567
|
+
if (fs3.existsSync(indexPath)) {
|
|
568
|
+
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);
|
|
569
|
+
let code = fs3.readFileSync(indexPath, "utf-8");
|
|
570
|
+
const svrArgs = sb.args?.length ? JSON.stringify(sb.args) : "[]";
|
|
571
|
+
code = code.replace(
|
|
572
|
+
/\{ module:\s*serverModule,\s*transport:\s*\w+\.TransportKind\.\w+\s*\}/,
|
|
573
|
+
`{ command: serverModule, args: ${svrArgs} }`
|
|
574
|
+
);
|
|
575
|
+
const serverPath = `require('path').join(__dirname, '..', 'server', '${binPath}')`;
|
|
576
|
+
code = code.replace(
|
|
577
|
+
/try\s*\{[^}]*?require\.resolve\([^)]+\)\s*;?\s*\}\s*catch\s*\{\s*\}/g,
|
|
578
|
+
`try { serverModule = ${serverPath} } catch {}`
|
|
579
|
+
);
|
|
580
|
+
fs3.writeFileSync(indexPath, code);
|
|
581
|
+
}
|
|
582
|
+
} catch (e) {
|
|
583
|
+
onProgress(4, 5, `Warning: serverBinary setup failed (${e.message})`, "install server binary manually");
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
const docSelPath = path3.join(build, "lib", "index.js");
|
|
587
|
+
if (fs3.existsSync(docSelPath)) {
|
|
588
|
+
let code = fs3.readFileSync(docSelPath, "utf-8");
|
|
589
|
+
const langSelector = info.languages.map((l) => `{ scheme: "file", language: "${l}" }`).join(", ");
|
|
590
|
+
code = code.replace(
|
|
591
|
+
/documentSelector:\s*\[\s*\{[^}]*?language:\s*['"][^'"]*['"][^}]*\}\s*\]/,
|
|
592
|
+
`documentSelector: [${langSelector}]`
|
|
593
|
+
);
|
|
594
|
+
code = code.replace(/serverModule\s*=\s*require\("path"\)\.join\(_dir,\s*_entry\);\s*/g, "");
|
|
595
|
+
code = code.replace(
|
|
596
|
+
/client\.start\(\);/g,
|
|
597
|
+
"client.start().catch(() => {/* init may complete async */});"
|
|
598
|
+
);
|
|
599
|
+
fs3.writeFileSync(docSelPath, code);
|
|
600
|
+
}
|
|
601
|
+
const pkgPath = path3.join(build, "package.json");
|
|
602
|
+
if (fs3.existsSync(pkgPath)) {
|
|
603
|
+
try {
|
|
604
|
+
const pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
|
|
605
|
+
const events = pkg.activationEvents || [];
|
|
606
|
+
const langEvents = info.languages.map((l) => `onLanguage:${l}`);
|
|
607
|
+
const newEvents = events.filter((e) => !e.startsWith("onLanguage:")).concat(langEvents);
|
|
608
|
+
if (newEvents.length > 0 && JSON.stringify(newEvents) !== JSON.stringify(events)) {
|
|
609
|
+
pkg.activationEvents = newEvents;
|
|
610
|
+
fs3.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
611
|
+
}
|
|
612
|
+
} catch {
|
|
613
|
+
}
|
|
614
|
+
}
|
|
326
615
|
}
|
|
327
616
|
function extensionsPkgPath() {
|
|
328
617
|
return path3.join(os3.homedir(), ".config", "coc", "extensions", "package.json");
|
|
@@ -346,11 +635,12 @@ async function installToCoc(name, onProgress) {
|
|
|
346
635
|
function metaPath(name) {
|
|
347
636
|
return path3.join(cacheDir(name), "meta.json");
|
|
348
637
|
}
|
|
349
|
-
function saveMeta(name) {
|
|
638
|
+
async function saveMeta(name) {
|
|
350
639
|
const srcDir = sourceDir(name);
|
|
351
640
|
try {
|
|
352
|
-
const
|
|
353
|
-
|
|
641
|
+
const log = await runWithOutput("git", ["-C", srcDir, "log", "-1", "--format=%h|%s|%ar"], srcDir);
|
|
642
|
+
const [commit, msg, date] = log.split("|");
|
|
643
|
+
fs3.writeFileSync(metaPath(name), JSON.stringify({ commit, msg, date, updatedAt: Date.now() }, null, 2));
|
|
354
644
|
} catch {
|
|
355
645
|
}
|
|
356
646
|
}
|
|
@@ -372,11 +662,27 @@ async function installPackage(state, name) {
|
|
|
372
662
|
try {
|
|
373
663
|
const input = await downloadSource(info, name, prog);
|
|
374
664
|
await convertSource(input, name, prog);
|
|
375
|
-
await buildPackage(name, prog);
|
|
665
|
+
await buildPackage(name, input, info, prog);
|
|
376
666
|
await installToCoc(name, prog);
|
|
377
|
-
saveMeta(name);
|
|
667
|
+
await saveMeta(name);
|
|
378
668
|
state.setDirty();
|
|
379
669
|
state.setPackageStatus(name, "installed");
|
|
670
|
+
import_coc.window.showInformationMessage(`coc-${name} installed`);
|
|
671
|
+
try {
|
|
672
|
+
const meta = JSON.parse(fs3.readFileSync(metaPath(name), "utf-8"));
|
|
673
|
+
if (meta.commit) {
|
|
674
|
+
state.mutate((s) => {
|
|
675
|
+
const p = s.packages.find((p2) => p2.info.name === name);
|
|
676
|
+
if (p) {
|
|
677
|
+
p.commit = meta.commit;
|
|
678
|
+
p.commitMsg = meta.msg;
|
|
679
|
+
p.commitDate = meta.date;
|
|
680
|
+
p.updated = true;
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
} catch {
|
|
685
|
+
}
|
|
380
686
|
} catch (e) {
|
|
381
687
|
state.setPackageStatus(name, "failed", { error: e.message });
|
|
382
688
|
}
|
|
@@ -404,6 +710,7 @@ async function uninstallPackage(state, name) {
|
|
|
404
710
|
}
|
|
405
711
|
state.setPackageStatus(name, "not-installed");
|
|
406
712
|
state.setDirty();
|
|
713
|
+
import_coc.window.showInformationMessage(`coc-${name} uninstalled`);
|
|
407
714
|
} catch (e) {
|
|
408
715
|
state.setPackageStatus(name, "failed", { error: e.message });
|
|
409
716
|
}
|
|
@@ -426,11 +733,27 @@ async function updatePackage(state, name) {
|
|
|
426
733
|
try {
|
|
427
734
|
const input = await downloadSource(info, name, prog);
|
|
428
735
|
await convertSource(input, name, prog);
|
|
429
|
-
await buildPackage(name, prog);
|
|
736
|
+
await buildPackage(name, input, info, prog);
|
|
430
737
|
await installToCoc(name, prog);
|
|
431
|
-
saveMeta(name);
|
|
738
|
+
await saveMeta(name);
|
|
432
739
|
state.setDirty();
|
|
433
740
|
state.setPackageStatus(name, "installed");
|
|
741
|
+
import_coc.window.showInformationMessage(`coc-${name} installed`);
|
|
742
|
+
try {
|
|
743
|
+
const meta = JSON.parse(fs3.readFileSync(metaPath(name), "utf-8"));
|
|
744
|
+
if (meta.commit) {
|
|
745
|
+
state.mutate((s) => {
|
|
746
|
+
const p = s.packages.find((p2) => p2.info.name === name);
|
|
747
|
+
if (p) {
|
|
748
|
+
p.commit = meta.commit;
|
|
749
|
+
p.commitMsg = meta.msg;
|
|
750
|
+
p.commitDate = meta.date;
|
|
751
|
+
p.updated = true;
|
|
752
|
+
}
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
} catch {
|
|
756
|
+
}
|
|
434
757
|
} catch (e) {
|
|
435
758
|
state.setPackageStatus(name, "failed", { error: e.message });
|
|
436
759
|
}
|
|
@@ -438,6 +761,10 @@ async function updatePackage(state, name) {
|
|
|
438
761
|
async function runWithOutput(cmd, args, cwd) {
|
|
439
762
|
return new Promise((resolve2, reject) => {
|
|
440
763
|
const child = (0, import_child_process.spawn)(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"], shell: true });
|
|
764
|
+
const timer = setTimeout(() => {
|
|
765
|
+
child.kill("SIGTERM");
|
|
766
|
+
reject(new Error(`Timed out after ${CMD_TIMEOUT / 1e3}s: ${cmd} ${args.join(" ")}`));
|
|
767
|
+
}, CMD_TIMEOUT);
|
|
441
768
|
let out = "";
|
|
442
769
|
child.stdout.on("data", (d) => {
|
|
443
770
|
out += d.toString();
|
|
@@ -445,10 +772,27 @@ async function runWithOutput(cmd, args, cwd) {
|
|
|
445
772
|
child.stderr.on("data", (d) => {
|
|
446
773
|
out += d.toString();
|
|
447
774
|
});
|
|
448
|
-
child.on("close", (code) =>
|
|
449
|
-
|
|
775
|
+
child.on("close", (code) => {
|
|
776
|
+
clearTimeout(timer);
|
|
777
|
+
code === 0 ? resolve2(out.trim()) : reject(new Error(`exit ${code}`));
|
|
778
|
+
});
|
|
779
|
+
child.on("error", (e) => {
|
|
780
|
+
clearTimeout(timer);
|
|
781
|
+
reject(e);
|
|
782
|
+
});
|
|
450
783
|
});
|
|
451
784
|
}
|
|
785
|
+
async function runConcurrent(items, fn, concurrency = 3) {
|
|
786
|
+
const pool = /* @__PURE__ */ new Set();
|
|
787
|
+
for (const item of items) {
|
|
788
|
+
const p = fn(item).finally(() => pool.delete(p));
|
|
789
|
+
pool.add(p);
|
|
790
|
+
if (pool.size >= concurrency) {
|
|
791
|
+
await Promise.race(pool);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
await Promise.all(pool);
|
|
795
|
+
}
|
|
452
796
|
async function checkUpdates(state) {
|
|
453
797
|
const s = state.getState();
|
|
454
798
|
const results = {};
|
|
@@ -548,8 +892,16 @@ var LineBuffer = class {
|
|
|
548
892
|
};
|
|
549
893
|
|
|
550
894
|
// src/tui.ts
|
|
895
|
+
var VERSION = (() => {
|
|
896
|
+
try {
|
|
897
|
+
const pkg = JSON.parse(require("fs").readFileSync(require("path").join(__dirname, "..", "package.json"), "utf-8"));
|
|
898
|
+
return pkg.version;
|
|
899
|
+
} catch {
|
|
900
|
+
return "0.0.0";
|
|
901
|
+
}
|
|
902
|
+
})();
|
|
551
903
|
var HELP_TEXT = [
|
|
552
|
-
|
|
904
|
+
` coc-loader v${VERSION} \u2014 VS Code extension \u2192 coc.nvim plugin converter`,
|
|
553
905
|
"",
|
|
554
906
|
" Keymaps:",
|
|
555
907
|
" i Install package under cursor",
|
|
@@ -557,10 +909,18 @@ var HELP_TEXT = [
|
|
|
557
909
|
" U Update all installed packages",
|
|
558
910
|
" C Check for updates from remote",
|
|
559
911
|
" X Uninstall package under cursor",
|
|
912
|
+
" R Reinstall package under cursor",
|
|
560
913
|
" Z Uninstall all installed packages (with confirm)",
|
|
914
|
+
" D Clean up orphaned packages",
|
|
915
|
+
" x Toggle mark",
|
|
916
|
+
" f Cycle filter: all \u2192 installed \u2192 not-installed",
|
|
917
|
+
" s Cycle sort: default \u2192 name \u2192 status \u2192 type",
|
|
918
|
+
" gg Jump to first package",
|
|
919
|
+
" G Jump to last package",
|
|
561
920
|
" <Enter> Toggle expand/collapse details",
|
|
562
921
|
" / Search filter",
|
|
563
|
-
" q
|
|
922
|
+
" q Close window",
|
|
923
|
+
" <Esc> Help\u2192Search\u2192Marks\u2192Busy guard\u2192Close",
|
|
564
924
|
"",
|
|
565
925
|
" " + "\u2500".repeat(40),
|
|
566
926
|
"",
|
|
@@ -588,13 +948,20 @@ var TUI = class {
|
|
|
588
948
|
i: "i",
|
|
589
949
|
u: "u",
|
|
590
950
|
X: "X",
|
|
591
|
-
|
|
951
|
+
R: "R",
|
|
952
|
+
cr: "<CR>",
|
|
953
|
+
f: "f",
|
|
954
|
+
s: "s",
|
|
955
|
+
x: "x",
|
|
956
|
+
D: "D",
|
|
957
|
+
gg: "gg",
|
|
958
|
+
G: "G"
|
|
592
959
|
};
|
|
593
960
|
this.rendering = false;
|
|
594
961
|
this.state = state;
|
|
595
962
|
}
|
|
596
963
|
async open() {
|
|
597
|
-
const nvim =
|
|
964
|
+
const nvim = import_coc2.workspace.nvim;
|
|
598
965
|
this.ns = await nvim.createNamespace("coc-loader");
|
|
599
966
|
await nvim.command("highlight default link CocConverterTitle Title");
|
|
600
967
|
await nvim.command("highlight default link CocConverterPill Visual");
|
|
@@ -639,7 +1006,7 @@ var TUI = class {
|
|
|
639
1006
|
this.render();
|
|
640
1007
|
});
|
|
641
1008
|
this.disposables.push(
|
|
642
|
-
|
|
1009
|
+
import_coc2.workspace.registerAutocmd({
|
|
643
1010
|
event: "WinEnter",
|
|
644
1011
|
request: true,
|
|
645
1012
|
callback: async () => {
|
|
@@ -663,10 +1030,14 @@ var TUI = class {
|
|
|
663
1030
|
`);
|
|
664
1031
|
}
|
|
665
1032
|
await this.setupKeymaps();
|
|
1033
|
+
updateRegistry().then(() => this.state.refreshPackages()).catch(() => {
|
|
1034
|
+
this.state.setStatusMessage("Failed to fetch remote registry (offline?)");
|
|
1035
|
+
setTimeout(() => this.state.setStatusMessage(), 5e3);
|
|
1036
|
+
});
|
|
666
1037
|
await this.render();
|
|
667
1038
|
}
|
|
668
1039
|
async getCursorLine0() {
|
|
669
|
-
const nvim =
|
|
1040
|
+
const nvim = import_coc2.workspace.nvim;
|
|
670
1041
|
const cursor = await nvim.call("nvim_win_get_cursor", [this.winid]);
|
|
671
1042
|
return cursor[0] - 1;
|
|
672
1043
|
}
|
|
@@ -696,6 +1067,16 @@ var TUI = class {
|
|
|
696
1067
|
this.state.setSearchQuery("");
|
|
697
1068
|
return;
|
|
698
1069
|
}
|
|
1070
|
+
const hasMarks = s.packages.some((p) => p.marked);
|
|
1071
|
+
if (hasMarks) {
|
|
1072
|
+
this.state.clearMarks();
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1075
|
+
const busy = s.packages.some((p) => ["installing", "updating", "uninstalling"].includes(p.status));
|
|
1076
|
+
if (busy) {
|
|
1077
|
+
import_coc2.window.showInformationMessage("Operation in progress, wait for it to finish");
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
699
1080
|
this.close();
|
|
700
1081
|
return;
|
|
701
1082
|
}
|
|
@@ -705,24 +1086,60 @@ var TUI = class {
|
|
|
705
1086
|
}
|
|
706
1087
|
if (id === "slash") {
|
|
707
1088
|
try {
|
|
708
|
-
const q = await
|
|
1089
|
+
const q = await import_coc2.workspace.nvim.call("input", ["Search: ", ""]);
|
|
709
1090
|
if (q) this.state.setSearchQuery(q);
|
|
710
1091
|
} catch {
|
|
711
1092
|
}
|
|
712
1093
|
return;
|
|
713
1094
|
}
|
|
1095
|
+
if (id === "f") {
|
|
1096
|
+
this.state.cycleViewFilter();
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1099
|
+
if (id === "s") {
|
|
1100
|
+
this.state.cycleSortBy();
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
if (id === "gg") {
|
|
1104
|
+
const firstLine = Math.min(...this.pkgLineMap.keys());
|
|
1105
|
+
if (isFinite(firstLine)) {
|
|
1106
|
+
await import_coc2.workspace.nvim.call("nvim_win_set_cursor", [this.winid, [firstLine + 1, 0]]);
|
|
1107
|
+
}
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
if (id === "G") {
|
|
1111
|
+
const lastLine = Math.max(...this.pkgLineMap.keys());
|
|
1112
|
+
if (isFinite(lastLine)) {
|
|
1113
|
+
await import_coc2.workspace.nvim.call("nvim_win_set_cursor", [this.winid, [lastLine + 1, 0]]);
|
|
1114
|
+
}
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
if (id === "D") {
|
|
1118
|
+
const installed = s.packages.filter((p) => p.status === "installed");
|
|
1119
|
+
const removed = installed.filter((p) => !getPackage(p.info.name));
|
|
1120
|
+
if (removed.length === 0) {
|
|
1121
|
+
import_coc2.window.showInformationMessage("No orphaned packages found");
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
const ok = await import_coc2.window.showPrompt(`Uninstall ${removed.length} orphaned package(s)?`);
|
|
1125
|
+
if (ok) {
|
|
1126
|
+
for (const p of removed) uninstallPackage(this.state, p.info.name);
|
|
1127
|
+
}
|
|
1128
|
+
return;
|
|
1129
|
+
}
|
|
714
1130
|
if (id === "U") {
|
|
715
1131
|
const installed = s.packages.filter((p) => p.status === "installed");
|
|
716
1132
|
if (installed.length === 0) return;
|
|
717
1133
|
this.state.setActivePill("U");
|
|
718
|
-
|
|
1134
|
+
const names = installed.map((p) => p.info.name);
|
|
1135
|
+
await runConcurrent(names, (name) => updatePackage(this.state, name));
|
|
719
1136
|
this.state.setActivePill(null);
|
|
720
1137
|
return;
|
|
721
1138
|
}
|
|
722
1139
|
if (id === "Z") {
|
|
723
1140
|
const installed = s.packages.filter((p) => p.status === "installed");
|
|
724
1141
|
if (installed.length === 0) return;
|
|
725
|
-
const ok = await
|
|
1142
|
+
const ok = await import_coc2.window.showPrompt(`Uninstall all ${installed.length} packages?`);
|
|
726
1143
|
if (ok) {
|
|
727
1144
|
for (const pkg of installed) uninstallPackage(this.state, pkg.info.name);
|
|
728
1145
|
}
|
|
@@ -738,6 +1155,10 @@ var TUI = class {
|
|
|
738
1155
|
if (!pkgName) return;
|
|
739
1156
|
const entry = this.state.getPackage(pkgName);
|
|
740
1157
|
if (!entry) return;
|
|
1158
|
+
if (id === "x") {
|
|
1159
|
+
this.state.toggleMark(pkgName);
|
|
1160
|
+
return;
|
|
1161
|
+
}
|
|
741
1162
|
if (id === "i" && entry.status === "not-installed") {
|
|
742
1163
|
await installPackage(this.state, pkgName);
|
|
743
1164
|
return;
|
|
@@ -750,6 +1171,11 @@ var TUI = class {
|
|
|
750
1171
|
uninstallPackage(this.state, pkgName);
|
|
751
1172
|
return;
|
|
752
1173
|
}
|
|
1174
|
+
if (id === "R" && entry.status === "installed") {
|
|
1175
|
+
await uninstallPackage(this.state, pkgName);
|
|
1176
|
+
await installPackage(this.state, pkgName);
|
|
1177
|
+
return;
|
|
1178
|
+
}
|
|
753
1179
|
if (id === "cr") {
|
|
754
1180
|
if (this.logLineSet.has(line0)) {
|
|
755
1181
|
this.state.toggleLog(pkgName);
|
|
@@ -760,7 +1186,7 @@ var TUI = class {
|
|
|
760
1186
|
}
|
|
761
1187
|
}
|
|
762
1188
|
async setupKeymaps() {
|
|
763
|
-
const buf =
|
|
1189
|
+
const buf = import_coc2.workspace.nvim.createBuffer(this.bufnr);
|
|
764
1190
|
const entries = [
|
|
765
1191
|
["q", "q"],
|
|
766
1192
|
["<Esc>", "esc"],
|
|
@@ -774,7 +1200,13 @@ var TUI = class {
|
|
|
774
1200
|
["H", "H"],
|
|
775
1201
|
["u", "u"],
|
|
776
1202
|
["X", "X"],
|
|
777
|
-
["
|
|
1203
|
+
["R", "R"],
|
|
1204
|
+
["f", "f"],
|
|
1205
|
+
["s", "s"],
|
|
1206
|
+
["x", "x"],
|
|
1207
|
+
["D", "D"],
|
|
1208
|
+
["gg", "gg"],
|
|
1209
|
+
["G", "G"],
|
|
778
1210
|
["<CR>", "cr"]
|
|
779
1211
|
];
|
|
780
1212
|
for (const [vimKey, id] of entries) {
|
|
@@ -793,20 +1225,20 @@ var TUI = class {
|
|
|
793
1225
|
this.disposables = [];
|
|
794
1226
|
if (this.winid) {
|
|
795
1227
|
try {
|
|
796
|
-
await
|
|
1228
|
+
await import_coc2.workspace.nvim.call("nvim_win_close", [this.winid, true]);
|
|
797
1229
|
} catch {
|
|
798
1230
|
}
|
|
799
1231
|
this.winid = 0;
|
|
800
1232
|
}
|
|
801
1233
|
if (needRestart) {
|
|
802
|
-
|
|
1234
|
+
import_coc2.workspace.nvim.command("CocRestart", true);
|
|
803
1235
|
}
|
|
804
1236
|
}
|
|
805
1237
|
async render() {
|
|
806
1238
|
if (!this.winid || this.rendering) return;
|
|
807
1239
|
this.rendering = true;
|
|
808
1240
|
try {
|
|
809
|
-
const nvim =
|
|
1241
|
+
const nvim = import_coc2.workspace.nvim;
|
|
810
1242
|
const state = this.state.getState();
|
|
811
1243
|
const filtered = this.state.getFilteredPackages();
|
|
812
1244
|
const result = state.showHelp ? this.renderHelp() : this.renderPackageList(state, filtered);
|
|
@@ -832,7 +1264,7 @@ var TUI = class {
|
|
|
832
1264
|
renderHelp() {
|
|
833
1265
|
const header = [
|
|
834
1266
|
"",
|
|
835
|
-
|
|
1267
|
+
` coc-loader v${VERSION}`,
|
|
836
1268
|
" press ? help | / search | q quit",
|
|
837
1269
|
" " + "\u2500".repeat(50),
|
|
838
1270
|
""
|
|
@@ -874,7 +1306,13 @@ var TUI = class {
|
|
|
874
1306
|
buf.highlight(/\([IU?C]\)/g, "CocConverterKey");
|
|
875
1307
|
buf.nl();
|
|
876
1308
|
buf.nl();
|
|
1309
|
+
const filterLabel = state.viewFilter === "all" ? "All" : state.viewFilter === "installed" ? "Installed" : "Available";
|
|
1310
|
+
const sortLabel = state.sortBy === "default" ? "Default" : state.sortBy === "name" ? "Name" : state.sortBy === "status" ? "Status" : "Type";
|
|
877
1311
|
buf.append(`Total: ${filtered.length} packages`, "CocConverterTotal");
|
|
1312
|
+
buf.append(` | `);
|
|
1313
|
+
buf.append(`F:${filterLabel}(f)`, "CocConverterPill");
|
|
1314
|
+
buf.append(` `);
|
|
1315
|
+
buf.append(`S:${sortLabel}(s)`, "CocConverterPill");
|
|
878
1316
|
if (state.statusMessage) {
|
|
879
1317
|
buf.append(" \xB7 ");
|
|
880
1318
|
buf.append(state.statusMessage, "Comment");
|
|
@@ -897,6 +1335,10 @@ var TUI = class {
|
|
|
897
1335
|
if (filtered.length === 0 && state.searchQuery) {
|
|
898
1336
|
buf.nl("no matching packages");
|
|
899
1337
|
}
|
|
1338
|
+
buf.nl();
|
|
1339
|
+
buf.append(" " + "\u2500".repeat(50), "Comment");
|
|
1340
|
+
buf.nl();
|
|
1341
|
+
buf.append(` ${filtered.length} packages \xB7 ${filterLabel} \xB7 ${sortLabel} order`, "Comment");
|
|
900
1342
|
const result = buf.render(2);
|
|
901
1343
|
return { lines: result.lines, pkgLineMap, logLines: logSet, highlights: result.highlights };
|
|
902
1344
|
}
|
|
@@ -905,7 +1347,12 @@ var TUI = class {
|
|
|
905
1347
|
const iconHl = entry.status === "installed" ? "CocConverterInstalled" : entry.status === "failed" ? "ErrorMsg" : "CocConverterAvailable";
|
|
906
1348
|
const pkgLine = buf.currentLine();
|
|
907
1349
|
pkgLineMap.set(pkgLine, entry.info.name);
|
|
908
|
-
|
|
1350
|
+
if (entry.marked) {
|
|
1351
|
+
buf.append("\u25B8", "CocConverterKey");
|
|
1352
|
+
buf.append(" ");
|
|
1353
|
+
} else {
|
|
1354
|
+
buf.append(" ");
|
|
1355
|
+
}
|
|
909
1356
|
buf.append(icon, iconHl);
|
|
910
1357
|
buf.append(" ");
|
|
911
1358
|
buf.append(entry.info.displayName);
|
|
@@ -914,17 +1361,28 @@ var TUI = class {
|
|
|
914
1361
|
if (entry.hasUpdate) {
|
|
915
1362
|
buf.append(" \u2191", "CocConverterKey");
|
|
916
1363
|
}
|
|
1364
|
+
if (entry.updated && entry.commit && entry.commitMsg) {
|
|
1365
|
+
buf.nl();
|
|
1366
|
+
const ln = buf.currentLine();
|
|
1367
|
+
buf.append(` ${entry.commit} ${entry.commitMsg}`, "Comment");
|
|
1368
|
+
if (entry.commitDate) {
|
|
1369
|
+
buf.append(` (${entry.commitDate})`, "Comment");
|
|
1370
|
+
}
|
|
1371
|
+
pkgLineMap.set(ln, entry.info.name);
|
|
1372
|
+
}
|
|
917
1373
|
if (entry.expanded) {
|
|
918
1374
|
buf.nl();
|
|
919
|
-
|
|
1375
|
+
const extras = [
|
|
920
1376
|
entry.info.description,
|
|
921
1377
|
`type ${entry.info.type}`,
|
|
922
1378
|
entry.commit ? `commit ${entry.commit}` : null,
|
|
923
1379
|
`source ${sourceStr(entry.info.source)}`,
|
|
924
1380
|
`languages ${entry.info.languages.join(", ")}`,
|
|
925
1381
|
`categories ${entry.info.categories.join(", ")}`,
|
|
926
|
-
`homepage ${entry.info.url}
|
|
927
|
-
|
|
1382
|
+
`homepage ${entry.info.url}`,
|
|
1383
|
+
entry.info.serverBinary ? `server ${entry.info.serverBinary.repo} (binary release)` : null
|
|
1384
|
+
];
|
|
1385
|
+
for (const text of extras.filter(Boolean)) {
|
|
928
1386
|
const ln = buf.currentLine();
|
|
929
1387
|
buf.nl(` ${text}`);
|
|
930
1388
|
pkgLineMap.set(ln, entry.info.name);
|
|
@@ -960,9 +1418,6 @@ var TUI = class {
|
|
|
960
1418
|
}
|
|
961
1419
|
buf.nl();
|
|
962
1420
|
}
|
|
963
|
-
hl(line, hlGroup, colStart, colEnd) {
|
|
964
|
-
this.hlLines.push({ line, hlGroup, colStart, colEnd });
|
|
965
|
-
}
|
|
966
1421
|
isOpen() {
|
|
967
1422
|
return this.winid !== 0;
|
|
968
1423
|
}
|
|
@@ -978,7 +1433,7 @@ var currentTUI = null;
|
|
|
978
1433
|
async function activate(context) {
|
|
979
1434
|
const state = new StateManager(createInitialState());
|
|
980
1435
|
context.subscriptions.push(
|
|
981
|
-
|
|
1436
|
+
import_coc3.commands.registerCommand("loader.open", async () => {
|
|
982
1437
|
if (currentTUI && currentTUI.isOpen()) {
|
|
983
1438
|
await currentTUI.close();
|
|
984
1439
|
}
|
|
@@ -987,67 +1442,67 @@ async function activate(context) {
|
|
|
987
1442
|
})
|
|
988
1443
|
);
|
|
989
1444
|
context.subscriptions.push(
|
|
990
|
-
|
|
1445
|
+
import_coc3.commands.registerCommand("loader.install", async (name) => {
|
|
991
1446
|
if (!name) {
|
|
992
|
-
name = await
|
|
1447
|
+
name = await import_coc3.workspace.nvim.call("input", ["Plugin name: ", ""]);
|
|
993
1448
|
if (!name) return;
|
|
994
1449
|
}
|
|
995
1450
|
const pkg = state.getPackage(name);
|
|
996
1451
|
if (!pkg) {
|
|
997
|
-
|
|
1452
|
+
import_coc3.window.showInformationMessage(`Unknown package: ${name}`);
|
|
998
1453
|
return;
|
|
999
1454
|
}
|
|
1000
1455
|
if (pkg.status === "installed") {
|
|
1001
|
-
|
|
1456
|
+
import_coc3.window.showInformationMessage(`${name} is already installed`);
|
|
1002
1457
|
return;
|
|
1003
1458
|
}
|
|
1004
1459
|
await installPackage(state, name);
|
|
1005
1460
|
})
|
|
1006
1461
|
);
|
|
1007
1462
|
context.subscriptions.push(
|
|
1008
|
-
|
|
1463
|
+
import_coc3.commands.registerCommand("loader.uninstall", async (name) => {
|
|
1009
1464
|
if (!name) {
|
|
1010
|
-
name = await
|
|
1465
|
+
name = await import_coc3.workspace.nvim.call("input", ["Plugin name: ", ""]);
|
|
1011
1466
|
if (!name) return;
|
|
1012
1467
|
}
|
|
1013
1468
|
const pkg = state.getPackage(name);
|
|
1014
1469
|
if (!pkg) {
|
|
1015
|
-
|
|
1470
|
+
import_coc3.window.showInformationMessage(`Unknown package: ${name}`);
|
|
1016
1471
|
return;
|
|
1017
1472
|
}
|
|
1018
1473
|
if (pkg.status !== "installed") {
|
|
1019
|
-
|
|
1474
|
+
import_coc3.window.showInformationMessage(`${name} is not installed`);
|
|
1020
1475
|
return;
|
|
1021
1476
|
}
|
|
1022
1477
|
uninstallPackage(state, name);
|
|
1023
1478
|
})
|
|
1024
1479
|
);
|
|
1025
1480
|
context.subscriptions.push(
|
|
1026
|
-
|
|
1481
|
+
import_coc3.commands.registerCommand("loader.update", async (name) => {
|
|
1027
1482
|
if (!name) {
|
|
1028
|
-
name = await
|
|
1483
|
+
name = await import_coc3.workspace.nvim.call("input", ["Plugin name: ", ""]);
|
|
1029
1484
|
if (!name) return;
|
|
1030
1485
|
}
|
|
1031
1486
|
const pkg = state.getPackage(name);
|
|
1032
1487
|
if (!pkg) {
|
|
1033
|
-
|
|
1488
|
+
import_coc3.window.showInformationMessage(`Unknown package: ${name}`);
|
|
1034
1489
|
return;
|
|
1035
1490
|
}
|
|
1036
1491
|
if (pkg.status !== "installed") {
|
|
1037
|
-
|
|
1492
|
+
import_coc3.window.showInformationMessage(`${name} is not installed`);
|
|
1038
1493
|
return;
|
|
1039
1494
|
}
|
|
1040
1495
|
await updatePackage(state, name);
|
|
1041
1496
|
})
|
|
1042
1497
|
);
|
|
1043
1498
|
context.subscriptions.push(
|
|
1044
|
-
|
|
1499
|
+
import_coc3.commands.registerCommand("loader.uninstallAll", async () => {
|
|
1045
1500
|
const installed = state.getState().packages.filter((p) => p.status === "installed");
|
|
1046
1501
|
if (installed.length === 0) {
|
|
1047
|
-
|
|
1502
|
+
import_coc3.window.showInformationMessage("No packages installed");
|
|
1048
1503
|
return;
|
|
1049
1504
|
}
|
|
1050
|
-
const ok = await
|
|
1505
|
+
const ok = await import_coc3.window.showPrompt(`Uninstall all ${installed.length} packages?`);
|
|
1051
1506
|
if (ok) {
|
|
1052
1507
|
for (const pkg of installed) {
|
|
1053
1508
|
uninstallPackage(state, pkg.info.name);
|
|
@@ -1056,23 +1511,42 @@ async function activate(context) {
|
|
|
1056
1511
|
})
|
|
1057
1512
|
);
|
|
1058
1513
|
context.subscriptions.push(
|
|
1059
|
-
|
|
1514
|
+
import_coc3.commands.registerCommand("loader.reinstall", async (name) => {
|
|
1515
|
+
if (!name) {
|
|
1516
|
+
name = await import_coc3.workspace.nvim.call("input", ["Plugin name: ", ""]);
|
|
1517
|
+
if (!name) return;
|
|
1518
|
+
}
|
|
1519
|
+
const pkg = state.getPackage(name);
|
|
1520
|
+
if (!pkg) {
|
|
1521
|
+
import_coc3.window.showInformationMessage(`Unknown package: ${name}`);
|
|
1522
|
+
return;
|
|
1523
|
+
}
|
|
1524
|
+
if (pkg.status !== "installed") {
|
|
1525
|
+
import_coc3.window.showInformationMessage(`${name} is not installed`);
|
|
1526
|
+
return;
|
|
1527
|
+
}
|
|
1528
|
+
await uninstallPackage(state, name);
|
|
1529
|
+
await installPackage(state, name);
|
|
1530
|
+
})
|
|
1531
|
+
);
|
|
1532
|
+
context.subscriptions.push(
|
|
1533
|
+
import_coc3.commands.registerCommand("loader.updateRegistry", async () => {
|
|
1060
1534
|
try {
|
|
1061
1535
|
const count = await updateRegistry();
|
|
1062
|
-
|
|
1536
|
+
import_coc3.window.showInformationMessage(`Registry updated: ${count} packages available. Restart coc to apply.`);
|
|
1063
1537
|
} catch (e) {
|
|
1064
|
-
|
|
1538
|
+
import_coc3.window.showErrorMessage(`Registry update failed: ${e.message}`);
|
|
1065
1539
|
}
|
|
1066
1540
|
})
|
|
1067
1541
|
);
|
|
1068
1542
|
context.subscriptions.push(
|
|
1069
|
-
|
|
1543
|
+
import_coc3.commands.registerCommand("loader._dispatch", async (key) => {
|
|
1070
1544
|
if (currentTUI) {
|
|
1071
1545
|
await currentTUI.handleKey(key);
|
|
1072
1546
|
}
|
|
1073
1547
|
})
|
|
1074
1548
|
);
|
|
1075
|
-
|
|
1549
|
+
import_coc3.window.showInformationMessage("coc-loader activated! Use :CocCommand loader.open");
|
|
1076
1550
|
}
|
|
1077
1551
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1078
1552
|
0 && (module.exports = {
|