dsh-vscode-mode 0.1.49 → 0.1.51
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 +6 -3
- package/lib/client.js +426 -61
- package/lib/client.js.map +1 -1
- package/lib/index.js +116 -17
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/rulesMdc.ts +141 -0
- package/src/client/sidebar/SidebarView.ts +2 -1
- package/src/client/sidebar/panels/RulesPanel.ts +190 -29
- package/src/client/styles/editor.css +20 -11
- package/src/client/ui/LspSettings.ts +56 -16
- package/src/lsp/providers.ts +76 -16
- package/src/lsp/rpc.ts +10 -3
- package/src/shared/lsp.ts +9 -0
- package/src/shared/rpc.ts +2 -0
package/lib/index.js
CHANGED
|
@@ -7537,7 +7537,13 @@ function candidateEmmyLua(home = dshHome()) {
|
|
|
7537
7537
|
candidates.sort((a, b) => (b.version ?? "").localeCompare(a.version ?? "", void 0, { numeric: true }) || a.path.localeCompare(b.path));
|
|
7538
7538
|
return candidates[0] ?? null;
|
|
7539
7539
|
}
|
|
7540
|
-
/**
|
|
7540
|
+
/**
|
|
7541
|
+
* LuaLS 自动发现候选(VSCode 扩展目录 + extmgr 目录下 sumneko.lua-* 的 server/bin 可执行)。
|
|
7542
|
+
* 多版本并存时按清单版本降序、路径升序排序(与 EmmyLua/DotRush 发现的排序策略一致)。
|
|
7543
|
+
* @author ddj 2026年09月03号
|
|
7544
|
+
* @param home DSH home(缺省真实;测试可注入临时目录)
|
|
7545
|
+
* @returns 排序后的候选列表(首个为建议选用者)
|
|
7546
|
+
*/
|
|
7541
7547
|
function candidateLuaServers(home = dshHome()) {
|
|
7542
7548
|
const plat = platformServerDir();
|
|
7543
7549
|
const suffix = exeSuffix();
|
|
@@ -7546,40 +7552,62 @@ function candidateLuaServers(home = dshHome()) {
|
|
|
7546
7552
|
const binDir = join(extDir, "server", "bin");
|
|
7547
7553
|
const binName = "lua-language-server" + suffix;
|
|
7548
7554
|
const bin = existsSync(join(binDir, binName)) ? join(binDir, binName) : join(binDir, plat, binName);
|
|
7549
|
-
if (existsSync(bin) && !out.
|
|
7555
|
+
if (existsSync(bin) && !out.some((c) => c.path === bin)) out.push({
|
|
7556
|
+
path: bin,
|
|
7557
|
+
version: manifestVersionOf(extDir)
|
|
7558
|
+
});
|
|
7550
7559
|
}
|
|
7551
|
-
return out;
|
|
7560
|
+
return out.sort((a, b) => (b.version ?? "").localeCompare(a.version ?? "", void 0, { numeric: true }) || a.path.localeCompare(b.path));
|
|
7552
7561
|
}
|
|
7553
7562
|
/**
|
|
7554
7563
|
* C# 自动发现候选:ms-dotnettools.csharp 的 Roslyn dll(需 dotnet)/ OmniSharp 可执行,
|
|
7555
7564
|
* 以及 DotRush 扩展自带服务器(extension/bin/LanguageServer/DotRush.dll,需对应 .NET 运行时)。
|
|
7565
|
+
* 同类多版本并存时取清单版本最高者(与 EmmyLua/DotRush 发现的排序策略一致)。
|
|
7556
7566
|
* @author ddj 2026年09月03号
|
|
7557
7567
|
* @param home DSH home(缺省真实;测试可注入临时目录)
|
|
7558
7568
|
* @returns 发现结果
|
|
7559
7569
|
*/
|
|
7560
7570
|
function candidateCSharpServers(home = dshHome()) {
|
|
7561
7571
|
const out = {};
|
|
7572
|
+
/** 命中收集 → 清单版本降序取最高(平级按路径稳定排序)。 */
|
|
7573
|
+
const bestOf = (hits) => hits.sort((a, b) => (b.version ?? "").localeCompare(a.version ?? "", void 0, { numeric: true }) || a.entry.localeCompare(b.entry))[0] ?? null;
|
|
7574
|
+
const roslynHits = [];
|
|
7575
|
+
const omniHits = [];
|
|
7562
7576
|
const dotrushHits = [];
|
|
7563
7577
|
for (const dir of vscodeExtensionsDirs(home)) {
|
|
7564
7578
|
for (const extDir of listMatchingDirs(dir, "ms-dotnettools.csharp-")) {
|
|
7579
|
+
const version = manifestVersionOf(extDir);
|
|
7565
7580
|
const roslyn = join(extDir, ".roslyn", "Microsoft.CodeAnalysis.LanguageServer.dll");
|
|
7566
|
-
if (
|
|
7581
|
+
if (existsSync(roslyn)) roslynHits.push({
|
|
7582
|
+
entry: roslyn,
|
|
7583
|
+
version
|
|
7584
|
+
});
|
|
7567
7585
|
const omni = join(extDir, ".omnisharp", "OmniSharp" + exeSuffix());
|
|
7568
|
-
if (
|
|
7586
|
+
if (existsSync(omni)) omniHits.push({
|
|
7587
|
+
entry: omni,
|
|
7588
|
+
version
|
|
7589
|
+
});
|
|
7569
7590
|
}
|
|
7570
7591
|
for (const extDir of listMatchingDirs(dir, "nromanov.dotrush-")) {
|
|
7571
7592
|
const dll = join(extDir, "extension", "bin", "LanguageServer", "DotRush.dll");
|
|
7572
7593
|
if (!existsSync(dll)) continue;
|
|
7573
7594
|
dotrushHits.push({
|
|
7574
|
-
dll,
|
|
7595
|
+
entry: dll,
|
|
7575
7596
|
version: manifestVersionOf(extDir)
|
|
7576
7597
|
});
|
|
7577
7598
|
}
|
|
7578
7599
|
}
|
|
7579
|
-
const
|
|
7580
|
-
if (
|
|
7581
|
-
out.
|
|
7582
|
-
out.
|
|
7600
|
+
const roslynBest = bestOf(roslynHits);
|
|
7601
|
+
if (roslynBest) {
|
|
7602
|
+
out.roslynDll = roslynBest.entry;
|
|
7603
|
+
out.roslynVersion = roslynBest.version;
|
|
7604
|
+
}
|
|
7605
|
+
const omniBest = bestOf(omniHits);
|
|
7606
|
+
if (omniBest) out.omnisharpExe = omniBest.entry;
|
|
7607
|
+
const dotrushBest = bestOf(dotrushHits);
|
|
7608
|
+
if (dotrushBest) {
|
|
7609
|
+
out.dotrushDll = dotrushBest.entry;
|
|
7610
|
+
out.dotrushVersion = dotrushBest.version;
|
|
7583
7611
|
}
|
|
7584
7612
|
const dotnet = findDotnet();
|
|
7585
7613
|
if (dotnet) out.dotnet = dotnet;
|
|
@@ -7683,13 +7711,15 @@ function resolveLuaProvider(manual, home = dshHome()) {
|
|
|
7683
7711
|
version: emmy.version,
|
|
7684
7712
|
providerName: "EmmyLua"
|
|
7685
7713
|
};
|
|
7686
|
-
const
|
|
7687
|
-
if (
|
|
7714
|
+
const best = candidateLuaServers(h)[0];
|
|
7715
|
+
if (best) return {
|
|
7688
7716
|
...base,
|
|
7689
7717
|
kind: "discover",
|
|
7690
|
-
argv: [
|
|
7718
|
+
argv: [best.path],
|
|
7691
7719
|
cwd: void 0,
|
|
7692
|
-
ready: true
|
|
7720
|
+
ready: true,
|
|
7721
|
+
version: best.version,
|
|
7722
|
+
providerName: "LuaLS"
|
|
7693
7723
|
};
|
|
7694
7724
|
const inPath = findInPath("lua-language-server" + exeSuffix());
|
|
7695
7725
|
if (inPath) return {
|
|
@@ -7785,6 +7815,67 @@ const PROVIDER_RESOLVERS = {
|
|
|
7785
7815
|
lua: resolveLuaProvider,
|
|
7786
7816
|
csharp: resolveCSharpProvider
|
|
7787
7817
|
};
|
|
7818
|
+
/**
|
|
7819
|
+
* 汇总某语言当前检测到的候选服务器(每类服务器一条、取该类最高版本;设置页展示用)。
|
|
7820
|
+
* chosen 以候选路径命中 spec.argv 判定;未选用(kind=none/manual 不匹配)时不标记。
|
|
7821
|
+
* @author ddj 2026年09月03号
|
|
7822
|
+
* @param languageId 语言 id
|
|
7823
|
+
* @param spec 已解析的 provider 规格
|
|
7824
|
+
* @param home DSH home(缺省真实;测试可注入临时目录)
|
|
7825
|
+
* @returns 候选列表(不支持的语言/检测异常返回空)
|
|
7826
|
+
*/
|
|
7827
|
+
function candidatesFor(languageId, spec, home = dshHome()) {
|
|
7828
|
+
/** 候选路径命中 spec.argv 时补 chosen 标记。 */
|
|
7829
|
+
const markChosen = (candidate) => spec.ready && candidate.path && spec.argv.includes(candidate.path) ? {
|
|
7830
|
+
...candidate,
|
|
7831
|
+
chosen: true
|
|
7832
|
+
} : candidate;
|
|
7833
|
+
try {
|
|
7834
|
+
if (languageId === "lua") {
|
|
7835
|
+
const out = [];
|
|
7836
|
+
const emmy = candidateEmmyLua(home);
|
|
7837
|
+
if (emmy) out.push(markChosen({
|
|
7838
|
+
name: "EmmyLua",
|
|
7839
|
+
version: emmy.version,
|
|
7840
|
+
path: emmy.path
|
|
7841
|
+
}));
|
|
7842
|
+
const lua = candidateLuaServers(home)[0];
|
|
7843
|
+
if (lua) out.push(markChosen({
|
|
7844
|
+
name: "LuaLS(sumneko.lua)",
|
|
7845
|
+
version: lua.version,
|
|
7846
|
+
path: lua.path
|
|
7847
|
+
}));
|
|
7848
|
+
const inPath = findInPath("lua-language-server" + exeSuffix());
|
|
7849
|
+
if (inPath) out.push(markChosen({
|
|
7850
|
+
name: "lua-language-server(PATH)",
|
|
7851
|
+
path: inPath
|
|
7852
|
+
}));
|
|
7853
|
+
return out;
|
|
7854
|
+
}
|
|
7855
|
+
if (languageId === "csharp") {
|
|
7856
|
+
const out = [];
|
|
7857
|
+
const found = candidateCSharpServers(home);
|
|
7858
|
+
if (found.roslynDll) out.push(markChosen({
|
|
7859
|
+
name: "Roslyn(ms-dotnettools.csharp)",
|
|
7860
|
+
version: found.roslynVersion,
|
|
7861
|
+
path: found.roslynDll
|
|
7862
|
+
}));
|
|
7863
|
+
if (found.dotrushDll) out.push(markChosen({
|
|
7864
|
+
name: "DotRush",
|
|
7865
|
+
version: found.dotrushVersion,
|
|
7866
|
+
path: found.dotrushDll
|
|
7867
|
+
}));
|
|
7868
|
+
if (found.omnisharpExe) out.push(markChosen({
|
|
7869
|
+
name: "OmniSharp",
|
|
7870
|
+
path: found.omnisharpExe
|
|
7871
|
+
}));
|
|
7872
|
+
return out;
|
|
7873
|
+
}
|
|
7874
|
+
return [];
|
|
7875
|
+
} catch (error) {
|
|
7876
|
+
return [];
|
|
7877
|
+
}
|
|
7878
|
+
}
|
|
7788
7879
|
/** 进程级缓存(home|languageId → 条目),同一 DSH home 的不同会话共享。 */
|
|
7789
7880
|
const specCache = /* @__PURE__ */ new Map();
|
|
7790
7881
|
/** 磁盘缓存是否已载入本进程(home → loaded),不同 profile 不串缓存。 */
|
|
@@ -8388,10 +8479,11 @@ function createLspRpc(deps) {
|
|
|
8388
8479
|
...location,
|
|
8389
8480
|
root
|
|
8390
8481
|
}));
|
|
8391
|
-
/** 当前 provider 检测结论 → 设置页 idle 状态(不启动 server
|
|
8482
|
+
/** 当前 provider 检测结论 → 设置页 idle 状态(不启动 server);附带未满足的环境需求与候选服务器。 */
|
|
8392
8483
|
const detectedStatus = (languageId, root) => {
|
|
8393
8484
|
const spec = resolveProviderSpec(ctx, pluginConfig, languageId);
|
|
8394
8485
|
const missingEnv = envRequirementsFor(languageId, dshHome());
|
|
8486
|
+
const candidates = candidatesFor(languageId, spec);
|
|
8395
8487
|
return {
|
|
8396
8488
|
languageId,
|
|
8397
8489
|
source: spec.kind,
|
|
@@ -8400,7 +8492,8 @@ function createLspRpc(deps) {
|
|
|
8400
8492
|
version: spec.version,
|
|
8401
8493
|
providerName: spec.providerName,
|
|
8402
8494
|
root,
|
|
8403
|
-
missingEnv: missingEnv.length ? missingEnv : void 0
|
|
8495
|
+
missingEnv: missingEnv.length ? missingEnv : void 0,
|
|
8496
|
+
candidates: candidates.length ? candidates : void 0
|
|
8404
8497
|
};
|
|
8405
8498
|
};
|
|
8406
8499
|
/**
|
|
@@ -8446,6 +8539,12 @@ function createLspRpc(deps) {
|
|
|
8446
8539
|
servers: manager.statusAll().filter((status) => status.root === sc.root)
|
|
8447
8540
|
};
|
|
8448
8541
|
},
|
|
8542
|
+
"edrv.lsp.detect": async () => {
|
|
8543
|
+
return {
|
|
8544
|
+
ok: true,
|
|
8545
|
+
servers: LSP_LANGUAGES.map((lang) => detectedStatus(lang))
|
|
8546
|
+
};
|
|
8547
|
+
},
|
|
8449
8548
|
"edrv.lsp.configGet": async () => {
|
|
8450
8549
|
const settings = configFromSettings(ctx);
|
|
8451
8550
|
const plugin = configFromPlugin(pluginConfig);
|
|
@@ -8461,7 +8560,7 @@ function createLspRpc(deps) {
|
|
|
8461
8560
|
},
|
|
8462
8561
|
"edrv.lsp.configUpdate": async (args) => {
|
|
8463
8562
|
const lang = args.languageId;
|
|
8464
|
-
if (!lang || !
|
|
8563
|
+
if (!lang || !LSP_LANGUAGES.includes(lang)) return {
|
|
8465
8564
|
ok: false,
|
|
8466
8565
|
error: "不支持的语言:" + lang
|
|
8467
8566
|
};
|