dsh-vscode-mode 0.1.50 → 0.1.52
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/lib/client.js +64 -27
- package/lib/client.js.map +1 -1
- package/lib/index.js +140 -100
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/ui/LspSettings.ts +56 -16
- package/src/index.ts +1 -2
- package/src/lsp/config.ts +13 -29
- package/src/lsp/providers.ts +76 -16
- package/src/lsp/rpc.ts +24 -20
- package/src/shared/lsp.ts +9 -0
- package/src/shared/rpc.ts +2 -0
- package/src/lsp/settings.ts +0 -50
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 不串缓存。 */
|
|
@@ -8098,8 +8189,16 @@ async function extractTo(buf, dir) {
|
|
|
8098
8189
|
}
|
|
8099
8190
|
//#endregion
|
|
8100
8191
|
//#region src/lsp/config.ts
|
|
8101
|
-
|
|
8192
|
+
/**
|
|
8193
|
+
* dsh-vscode-mode host — LSP 配置读取与 provider 解析装配。
|
|
8194
|
+
* 配置来源优先级:运行时覆盖(设置页保存,重启失效)> 插件组合配置 > 默认。
|
|
8195
|
+
* 原 settings section(ns dsh-vscode-mode.languageServers)命名空间不合法
|
|
8196
|
+
* (DSH settings 仅允许 /^[a-z][a-z0-9-]*$/,点号命名空间永久不可注册),
|
|
8197
|
+
* 已降级为配置值(插件组合配置 + 会话内运行时覆盖),不再尝试 settings 安装。
|
|
8198
|
+
* 作者 ddj 2026-08-27 / 2026-09-02
|
|
8199
|
+
*/
|
|
8102
8200
|
const LSP_LANGUAGES = ["lua", "csharp"];
|
|
8201
|
+
/** 清洗单语言配置:仅保留合法字段并剥离 undefined(稀疏覆盖语义,清空字段即回落组合配置)。 */
|
|
8103
8202
|
function sanitizeLang(raw) {
|
|
8104
8203
|
if (!raw || typeof raw !== "object") return void 0;
|
|
8105
8204
|
const obj = raw;
|
|
@@ -8120,22 +8219,7 @@ function configFromPlugin(config) {
|
|
|
8120
8219
|
}
|
|
8121
8220
|
return out;
|
|
8122
8221
|
}
|
|
8123
|
-
/**
|
|
8124
|
-
function configFromSettings(ctx) {
|
|
8125
|
-
try {
|
|
8126
|
-
const value = (ctx.get("settings")?.describe?.({ redactSecrets: true })?.find((item) => item.ns === LSP_SETTINGS_NS))?.value;
|
|
8127
|
-
if (!value || typeof value !== "object") return {};
|
|
8128
|
-
const out = {};
|
|
8129
|
-
for (const lang of LSP_LANGUAGES) {
|
|
8130
|
-
const v = sanitizeLang(value[lang]);
|
|
8131
|
-
if (v) out[lang] = v;
|
|
8132
|
-
}
|
|
8133
|
-
return out;
|
|
8134
|
-
} catch (error) {
|
|
8135
|
-
return {};
|
|
8136
|
-
}
|
|
8137
|
-
}
|
|
8138
|
-
/** 合并配置:settings 覆盖插件配置。 */
|
|
8222
|
+
/** 合并配置:上层(运行时覆盖/settings)覆盖插件组合配置。 */
|
|
8139
8223
|
function mergeConfig(a, b) {
|
|
8140
8224
|
const out = { ...a };
|
|
8141
8225
|
for (const lang of LSP_LANGUAGES) {
|
|
@@ -8150,14 +8234,14 @@ function mergeConfig(a, b) {
|
|
|
8150
8234
|
return out;
|
|
8151
8235
|
}
|
|
8152
8236
|
/**
|
|
8153
|
-
* 解析某语言的 provider spec
|
|
8154
|
-
* @author ddj 2026年08月27号
|
|
8155
|
-
* @param ctx DSH 上下文
|
|
8237
|
+
* 解析某语言的 provider spec(插件组合配置 + 运行时覆盖层合并后)。
|
|
8238
|
+
* @author ddj 2026年08月27号 / 2026年09月02号
|
|
8156
8239
|
* @param pluginConfig 插件组合配置
|
|
8157
8240
|
* @param languageId 语言 id
|
|
8241
|
+
* @param override 运行时覆盖层(设置页保存值,重启失效;缺省为空)
|
|
8158
8242
|
* @returns provider 规格
|
|
8159
8243
|
*/
|
|
8160
|
-
function resolveProviderSpec(
|
|
8244
|
+
function resolveProviderSpec(pluginConfig, languageId, override) {
|
|
8161
8245
|
const resolver = PROVIDER_RESOLVERS[languageId];
|
|
8162
8246
|
if (!resolver) return {
|
|
8163
8247
|
languageId,
|
|
@@ -8166,7 +8250,7 @@ function resolveProviderSpec(ctx, pluginConfig, languageId) {
|
|
|
8166
8250
|
ready: false,
|
|
8167
8251
|
reason: "不支持的语言:" + languageId
|
|
8168
8252
|
};
|
|
8169
|
-
const lang = mergeConfig(configFromPlugin(pluginConfig),
|
|
8253
|
+
const lang = mergeConfig(configFromPlugin(pluginConfig), override ?? {})[languageId];
|
|
8170
8254
|
if (lang && lang.enabled === false) return {
|
|
8171
8255
|
languageId,
|
|
8172
8256
|
kind: "none",
|
|
@@ -8364,6 +8448,8 @@ function createDocTracker() {
|
|
|
8364
8448
|
function createLspRpc(deps) {
|
|
8365
8449
|
const { ctx, pluginConfig, manager } = deps;
|
|
8366
8450
|
const tracker = createDocTracker();
|
|
8451
|
+
/** 运行时覆盖层:设置页保存值(内存态,重启回落组合配置值;每 apply 新建,插件重载自动复位)。 */
|
|
8452
|
+
const runtimeConfig = {};
|
|
8367
8453
|
onRuntimeProvisioned(() => {
|
|
8368
8454
|
clearProviderCache();
|
|
8369
8455
|
manager.resetLanguage("csharp");
|
|
@@ -8382,16 +8468,17 @@ function createLspRpc(deps) {
|
|
|
8382
8468
|
return { err: String(error) };
|
|
8383
8469
|
}
|
|
8384
8470
|
};
|
|
8385
|
-
const acquireServer = (root, lang) => manager.acquire(root, lang, (languageId) => resolveProviderSpec(
|
|
8471
|
+
const acquireServer = (root, lang) => manager.acquire(root, lang, (languageId) => resolveProviderSpec(pluginConfig, languageId, runtimeConfig));
|
|
8386
8472
|
const serverOf = (root, lang) => manager.peek(root, lang);
|
|
8387
8473
|
const rootLocations = (locations, root) => locations.map((location) => ({
|
|
8388
8474
|
...location,
|
|
8389
8475
|
root
|
|
8390
8476
|
}));
|
|
8391
|
-
/** 当前 provider 检测结论 → 设置页 idle 状态(不启动 server
|
|
8477
|
+
/** 当前 provider 检测结论 → 设置页 idle 状态(不启动 server);附带未满足的环境需求与候选服务器。 */
|
|
8392
8478
|
const detectedStatus = (languageId, root) => {
|
|
8393
|
-
const spec = resolveProviderSpec(
|
|
8479
|
+
const spec = resolveProviderSpec(pluginConfig, languageId, runtimeConfig);
|
|
8394
8480
|
const missingEnv = envRequirementsFor(languageId, dshHome());
|
|
8481
|
+
const candidates = candidatesFor(languageId, spec);
|
|
8395
8482
|
return {
|
|
8396
8483
|
languageId,
|
|
8397
8484
|
source: spec.kind,
|
|
@@ -8400,7 +8487,8 @@ function createLspRpc(deps) {
|
|
|
8400
8487
|
version: spec.version,
|
|
8401
8488
|
providerName: spec.providerName,
|
|
8402
8489
|
root,
|
|
8403
|
-
missingEnv: missingEnv.length ? missingEnv : void 0
|
|
8490
|
+
missingEnv: missingEnv.length ? missingEnv : void 0,
|
|
8491
|
+
candidates: candidates.length ? candidates : void 0
|
|
8404
8492
|
};
|
|
8405
8493
|
};
|
|
8406
8494
|
/**
|
|
@@ -8446,48 +8534,34 @@ function createLspRpc(deps) {
|
|
|
8446
8534
|
servers: manager.statusAll().filter((status) => status.root === sc.root)
|
|
8447
8535
|
};
|
|
8448
8536
|
},
|
|
8449
|
-
"edrv.lsp.
|
|
8450
|
-
|
|
8451
|
-
|
|
8452
|
-
|
|
8453
|
-
for (const lang of Object.keys(settings)) merged[lang] = {
|
|
8454
|
-
...plugin[lang],
|
|
8455
|
-
...settings[lang]
|
|
8537
|
+
"edrv.lsp.detect": async () => {
|
|
8538
|
+
return {
|
|
8539
|
+
ok: true,
|
|
8540
|
+
servers: LSP_LANGUAGES.map((lang) => detectedStatus(lang))
|
|
8456
8541
|
};
|
|
8542
|
+
},
|
|
8543
|
+
"edrv.lsp.configGet": async () => {
|
|
8457
8544
|
return {
|
|
8458
8545
|
ok: true,
|
|
8459
|
-
config:
|
|
8546
|
+
config: mergeConfig(configFromPlugin(pluginConfig), runtimeConfig)
|
|
8460
8547
|
};
|
|
8461
8548
|
},
|
|
8462
8549
|
"edrv.lsp.configUpdate": async (args) => {
|
|
8463
8550
|
const lang = args.languageId;
|
|
8464
|
-
if (!lang || !
|
|
8551
|
+
if (!lang || !LSP_LANGUAGES.includes(lang)) return {
|
|
8465
8552
|
ok: false,
|
|
8466
8553
|
error: "不支持的语言:" + lang
|
|
8467
8554
|
};
|
|
8468
|
-
const
|
|
8469
|
-
const target = {
|
|
8470
|
-
...current,
|
|
8471
|
-
[lang]: { ...current[lang] ?? {} }
|
|
8472
|
-
}[lang];
|
|
8555
|
+
const target = { ...runtimeConfig[lang] ?? {} };
|
|
8473
8556
|
if (args.enabled !== void 0) target.enabled = args.enabled;
|
|
8474
8557
|
if (args.command !== void 0) target.command = args.command || void 0;
|
|
8475
8558
|
if (args.path !== void 0) target.path = args.path || void 0;
|
|
8559
|
+
runtimeConfig[lang] = sanitizeLang(target) ?? {};
|
|
8476
8560
|
try {
|
|
8477
|
-
const settings = ctx.get("settings");
|
|
8478
|
-
if (!settings?.update) return {
|
|
8479
|
-
ok: false,
|
|
8480
|
-
error: "设置服务不可用"
|
|
8481
|
-
};
|
|
8482
|
-
await settings.update(LSP_SETTINGS_NS, { [lang]: target });
|
|
8483
8561
|
const servers = await redetectLanguage(lang);
|
|
8484
|
-
const stored = (settings.describe?.({ redactSecrets: true })?.find((item) => item.ns === LSP_SETTINGS_NS))?.value;
|
|
8485
8562
|
return {
|
|
8486
8563
|
ok: true,
|
|
8487
|
-
config:
|
|
8488
|
-
...configFromPlugin(pluginConfig),
|
|
8489
|
-
...stored
|
|
8490
|
-
},
|
|
8564
|
+
config: mergeConfig(configFromPlugin(pluginConfig), runtimeConfig),
|
|
8491
8565
|
servers
|
|
8492
8566
|
};
|
|
8493
8567
|
} catch (error) {
|
|
@@ -8827,40 +8901,6 @@ function createLspRpc(deps) {
|
|
|
8827
8901
|
};
|
|
8828
8902
|
}
|
|
8829
8903
|
//#endregion
|
|
8830
|
-
//#region src/lsp/settings.ts
|
|
8831
|
-
/**
|
|
8832
|
-
* 安装 LSP 设置 section。
|
|
8833
|
-
* @author ddj 2026年08月27号
|
|
8834
|
-
* @param ctx DSH 上下文
|
|
8835
|
-
* @param entry 初始配置
|
|
8836
|
-
* @returns 是否成功安装
|
|
8837
|
-
*/
|
|
8838
|
-
async function installLspSettingsSection(ctx, entry) {
|
|
8839
|
-
let deps = null;
|
|
8840
|
-
try {
|
|
8841
|
-
deps = await loadSettingsDeps();
|
|
8842
|
-
} catch {}
|
|
8843
|
-
if (!deps) return false;
|
|
8844
|
-
try {
|
|
8845
|
-
const z = deps.z;
|
|
8846
|
-
const langShape = {};
|
|
8847
|
-
for (const lang of LSP_LANGUAGES) langShape[lang] = z.object({
|
|
8848
|
-
enabled: z.boolean(),
|
|
8849
|
-
command: z.string(),
|
|
8850
|
-
path: z.string()
|
|
8851
|
-
}).default({});
|
|
8852
|
-
const schema = z.object(langShape).default({});
|
|
8853
|
-
const strategy = await runSettingsInstall(ctx, LSP_SETTINGS_NS, schema, entry, {
|
|
8854
|
-
setSource: () => {},
|
|
8855
|
-
onChange: () => {}
|
|
8856
|
-
});
|
|
8857
|
-
return strategy === "legacy" || strategy === "service";
|
|
8858
|
-
} catch (error) {
|
|
8859
|
-
console.error("[dsh-vscode-mode] LSP 设置 section 安装失败:" + String(error));
|
|
8860
|
-
return false;
|
|
8861
|
-
}
|
|
8862
|
-
}
|
|
8863
|
-
//#endregion
|
|
8864
8904
|
//#region src/index.ts
|
|
8865
8905
|
/**
|
|
8866
8906
|
* @dsh-external 生态 → dsh-vscode-mode:DSH 上的类 VSCode 编码体验(Host 半入口)。
|
|
@@ -8895,7 +8935,7 @@ function apply(ctx, config) {
|
|
|
8895
8935
|
/** 兼容性警告收集(route 护栏等写入,启动日志一并输出)。 */
|
|
8896
8936
|
const warnings = [];
|
|
8897
8937
|
setupOpenSettings(ctx, config, () => {});
|
|
8898
|
-
|
|
8938
|
+
/** LSP 配置为配置值模式:插件组合配置 + 会话内运行时覆盖(原 settings section 命名空间不合法,见 lsp/config.ts)。 */
|
|
8899
8939
|
/** 规则注入 section(~/.dsh/rules 与 <工作区>/.dsh/rules;旧版 DSH 无 systemPrompt 时静默降级)。 */
|
|
8900
8940
|
const rulesInstalled = installRulesSection(ctx);
|
|
8901
8941
|
if (!rulesInstalled) ctx.logger?.warn?.("[" + name + "] 未检测到 systemPrompt 服务,规则仅可管理不注入");
|