dsh-vscode-mode 0.15.2 → 0.15.3

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
@@ -464,13 +464,13 @@ profile 请替换为实际目标,不要把示例目录当成当前运行 profi
464
464
 
465
465
  ```bash
466
466
  # ① Git 安装(clone + prepare 构建;推荐打固定 tag)
467
- dsh plugin --profile web add github:Lenonss/DSH_VsCodeMode#v0.15.2
467
+ dsh plugin --profile web add github:Lenonss/DSH_VsCodeMode#v0.15.3
468
468
 
469
469
  # ② npm 注册表(发布到 npm 后)
470
- dsh plugin --profile web add dsh-vscode-mode@0.15.2
470
+ dsh plugin --profile web add dsh-vscode-mode@0.15.3
471
471
 
472
472
  # ③ GitHub Release tgz 直装(Release asset 可用后)
473
- dsh plugin --profile web add https://github.com/Lenonss/DSH_VsCodeMode/releases/download/v0.15.2/dsh-vscode-mode-0.15.2.tgz
473
+ dsh plugin --profile web add https://github.com/Lenonss/DSH_VsCodeMode/releases/download/v0.15.3/dsh-vscode-mode-0.15.3.tgz
474
474
  ```
475
475
 
476
476
  > **DSH 版本政策(0.14.10 起)**:六项 DSH peer 统一声明为 `*`,不再维护逐版
