dsh-vscode-mode 0.5.3 → 0.6.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.
Files changed (65) hide show
  1. package/README.md +55 -2
  2. package/lib/client.js +5173 -355
  3. package/lib/client.js.map +1 -1
  4. package/lib/index.js +2356 -126
  5. package/lib/index.js.map +1 -1
  6. package/package.json +1 -1
  7. package/src/client/dap/BpWidget.ts +262 -0
  8. package/src/client/dap/bpMenu.ts +91 -0
  9. package/src/client/dap/bpRowMenu.ts +53 -0
  10. package/src/client/dap/breakpoints.ts +222 -0
  11. package/src/client/dap/decorate.ts +128 -0
  12. package/src/client/dap/hintLine.ts +29 -0
  13. package/src/client/dap/hover.ts +166 -0
  14. package/src/client/dap/hoverMode.ts +159 -0
  15. package/src/client/dap/hoverTree.ts +722 -0
  16. package/src/client/dap/launchInsert.ts +229 -0
  17. package/src/client/dap/launchSnippetProvider.ts +206 -0
  18. package/src/client/dap/modelPath.ts +23 -0
  19. package/src/client/dap/panelSplit.ts +105 -0
  20. package/src/client/dap/pidPick.ts +24 -0
  21. package/src/client/dap/store.ts +571 -0
  22. package/src/client/dap/toolbarDrag.ts +51 -0
  23. package/src/client/dap/trace.ts +22 -0
  24. package/src/client/dap/variableTree.ts +62 -0
  25. package/src/client/index.ts +9 -0
  26. package/src/client/monaco/lsp/index.ts +15 -0
  27. package/src/client/monaco/lsp/providers.ts +2 -0
  28. package/src/client/monaco/theme.ts +15 -0
  29. package/src/client/sidebar/panels/DebugPanel.ts +613 -0
  30. package/src/client/sidebar/panels/SvnPanel.ts +167 -23
  31. package/src/client/sidebar/panels/index.ts +19 -0
  32. package/src/client/sidebar/types.ts +2 -0
  33. package/src/client/styles/editor.css +176 -0
  34. package/src/client/svnActions.ts +18 -1
  35. package/src/client/svnLog.ts +3 -3
  36. package/src/client/svnStatus.ts +140 -2
  37. package/src/client/ui/EditorView.ts +544 -16
  38. package/src/client/ui/SideBySideDiff.tsx +214 -29
  39. package/src/client/ui/SvnDiffPanel.ts +21 -8
  40. package/src/client/ui/SvnLogDialog.ts +44 -2
  41. package/src/client/ui/SvnPatchDialog.ts +63 -0
  42. package/src/client/ui/SvnSumDialog.ts +77 -0
  43. package/src/client/ui/commandCatalog.ts +49 -0
  44. package/src/client/ui/svnExport.ts +71 -0
  45. package/src/dap/configSnippets.ts +269 -0
  46. package/src/dap/discovery.ts +198 -0
  47. package/src/dap/launchConfig.ts +127 -0
  48. package/src/dap/manager.ts +588 -0
  49. package/src/dap/processList.ts +76 -0
  50. package/src/dap/protocol.ts +80 -0
  51. package/src/dap/provider.ts +49 -0
  52. package/src/dap/rpc.ts +192 -0
  53. package/src/dap/sourcePath.ts +82 -0
  54. package/src/index.ts +7 -3
  55. package/src/lsp/providers.ts +3 -2
  56. package/src/reveal.ts +31 -20
  57. package/src/rpc.ts +11 -3
  58. package/src/search/ripgrep.ts +127 -11
  59. package/src/shared/dap.ts +262 -0
  60. package/src/shared/keybindings.ts +7 -0
  61. package/src/shared/rpc.ts +40 -2
  62. package/src/shared/svn.ts +147 -0
  63. package/src/shared/svnActions.ts +20 -0
  64. package/src/svn.ts +320 -11
  65. package/src/workspace.ts +0 -75
