coc-vscode-loader 1.1.9 → 1.2.0
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/converter/src/cli.ts +33 -2
- package/converter/src/convert.ts +294 -361
- package/converter/src/scanner.ts +5 -89
- package/converter/src/steps/bridge.ts +142 -0
- package/converter/src/steps/index.ts +29 -0
- package/converter/src/steps/language-client.ts +150 -0
- package/converter/src/steps/mark-unsupported.ts +81 -0
- package/converter/src/steps/source.ts +159 -0
- package/converter/src/transforms/class-to-factory.ts +1 -2
- package/converter/src/transforms/enum-offset.ts +0 -17
- package/converter/src/transforms/provider-register.ts +7 -1
- package/converter/src/transforms/strip-volar.ts +29 -0
- package/converter/src/types.ts +117 -0
- package/lib/index.js +40 -58
- package/package.json +1 -1
|
@@ -39,8 +39,7 @@ export const transformClassToFactory: Transform = (ctx) => {
|
|
|
39
39
|
(match, type) => `${type}.create(`
|
|
40
40
|
)
|
|
41
41
|
|
|
42
|
-
// CompletionItem.create(label)
|
|
43
|
-
// Convert `CompletionItem.create(label, kind)` to `item = CompletionItem.create(label); item.kind = kind`
|
|
42
|
+
// CompletionItem.create(label, kind) → item = CompletionItem.create(label); item.kind = kind
|
|
44
43
|
text = text.replace(
|
|
45
44
|
/const\s+(\w+)\s*=\s*CompletionItem\.create\(([^,]+),\s*([^)]+)\)/g,
|
|
46
45
|
(_, varName, label, kind) => {
|
|
@@ -19,23 +19,6 @@ export const transformEnumOffset: Transform = (ctx) => {
|
|
|
19
19
|
const { file } = ctx
|
|
20
20
|
let content = file.getText()
|
|
21
21
|
|
|
22
|
-
// Detect hardcoded numbers used in enum position (e.g., CompletionItemKind.Xxx).
|
|
23
|
-
// This is hard to detect perfectly, so we log a note when numeric literals
|
|
24
|
-
// appear near enum-type names.
|
|
25
|
-
const enumPatterns = [
|
|
26
|
-
'CompletionItemKind', 'SymbolKind', 'DocumentHighlightKind', 'DiagnosticSeverity',
|
|
27
|
-
'CompletionTriggerKind', 'InlineCompletionTriggerKind',
|
|
28
|
-
]
|
|
29
|
-
|
|
30
|
-
for (const enumName of enumPatterns) {
|
|
31
|
-
// Check if the enum is imported/used with a hardcoded number nearby
|
|
32
|
-
const enumRefs = content.match(new RegExp(`${enumName}\\.\\w+`, 'g'))
|
|
33
|
-
if (enumRefs) {
|
|
34
|
-
// Symbol references are fine - they resolve at runtime
|
|
35
|
-
// Only note if there are raw numbers being compared
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
22
|
// Replace any numeric enum comparisons with comments
|
|
40
23
|
// e.g., `severity === 0` → `severity === 0 /* DiagnosticSeverity.Error = 1 in coc */`
|
|
41
24
|
content = content.replace(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as path from 'path'
|
|
1
2
|
import { Transform } from '../types.js'
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -32,10 +33,15 @@ export const transformProviderRegister: Transform = (ctx) => {
|
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
// 2. registerCompletionItemProvider: insert name + shortcut at beginning
|
|
36
|
+
// Shortcut derived from source file name (first 2 uppercase letters)
|
|
37
|
+
const fileName = file.getFilePath() || 'plugin'
|
|
38
|
+
const baseName = path.basename(fileName, '.ts')
|
|
39
|
+
const shortcut = baseName.replace(/[^a-zA-Z]/g, '').substring(0, 2).toUpperCase() || 'PL'
|
|
35
40
|
if (content.includes('registerCompletionItemProvider')) {
|
|
41
|
+
const pluginName = path.basename(path.dirname(path.dirname(fileName))) || 'plugin'
|
|
36
42
|
content = content.replace(
|
|
37
43
|
/registerCompletionItemProvider\(/g,
|
|
38
|
-
`registerCompletionItemProvider('
|
|
44
|
+
`registerCompletionItemProvider('${pluginName}', '${shortcut}', `
|
|
39
45
|
)
|
|
40
46
|
// Wrap the last argument in an array if it's a string (trigger chars)
|
|
41
47
|
content = content.replace(
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Transform } from '../types.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Remove Volar-specific framework imports that are not compatible with coc.nvim.
|
|
5
|
+
* The Volar extension uses @volar/vscode and reactive-vscode meta-framework,
|
|
6
|
+
* which need to be stripped since the bridge step provides alternative setup.
|
|
7
|
+
*/
|
|
8
|
+
export const transformStripVolar: Transform = (ctx) => {
|
|
9
|
+
const { file } = ctx
|
|
10
|
+
let content = file.getText()
|
|
11
|
+
let changed = false
|
|
12
|
+
|
|
13
|
+
const patterns = [
|
|
14
|
+
/import .* from ['"]@volar\/vscode['"];?\n?/g,
|
|
15
|
+
/import .* from ['"]reactive-vscode['"];?\n?/g,
|
|
16
|
+
/import \* as lsp from ['"]@volar\/vscode\/node['"];?\n?/g,
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
for (const re of patterns) {
|
|
20
|
+
if (re.test(content)) {
|
|
21
|
+
content = content.replace(re, '')
|
|
22
|
+
changed = true
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (changed) {
|
|
27
|
+
file.replaceWithText(content)
|
|
28
|
+
}
|
|
29
|
+
}
|
package/converter/src/types.ts
CHANGED
|
@@ -6,3 +6,120 @@ export interface TransformContext {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export type Transform = (ctx: TransformContext) => void
|
|
9
|
+
|
|
10
|
+
// ---- Step type definitions ----
|
|
11
|
+
|
|
12
|
+
export interface ServerModuleConfig {
|
|
13
|
+
kind: 'module'
|
|
14
|
+
package: string
|
|
15
|
+
entry?: 'main' | 'bin'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ServerBinaryConfig {
|
|
19
|
+
kind: 'binary'
|
|
20
|
+
package: string
|
|
21
|
+
binary: {
|
|
22
|
+
repo: string
|
|
23
|
+
asset: string
|
|
24
|
+
binaryPath?: string
|
|
25
|
+
}
|
|
26
|
+
args?: string[]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type ServerConfig = ServerModuleConfig | ServerBinaryConfig
|
|
30
|
+
|
|
31
|
+
export interface LanguageClientStep {
|
|
32
|
+
type: 'language-client'
|
|
33
|
+
id?: string
|
|
34
|
+
server: ServerConfig
|
|
35
|
+
transport?: 'ipc' | 'stdio'
|
|
36
|
+
languages: string[]
|
|
37
|
+
multiRoot?: boolean
|
|
38
|
+
/** Enable debug logging in generated code */
|
|
39
|
+
verbose?: boolean
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface SourceStep {
|
|
43
|
+
type: 'source'
|
|
44
|
+
transforms: string[]
|
|
45
|
+
entry?: string
|
|
46
|
+
keepDeps?: string[] | Record<string, string>
|
|
47
|
+
activationEvents?: string[]
|
|
48
|
+
/** Enable debug logging in generated/transformed code */
|
|
49
|
+
verbose?: boolean
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface BridgeStep {
|
|
53
|
+
type: 'bridge'
|
|
54
|
+
preset?: string
|
|
55
|
+
/** Override preset options (extensions, services, etc.) */
|
|
56
|
+
options?: {
|
|
57
|
+
extensions?: string[]
|
|
58
|
+
services?: string[]
|
|
59
|
+
}
|
|
60
|
+
/** Enable debug logging in generated bridge code */
|
|
61
|
+
verbose?: boolean
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface MarkUnsupportedStep {
|
|
65
|
+
type: 'mark-unsupported'
|
|
66
|
+
features: string[]
|
|
67
|
+
/** Enable detailed output during conversion */
|
|
68
|
+
verbose?: boolean
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export type ConvertStep = LanguageClientStep | SourceStep | BridgeStep | MarkUnsupportedStep
|
|
72
|
+
|
|
73
|
+
// ---- Step execution ----
|
|
74
|
+
|
|
75
|
+
export interface StepResult {
|
|
76
|
+
generatedFiles: Array<{ path: string; content: string }>
|
|
77
|
+
entryPoint?: string
|
|
78
|
+
keepDeps: Record<string, string>
|
|
79
|
+
activationEvents: string[]
|
|
80
|
+
serverBinary?: {
|
|
81
|
+
repo: string
|
|
82
|
+
asset: string
|
|
83
|
+
binaryPath?: string
|
|
84
|
+
args?: string[]
|
|
85
|
+
}
|
|
86
|
+
/** Code to inject into previously generated files (target path, code to insert, insertion point) */
|
|
87
|
+
codeInjections?: Array<{
|
|
88
|
+
target: string // file to modify (e.g. 'src/index.ts')
|
|
89
|
+
importCode?: string // import line to add at top
|
|
90
|
+
insertBefore?: string // regex pattern to insert code before
|
|
91
|
+
insertAfter?: string // regex pattern to insert code after
|
|
92
|
+
code: string // code to insert
|
|
93
|
+
}>
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface StepContext {
|
|
97
|
+
input: string
|
|
98
|
+
output: string
|
|
99
|
+
project: Project
|
|
100
|
+
origPkg: Record<string, any>
|
|
101
|
+
verbose?: boolean
|
|
102
|
+
/** Preset definitions from registry (e.g. bridge presets) */
|
|
103
|
+
presets?: Record<string, any>
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface StepGenerator {
|
|
107
|
+
type: string
|
|
108
|
+
generate(ctx: StepContext, step: ConvertStep): StepResult
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function isLanguageClientStep(s: ConvertStep): s is LanguageClientStep {
|
|
112
|
+
return s.type === 'language-client'
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function isSourceStep(s: ConvertStep): s is SourceStep {
|
|
116
|
+
return s.type === 'source'
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function isBridgeStep(s: ConvertStep): s is BridgeStep {
|
|
120
|
+
return s.type === 'bridge'
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function isMarkUnsupportedStep(s: ConvertStep): s is MarkUnsupportedStep {
|
|
124
|
+
return s.type === 'mark-unsupported'
|
|
125
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -39,7 +39,7 @@ var require_package = __commonJS({
|
|
|
39
39
|
"package.json"(exports2, module2) {
|
|
40
40
|
module2.exports = {
|
|
41
41
|
name: "coc-vscode-loader",
|
|
42
|
-
version: "1.
|
|
42
|
+
version: "1.2.0",
|
|
43
43
|
description: "Run VS Code extensions seamlessly in coc.nvim",
|
|
44
44
|
main: "lib/index.js",
|
|
45
45
|
keywords: [
|
|
@@ -159,9 +159,13 @@ async function fetchRegistryJSON(url) {
|
|
|
159
159
|
(0, import_child_process.execFile)("curl", ["-sL", url], { encoding: "utf-8", maxBuffer: 5 * 1024 * 1024 }, (err, stdout) => {
|
|
160
160
|
if (err) reject(new Error(`curl failed: ${err.message}`));
|
|
161
161
|
else {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
162
|
+
try {
|
|
163
|
+
const data = JSON.parse(stdout);
|
|
164
|
+
if (!Array.isArray(data)) reject(new Error("Invalid registry format"));
|
|
165
|
+
else resolve2(data);
|
|
166
|
+
} catch (e) {
|
|
167
|
+
reject(new Error(`Invalid JSON from registry: ${e.message}`));
|
|
168
|
+
}
|
|
165
169
|
}
|
|
166
170
|
});
|
|
167
171
|
});
|
|
@@ -437,8 +441,10 @@ function pluginDir(name) {
|
|
|
437
441
|
function converterCliPath() {
|
|
438
442
|
const base = path3.resolve(__dirname, "..");
|
|
439
443
|
const candidates = [
|
|
440
|
-
|
|
441
|
-
path3.join(base, "..", "converter", "src", "cli.ts")
|
|
444
|
+
// In dev mode (symlink), the converter is at repo root
|
|
445
|
+
path3.join(base, "..", "converter", "src", "cli.ts"),
|
|
446
|
+
// In npm install, the converter is bundled inside the package
|
|
447
|
+
path3.join(base, "converter", "src", "cli.ts")
|
|
442
448
|
];
|
|
443
449
|
for (const p of candidates) {
|
|
444
450
|
if (fs3.existsSync(p)) return p;
|
|
@@ -450,7 +456,7 @@ function converterCliPath() {
|
|
|
450
456
|
var CMD_TIMEOUT = 3e5;
|
|
451
457
|
async function run(cmd, args, cwd, onLine) {
|
|
452
458
|
return new Promise((resolve2, reject) => {
|
|
453
|
-
const child = (0, import_child_process2.spawn)(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"], shell:
|
|
459
|
+
const child = (0, import_child_process2.spawn)(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"], shell: false });
|
|
454
460
|
const timer = setTimeout(() => {
|
|
455
461
|
child.kill("SIGTERM");
|
|
456
462
|
reject(new Error(`Timed out after ${CMD_TIMEOUT / 1e3}s: ${cmd} ${args.join(" ")}`));
|
|
@@ -492,7 +498,7 @@ async function downloadSource(info, name, onProgress) {
|
|
|
492
498
|
}
|
|
493
499
|
return info.source.subdir ? path3.join(srcDir, info.source.subdir) : srcDir;
|
|
494
500
|
}
|
|
495
|
-
async function convertSource(inputDir, name, onProgress) {
|
|
501
|
+
async function convertSource(inputDir, name, info, onProgress) {
|
|
496
502
|
const build = buildDir(name);
|
|
497
503
|
if (fs3.existsSync(build)) fs3.rmSync(build, { recursive: true });
|
|
498
504
|
const cli = converterCliPath();
|
|
@@ -502,9 +508,23 @@ async function convertSource(inputDir, name, onProgress) {
|
|
|
502
508
|
const log2 = (chunk) => onProgress(2, 5, chunk.trim(), "");
|
|
503
509
|
await run("npm", ["install", "--legacy-peer-deps", "--production"], converterDir, log2);
|
|
504
510
|
}
|
|
511
|
+
if (!info.convert || !Array.isArray(info.convert) || info.convert.length === 0) {
|
|
512
|
+
throw new Error(`Registry entry "${name}" has no "convert" config. Please update the registry.`);
|
|
513
|
+
}
|
|
514
|
+
const convertFile = path3.join(cacheDir(name), "convert-config.json");
|
|
515
|
+
fs3.mkdirSync(path3.dirname(convertFile), { recursive: true });
|
|
516
|
+
fs3.writeFileSync(convertFile, JSON.stringify(info.convert));
|
|
517
|
+
const presetsFile = path3.join(cacheDir(name), "presets-config.json");
|
|
518
|
+
const registryDir = path3.resolve(__dirname, "..", "..", "coc-vscode-registry");
|
|
519
|
+
const presetsPath = path3.join(registryDir, "presets.json");
|
|
520
|
+
if (fs3.existsSync(presetsPath)) {
|
|
521
|
+
fs3.writeFileSync(presetsFile, fs3.readFileSync(presetsPath));
|
|
522
|
+
}
|
|
523
|
+
const args = ["tsx", cli, "convert", inputDir, "-o", build, "--convert-file", convertFile];
|
|
524
|
+
if (fs3.existsSync(presetsFile)) args.push("--presets-file", presetsFile);
|
|
505
525
|
onProgress(2, 5, "Converting...", `converter convert ${inputDir} -o ${build}`);
|
|
506
526
|
const log = (chunk) => onProgress(2, 5, chunk.trim(), "");
|
|
507
|
-
await run("npx",
|
|
527
|
+
await run("npx", args, cacheDir(name), log);
|
|
508
528
|
}
|
|
509
529
|
async function buildPackage(name, inputDir, info, onProgress) {
|
|
510
530
|
const build = buildDir(name);
|
|
@@ -614,56 +634,18 @@ async function buildPackage(name, inputDir, info, onProgress) {
|
|
|
614
634
|
}
|
|
615
635
|
const indexPath = path3.join(build, "lib", "index.js");
|
|
616
636
|
if (fs3.existsSync(indexPath)) {
|
|
617
|
-
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);
|
|
618
637
|
let code = fs3.readFileSync(indexPath, "utf-8");
|
|
619
|
-
|
|
620
|
-
code = code.replace(
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
);
|
|
624
|
-
const serverPath = `require('path').join(__dirname, '..', 'server', '${binPath}')`;
|
|
625
|
-
code = code.replace(
|
|
626
|
-
/try\s*\{[^}]*?require\.resolve\([^)]+\)\s*;?\s*\}\s*catch\s*\{\s*\}/g,
|
|
627
|
-
`try { serverModule = ${serverPath} } catch {}`
|
|
628
|
-
);
|
|
629
|
-
code = code.replace(
|
|
630
|
-
/let\s+serverModule\s*=\s*config\.get\([^)]+\)\s*;?\s*/g,
|
|
631
|
-
`let serverModule = ${serverPath};`
|
|
632
|
-
);
|
|
638
|
+
code = code.replace(/\{\{version}}/g, version);
|
|
639
|
+
code = code.replace(/\{\{platform}}/g, platform);
|
|
640
|
+
code = code.replace(/\{\{arch}}/g, arch2);
|
|
641
|
+
code = code.replace(/\{\{raw-arch}}/g, rawArch);
|
|
642
|
+
code = code.replace(/\{\{rust-target}}/g, rustTarget);
|
|
633
643
|
fs3.writeFileSync(indexPath, code);
|
|
634
644
|
}
|
|
635
645
|
} catch (e) {
|
|
636
646
|
onProgress(4, 5, `Warning: serverBinary setup failed (${e.message})`, "install server binary manually");
|
|
637
647
|
}
|
|
638
648
|
}
|
|
639
|
-
const docSelPath = path3.join(build, "lib", "index.js");
|
|
640
|
-
if (fs3.existsSync(docSelPath)) {
|
|
641
|
-
let code = fs3.readFileSync(docSelPath, "utf-8");
|
|
642
|
-
const langSelector = info.languages.map((l) => `{ scheme: "file", language: "${l}" }`).join(", ");
|
|
643
|
-
code = code.replace(
|
|
644
|
-
/documentSelector:\s*\[\s*\{[^}]*?language:\s*['"][^'"]*['"][^}]*\}\s*\]/,
|
|
645
|
-
`documentSelector: [${langSelector}]`
|
|
646
|
-
);
|
|
647
|
-
code = code.replace(
|
|
648
|
-
/client\.start\(\);/g,
|
|
649
|
-
"client.start().catch(() => {/* init may complete async */});"
|
|
650
|
-
);
|
|
651
|
-
fs3.writeFileSync(docSelPath, code);
|
|
652
|
-
}
|
|
653
|
-
const pkgPath = path3.join(build, "package.json");
|
|
654
|
-
if (fs3.existsSync(pkgPath)) {
|
|
655
|
-
try {
|
|
656
|
-
const pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
|
|
657
|
-
const events = pkg.activationEvents || [];
|
|
658
|
-
const langEvents = info.languages.map((l) => `onLanguage:${l}`);
|
|
659
|
-
const newEvents = events.filter((e) => !e.startsWith("onLanguage:")).concat(langEvents);
|
|
660
|
-
if (newEvents.length > 0 && JSON.stringify(newEvents) !== JSON.stringify(events)) {
|
|
661
|
-
pkg.activationEvents = newEvents;
|
|
662
|
-
fs3.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
663
|
-
}
|
|
664
|
-
} catch {
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
649
|
}
|
|
668
650
|
function extensionsPkgPath() {
|
|
669
651
|
return path3.join(os3.homedir(), ".config", "coc", "extensions", "package.json");
|
|
@@ -676,7 +658,7 @@ async function installToCoc(name, onProgress) {
|
|
|
676
658
|
fs3.mkdirSync(path3.dirname(dest), { recursive: true });
|
|
677
659
|
fs3.cpSync(src, dest, { recursive: true });
|
|
678
660
|
const pkgPath = extensionsPkgPath();
|
|
679
|
-
const pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
|
|
661
|
+
const pkg = fs3.existsSync(pkgPath) ? JSON.parse(fs3.readFileSync(pkgPath, "utf-8")) : { dependencies: {} };
|
|
680
662
|
pkg.dependencies = pkg.dependencies || {};
|
|
681
663
|
const depName = `coc-${name}`;
|
|
682
664
|
if (!pkg.dependencies[depName]) {
|
|
@@ -714,7 +696,7 @@ async function installPackage(state, name) {
|
|
|
714
696
|
state.setPackageStatus(name, "installing", { progress: "Starting..." });
|
|
715
697
|
try {
|
|
716
698
|
const input = await downloadSource(info, name, prog);
|
|
717
|
-
await convertSource(input, name, prog);
|
|
699
|
+
await convertSource(input, name, info, prog);
|
|
718
700
|
await buildPackage(name, input, info, prog);
|
|
719
701
|
await installToCoc(name, prog);
|
|
720
702
|
await saveMeta(name);
|
|
@@ -786,13 +768,13 @@ async function updatePackage(state, name) {
|
|
|
786
768
|
state.setPackageStatus(name, "updating", { progress: "Starting..." });
|
|
787
769
|
try {
|
|
788
770
|
const input = await downloadSource(info, name, prog);
|
|
789
|
-
await convertSource(input, name, prog);
|
|
771
|
+
await convertSource(input, name, info, prog);
|
|
790
772
|
await buildPackage(name, input, info, prog);
|
|
791
773
|
await installToCoc(name, prog);
|
|
792
774
|
await saveMeta(name);
|
|
793
775
|
state.setDirty();
|
|
794
776
|
state.setPackageStatus(name, "installed");
|
|
795
|
-
import_coc.window.showInformationMessage(`coc-${name}
|
|
777
|
+
import_coc.window.showInformationMessage(`coc-${name} updated`);
|
|
796
778
|
try {
|
|
797
779
|
const meta = JSON.parse(fs3.readFileSync(metaPath(name), "utf-8"));
|
|
798
780
|
if (meta.commit) {
|
|
@@ -814,7 +796,7 @@ async function updatePackage(state, name) {
|
|
|
814
796
|
}
|
|
815
797
|
async function runWithOutput(cmd, args, cwd) {
|
|
816
798
|
return new Promise((resolve2, reject) => {
|
|
817
|
-
const child = (0, import_child_process2.spawn)(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"], shell:
|
|
799
|
+
const child = (0, import_child_process2.spawn)(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"], shell: false });
|
|
818
800
|
const timer = setTimeout(() => {
|
|
819
801
|
child.kill("SIGTERM");
|
|
820
802
|
reject(new Error(`Timed out after ${CMD_TIMEOUT / 1e3}s: ${cmd} ${args.join(" ")}`));
|
|
@@ -1227,7 +1209,7 @@ var TUI = class {
|
|
|
1227
1209
|
return;
|
|
1228
1210
|
}
|
|
1229
1211
|
if (id === "X" && entry.status === "installed") {
|
|
1230
|
-
uninstallPackage(this.state, pkgName);
|
|
1212
|
+
await uninstallPackage(this.state, pkgName);
|
|
1231
1213
|
return;
|
|
1232
1214
|
}
|
|
1233
1215
|
if (id === "R" && entry.status === "installed") {
|