@@ -808,6 +808,8 @@ Keep All / Undo All 却是亮的。修复:单文件 Keep / Undo 覆盖冲突
808
808
  完整变更见 [GitHub Releases](https://github.com/Lenonss/DSH_VsCodeMode/releases)。
809
809
  近期关键版本:
810
810
 
811
+ - **v0.15.3**:**搜索结果强制刷新**——目标文件内容被改动后,工作区搜索不再残留过期匹配:内容变更(编辑器保存、外部改动或结构变更)会自动重新执行当前查询,同关键词重搜不再命中 60 秒结果缓存(`edrv.searchContent` 新增 `force` 选项,仅本次调用跳过缓存读取、仍写入新结果)。更新后需重启 DSH Host;真实 GUI 现场重测尚未执行,发布不代表现场验收完成,详见 [0.15.3 发布说明](docs/release-0.15.3.md)。
812
+
811
813
  - **v0.15.2**:**SVN 更新窗口排序与冲突操作**——操作、路径、类型列支持升降序切换;存在冲突时右下角显示跳转按钮,按当前排序循环定位未解决项。冲突项右键提供使用对方/自身完整文件解决、标记解决与还原,操作前确认、操作后重读 SVN 状态;属性与树冲突按实际支持能力提供操作,避免误用文本冲突策略。覆盖排序、DOM 交互与真实 SVN 冲突回归。真实 GUI 尚未验收;发布不代表当前实例已升级。
812
814
 
813
815
  - **v0.15.0**:**文件页签拖拽与多编辑组**——拖拽重排、跨组移动、四向分屏、页面内可移动浮窗,以及拖入当前 DSH 输入框添加文件引用(不自动发送)。保留编辑缓冲与视图状态,关闭浮窗将文件归回主组;拖拽落点预览跟随主题、25% 不透明度、无描边。保留 v0.14.13 的资源管理器跟随功能,详见 [0.15.0 发布说明](docs/release-0.15.0.md)。
package/lib/client.js CHANGED
@@ -32595,6 +32595,8 @@ window.__ModuleLoader__.load({
32595
32595
  * 作者 ddj 2026-08-26
32596
32596
  */
32597
32597
  const DEBOUNCE_MS = 250;
32598
+ /** 文件变更后的重搜去抖:合并一次写盘的 refresh+file-changed 双事件与批量保存。 */
32599
+ const REFRESH_DEBOUNCE_MS = 300;
32598
32600
  const INCLUDE_PLACEHOLDER = "例如 *.ts, src/**/include";
32599
32601
  /**
32600
32602
  * 逗号切分 glob 列表(trim + 去空)。
@@ -32633,6 +32635,28 @@ window.__ModuleLoader__.load({
32633
32635
  }
32634
32636
  }
32635
32637
  /**
32638
+ * 判断文件变化通知是否属于本面板作用域。
32639
+ * @author ddj 2026年10月14号
32640
+ * @param detail 事件 detail(scope 可缺省)
32641
+ * @param scope 本面板作用域
32642
+ * @returns 是否触发重搜
32643
+ */
32644
+ function noticeInScope(detail, scope) {
32645
+ const changed = detail?.scope;
32646
+ return !changed || changed === scope;
32647
+ }
32648
+ /**
32649
+ * 判断文件变化通知是否可能改变内容搜索命中。
32650
+ * 文件增删改名(structure)会增删命中,一并重搜;SVN 状态刷新(svn)不代表内容变化,跳过以免无谓全库扫描。
32651
+ * @author ddj 2026年10月14号
32652
+ * @param detail 事件 detail(kind 可缺省)
32653
+ * @returns 是否触发重搜
32654
+ */
32655
+ function noticeTouchesContent(detail) {
32656
+ const kind = detail?.kind;
32657
+ return !kind || kind === "text" || kind === "structure";
32658
+ }
32659
+ /**
32636
32660
  * 命中行文本三段切分(before/命中/after,列为 1-based UTF-16)。
32637
32661
  * @param text 行文本
32638
32662
  * @param start 起始列
@@ -32681,6 +32705,7 @@ window.__ModuleLoader__.load({
32681
32705
  queryRef.current = query;
32682
32706
  const activePathRef = react.default.useRef(activePath);
32683
32707
  activePathRef.current = activePath;
32708
+ const refreshTimerRef = react.default.useRef(null);
32684
32709
  const requestRef = react.default.useRef({
32685
32710
  matchCase,
32686
32711
  wholeWord,
@@ -32746,9 +32771,11 @@ window.__ModuleLoader__.load({
32746
32771
  ]);
32747
32772
  /**
32748
32773
  * 执行内容搜索(请求参数从 ref 读最新值)。
32774
+ * @author ddj 2026年10月14号
32749
32775
  * @param text 搜索词
32776
+ * @param force 是否强制绕过 host 短期缓存(文件变更后的重搜必须读最新磁盘内容)
32750
32777
  */
32751
- const runSearch = (text) => {
32778
+ const runSearch = (text, force) => {
32752
32779
  const s = ++seqRef.current;
32753
32780
  const clean = String(text ?? "").trim();
32754
32781
  if (clean.length < 2) {
@@ -32775,7 +32802,8 @@ window.__ModuleLoader__.load({
32775
32802
  wholeWord: req.wholeWord,
32776
32803
  regex: req.regex,
32777
32804
  include: req.include,
32778
- exclude: req.exclude
32805
+ exclude: req.exclude,
32806
+ ...force === true ? { force: true } : {}
32779
32807
  }).then((res) => {
32780
32808
  if (s !== seqRef.current) return;
32781
32809
  if (res && res.ok) {
@@ -32795,6 +32823,8 @@ window.__ModuleLoader__.load({
32795
32823
  setStatus("error");
32796
32824
  });
32797
32825
  };
32826
+ const runSearchRef = react.default.useRef(runSearch);
32827
+ runSearchRef.current = runSearch;
32798
32828
  /**
32799
32829
  * 输入变化:防抖触发搜索。
32800
32830
  * @param value 新输入
@@ -32901,6 +32931,26 @@ window.__ModuleLoader__.load({
32901
32931
  window.addEventListener("edrv:search-focus", onFocus);
32902
32932
  return () => window.removeEventListener("edrv:search-focus", onFocus);
32903
32933
  }, []);
32934
+ react.default.useEffect(() => {
32935
+ /** @private @author ddj 2026年10月14号 @description 合并同一次写盘的多条通知后强制重搜 */
32936
+ const onChanged = (event) => {
32937
+ const detail = event?.detail ?? {};
32938
+ if (!noticeInScope(detail, scope)) return;
32939
+ if (!noticeTouchesContent(detail)) return;
32940
+ if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current);
32941
+ refreshTimerRef.current = setTimeout(() => runSearchRef.current(queryRef.current, true), REFRESH_DEBOUNCE_MS);
32942
+ };
32943
+ window.addEventListener("edrv:file-changed", onChanged);
32944
+ window.addEventListener("edrv:refresh", onChanged);
32945
+ return () => {
32946
+ window.removeEventListener("edrv:file-changed", onChanged);
32947
+ window.removeEventListener("edrv:refresh", onChanged);
32948
+ if (refreshTimerRef.current) {
32949
+ clearTimeout(refreshTimerRef.current);
32950
+ refreshTimerRef.current = null;
32951
+ }
32952
+ };
32953
+ }, []);
32904
32954
  react.default.useLayoutEffect(() => {
32905
32955
  if (!focusTick) return;
32906
32956
  inputRef.current?.focus?.();