@@ -0,0 +1,62 @@
1
+ /**
2
+ * dsh-vscode-mode client — DAP 变量树纯函数。
3
+ * 把 DAP variablesReference 缓存展平成可渲染 sibling rows,避免把子行嵌套进父级
4
+ * 横向 flex 行导致变量重叠;同时限制递归深度与总行数,保护侧栏性能。
5
+ * 作者 ddj 2026年09月29号
6
+ */
7
+
8
+ /** DAP 变量最小视图。 */
9
+ export interface VariableLike {
10
+ name: string
11
+ value: string
12
+ type?: string
13
+ ref: number
14
+ }
15
+
16
+ /** 展平后的变量行。 */
17
+ export interface VariableRow {
18
+ key: string
19
+ variable: VariableLike
20
+ depth: number
21
+ }
22
+
23
+ /** 展平选项。 */
24
+ export interface VariableTreeOptions {
25
+ maxRows?: number
26
+ maxDepth?: number
27
+ }
28
+
29
+ /**
30
+ * 将变量树展平为 sibling rows;循环 ref 只展开一次,避免异常适配器数据造成递归。
31
+ * @author ddj 2026年09月29号
32
+ * @param roots 根变量
33
+ * @param expanded 已展开的 variablesReference
34
+ * @param cache ref → 子变量缓存
35
+ * @param options 行数/深度上限
36
+ */
37
+ export function flattenVariableRows(
38
+ roots: readonly VariableLike[],
39
+ expanded: ReadonlySet<number>,
40
+ cache: ReadonlyMap<number, readonly VariableLike[]>,
41
+ options: VariableTreeOptions = {},
42
+ ): VariableRow[] {
43
+ const rows: VariableRow[] = []
44
+ const maxRows = options.maxRows ?? 1000
45
+ const maxDepth = options.maxDepth ?? 32
46
+ const walk = (items: readonly VariableLike[], depth: number, ancestry: ReadonlySet<number>, prefix: string): void => {
47
+ if (depth > maxDepth || rows.length >= maxRows) return
48
+ for (let index = 0; index < items.length && rows.length < maxRows; index += 1) {
49
+ const variable = items[index]
50
+ const key = prefix + '/' + index + ':' + variable.name
51
+ rows.push({ key, variable, depth })
52
+ if (variable.ref <= 0 || !expanded.has(variable.ref) || ancestry.has(variable.ref)) continue
53
+ const children = cache.get(variable.ref)
54
+ if (!children?.length) continue
55
+ const nextAncestry = new Set(ancestry)
56
+ nextAncestry.add(variable.ref)
57
+ walk(children, depth + 1, nextAncestry, key)
58
+ }
59
+ }
60
+ walk(roots, 0, new Set(), 'root')
61
+ return rows
62
+ }
@@ -41,6 +41,7 @@ import { createFilePanel } from './sidebar/panels/index.js'
41
41
  import { createSearchPanel } from './sidebar/panels/index.js'
42
42
  import { createRulesPanel } from './sidebar/panels/index.js'
43
43
  import { createSvnPanel } from './sidebar/panels/index.js'
44
+ import { createDebugPanel } from './sidebar/panels/index.js'
44
45
  import { createTreeMenuRegistry } from './sidebar/contextMenu.js'
45
46
  import { createDefaultFileMenuItems } from './sidebar/menuItems.js'
46
47
  import { createOutlinePanel } from './outline/index.js'
@@ -54,8 +55,10 @@ import { editorLimitApply } from './editorLimit.js'
54
55
  import { log } from './log.js'
55
56
  import { setupLsp, setSession, disposeLsp } from './monaco/lsp/index.js'
56
57
  import { disposeSnippets } from './snippets/provider.js'
58
+ import { disposeLaunchJson } from './dap/launchSnippetProvider.js'
57
59
  import { disposeAiInline } from './ai/inlineProvider.js'
58
60
  import { readSessionScope, subscribeScope } from './sessionScope.js'
61
+ import { dapStore } from './dap/store.js'
59
62
  import type { CompatAdapter } from '../shared/compat.js'
60
63
 
61
64
  // ⚠️ inject 只列必需服务:webUiSettings 是 @linxin666/dsh-client-ui-web-ui-settings 提供的
