dsh-vscode-mode 0.15.5 → 0.15.7

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 CHANGED
@@ -465,13 +465,13 @@ profile 请替换为实际目标,不要把示例目录当成当前运行 profi
465
465
 
466
466
  ```bash
467
467
  # ① Git 安装(clone + prepare 构建;推荐打固定 tag)
468
- dsh plugin --profile web add github:Lenonss/DSH_VsCodeMode#v0.15.5
468
+ dsh plugin --profile web add github:Lenonss/DSH_VsCodeMode#v0.15.7
469
469
 
470
470
  # ② npm 注册表(发布到 npm 后)
471
- dsh plugin --profile web add dsh-vscode-mode@0.15.5
471
+ dsh plugin --profile web add dsh-vscode-mode@0.15.7
472
472
 
473
473
  # ③ GitHub Release tgz 直装(Release asset 可用后)
474
- dsh plugin --profile web add https://github.com/Lenonss/DSH_VsCodeMode/releases/download/v0.15.5/dsh-vscode-mode-0.15.5.tgz
474
+ dsh plugin --profile web add https://github.com/Lenonss/DSH_VsCodeMode/releases/download/v0.15.7/dsh-vscode-mode-0.15.7.tgz
475
475
  ```
476
476
 
477
477
  > **DSH 版本政策(0.14.10 起)**:六项 DSH peer 统一声明为 `*`,不再维护逐版
