dsh-vscode-mode 0.1.6 → 0.1.10
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 +243 -47
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
- package/src/client/monaco/diffRender.ts +17 -2
- package/src/client/monaco/loader.ts +56 -9
- package/src/client/styles/editor.css +16 -2
- package/src/client/ui/EditorView.ts +114 -19
package/lib/client.js
CHANGED
|
@@ -29,7 +29,7 @@ window.__ModuleLoader__.load({
|
|
|
29
29
|
let react = require("react");
|
|
30
30
|
react = __toESM(react, 1);
|
|
31
31
|
//#region \0dsh-css:/home/runner/work/DSH_VsCodeMode/DSH_VsCodeMode/src/client/styles/editor.css.mjs
|
|
32
|
-
const css = "/* dsh-vscode-mode 编辑区样式(原 ensureEdrvStyles 字符串,落盘为真 .css,由 tsdown CSS-inline 注入) */\n/* 浅色主题(对齐参考图:#f8f8f8 近白底 + 薄荷绿药丸 + 青绿文字 + 三文鱼 undo + 浅灰边框):\n 在 [data-edrv-view] 作用域内重定义 --dsw-alias-*,级联命中组件内联样式与 CSS。 */\n[data-edrv-view] { --edrv-tab-h: 34px; --dsw-alias-bg-base: #f8f8f8; --dsw-alias-bg-layer-1: #ffffff; --dsw-alias-bg-layer-2: #f0f4f4; --dsw-alias-bg-overlay: #ffffff; --dsw-alias-label-primary: #1f2933; --dsw-alias-label-secondary: #52606d; --dsw-alias-label-tertiary: #9aa5b1; --dsw-alias-border-l1: #e0e6e8; --dsw-alias-border-l2: #cbd2d9; --dsw-alias-brand-primary: #0f9d58; --dsw-alias-state-success-primary: #0f9d58; --dsw-alias-state-error-primary: #d9534f; --dsw-alias-state-warn-primary: #d97706; --dsw-alias-interactive-bg-hover: rgba(15,157,88,.08); }\n\n[data-edrv-view] .edrv-tabs { display: flex; align-items: center; gap: 2px; padding: 2px 8px 0; background: var(--dsw-alias-bg-layer-1, transparent); overflow-x: auto; scrollbar-width: thin; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 8px 0 12px; border: none; border-radius: 6px 6px 0 0; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); font-size: 12px; cursor: pointer; white-space: nowrap; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-tab.edrv-tab-active { background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); box-shadow: inset 0 -2px 0 var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-tab .edrv-tab-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--dsw-alias-brand-primary, #4f8cff); flex-shrink: 0; }\n[data-edrv-view] .edrv-tab .edrv-tab-x { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 4px; color: var(--dsw-alias-label-tertiary, #888); font-size: 11px; }\n[data-edrv-view] .edrv-tab .edrv-tab-x:hover { background: rgba(255,255,255,.12); color: var(--dsw-alias-label-primary, #eee); }\n[data-edrv-view] .edrv-tab-add { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin-left: 2px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); font-size: 14px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab-add:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-pathbar { display: flex; align-items: center; gap: 8px; height: 26px; padding: 0 10px; background: var(--dsw-alias-bg-layer-1, #ffffff); border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); font-size: 12px; flex-shrink: 0; overflow: hidden; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-name { font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-full { flex: 1; min-width: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; direction: rtl; text-align: left; }\n[data-edrv-view] .edrv-path-input { flex: 1; min-width: 140px; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search-wrap { position: relative; flex-shrink: 0; display: flex; align-items: center; padding: 2px 8px 2px 4px; }\n[data-edrv-view] .edrv-search { width: 190px; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-pop { position: absolute; top: calc(100% + 4px); right: 8px; width: min(460px, calc(100vw - 24px)); max-height: 300px; overflow: auto; background: var(--dsw-alias-bg-overlay, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 10px; box-shadow: 0 6px 20px rgba(0,0,0,.4); z-index: 60; padding: 4px; }\n[data-edrv-view] .edrv-search-item { display: flex; flex-direction: column; gap: 1px; padding: 5px 8px; border-radius: 6px; cursor: pointer; }\n[data-edrv-view] .edrv-search-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.07)); }\n[data-edrv-view] .edrv-search-item .n { color: var(--dsw-alias-label-primary, #eee); font-size: 12px; word-break: break-all; }\n[data-edrv-view] .edrv-search-item .d { color: var(--dsw-alias-label-tertiary, #888); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-search-empty { padding: 8px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #888); }\n[data-edrv-view] .edrv-btn-mini { font-size: 11px; padding: 2px 9px; border: none; border-radius: 999px; cursor: pointer; color: #fff; font-weight: 600; white-space: nowrap; }\n[data-edrv-view] .edrv-btn-keep { background: var(--dsw-alias-state-success-primary, #2e9e44); }\n[data-edrv-view] .edrv-btn-undo { background: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-btn-mini:disabled { opacity: .45; cursor: default; }\n[data-edrv-view] .edrv-statusbar { display: flex; align-items: center; gap: 10px; padding: 3px 10px; border-top: 1px solid var(--dsw-alias-border-l1, #333); background: var(--dsw-alias-bg-layer-1, transparent); font-size: 11px; color: var(--dsw-alias-label-tertiary, #888); flex-shrink: 0; white-space: nowrap; overflow: hidden; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-path { flex: 1; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-diffchip { font-size: 11px; padding: 2px 10px; border: 1px solid var(--dsw-alias-border-l1, #333); border-radius: 999px; background: var(--dsw-alias-bg-layer-2, transparent); color: var(--dsw-alias-state-warn-primary, #b7791f); cursor: pointer; white-space: nowrap; flex-shrink: 0; }\n[data-edrv-view] .edrv-chip-btn { font-size: 12px; padding: 2px 6px; border: none; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); cursor: pointer; border-radius: 4px; flex-shrink: 0; }\n[data-edrv-view] .edrv-chip-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-mn-add-line { background: rgba(15,157,88,.10); }\n[data-edrv-view] .edrv-mn-gutter-add { color: #0f9d58 !important; font-weight: 700; display: flex !important; align-items: center; justify-content: center; }\n[data-edrv-view] .edrv-mn-gutter-add::before { content: \"+\"; }\n[data-edrv-view] .edrv-del-zone { background: #fdeaea; border-top: 1px solid rgba(217,83,79,.35); border-bottom: 1px solid rgba(217,83,79,.35); box-shadow: inset 0 0 0 1px rgba(217,83,79,.12); }\n[data-edrv-view] .edrv-del-row { white-space: pre; font-family: var(--ds-font-family-code, ui-monospace, monospace); font-size: 12.5px; line-height: 20px; color: #c0392b; }\n[data-edrv-view] .edrv-del-text { display: inline-block; white-space: pre; }\n[data-edrv-view] .edrv-minus-overlay { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 6; }\n[data-edrv-view] .edrv-minus-item { position: absolute; width: 16px; text-align: center; color: #d9534f; font-weight: 700; font-size: 12.5px; line-height: 20px; }\n[data-edrv-view] .edrv-monaco-host { flex: 1; min-height: 0; position: relative; }\n[data-edrv-view] .edrv-monaco-host > div { position: absolute; inset: 0; }\n[data-edrv-view] .edrv-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; height: 100%; color: var(--dsw-alias-label-tertiary, #777); font-size: 13px; }\n[data-edrv-view] .edrv-diffbar { position: absolute; left: 0; right: 0; bottom: 10px; margin: 0 auto; z-index: 25; width: fit-content; max-width: calc(100% - 20px); border-radius: 10px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 4px 16px rgba(31,41,51,.12); overflow: visible; display: flex; flex-direction: column; }\n[data-edrv-view] .edrv-diffbar-row { display: flex; align-items: center; gap: 6px; height: 34px; padding: 0 8px; flex-wrap: nowrap; }\n[data-edrv-view] .edrv-diffbar-count { font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); min-width: 42px; text-align: center; white-space: nowrap; cursor: pointer; }\n[data-edrv-view] .edrv-diffbar-count.edrv-count-file { min-width: 64px; cursor: default; }\n[data-edrv-view] .edrv-diffbar-file { flex: 1; min-width: 0; font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-pill { font-size: 11px; padding: 3px 10px; border: none; border-radius: 999px; cursor: pointer; white-space: nowrap; font-weight: 600; }\n[data-edrv-view] .edrv-pill-keep { background: #e8f8e8; color: #0f7a45; border: 1px solid rgba(15,157,88,.4); }\n[data-edrv-view] .edrv-pill-undo { background: #fdeaea; color: #c0392b; border: 1px solid rgba(217,83,79,.4); }\n[data-edrv-view] .edrv-pill-ghost { background: #ffffff; color: var(--dsw-alias-label-secondary, #52606d); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-pill:disabled { opacity: .45; cursor: default; }\n[data-edrv-view] .edrv-diffbar-menu { position: absolute; right: 8px; bottom: calc(100% + 6px); z-index: 45; min-width: 160px; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 6px 20px rgba(31,41,51,.16); padding: 4px; display: flex; flex-direction: column; gap: 2px; }\n[data-edrv-view] .edrv-diffmenu-item { display: flex; align-items: center; gap: 8px; font-size: 12px; padding: 6px 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; text-align: left; }\n[data-edrv-view] .edrv-diffmenu-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-diffmenu-item.danger { color: var(--dsw-alias-state-error-primary, #d9534f); }\n[data-edrv-view] .edrv-diffmenu-sep { height: 1px; margin: 2px 4px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-diffbar-body { max-height: 130px; max-width: min(560px, calc(100vw - 40px)); overflow: auto; padding: 4px 8px 8px; display: flex; flex-direction: column; gap: 4px; border-top: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-diffrow { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 6px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); cursor: pointer; flex-wrap: wrap; }\n[data-edrv-view] .edrv-diffrow:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-diffrow-l { font-size: 11px; color: var(--dsw-alias-label-primary, #1f2933); min-width: 74px; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-o { font-size: 11px; color: var(--dsw-alias-state-error-primary, #d9534f); font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-n { font-size: 11px; color: var(--dsw-alias-state-success-primary, #0f9d58); font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-tag { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-diffrow-stale { border-color: rgba(217,119,6,.5); cursor: default; }\n[data-edrv-view] .edrv-diffbox-others { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 4px 2px 0; border-top: 1px solid var(--dsw-alias-border-l1, #e0e6e8); margin-top: 2px; }\n[data-edrv-view] .edrv-diffrow-file { font-size: 11px; padding: 2px 10px; border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 999px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); cursor: pointer; white-space: nowrap; max-width: 200px; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-diffrow-file:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); color: var(--dsw-alias-label-primary, #1f2933); }\n/* 编辑区 hover 差异块的 Keep/Undo 浮层 */\n[data-edrv-view] .edrv-hoveract { position: absolute; z-index: 30; display: flex; align-items: center; gap: 4px; padding: 2px 6px; border-radius: 8px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 4px 14px rgba(31,41,51,.14); }\n[data-edrv-view] .edrv-launch { position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 40; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #555); box-shadow: 0 6px 24px rgba(0,0,0,.5); display: flex; flex-direction: column; max-height: 60%; overflow: hidden; }\n[data-edrv-view] .edrv-launch-head { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--dsw-alias-border-l1, #333); }\n[data-edrv-view] .edrv-launch-tab { font-size: 12px; padding: 3px 12px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); cursor: pointer; }\n[data-edrv-view] .edrv-launch-tab.on { background: var(--dsw-alias-bg-layer-2, transparent); color: var(--dsw-alias-label-primary, #eee); font-weight: 600; }\n[data-edrv-view] .edrv-launch-body { flex: 1; min-height: 0; overflow: auto; padding: 6px 8px; display: flex; flex-direction: column; gap: 4px; }\n[data-edrv-view] .edrv-launch-row { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1, #333); border-radius: 6px; cursor: pointer; flex-wrap: wrap; }\n[data-edrv-view] .edrv-launch-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-launch-path { flex: 1; min-width: 0; font-size: 12px; color: var(--dsw-alias-label-primary, #eee); word-break: break-all; }\n[data-edrv-view] .edrv-launch-cnt { font-size: 11px; color: var(--dsw-alias-label-tertiary, #888); white-space: nowrap; }\n[data-edrv-view] .edrv-launch-arch { display: flex; flex-direction: column; gap: 6px; }\n[data-edrv-view] .monaco-editor, [data-edrv-view] .monaco-editor .margin, [data-edrv-view] .monaco-editor-background { background: transparent !important; }\n[data-edrv-view] .monaco-editor .scrollbar .slider { background: rgba(128,128,128,.3) !important; }\n";
|
|
32
|
+
const css = "/* dsh-vscode-mode 编辑区样式(原 ensureEdrvStyles 字符串,落盘为真 .css,由 tsdown CSS-inline 注入) */\n/* 浅色主题(对齐参考图:#f8f8f8 近白底 + 薄荷绿药丸 + 青绿文字 + 三文鱼 undo + 浅灰边框):\n 在 [data-edrv-view] 作用域内重定义 --dsw-alias-*,级联命中组件内联样式与 CSS。 */\n[data-edrv-view] { --edrv-tab-h: 34px; --dsw-alias-bg-base: #f8f8f8; --dsw-alias-bg-layer-1: #ffffff; --dsw-alias-bg-layer-2: #f0f4f4; --dsw-alias-bg-overlay: #ffffff; --dsw-alias-label-primary: #1f2933; --dsw-alias-label-secondary: #52606d; --dsw-alias-label-tertiary: #9aa5b1; --dsw-alias-border-l1: #e0e6e8; --dsw-alias-border-l2: #cbd2d9; --dsw-alias-brand-primary: #0f9d58; --dsw-alias-state-success-primary: #0f9d58; --dsw-alias-state-error-primary: #d9534f; --dsw-alias-state-warn-primary: #d97706; --dsw-alias-interactive-bg-hover: rgba(15,157,88,.08); }\n\n[data-edrv-view] .edrv-tabs { display: flex; align-items: center; gap: 2px; padding: 2px 8px 0; background: var(--dsw-alias-bg-layer-1, transparent); overflow-x: auto; scrollbar-width: thin; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 8px 0 12px; border: none; border-radius: 6px 6px 0 0; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); font-size: 12px; cursor: pointer; white-space: nowrap; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-tab.edrv-tab-active { background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); box-shadow: inset 0 -2px 0 var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-tab .edrv-tab-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--dsw-alias-brand-primary, #4f8cff); flex-shrink: 0; }\n[data-edrv-view] .edrv-tab .edrv-tab-x { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 4px; color: var(--dsw-alias-label-tertiary, #888); font-size: 11px; }\n[data-edrv-view] .edrv-tab .edrv-tab-x:hover { background: rgba(255,255,255,.12); color: var(--dsw-alias-label-primary, #eee); }\n[data-edrv-view] .edrv-tab-add { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin-left: 2px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); font-size: 14px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab-add:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-pathbar { display: flex; align-items: center; gap: 8px; height: 26px; padding: 0 10px; background: var(--dsw-alias-bg-layer-1, #ffffff); border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); font-size: 12px; flex-shrink: 0; overflow: hidden; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-name { font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-full { flex: 1; min-width: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; direction: rtl; text-align: left; }\n[data-edrv-view] .edrv-path-input { flex: 1; min-width: 140px; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search-wrap { position: relative; flex-shrink: 0; display: flex; align-items: center; padding: 2px 8px 2px 4px; }\n[data-edrv-view] .edrv-search { width: 190px; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-pop { position: absolute; top: calc(100% + 4px); right: 8px; width: min(460px, calc(100vw - 24px)); max-height: 300px; overflow: auto; background: var(--dsw-alias-bg-overlay, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 10px; box-shadow: 0 6px 20px rgba(0,0,0,.4); z-index: 60; padding: 4px; }\n[data-edrv-view] .edrv-search-item { display: flex; flex-direction: column; gap: 1px; padding: 5px 8px; border-radius: 6px; cursor: pointer; }\n[data-edrv-view] .edrv-search-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.07)); }\n[data-edrv-view] .edrv-search-item .n { color: var(--dsw-alias-label-primary, #eee); font-size: 12px; word-break: break-all; }\n[data-edrv-view] .edrv-search-item .d { color: var(--dsw-alias-label-tertiary, #888); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-search-empty { padding: 8px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #888); }\n[data-edrv-view] .edrv-btn-mini { font-size: 11px; padding: 2px 9px; border: none; border-radius: 999px; cursor: pointer; color: #fff; font-weight: 600; white-space: nowrap; }\n[data-edrv-view] .edrv-btn-keep { background: var(--dsw-alias-state-success-primary, #2e9e44); }\n[data-edrv-view] .edrv-btn-undo { background: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-btn-mini:disabled { opacity: .45; cursor: default; }\n[data-edrv-view] .edrv-statusbar { display: flex; align-items: center; gap: 10px; padding: 3px 10px; border-top: 1px solid var(--dsw-alias-border-l1, #333); background: var(--dsw-alias-bg-layer-1, transparent); font-size: 11px; color: var(--dsw-alias-label-tertiary, #888); flex-shrink: 0; white-space: nowrap; overflow: hidden; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-path { flex: 1; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-diffchip { font-size: 11px; padding: 2px 10px; border: 1px solid var(--dsw-alias-border-l1, #333); border-radius: 999px; background: var(--dsw-alias-bg-layer-2, transparent); color: var(--dsw-alias-state-warn-primary, #b7791f); cursor: pointer; white-space: nowrap; flex-shrink: 0; }\n[data-edrv-view] .edrv-chip-btn { font-size: 12px; padding: 2px 6px; border: none; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); cursor: pointer; border-radius: 4px; flex-shrink: 0; }\n[data-edrv-view] .edrv-chip-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-mn-add-line { background: rgba(15,157,88,.10); }\n[data-edrv-view] .edrv-mn-gutter-add { color: #0f9d58 !important; font-weight: 700; display: flex !important; align-items: center; justify-content: center; }\n[data-edrv-view] .edrv-mn-gutter-add::before { content: \"+\"; }\n[data-edrv-view] .edrv-del-zone { background: #fdeaea; border-top: 1px solid rgba(217,83,79,.35); border-bottom: 1px solid rgba(217,83,79,.35); box-shadow: inset 0 0 0 1px rgba(217,83,79,.12); }\n[data-edrv-view] .edrv-del-row { white-space: pre; font-family: var(--ds-font-family-code, ui-monospace, monospace); font-size: 12.5px; line-height: 20px; color: #c0392b; }\n[data-edrv-view] .edrv-del-text { display: inline-block; white-space: pre; }\n[data-edrv-view] .edrv-minus-overlay { position: absolute; left: 0; top: 0; width: 100%; height: 100%; max-width: 100%; overflow: visible; pointer-events: none; z-index: 6; }\n[data-edrv-view] .edrv-minus-item { position: absolute; box-sizing: border-box; max-width: 100%; overflow: hidden; }\n[data-edrv-view] .edrv-minus-item::before { content: ''; position: absolute; left: 4px; top: 50%; width: 8px; height: 2px; transform: translateY(-50%); border-radius: 2px; background: #d9534f; }\n[data-edrv-view] .edrv-monaco-host { flex: 1; min-height: 0; position: relative; }\n[data-edrv-view] .edrv-monaco-host > div { position: absolute; inset: 0; }\n[data-edrv-view] .edrv-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; height: 100%; color: var(--dsw-alias-label-tertiary, #777); font-size: 13px; }\n[data-edrv-view] .edrv-diffbar { position: absolute; left: 0; right: 0; bottom: 10px; margin: 0 auto; z-index: 25; width: fit-content; max-width: calc(100% - 20px); border-radius: 10px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 4px 16px rgba(31,41,51,.12); overflow: visible; display: flex; flex-direction: column; }\n[data-edrv-view] .edrv-diffbar-row { display: flex; align-items: center; gap: 6px; height: 34px; padding: 0 8px; flex-wrap: nowrap; }\n[data-edrv-view] .edrv-diffbar-count { font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); min-width: 42px; text-align: center; white-space: nowrap; cursor: pointer; }\n[data-edrv-view] .edrv-diffbar-count.edrv-count-file { min-width: 64px; cursor: default; }\n[data-edrv-view] .edrv-diffbar-file { flex: 1; min-width: 0; font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-pill { font-size: 11px; padding: 3px 10px; border: none; border-radius: 999px; cursor: pointer; white-space: nowrap; font-weight: 600; }\n[data-edrv-view] .edrv-pill-keep { background: #e8f8e8; color: #0f7a45; border: 1px solid rgba(15,157,88,.4); }\n[data-edrv-view] .edrv-pill-undo { background: #fdeaea; color: #c0392b; border: 1px solid rgba(217,83,79,.4); }\n[data-edrv-view] .edrv-pill-ghost { background: #ffffff; color: var(--dsw-alias-label-secondary, #52606d); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-pill:disabled { opacity: .45; cursor: default; }\n[data-edrv-view] .edrv-diffbar-menu { position: absolute; right: 8px; bottom: calc(100% + 6px); z-index: 45; min-width: 160px; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 6px 20px rgba(31,41,51,.16); padding: 4px; display: flex; flex-direction: column; gap: 2px; }\n[data-edrv-view] .edrv-diffmenu-item { display: flex; align-items: center; gap: 8px; font-size: 12px; padding: 6px 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; text-align: left; }\n[data-edrv-view] .edrv-diffmenu-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-diffmenu-item.danger { color: var(--dsw-alias-state-error-primary, #d9534f); }\n[data-edrv-view] .edrv-diffmenu-sep { height: 1px; margin: 2px 4px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-diffbar-body { max-height: 130px; max-width: min(560px, calc(100vw - 40px)); overflow: auto; padding: 4px 8px 8px; display: flex; flex-direction: column; gap: 4px; border-top: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-diffrow { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 6px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); cursor: pointer; flex-wrap: wrap; }\n[data-edrv-view] .edrv-diffrow:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-diffrow-l { font-size: 11px; color: var(--dsw-alias-label-primary, #1f2933); min-width: 74px; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-o { font-size: 11px; color: var(--dsw-alias-state-error-primary, #d9534f); font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-n { font-size: 11px; color: var(--dsw-alias-state-success-primary, #0f9d58); font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-tag { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-diffrow-stale { border-color: rgba(217,119,6,.5); cursor: default; }\n[data-edrv-view] .edrv-diffbox-others { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 4px 2px 0; border-top: 1px solid var(--dsw-alias-border-l1, #e0e6e8); margin-top: 2px; }\n[data-edrv-view] .edrv-diffrow-file { font-size: 11px; padding: 2px 10px; border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 999px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); cursor: pointer; white-space: nowrap; max-width: 200px; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-diffrow-file:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); color: var(--dsw-alias-label-primary, #1f2933); }\n/* 编辑区 hover 差异块的 Keep/Undo 浮层 */\n[data-edrv-view] .edrv-hoveract { position: absolute; z-index: 30; display: flex; align-items: center; gap: 4px; padding: 2px 6px; border-radius: 8px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 4px 14px rgba(31,41,51,.14); }\n[data-edrv-view] .edrv-launch { position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 40; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #555); box-shadow: 0 6px 24px rgba(0,0,0,.5); display: flex; flex-direction: column; max-height: 60%; overflow: hidden; }\n[data-edrv-view] .edrv-launch-head { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--dsw-alias-border-l1, #333); }\n[data-edrv-view] .edrv-launch-tab { font-size: 12px; padding: 3px 12px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); cursor: pointer; }\n[data-edrv-view] .edrv-launch-tab.on { background: var(--dsw-alias-bg-layer-2, transparent); color: var(--dsw-alias-label-primary, #eee); font-weight: 600; }\n[data-edrv-view] .edrv-launch-body { flex: 1; min-height: 0; overflow: auto; padding: 6px 8px; display: flex; flex-direction: column; gap: 4px; }\n[data-edrv-view] .edrv-launch-row { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1, #333); border-radius: 6px; cursor: pointer; flex-wrap: wrap; }\n[data-edrv-view] .edrv-launch-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-launch-path { flex: 1; min-width: 0; font-size: 12px; color: var(--dsw-alias-label-primary, #eee); word-break: break-all; }\n[data-edrv-view] .edrv-launch-cnt { font-size: 11px; color: var(--dsw-alias-label-tertiary, #888); white-space: nowrap; }\n[data-edrv-view] .edrv-launch-arch { display: flex; flex-direction: column; gap: 6px; }\n[data-edrv-view] .monaco-editor { overflow: hidden !important; }\n[data-edrv-view] .monaco-editor .sticky-widget { z-index: 30 !important; background: var(--dsw-alias-bg-base, #f8f8f8) !important; }\n[data-edrv-view] .monaco-editor .sticky-widget .sticky-line-content,\n[data-edrv-view] .monaco-editor .sticky-widget .sticky-line-number { background: var(--dsw-alias-bg-base, #f8f8f8) !important; }\n[data-edrv-view] .monaco-editor, [data-edrv-view] .monaco-editor .margin, [data-edrv-view] .monaco-editor-background { background: transparent !important; }\n[data-edrv-view] .monaco-editor .scrollbar .slider { background: rgba(128,128,128,.3) !important; }\n[data-edrv-view] .edrv-loading { gap: 8px; padding: 20px; }\n[data-edrv-view] .edrv-loading-title { color: var(--dsw-alias-label-primary, #1f2933); font-size: 13px; }\n[data-edrv-view] .edrv-progress { width: min(360px, 72%); height: 6px; overflow: hidden; border-radius: 999px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-progress-value { height: 100%; border-radius: inherit; background: var(--dsw-alias-brand-primary, #0f9d58); transition: width .24s ease; }\n[data-edrv-view] .edrv-loading-percent { color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; font-variant-numeric: tabular-nums; }\n@media (prefers-reduced-motion: reduce) {\n [data-edrv-view] .edrv-progress-value { transition: none; }\n}\n\n";
|
|
33
33
|
const tagId = "dsh-vscode-mode/editor.css";
|
|
34
34
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
35
35
|
const tag = document.createElement("style");
|
|
@@ -114,6 +114,63 @@ window.__ModuleLoader__.load({
|
|
|
114
114
|
*/
|
|
115
115
|
const MONACO_BASE = "/edrv/vendor/monaco/vs";
|
|
116
116
|
let monacoPromise = null;
|
|
117
|
+
let monacoStage = {
|
|
118
|
+
phase: "idle",
|
|
119
|
+
progress: 0,
|
|
120
|
+
message: "准备加载 Monaco…"
|
|
121
|
+
};
|
|
122
|
+
const stageListeners = /* @__PURE__ */ new Set();
|
|
123
|
+
/**
|
|
124
|
+
* Monaco 加载阶段:这是阶段进度而非网络字节进度,避免误导用户。
|
|
125
|
+
* @author ddj 2026年08月22号
|
|
126
|
+
*/
|
|
127
|
+
const MONACO_STAGES = {
|
|
128
|
+
loader: {
|
|
129
|
+
progress: 18,
|
|
130
|
+
message: "加载 Monaco 引导模块…"
|
|
131
|
+
},
|
|
132
|
+
core: {
|
|
133
|
+
progress: 72,
|
|
134
|
+
message: "加载编辑器核心模块…"
|
|
135
|
+
},
|
|
136
|
+
ready: {
|
|
137
|
+
progress: 100,
|
|
138
|
+
message: "Monaco 编辑器已就绪"
|
|
139
|
+
},
|
|
140
|
+
error: {
|
|
141
|
+
progress: 0,
|
|
142
|
+
message: "Monaco 编辑器加载失败"
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* 发布 Monaco 加载阶段,监听器异常不得影响编辑器加载。
|
|
147
|
+
* @author ddj 2026年08月22号
|
|
148
|
+
* @param phase 阶段名
|
|
149
|
+
* @param progress 阶段百分比
|
|
150
|
+
* @param message 用户可读状态
|
|
151
|
+
*/
|
|
152
|
+
function publishStage(phase, progress, message) {
|
|
153
|
+
monacoStage = {
|
|
154
|
+
phase,
|
|
155
|
+
progress,
|
|
156
|
+
message
|
|
157
|
+
};
|
|
158
|
+
for (const listener of stageListeners) try {
|
|
159
|
+
listener(monacoStage);
|
|
160
|
+
} catch (error) {}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 订阅 Monaco 加载阶段。
|
|
164
|
+
* @author ddj 2026年08月22号
|
|
165
|
+
* @param listener 阶段回调
|
|
166
|
+
* @returns 取消订阅函数
|
|
167
|
+
*/
|
|
168
|
+
function subscribeStage(listener) {
|
|
169
|
+
if (typeof listener !== "function") return () => {};
|
|
170
|
+
stageListeners.add(listener);
|
|
171
|
+
listener(monacoStage);
|
|
172
|
+
return () => stageListeners.delete(listener);
|
|
173
|
+
}
|
|
117
174
|
/** 扩展名 → Monaco language id(常见语言;未知回退 plaintext)。 */
|
|
118
175
|
const LANG_BY_EXT = {
|
|
119
176
|
js: "javascript",
|
|
@@ -184,34 +241,40 @@ window.__ModuleLoader__.load({
|
|
|
184
241
|
* @author ddj 2026年08月20号
|
|
185
242
|
* @returns Promise<object> window.monaco
|
|
186
243
|
*/
|
|
187
|
-
function loadMonaco() {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
monacoPromise = null;
|
|
194
|
-
reject(/* @__PURE__ */ new Error("Monaco 模块加载失败:" + String(err)));
|
|
195
|
-
});
|
|
196
|
-
} catch (error) {
|
|
244
|
+
function loadMonaco(onProgress) {
|
|
245
|
+
const unsubscribe = subscribeStage(onProgress);
|
|
246
|
+
if (!monacoPromise) {
|
|
247
|
+
publishStage("loader", MONACO_STAGES.loader.progress, MONACO_STAGES.loader.message);
|
|
248
|
+
monacoPromise = new Promise((resolve, reject) => {
|
|
249
|
+
const fail = (error) => {
|
|
197
250
|
monacoPromise = null;
|
|
251
|
+
publishStage("error", MONACO_STAGES.error.progress, MONACO_STAGES.error.message);
|
|
198
252
|
reject(error);
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
if (document.querySelector("script[data-edrv-monaco-loader]")) boot();
|
|
202
|
-
else {
|
|
203
|
-
const s = document.createElement("script");
|
|
204
|
-
s.src = "/edrv/vendor/monaco/vs/loader.js";
|
|
205
|
-
s.dataset.edrvMonacoLoader = "1";
|
|
206
|
-
s.onload = boot;
|
|
207
|
-
s.onerror = () => {
|
|
208
|
-
monacoPromise = null;
|
|
209
|
-
reject(/* @__PURE__ */ new Error("Monaco loader 加载失败"));
|
|
210
253
|
};
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
254
|
+
const boot = () => {
|
|
255
|
+
try {
|
|
256
|
+
window.require.config({ paths: { vs: MONACO_BASE } });
|
|
257
|
+
publishStage("core", MONACO_STAGES.core.progress, MONACO_STAGES.core.message);
|
|
258
|
+
window.require(["vs/editor/editor.main"], () => {
|
|
259
|
+
publishStage("ready", MONACO_STAGES.ready.progress, MONACO_STAGES.ready.message);
|
|
260
|
+
resolve(window.monaco);
|
|
261
|
+
}, (err) => fail(/* @__PURE__ */ new Error("Monaco 模块加载失败:" + String(err))));
|
|
262
|
+
} catch (error) {
|
|
263
|
+
fail(error);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
if (document.querySelector("script[data-edrv-monaco-loader]")) boot();
|
|
267
|
+
else {
|
|
268
|
+
const s = document.createElement("script");
|
|
269
|
+
s.src = "/edrv/vendor/monaco/vs/loader.js";
|
|
270
|
+
s.dataset.edrvMonacoLoader = "1";
|
|
271
|
+
s.onload = boot;
|
|
272
|
+
s.onerror = () => fail(/* @__PURE__ */ new Error("Monaco loader 加载失败"));
|
|
273
|
+
document.head.appendChild(s);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
return monacoPromise.finally(unsubscribe);
|
|
215
278
|
}
|
|
216
279
|
//#endregion
|
|
217
280
|
//#region src/client/monaco/diffRender.ts
|
|
@@ -305,8 +368,10 @@ window.__ModuleLoader__.load({
|
|
|
305
368
|
try {
|
|
306
369
|
li = editor.getLayoutInfo();
|
|
307
370
|
} catch (e) {}
|
|
308
|
-
const
|
|
371
|
+
const rawLeft = li ? li.decorationsLeft : 0;
|
|
309
372
|
const width = li && li.decorationsWidth > 0 ? li.decorationsWidth : 16;
|
|
373
|
+
const maxLeft = Math.max(0, root.clientWidth - width);
|
|
374
|
+
const left = Math.max(0, Math.min(maxLeft, rawLeft + 12));
|
|
310
375
|
const lineCount = editor.getModel().getLineCount();
|
|
311
376
|
let itemIdx = 0;
|
|
312
377
|
let zi = 0;
|
|
@@ -318,7 +383,7 @@ window.__ModuleLoader__.load({
|
|
|
318
383
|
for (let i = 0; i < z.n; i++) {
|
|
319
384
|
const item = document.createElement("div");
|
|
320
385
|
item.className = "edrv-minus-item";
|
|
321
|
-
item.textContent = "
|
|
386
|
+
item.textContent = "";
|
|
322
387
|
item.style.width = width + "px";
|
|
323
388
|
item.style.height = lineH + "px";
|
|
324
389
|
item.dataset.zone = String(zi);
|
|
@@ -346,7 +411,14 @@ window.__ModuleLoader__.load({
|
|
|
346
411
|
const edRect = root.getBoundingClientRect();
|
|
347
412
|
const st = editor.getScrollTop() || 0;
|
|
348
413
|
const items = overlay.querySelectorAll(".edrv-minus-item");
|
|
414
|
+
let correctedLeft = left;
|
|
415
|
+
try {
|
|
416
|
+
const layout = editor.getLayoutInfo();
|
|
417
|
+
const markerWidth = layout.decorationsWidth > 0 ? layout.decorationsWidth : width;
|
|
418
|
+
correctedLeft = Math.max(0, Math.min(Math.max(0, root.clientWidth - markerWidth), (layout.decorationsLeft || 0) + 12));
|
|
419
|
+
} catch (e) {}
|
|
349
420
|
for (const item of items) {
|
|
421
|
+
item.style.left = correctedLeft + "px";
|
|
350
422
|
const zIndex = Number(item.dataset.zone);
|
|
351
423
|
const rIndex = Number(item.dataset.row);
|
|
352
424
|
const z = createdZones[zIndex];
|
|
@@ -1116,6 +1188,11 @@ window.__ModuleLoader__.load({
|
|
|
1116
1188
|
const [content, setContent] = react.default.useState(null);
|
|
1117
1189
|
const [status, setStatus] = react.default.useState("");
|
|
1118
1190
|
const [error, setError] = react.default.useState(null);
|
|
1191
|
+
const [loadError, setLoadError] = react.default.useState(null);
|
|
1192
|
+
const [loadStage, setLoadStage] = react.default.useState({
|
|
1193
|
+
progress: 0,
|
|
1194
|
+
message: "准备加载编辑器…"
|
|
1195
|
+
});
|
|
1119
1196
|
const [openInput, setOpenInput] = react.default.useState(false);
|
|
1120
1197
|
const [pathDraft, setPathDraft] = react.default.useState("");
|
|
1121
1198
|
const [cursor, setCursor] = react.default.useState("");
|
|
@@ -1136,7 +1213,10 @@ window.__ModuleLoader__.load({
|
|
|
1136
1213
|
const lineRegionMapRef = react.default.useRef(/* @__PURE__ */ new Map());
|
|
1137
1214
|
const hoverKeyRef = react.default.useRef(null);
|
|
1138
1215
|
const hoverTopRef = react.default.useRef(null);
|
|
1216
|
+
const hoverRightRef = react.default.useRef(null);
|
|
1139
1217
|
const hideTimerRef = react.default.useRef(null);
|
|
1218
|
+
const hoverEditorRef = react.default.useRef(false);
|
|
1219
|
+
const hoverPanelRef = react.default.useRef(false);
|
|
1140
1220
|
const batchBusyRef = react.default.useRef(false);
|
|
1141
1221
|
const diffRendererRef = react.default.useRef(null);
|
|
1142
1222
|
if (!diffRendererRef.current) diffRendererRef.current = createDiffRenderer((sid, t) => dbg(sid, t));
|
|
@@ -1187,6 +1267,11 @@ window.__ModuleLoader__.load({
|
|
|
1187
1267
|
};
|
|
1188
1268
|
const loadContent = (path, sid) => {
|
|
1189
1269
|
const seq = ++loadSeqRef.current;
|
|
1270
|
+
setLoadError(null);
|
|
1271
|
+
setLoadStage({
|
|
1272
|
+
progress: monaco ? 72 : 12,
|
|
1273
|
+
message: "读取文件内容…"
|
|
1274
|
+
});
|
|
1190
1275
|
rpc("edrv.read", {
|
|
1191
1276
|
sessionId: sid,
|
|
1192
1277
|
path
|
|
@@ -1194,16 +1279,23 @@ window.__ModuleLoader__.load({
|
|
|
1194
1279
|
if (seq !== loadSeqRef.current || path !== active) return;
|
|
1195
1280
|
if (res && res.ok) {
|
|
1196
1281
|
setContent(res.content);
|
|
1282
|
+
setLoadStage((prev) => ({
|
|
1283
|
+
progress: Math.max(84, prev.progress),
|
|
1284
|
+
message: "文件已读取,准备创建编辑器…"
|
|
1285
|
+
}));
|
|
1197
1286
|
setStatus("已加载");
|
|
1198
1287
|
} else {
|
|
1199
|
-
|
|
1288
|
+
const message = res?.error ? String(res.error) : "读取失败";
|
|
1289
|
+
setLoadError(message);
|
|
1290
|
+
setError(message);
|
|
1200
1291
|
setStatus("读取失败");
|
|
1201
1292
|
}
|
|
1202
1293
|
}).catch((e) => {
|
|
1203
|
-
if (seq
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1294
|
+
if (seq !== loadSeqRef.current) return;
|
|
1295
|
+
const message = "read异常:" + String(e);
|
|
1296
|
+
setLoadError(message);
|
|
1297
|
+
setError(message);
|
|
1298
|
+
setStatus("读取失败");
|
|
1207
1299
|
});
|
|
1208
1300
|
};
|
|
1209
1301
|
react.default.useEffect(() => {
|
|
@@ -1260,13 +1352,26 @@ window.__ModuleLoader__.load({
|
|
|
1260
1352
|
react.default.useEffect(() => {
|
|
1261
1353
|
if (!active) return;
|
|
1262
1354
|
setContent(null);
|
|
1355
|
+
setLoadError(null);
|
|
1356
|
+
setLoadStage({
|
|
1357
|
+
progress: 10,
|
|
1358
|
+
message: "准备读取文件…"
|
|
1359
|
+
});
|
|
1263
1360
|
setStatus("加载中…");
|
|
1264
1361
|
loadContent(active, sessionId);
|
|
1265
1362
|
}, [active, sessionId]);
|
|
1266
1363
|
react.default.useEffect(() => {
|
|
1267
1364
|
if (monaco || monacoErr) return;
|
|
1268
1365
|
let alive = true;
|
|
1269
|
-
|
|
1366
|
+
const onProgress = (stage) => {
|
|
1367
|
+
if (!alive) return;
|
|
1368
|
+
const progress = stage.phase === "ready" ? 70 : Math.round(10 + stage.progress * .6);
|
|
1369
|
+
setLoadStage((prev) => ({
|
|
1370
|
+
progress: Math.max(prev.progress, progress),
|
|
1371
|
+
message: stage.message
|
|
1372
|
+
}));
|
|
1373
|
+
};
|
|
1374
|
+
loadMonaco(onProgress).then((m) => {
|
|
1270
1375
|
if (alive) setMonaco(m);
|
|
1271
1376
|
}).catch((e) => {
|
|
1272
1377
|
if (alive) {
|
|
@@ -1335,6 +1440,10 @@ window.__ModuleLoader__.load({
|
|
|
1335
1440
|
const ed = editorRef.current;
|
|
1336
1441
|
const model = getModel(active, content);
|
|
1337
1442
|
if (ed.getModel() !== model) ed.setModel(model);
|
|
1443
|
+
setLoadStage((prev) => ({
|
|
1444
|
+
progress: Math.max(96, prev.progress),
|
|
1445
|
+
message: "创建编辑器视图…"
|
|
1446
|
+
}));
|
|
1338
1447
|
}, [
|
|
1339
1448
|
monaco,
|
|
1340
1449
|
active,
|
|
@@ -1343,6 +1452,10 @@ window.__ModuleLoader__.load({
|
|
|
1343
1452
|
react.default.useEffect(() => {
|
|
1344
1453
|
if (!monaco || !editorRef.current || !active || content === null) return;
|
|
1345
1454
|
diffRendererRef.current.render(monaco, editorRef.current, pendingRegions, sessionId);
|
|
1455
|
+
setLoadStage({
|
|
1456
|
+
progress: 100,
|
|
1457
|
+
message: "编辑器已就绪"
|
|
1458
|
+
});
|
|
1346
1459
|
}, [
|
|
1347
1460
|
monaco,
|
|
1348
1461
|
active,
|
|
@@ -1408,41 +1521,49 @@ window.__ModuleLoader__.load({
|
|
|
1408
1521
|
setCursor("Ln " + e.position.lineNumber + ", Col " + e.position.column);
|
|
1409
1522
|
});
|
|
1410
1523
|
const hideSoon = () => {
|
|
1411
|
-
if (hideTimerRef.current) return;
|
|
1524
|
+
if (hoverEditorRef.current || hoverPanelRef.current || hideTimerRef.current) return;
|
|
1412
1525
|
hideTimerRef.current = setTimeout(() => {
|
|
1413
1526
|
hideTimerRef.current = null;
|
|
1527
|
+
if (hoverEditorRef.current || hoverPanelRef.current) return;
|
|
1414
1528
|
hoverKeyRef.current = null;
|
|
1415
1529
|
hoverTopRef.current = null;
|
|
1416
1530
|
setHoverAct(null);
|
|
1417
1531
|
}, 180);
|
|
1418
1532
|
};
|
|
1419
1533
|
ed.onMouseMove((e) => {
|
|
1534
|
+
hoverEditorRef.current = true;
|
|
1420
1535
|
const line = e?.target?.position?.lineNumber;
|
|
1421
1536
|
const map = lineRegionMapRef.current;
|
|
1422
1537
|
if (!line || !map.size) {
|
|
1538
|
+
hoverEditorRef.current = false;
|
|
1423
1539
|
hideSoon();
|
|
1424
1540
|
return;
|
|
1425
1541
|
}
|
|
1426
1542
|
const hit = map.get(line);
|
|
1427
1543
|
if (!hit) {
|
|
1544
|
+
hoverEditorRef.current = false;
|
|
1428
1545
|
hideSoon();
|
|
1429
1546
|
return;
|
|
1430
1547
|
}
|
|
1431
1548
|
const key = callIdAttr(hit.callId, hit.idx);
|
|
1432
1549
|
const top = Math.max(0, ed.getTopForLineNumber(Math.max(1, hit.start)) - ed.getScrollTop());
|
|
1433
|
-
|
|
1550
|
+
const layout = ed.getLayoutInfo();
|
|
1551
|
+
const minimapLeft = layout.minimap?.minimapLeft || 0;
|
|
1552
|
+
const right = minimapLeft > 0 ? Math.max(12, layout.width - minimapLeft + 8) : Math.max(12, layout.verticalScrollbarWidth + 8);
|
|
1553
|
+
if (hoverKeyRef.current === key && hoverTopRef.current === top && hoverRightRef.current === right) return;
|
|
1434
1554
|
hoverKeyRef.current = key;
|
|
1435
1555
|
hoverTopRef.current = top;
|
|
1556
|
+
hoverRightRef.current = right;
|
|
1436
1557
|
if (hideTimerRef.current) {
|
|
1437
1558
|
clearTimeout(hideTimerRef.current);
|
|
1438
1559
|
hideTimerRef.current = null;
|
|
1439
1560
|
}
|
|
1440
1561
|
setHoverAct({
|
|
1441
1562
|
region: hit,
|
|
1442
|
-
top
|
|
1563
|
+
top,
|
|
1564
|
+
right
|
|
1443
1565
|
});
|
|
1444
1566
|
});
|
|
1445
|
-
ed.onMouseLeave(hideSoon);
|
|
1446
1567
|
editorRef.current = ed;
|
|
1447
1568
|
}, []);
|
|
1448
1569
|
react.default.useEffect(() => {
|
|
@@ -1504,6 +1625,22 @@ window.__ModuleLoader__.load({
|
|
|
1504
1625
|
refreshRecords();
|
|
1505
1626
|
};
|
|
1506
1627
|
/**
|
|
1628
|
+
* 关闭当前差异浮窗并清理 hover 锚点。
|
|
1629
|
+
* @author ddj 2026年08月21号
|
|
1630
|
+
*/
|
|
1631
|
+
const dismissHover = () => {
|
|
1632
|
+
hoverKeyRef.current = null;
|
|
1633
|
+
hoverTopRef.current = null;
|
|
1634
|
+
hoverRightRef.current = null;
|
|
1635
|
+
hoverEditorRef.current = false;
|
|
1636
|
+
hoverPanelRef.current = false;
|
|
1637
|
+
if (hideTimerRef.current) {
|
|
1638
|
+
clearTimeout(hideTimerRef.current);
|
|
1639
|
+
hideTimerRef.current = null;
|
|
1640
|
+
}
|
|
1641
|
+
setHoverAct(null);
|
|
1642
|
+
};
|
|
1643
|
+
/**
|
|
1507
1644
|
* 对单个差异区域执行采纳/不采纳。
|
|
1508
1645
|
* @author ddj 2026年08月20号
|
|
1509
1646
|
* @param region 差异区域(callId/idx/create)
|
|
@@ -1686,39 +1823,98 @@ window.__ModuleLoader__.load({
|
|
|
1686
1823
|
onClick: reloadFile
|
|
1687
1824
|
}, "⟳"));
|
|
1688
1825
|
const otherFiles = sum.pendingFiles.filter((f) => f.path !== active);
|
|
1826
|
+
/**
|
|
1827
|
+
* 渲染编辑器/文件加载进度面板。
|
|
1828
|
+
* @author ddj 2026年08月22号
|
|
1829
|
+
* @param message 当前加载阶段
|
|
1830
|
+
* @param progress 阶段进度
|
|
1831
|
+
* @param retry 可选重试回调
|
|
1832
|
+
* @returns 加载面板 React 元素
|
|
1833
|
+
*/
|
|
1834
|
+
const loadingBody = (message, progress, retry) => react.default.createElement("div", {
|
|
1835
|
+
className: "edrv-empty edrv-loading",
|
|
1836
|
+
"aria-live": "polite"
|
|
1837
|
+
}, react.default.createElement("div", { className: "edrv-loading-title" }, message), react.default.createElement("div", {
|
|
1838
|
+
className: "edrv-progress",
|
|
1839
|
+
role: "progressbar",
|
|
1840
|
+
"aria-label": "编辑器加载进度",
|
|
1841
|
+
"aria-valuemin": 0,
|
|
1842
|
+
"aria-valuemax": 100,
|
|
1843
|
+
"aria-valuenow": progress
|
|
1844
|
+
}, react.default.createElement("div", {
|
|
1845
|
+
className: "edrv-progress-value",
|
|
1846
|
+
style: { width: Math.max(0, Math.min(100, progress)) + "%" }
|
|
1847
|
+
})), react.default.createElement("div", { className: "edrv-loading-percent" }, Math.round(progress) + "%"), retry ? react.default.createElement("button", {
|
|
1848
|
+
className: "edrv-pill edrv-pill-ghost",
|
|
1849
|
+
onClick: retry
|
|
1850
|
+
}, "重试") : null);
|
|
1689
1851
|
let body;
|
|
1690
|
-
if (!monaco && !monacoErr) body =
|
|
1691
|
-
else if (monacoErr) body = react.default.createElement("div", { className: "edrv-empty" }, react.default.createElement("div", null, "Monaco 编辑器加载失败:" + String(monacoErr)), react.default.createElement("div", { style: { fontSize: 11 } }, "请确认插件包 assets/vendor/monaco 完整(/edrv/vendor 路由可达)")
|
|
1852
|
+
if (!monaco && !monacoErr) body = loadingBody(loadStage.message, loadStage.progress);
|
|
1853
|
+
else if (monacoErr) body = react.default.createElement("div", { className: "edrv-empty" }, react.default.createElement("div", null, "Monaco 编辑器加载失败:" + String(monacoErr)), react.default.createElement("div", { style: { fontSize: 11 } }, "请确认插件包 assets/vendor/monaco 完整(/edrv/vendor 路由可达)"), react.default.createElement("button", {
|
|
1854
|
+
className: "edrv-pill edrv-pill-ghost",
|
|
1855
|
+
onClick: () => {
|
|
1856
|
+
setMonacoErr(null);
|
|
1857
|
+
setLoadStage({
|
|
1858
|
+
progress: 0,
|
|
1859
|
+
message: "准备重试 Monaco…"
|
|
1860
|
+
});
|
|
1861
|
+
}
|
|
1862
|
+
}, "重试"));
|
|
1692
1863
|
else if (!active) body = react.default.createElement("div", { className: "edrv-empty" }, react.default.createElement("div", null, "暂无打开的文件"), react.default.createElement("div", { style: { fontSize: 12 } }, "使用右上搜索框 (Ctrl+P) 打开工作区文件;agent 修改文件后顶部会出现差异角标"));
|
|
1693
|
-
else if (content === null) body =
|
|
1864
|
+
else if (content === null && loadError) body = loadingBody("文件加载失败:" + loadError, 0, () => {
|
|
1865
|
+
setLoadError(null);
|
|
1866
|
+
setContent(null);
|
|
1867
|
+
setLoadStage({
|
|
1868
|
+
progress: 10,
|
|
1869
|
+
message: "重新读取文件…"
|
|
1870
|
+
});
|
|
1871
|
+
loadContent(active, sessionId);
|
|
1872
|
+
});
|
|
1873
|
+
else if (content === null) body = loadingBody(loadStage.message || "读取文件内容…", loadStage.progress);
|
|
1694
1874
|
else body = react.default.createElement("div", { className: "edrv-monaco-host" }, react.default.createElement("div", { ref: ensureEditor }));
|
|
1695
1875
|
const hoverEl = hoverAct && !launcherOpen ? react.default.createElement("div", {
|
|
1696
1876
|
className: "edrv-hoveract",
|
|
1697
1877
|
style: {
|
|
1698
1878
|
top: hoverAct.top,
|
|
1699
|
-
right: 12
|
|
1879
|
+
right: hoverAct.right ?? 12
|
|
1700
1880
|
},
|
|
1701
1881
|
onMouseEnter: () => {
|
|
1882
|
+
hoverPanelRef.current = true;
|
|
1883
|
+
if (hideTimerRef.current) {
|
|
1884
|
+
clearTimeout(hideTimerRef.current);
|
|
1885
|
+
hideTimerRef.current = null;
|
|
1886
|
+
}
|
|
1887
|
+
},
|
|
1888
|
+
onMouseMove: () => {
|
|
1889
|
+
hoverPanelRef.current = true;
|
|
1702
1890
|
if (hideTimerRef.current) {
|
|
1703
1891
|
clearTimeout(hideTimerRef.current);
|
|
1704
1892
|
hideTimerRef.current = null;
|
|
1705
1893
|
}
|
|
1706
1894
|
},
|
|
1707
1895
|
onMouseLeave: () => {
|
|
1708
|
-
|
|
1896
|
+
hoverPanelRef.current = false;
|
|
1897
|
+
if (hoverEditorRef.current || hideTimerRef.current) return;
|
|
1898
|
+
hideTimerRef.current = setTimeout(() => {
|
|
1709
1899
|
hideTimerRef.current = null;
|
|
1900
|
+
if (hoverEditorRef.current || hoverPanelRef.current) return;
|
|
1710
1901
|
hoverKeyRef.current = null;
|
|
1711
1902
|
hoverTopRef.current = null;
|
|
1712
1903
|
setHoverAct(null);
|
|
1713
|
-
},
|
|
1714
|
-
hideTimerRef.current = t;
|
|
1904
|
+
}, 420);
|
|
1715
1905
|
}
|
|
1716
1906
|
}, react.default.createElement("button", {
|
|
1717
1907
|
className: "edrv-pill edrv-pill-keep",
|
|
1718
|
-
onClick: () =>
|
|
1908
|
+
onClick: () => {
|
|
1909
|
+
dismissHover();
|
|
1910
|
+
actHunk(hoverAct.region, false);
|
|
1911
|
+
}
|
|
1719
1912
|
}, "✓ Keep"), react.default.createElement("button", {
|
|
1720
1913
|
className: "edrv-pill edrv-pill-undo",
|
|
1721
|
-
onClick: () =>
|
|
1914
|
+
onClick: () => {
|
|
1915
|
+
dismissHover();
|
|
1916
|
+
actHunk(hoverAct.region, true);
|
|
1917
|
+
}
|
|
1722
1918
|
}, "↩ Undo")) : null;
|
|
1723
1919
|
const overlay = launcherOpen ? react.default.createElement(react.default.Fragment, null, react.default.createElement("div", {
|
|
1724
1920
|
style: {
|