@@ -194,6 +197,11 @@ export function apply(ctx: any): void {
194
197
  ctx.effect(() => sidebarPanels.register(createRulesPanel()), 'vscode-mode: sidebar panel rules')
195
198
  // SVN 变更面板:活动栏「SVN 变更」页签(工作副本状态列表;visible 守卫使非 SVN 工作区不出现)
196
199
  ctx.effect(() => sidebarPanels.register(createSvnPanel()), 'vscode-mode: sidebar panel svn')
200
+ // 调试面板:活动栏「调试」页签(VS Code 调试视图四段布局 + REPL;DAP 桥接)
201
+ ctx.effect(() => sidebarPanels.register(createDebugPanel()), 'vscode-mode: sidebar panel debug')
202
+ // 客户端(重)装配对账:host 的 DapSession 常驻,而本模块状态随刷新/HMR 归零,
203
+ // 不对账则调试面板与暂停态 hover 静默失效(见 dapStore.resync)。
204
+ void dapStore.resync()
197
205
  // 文件右键菜单项注册表(对外 provide,供本插件/第三方注册;内置「在文件浏览器中打开」)
198
206
  const fileMenuItems = createTreeMenuRegistry()
199
207
  ctx.provide('edrvFileContextMenuItems', fileMenuItems)
@@ -448,6 +456,7 @@ export function apply(ctx: any): void {
448
456
  // 不做会导致重载后重复注册(补全/跳转/hover 各翻倍)与陈旧开关残留。
449
457
  ctx.effect(() => () => {
450
458
  try { disposeSnippets() } catch { /* 卸载异常不得阻断其余清理 */ }
459
+ try { disposeLaunchJson() } catch { /* 同上 */ }
451
460
  try { disposeAiInline() } catch { /* 同上 */ }
452
461
  try { disposeLsp() } catch { /* 同上 */ }
453
462
  }, 'vscode-mode: monaco providers teardown')
@@ -6,6 +6,9 @@
6
6
  * 作者 ddj 2026-08-27
7
7
  */
8
8
  import { registerLspProviders, disposeLspProviders, hideReferencesOverlay } from './providers.js'
9
+ import { registerDapHover, disposeDapHover } from '../../dap/hover.js'
10
+ import { installHoverTree, disposeHoverTree } from '../../dap/hoverTree.js'
11
+ import { installHoverMode, disposeHoverMode } from '../../dap/hoverMode.js'
9
12
  import { setLspSession, refreshStatus, lspStatusFor, onLspProgress, bindLspSession } from './lspClient.js'
10
13
 
11
14
  let monacoRef = null
@@ -19,7 +22,16 @@ const LSP_SESSION_GLOBAL = '__edrvLspSessionUnbind__'
19
22
  /** Monaco 加载后装配(幂等;重复调用仅刷新会话)。 */
20
23
  export function setupLsp(monaco) {
21
24
  monacoRef = monaco
25
+ // 注册顺序决定同分 provider 的 ordinal:LanguageFeatureRegistry._compareByScoreAndTime 对
26
+ // 同分选择器按 _time 倒序(后注册者排前),hover 部件再按 ordinal 升序渲染 —— 因此 DAP
27
+ // 必须**最后**注册,暂停态的调试值行才会稳定渲染在 LSP 文档行之前;反序会让调试值被
28
+ // LSP 长文档挤到浮窗下方(超出 maxHeight 需滚动,等同看不到)。
22
29
  registerLspProviders(monaco)
30
+ registerDapHover(monaco)
31
+ // hover 变量树的 DOM 绑定(观察 hover 面板插入/重渲染;幂等)
32
+ installHoverTree()
33
+ // Alt 跟踪:暂停态默认调试值浮窗、按住 Alt 切 LSP 信息(对齐 CodeBuddy)
34
+ installHoverMode()
23
35
  // 会话广播订阅只装一次:跨重载时上一代已订阅(取消函数落 window,模块级状态会复位),
24
36
  // 只判 sessionBound 会重复订阅 → 同一 LSP 会话事件被处理多次。
25
37
  const host = /* @__PURE__ */ (typeof window === 'undefined' ? undefined : window)
@@ -52,6 +64,9 @@ export function disposeLspOverlay() {
52
64
  */
53
65
  export function disposeLsp() {
54
66
  disposeLspProviders()
67
+ disposeDapHover()
68
+ disposeHoverTree()
69
+ disposeHoverMode()
55
70
  const unbind = sessionUnbind
56
71
  if (typeof unbind === 'function') {
57
72
  try { unbind() } catch { /* 已解绑 */ }
@@ -136,6 +136,8 @@ export function registerLspProviders(monaco) {
136
136
  }),
137
137
  monaco.languages.registerHoverProvider(LSP_LANGS, {
138
138
  provideHover: async (model, position, token) => {
139
+ // 暂停态的 LSP 行由调试 hover 层默认隐藏、按住 Alt 时显示(见 dap/hoverTree.ts),
140
+ // 因此这里照常返回内容,不再按位置让位。
139
141
  const path = pathOfModel(model)
140
142
  if (!path) return null
141
143
  const hover = await fetchHover(path, model.getValue(), position)
@@ -137,6 +137,14 @@ const DARK_COLORS = {
137
137
  'scrollbarSlider.background': '#79797966',
138
138
  'scrollbarSlider.hoverBackground': '#646464b3',
139
139
  'scrollbarSlider.activeBackground': '#bfbfbf66',
140
+ // 差异视图色块(本仓库 vendored Monaco 无 .line-insert 静态背景规则,靠主题键保证;
141
+ // 色相取自研差异 UI 同源:绿 #0f9d58 / 红 #d9534f,alpha 提到肉眼可辨)
142
+ 'diffEditor.insertedLineBackground': '#0f9d5830',
143
+ 'diffEditor.removedLineBackground': '#d9534f2e',
144
+ 'diffEditor.insertedTextBackground': '#0f9d5833',
145
+ 'diffEditor.removedTextBackground': '#d9534f40',
146
+ 'diffEditorGutter.insertedLineBackground': '#0f9d5859',
147
+ 'diffEditorGutter.removedLineBackground': '#d9534f59',
140
148
  }
141
149
 
142
150
  const LIGHT_COLORS = {
@@ -157,6 +165,13 @@ const LIGHT_COLORS = {
157
165
  'scrollbarSlider.background': '#64646466',
158
166
  'scrollbarSlider.hoverBackground': '#646464b3',
159
167
  'scrollbarSlider.activeBackground': '#00000099',
168
+ // 差异视图色块(同上:主题键保证整行背景可见;色相/透明度与暗色一致)
169
+ 'diffEditor.insertedLineBackground': '#0f9d5830',
170
+ 'diffEditor.removedLineBackground': '#d9534f2e',
171
+ 'diffEditor.insertedTextBackground': '#0f9d5833',
172
+ 'diffEditor.removedTextBackground': '#d9534f40',
173
+ 'diffEditorGutter.insertedLineBackground': '#0f9d5859',
174
+ 'diffEditorGutter.removedLineBackground': '#d9534f59',
160
175
  }
161
176
 
162
177
  /**