@@ -809,6 +809,9 @@ Keep All / Undo All 却是亮的。修复:单文件 Keep / Undo 覆盖冲突
809
809
  完整变更见 [GitHub Releases](https://github.com/Lenonss/DSH_VsCodeMode/releases)。
810
810
  近期关键版本:
811
811
 
812
+ - **v0.15.7**:**Lua 成员链跳转与枚举引用**——规避 EmmyLua 标识符词边界解析问题,从引用结果推导跨文件声明;Lua 表字面量枚举键 Ctrl+点击打开引用 Peek,使用处仍按原生定义跳转。真实 GUI 点击尚未完成验收,用户接受此缺口;发布不自动安装或重启当前实例,详见 [0.15.7 发布说明](docs/release-0.15.7.md)。
813
+ - **v0.15.6**:**统一 SVN 项目更新入口**——资源管理器顶部 ↓ 与 SVN 变更页全局 ↓ 均打开插件自带 SVN 更新窗口,目标为当前项目根目录;非 SVN、能力未知或 CLI 不可用时不显示虚假的 SVN 读取提示。保留只读远端检查与本地刷新;本次真实 GUI 未验证,用户已接受此发布缺口,不自动安装或重启,详见 [0.15.6 发布说明](docs/release-0.15.6.md)。
814
+
812
815
  - **v0.15.5**:**浮窗性能与客户端适配**——拖动/缩放改为逐帧直写几何、结束单次提交,多窗口共享视口监听;SVN 日志行表 memo 与选中集优化,冲突状态读取按批 4 并发。LSP 去抖发送前惰性读取全文,隐藏页面心跳目标周期降为 15 秒;兼容性摘要按版本、安装事实与用户选择显示适用诊断,补充搜索刷新回归。保留 0.15.4 全部功能;本次真实 GUI 未重测,用户已接受此发布缺口,未安装/重启当前实例,详见 [0.15.5 发布说明](docs/release-0.15.5.md)。
813
816
 
814
817
  - **v0.15.4**:**SVN 非模态浮窗与独立文件对比**——更新、日志、统计、补丁、目录对比及智能整理采用与文件编辑相同的页面内浮窗,支持移动、调整尺寸、点击置顶与后台 DSH 交互。文件对比不再占据主编辑区,保留二进制/编码提示和来源任务返回逻辑;确认类弹窗保持模态。真实 GUI 交互尚未验收,用户已接受此发布缺口;资源管理器“目录不存在”原因未定位,本版不宣称修复该提示。
package/lib/client.js CHANGED
@@ -13651,7 +13651,7 @@ window.__ModuleLoader__.load({
13651
13651
  * dsh-vscode-mode client — Monaco LSP provider 注册 + 跳转/引用命令。
13652
13652
  * 数据层:Definition/Reference/DocumentSymbol/Hover provider(同一文件内跳转 Monaco 原生可用)。
13653
13653
  * 交互层:edrv.goToDefinition(F12)/ edrv.findReferences(Shift+F12 / 右键)均走 Monaco 原生命令;
13654
- * Ctrl+点击同样交给原生(多结果弹 Peek 让用户选、无定义时按 alternativeDefinitionCommand 降级),
13654
+ * Ctrl+点击使用处交给原生;Lua 表枚举字段声明处改为打开引用 Peek,
13655
13655
  * 数据经 host 的 LSP RPC 提供(registerEditorOpener 接管 edrv:// 点击跳转)。
13656
13656
  * 作者 ddj 2026-08-27 / 2026-09-11
13657
13657
  */
@@ -13915,6 +13915,69 @@ window.__ModuleLoader__.load({
13915
13915
  return false;
13916
13916
  }
13917
13917
  }
13918
+ /**
13919
+ * 判定 Ctrl+点击是否落在 Lua 表的字段声明键上(`TaskStateChange = 50000`)。
13920
+ * 仅拦截表字面量内的键,不改动使用处的原生跳转行为。
13921
+ * @author ddj 2026年10月16号
13922
+ * @param model 当前 Monaco 文档
13923
+ * @param position 鼠标命中位置
13924
+ * @returns 是否为表字段声明键
13925
+ */
13926
+ function isLuaTableKey(model, position) {
13927
+ if (model?.getLanguageId?.() !== "lua" || !position) return false;
13928
+ const line = model.getLineContent(position.lineNumber);
13929
+ const key = model.getWordAtPosition(position);
13930
+ if (!key || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(key.word)) return false;
13931
+ if (!/^\s*=\s*(?!=)/.test(line.slice(key.endColumn - 1))) return false;
13932
+ if (!/^\s*$/.test(line.slice(0, key.startColumn - 1))) return false;
13933
+ for (let lineNumber = position.lineNumber - 1; lineNumber >= Math.max(1, position.lineNumber - 100); lineNumber--) {
13934
+ const previous = model.getLineContent(lineNumber).trim();
13935
+ if (!previous || previous.startsWith("--")) continue;
13936
+ if (/^(?:[A-Za-z_][A-Za-z0-9_]*\s*\.\s*)*[A-Za-z_][A-Za-z0-9_]*\s*=\s*\{\s*(?:--.*)?$/.test(previous)) return true;
13937
+ if (!/^[A-Za-z_][A-Za-z0-9_]*\s*=\s*[^{}]*,?\s*(?:--.*)?$/.test(previous)) return false;
13938
+ }
13939
+ return false;
13940
+ }
13941
+ /**
13942
+ * 仅在 Lua 表字段声明处把 Ctrl+点击交给引用 Peek;其他点击留给 Monaco 原生导航。
13943
+ * 使用 DOM capture 阶段阻止原生 gotoDefinitionAtPosition 同时触发,避免跳转和 Peek 竞态。
13944
+ * @author ddj 2026年10月16号
13945
+ * @param ed Monaco 编辑器
13946
+ * @param monaco Monaco API
13947
+ * @returns 解绑回调
13948
+ */
13949
+ function bindLuaKeyRefs(ed, monaco) {
13950
+ const node = ed?.getDomNode?.();
13951
+ if (!node) return () => {};
13952
+ const keyAt = (event) => {
13953
+ if (event.button !== 0 || !event.ctrlKey && !event.metaKey || event.altKey || event.shiftKey) return null;
13954
+ const target = ed.getTargetAtClientPoint?.(event.clientX, event.clientY);
13955
+ const content = monaco.editor?.MouseTargetType?.CONTENT_TEXT ?? 6;
13956
+ return target?.type === content && isLuaTableKey(ed.getModel(), target.position) ? target.position : null;
13957
+ };
13958
+ let suppressUp = false;
13959
+ const onDown = (event) => {
13960
+ const position = keyAt(event);
13961
+ if (!position) return;
13962
+ suppressUp = true;
13963
+ event.preventDefault();
13964
+ event.stopPropagation();
13965
+ ed.setPosition(position);
13966
+ triggerReferencePeek(ed);
13967
+ };
13968
+ const onUp = (event) => {
13969
+ if (!suppressUp) return;
13970
+ suppressUp = false;
13971
+ event.preventDefault();
13972
+ event.stopPropagation();
13973
+ };
13974
+ node.addEventListener("mousedown", onDown, true);
13975
+ node.addEventListener("mouseup", onUp, true);
13976
+ return () => {
13977
+ node.removeEventListener("mousedown", onDown, true);
13978
+ node.removeEventListener("mouseup", onUp, true);
13979
+ };
13980
+ }
13918
13981
  /** Shift+F12 / 右键「查找所有引用」:走 Monaco 原生 References Peek(两栏引用视图)。 */
13919
13982
  async function runFindReferences(ed) {
13920
13983
  const position = ed.getPosition();
@@ -24394,6 +24457,8 @@ window.__ModuleLoader__.load({
24394
24457
  });
24395
24458
  syncSvnMenuActs(ed);
24396
24459
  bindLspUnderline(ed, m);
24460
+ const unbindLuaKeyRefs = bindLuaKeyRefs(ed, m);
24461
+ ed.onDidDispose(unbindLuaKeyRefs);
24397
24462
  trackAiEditor(ed);
24398
24463
  ed.addCommand(m.KeyMod.Alt | m.KeyCode.Backslash, () => {
24399
24464
  ed.trigger("edrv-ai", "editor.action.inlineSuggest.trigger", null);
@@ -32155,7 +32220,7 @@ window.__ModuleLoader__.load({
32155
32220
  ...remote,
32156
32221
  local: snapshot?.view.marks ?? null,
32157
32222
  remote: snapshot ? remote.remote : null,
32158
- message: localMessage(snapshot?.view) + (remote.message ? ";" + remote.message : ""),
32223
+ message: ready ? localMessage(snapshot?.view) + (remote.message ? ";" + remote.message : "") : "",
32159
32224
  canCheck: ready && snapshot !== null,
32160
32225
  refreshLocal
32161
32226
  };
@@ -32709,6 +32774,11 @@ window.__ModuleLoader__.load({
32709
32774
  separator: item.separator,
32710
32775
  onClick: () => item.run(menu.target, ctx)
32711
32776
  })) : [];
32777
+ /** @private @author ddj 2026年10月15号 Open the existing update window for the current project root. */
32778
+ function updateProject() {
32779
+ ctx?.openSvnUpdate?.("");
32780
+ }
32781
+ const updateHint = !ctx?.svn?.svnCli ? "SVN CLI 不可用" : !ctx?.openSvnUpdate ? "SVN 更新窗口不可用" : "更新项目(打开 SVN 更新窗口)";
32712
32782
  const errorList = Object.entries(errors);
32713
32783
  const errorText = errorList.length ? errorList[0][1] : null;
32714
32784
  return react.default.createElement("div", {
@@ -32720,11 +32790,11 @@ window.__ModuleLoader__.load({
32720
32790
  }, rootName), react.default.createElement("span", { style: { flex: 1 } }), ctx?.svn?.managed ? react.default.createElement(_deepseek_ai_dsh_client_ui_primitives.Button, {
32721
32791
  variant: "toolbar",
32722
32792
  size: "sm",
32723
- disabled: !svn.canCheck || svn.busy,
32724
- title: "检查仓库更新(只读;不会执行 svn update)",
32725
- onClick: svn.checkRemote,
32726
- "aria-label": "检查仓库更新"
32727
- }, svn.busy ? "…" : "↓") : null, react.default.createElement("button", {
32793
+ disabled: !ctx.svn.svnCli || !ctx.openSvnUpdate,
32794
+ title: updateHint,
32795
+ onClick: updateProject,
32796
+ "aria-label": "更新项目"
32797
+ }, "↓") : null, react.default.createElement("button", {
32728
32798
  className: "edrv-side-btn",
32729
32799
  title: "刷新目录树",
32730
32800
  onClick: () => emitRefresh({
@@ -35190,6 +35260,11 @@ window.__ModuleLoader__.load({
35190
35260
  revert: onRevert
35191
35261
  })
35192
35262
  });
35263
+ /** @private @author ddj 2026年10月15号 Open the shared update window independently of selection and local changes. */
35264
+ function updateProject() {
35265
+ ctxRef.current?.openSvnUpdate?.("");
35266
+ }
35267
+ const updateHint = !managed ? "SVN CLI 或工作副本不可用" : !ctx?.openSvnUpdate ? "SVN 更新窗口不可用" : "更新项目(打开 SVN 更新窗口)";
35193
35268
  const rootName = ctx?.svn?.wcRoot ? String(ctx.svn.wcRoot).split(/[\\/]/).pop() || ctx.svn.wcRoot : "";
35194
35269
  const remoteEl = remote === null ? null : react.default.createElement("div", { className: "edrv-svn-hintbar" + (remote.failed ? " edrv-svn-hintbar-warn" : "") }, react.default.createElement("span", { style: { flex: 1 } }, remote.failed ? "远端检查失败(网络不可达或超时;可用 ⟳ 或「检查远端」重试)" : remote.outdated.length ? "远端有 " + remote.outdated.length + " 个更新(against r" + (remote.againstRev ?? "?") + "),其中本地已改 " + remote.outdated.filter((item) => item.path && versionedPathSet.has(item.path)).length + " 个;更新前请先提交或还原" : "远端无更新(against r" + (remote.againstRev ?? "?") + ")"), react.default.createElement("button", {
35195
35270
  className: "edrv-svn-act",
@@ -35225,6 +35300,12 @@ window.__ModuleLoader__.load({
35225
35300
  className: "edrv-side-root",
35226
35301
  title: ctx?.svn?.wcRoot || ""
35227
35302
  }, rootName), react.default.createElement("span", { style: { flex: 1 } }), react.default.createElement("span", { className: "edrv-svn-head-icons" }, react.default.createElement("button", {
35303
+ className: "edrv-side-btn",
35304
+ title: updateHint,
35305
+ "aria-label": "更新项目",
35306
+ disabled: !managed || !ctx?.openSvnUpdate,
35307
+ onClick: updateProject
35308
+ }, "↓"), react.default.createElement("button", {
35228
35309
  className: "edrv-side-btn",
35229
35310
  title: "检查远端更新(svn status -u;约数秒,离线自动降级)",
35230
35311
  onClick: checkRemote