dsh-vscode-mode 0.9.0 → 0.11.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.
- package/README.md +42 -3
- package/lib/client.js +1587 -301
- package/lib/client.js.map +1 -1
- package/lib/index.js +2163 -1042
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/addToConversation.ts +74 -28
- package/src/client/dap/hover.ts +2 -7
- package/src/client/index.ts +25 -0
- package/src/client/luaReservedWords.ts +10 -0
- package/src/client/monaco/lsp/keywords.ts +121 -0
- package/src/client/monaco/lsp/lspClient.ts +68 -6
- package/src/client/monaco/lsp/memberScope.ts +90 -0
- package/src/client/monaco/lsp/providers.ts +14 -4
- package/src/client/settingsDocRouter.ts +52 -0
- package/src/client/sidebar/menuItems.ts +1 -0
- package/src/client/sidebar/panels/SvnPanel.ts +1 -1
- package/src/client/sidebar/types.ts +2 -0
- package/src/client/styles/editor.css +143 -37
- package/src/client/svnActions.ts +4 -4
- package/src/client/ui/ContextMenu.ts +4 -2
- package/src/client/ui/EditorView.ts +132 -52
- package/src/client/ui/SvnLogDialog.ts +200 -69
- package/src/client/ui/SvnUpdateDialog.ts +472 -0
- package/src/client/ui/svnUpdateModel.ts +135 -0
- package/src/index.ts +2 -0
- package/src/lsp/completionCap.ts +80 -0
- package/src/lsp/manager.ts +42 -10
- package/src/lsp/rpc.ts +8 -5
- package/src/lsp/server.ts +18 -4
- package/src/rpc.ts +74 -2
- package/src/settingsDocPath.ts +30 -0
- package/src/shared/rpc.ts +12 -2
- package/src/shared/svn.ts +38 -0
- package/src/svn.ts +102 -7
- package/src/svnText.ts +22 -13
- package/src/svnUpdateJob.ts +588 -0
|
@@ -56,6 +56,7 @@ import { statusOfAdd } from '../addToConversation.js'
|
|
|
56
56
|
import { setSearchScope, setSearchSeed } from '../searchSeed.js'
|
|
57
57
|
import { CACHE_KEY } from '../paths.js'
|
|
58
58
|
import { runGoToDefinition, runFindReferences, hideReferencesOverlay } from '../monaco/lsp/providers.js'
|
|
59
|
+
import { isLuaTypeSlot } from '../monaco/lsp/keywords.js'
|
|
59
60
|
import { bindLspUnderline } from '../monaco/lsp/underline.js'
|
|
60
61
|
import { onLspProgress, refreshStatus, setSession as setLspSession } from '../monaco/lsp/index.js'
|
|
61
62
|
import { setupAiInline, trackAiEditor, aiInlineEnabled } from '../ai/inlineProvider.js'
|
|
@@ -69,7 +70,7 @@ import {
|
|
|
69
70
|
} from '../tabActions.js'
|
|
70
71
|
import { getMaxOpenEditors } from '../editorLimit.js'
|
|
71
72
|
import { buildTabMenu } from '../tabMenu.js'
|
|
72
|
-
import { ensureSvnChanges, ensureSvnStatus, getSvnChanges, getSvnStatus, refreshSvnChanges, svnAdd, svnChangeMapOf, svnDiffBase, svnDiffLocalPair, svnEditorActions, svnRevert, svnTortoise
|
|
73
|
+
import { ensureSvnChanges, ensureSvnStatus, getSvnChanges, getSvnStatus, refreshSvnChanges, svnAdd, svnChangeMapOf, svnDiffBase, svnDiffLocalPair, svnEditorActions, svnRevert, svnTortoise } from '../svnStatus.js'
|
|
73
74
|
import { ensureSvnLog, getSvnLog, refreshSvnLog, svnDiffPair, svnDiffRev, svnDiffWorking, svnLogKeyOf, svnLogLoadedLimit, svnLogTruncated, svnWcRev, SVN_LOG_SHOW_ALL_LIMIT } from '../svnLog.js'
|
|
74
75
|
import { runSvnAction } from '../svnActions.js'
|
|
75
76
|
import { dshTrace } from '../svnStore.js'
|
|
@@ -82,6 +83,9 @@ import { promptName } from './PromptDialog.js'
|
|
|
82
83
|
import { openWithDialog } from '../openWithDialog.js'
|
|
83
84
|
import { copyText as copyClipText } from '../copyText.js'
|
|
84
85
|
import { SvnLogDialog } from './SvnLogDialog.js'
|
|
86
|
+
import { SvnUpdateDialog } from './SvnUpdateDialog.js'
|
|
87
|
+
import { sameUpdateOwner, updateDone } from './svnUpdateModel.js'
|
|
88
|
+
import { IconRefreshOutline16 } from './icons.js'
|
|
85
89
|
import { SvnPatchDialog } from './SvnPatchDialog.js'
|
|
86
90
|
import { SvnSumDialog } from './SvnSumDialog.js'
|
|
87
91
|
import { LogDialog } from './LogDialog.js'
|
|
@@ -95,6 +99,23 @@ import { clampToolbarPosition, loadToolbarPosition, saveToolbarPosition } from '
|
|
|
95
99
|
import { editorModelPathOf } from '../dap/modelPath.js'
|
|
96
100
|
import { dapTrace } from '../dap/trace.js'
|
|
97
101
|
|
|
102
|
+
/**
|
|
103
|
+
* 只在 Lua 注解类型槽开启注释自动建议;跨文件/离开类型槽立即恢复默认。
|
|
104
|
+
* @author ddj 2026年09月24号
|
|
105
|
+
* @param ed 当前 Monaco 编辑器
|
|
106
|
+
* @param monaco Monaco API(读取 quickSuggestions 枚举)
|
|
107
|
+
*/
|
|
108
|
+
function syncTypeSuggest(ed, monaco) {
|
|
109
|
+
const model = ed.getModel()
|
|
110
|
+
const position = ed.getPosition()
|
|
111
|
+
const typeSlot = model?.getLanguageId() === 'lua' && position
|
|
112
|
+
&& isLuaTypeSlot(model, position, model.getWordUntilPosition(position))
|
|
113
|
+
const options = ed.getOption(monaco.editor.EditorOption.quickSuggestions)
|
|
114
|
+
const comments = typeSlot ? 'on' : 'off'
|
|
115
|
+
if (options.comments === comments) return
|
|
116
|
+
ed.updateOptions({ quickSuggestions: { ...options, comments } })
|
|
117
|
+
}
|
|
118
|
+
|
|
98
119
|
/** 日志弹窗每次加载条数(「加载更多」按此步长递增;上限由 host 的 SVN_LOG_SHOW_ALL_CAP 约束)。 */
|
|
99
120
|
const SVN_LOG_PAGE = 100
|
|
100
121
|
|
|
@@ -252,7 +273,30 @@ export function EditorView(props) {
|
|
|
252
273
|
const [svnLogError, setSvnLogError] = React.useState('') // 日志错误文案
|
|
253
274
|
const [svnLogWcRev, setSvnLogWcRev] = React.useState(null) // P1-9:文件目标的工作副本版号(null = 不加粗)
|
|
254
275
|
const [dlogOpen, setDlogOpen] = React.useState(false) // 诊断日志弹窗(自取数据,null 语义无需状态层)
|
|
255
|
-
const [
|
|
276
|
+
const [svnUpdateDialog, setSvnUpdateDialog] = React.useState(null) // {path,sessionId,scope,resumeJobId?};窗口内自取增量
|
|
277
|
+
const [svnUpdateReturn, setSvnUpdateReturn] = React.useState(null) // 从日志/差异返回时恢复同一 job
|
|
278
|
+
const [recentUpdate, setRecentUpdate] = React.useState(null) // {jobId,path,sessionId,scope};只读恢复入口
|
|
279
|
+
const [updateOpenWith, setUpdateOpenWith] = React.useState(false) // 二级弹窗 Esc 不联动关闭父窗口
|
|
280
|
+
const svnUpdateDoneRef = React.useRef(new Set()) // job 终态刷新一次,往返日志/差异不重复刷新
|
|
281
|
+
// @author ddj 2026年09月24号:切换作用域只关闭窗口,不取消旧工作副本中已启动的任务
|
|
282
|
+
React.useEffect(() => {
|
|
283
|
+
setSvnUpdateDialog(null)
|
|
284
|
+
setSvnUpdateReturn(null)
|
|
285
|
+
setRecentUpdate(null)
|
|
286
|
+
setUpdateOpenWith(false)
|
|
287
|
+
}, [sessionId, scope])
|
|
288
|
+
// @author ddj 2026年09月24号:只读恢复原工作区的活动更新,不调用 updateStart
|
|
289
|
+
React.useEffect(() => {
|
|
290
|
+
if (!sessionId || svnStatus?.managed !== true) return undefined
|
|
291
|
+
let alive = true
|
|
292
|
+
void rpc('svn.updateActive', { sessionId }).then((outcome) => {
|
|
293
|
+
if (!alive || !outcome.ok || !outcome.job) return
|
|
294
|
+
const recovered = { path: outcome.job.target, sessionId, scope, resumeJobId: outcome.job.jobId }
|
|
295
|
+
if (updateDone(outcome.job.phase)) setRecentUpdate(recovered)
|
|
296
|
+
else setSvnUpdateDialog((current) => current ?? recovered)
|
|
297
|
+
}).catch(() => {})
|
|
298
|
+
return () => { alive = false }
|
|
299
|
+
}, [sessionId, scope, svnStatus?.managed])
|
|
256
300
|
const [sidebarOn, setSidebarOn] = React.useState(layout !== 'side') // 侧边栏显隐(侧栏形态默认收起)
|
|
257
301
|
const [sidebarW, setSidebarW] = React.useState(() => getSidebarMinWidth()) // 侧边栏宽度(初值 = 最小宽度,默认 300)
|
|
258
302
|
const [activePanel, setActivePanel] = React.useState('explorer') // 激活面板 id
|
|
@@ -1727,6 +1771,7 @@ export function EditorView(props) {
|
|
|
1727
1771
|
sessionId,
|
|
1728
1772
|
scope,
|
|
1729
1773
|
path: def.id === 'update' ? (relPath ?? '') : relPath,
|
|
1774
|
+
openSvnUpdate: (p) => runSvnUpdate(p),
|
|
1730
1775
|
notify: (message) => setStatus(message),
|
|
1731
1776
|
openSvnDiff: (p) => runSvnDiffBase(p),
|
|
1732
1777
|
openSvnLocalPair: runSvnDiffLocalPair,
|
|
@@ -1904,6 +1949,7 @@ export function EditorView(props) {
|
|
|
1904
1949
|
const ed = editorRef.current
|
|
1905
1950
|
const model = getModel(active, content)
|
|
1906
1951
|
if (ed.getModel() !== model) ed.setModel(model)
|
|
1952
|
+
syncTypeSuggest(ed, monaco)
|
|
1907
1953
|
restoreViewState(active)
|
|
1908
1954
|
setLoadStage((prev) => ({ progress: Math.max(96, prev.progress), message: '创建编辑器视图…' }))
|
|
1909
1955
|
}, [monaco, active, content, contentReady, mdPreviewing])
|
|
@@ -1997,9 +2043,11 @@ export function EditorView(props) {
|
|
|
1997
2043
|
// 保存改由窗口级快捷键监听执行(键位可配置;见上方 edrv.save 监听)
|
|
1998
2044
|
ed.onDidChangeModelContent(() => {
|
|
1999
2045
|
if (!ed.getModel() || programmaticRef.current) return
|
|
2046
|
+
syncTypeSuggest(ed, m)
|
|
2000
2047
|
onEditRef.current?.()
|
|
2001
2048
|
})
|
|
2002
2049
|
ed.onDidChangeCursorPosition((e) => {
|
|
2050
|
+
syncTypeSuggest(ed, m)
|
|
2003
2051
|
setCursor('Ln ' + e.position.lineNumber + ', Col ' + e.position.column)
|
|
2004
2052
|
// 整行移动(↓↑)刚定位时保留期望列;其余光标移动(点击/打字/方向键)清空期望列
|
|
2005
2053
|
if (rowNavMoveRef.current) rowNavMoveRef.current = false
|
|
@@ -2740,17 +2788,15 @@ export function EditorView(props) {
|
|
|
2740
2788
|
|
|
2741
2789
|
// 供 Monaco 原生右键菜单 addAction 读取的最新动作闭包(空依赖回调不随渲染重建)
|
|
2742
2790
|
/**
|
|
2743
|
-
*
|
|
2744
|
-
*
|
|
2791
|
+
* 四入口共用的更新窗口:仅显式点击触发,不在背景静默更新。
|
|
2792
|
+
* @author ddj 2026年09月24号
|
|
2793
|
+
* @param relPath 工作区相对目标;空串代表根
|
|
2745
2794
|
*/
|
|
2746
2795
|
const runSvnUpdate = (relPath) => {
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
// P3:有条目级明细时展示结果条(无变化则清空,不留旧结果)
|
|
2752
|
-
setSvnUpdateResult(o.ok ? { summary: o.message, entries: o.entries ?? [], conflicts: o.conflicts ?? [] } : null)
|
|
2753
|
-
})
|
|
2796
|
+
closeCommandPalette()
|
|
2797
|
+
setSvnUpdateReturn(null)
|
|
2798
|
+
setRecentUpdate(null)
|
|
2799
|
+
setSvnUpdateDialog({ path: relPath ?? '', sessionId, scope })
|
|
2754
2800
|
}
|
|
2755
2801
|
/** 强制重查 SVN 变更清单(命令栏「SVN 刷新变更」)。 */
|
|
2756
2802
|
const runSvnReload = () => {
|
|
@@ -2857,8 +2903,9 @@ export function EditorView(props) {
|
|
|
2857
2903
|
* @param relPath 目标工作区相对路径
|
|
2858
2904
|
* @param revision 左侧版本
|
|
2859
2905
|
* @param logTarget 来自日志弹窗时的日志目标(不传 = 非日志入口)
|
|
2906
|
+
* @param onOpened 差异视图成功打开后触发(更新结果返回用)
|
|
2860
2907
|
*/
|
|
2861
|
-
const runSvnDiffWorking = (relPath, revision, logTarget) => {
|
|
2908
|
+
const runSvnDiffWorking = (relPath, revision, logTarget, onOpened) => {
|
|
2862
2909
|
if (!relPath) { setStatus('仅文件目标支持与工作副本比较'); return }
|
|
2863
2910
|
setStatus('读取 r' + revision + ' ↔ 工作副本 差异…')
|
|
2864
2911
|
void svnDiffWorking(sessionId, relPath, revision).then((outcome) => {
|
|
@@ -2877,6 +2924,7 @@ export function EditorView(props) {
|
|
|
2877
2924
|
logTarget,
|
|
2878
2925
|
})
|
|
2879
2926
|
setStatus('已打开 r' + revision + ' ↔ 工作副本 差异')
|
|
2927
|
+
onOpened?.()
|
|
2880
2928
|
})
|
|
2881
2929
|
}
|
|
2882
2930
|
|
|
@@ -3032,6 +3080,7 @@ export function EditorView(props) {
|
|
|
3032
3080
|
sessionId,
|
|
3033
3081
|
scope,
|
|
3034
3082
|
path,
|
|
3083
|
+
openSvnUpdate: (p) => runSvnUpdate(p),
|
|
3035
3084
|
notify: (message) => setStatus(message),
|
|
3036
3085
|
openSvnDiff: (p) => runSvnDiffBase(p),
|
|
3037
3086
|
openSvnLocalPair: runSvnDiffLocalPair,
|
|
@@ -3239,6 +3288,12 @@ export function EditorView(props) {
|
|
|
3239
3288
|
const pathBar = React.createElement('div', { className: 'edrv-pathbar', title: active || '' },
|
|
3240
3289
|
React.createElement('span', { className: 'edrv-pb-name' }, active ? String(active).split(/[\\/]/).pop() : '未打开文件'),
|
|
3241
3290
|
React.createElement('span', { className: 'edrv-pb-full' }, active || '使用右上搜索框 (' + (chordOf('edrv.quickOpen') ?? 'Ctrl+P') + ') 打开文件'),
|
|
3291
|
+
(recentUpdate && !svnUpdateDialog && sameUpdateOwner(recentUpdate, sessionId, scope)
|
|
3292
|
+
? React.createElement('button', {
|
|
3293
|
+
className: 'edrv-pb-update', type: 'button', title: '查看最近 SVN 更新结果(不重新更新)',
|
|
3294
|
+
onClick: () => setSvnUpdateDialog(recentUpdate),
|
|
3295
|
+
}, React.createElement(IconRefreshOutline16, { size: 14 }), '最近更新')
|
|
3296
|
+
: null),
|
|
3242
3297
|
// Markdown 预览/源码切换(需求 4):仅 .md 文件出现;命令栏与 Ctrl+Shift+V 为同一动作
|
|
3243
3298
|
(isMdActive ? React.createElement('button', {
|
|
3244
3299
|
className: 'edrv-pill edrv-pill-ghost edrv-pb-mdbtn',
|
|
@@ -3406,7 +3461,13 @@ export function EditorView(props) {
|
|
|
3406
3461
|
leftLabel: svnDiff.leftLabel,
|
|
3407
3462
|
rightLabel: svnDiff.rightLabel,
|
|
3408
3463
|
onBack: svnDiff.logTarget !== undefined ? backToSvnLog : undefined,
|
|
3409
|
-
onClose: () =>
|
|
3464
|
+
onClose: () => {
|
|
3465
|
+
setSvnDiff(null)
|
|
3466
|
+
if (svnUpdateReturn?.from === 'diff') {
|
|
3467
|
+
setSvnUpdateDialog(svnUpdateReturn.dialog)
|
|
3468
|
+
setSvnUpdateReturn(null)
|
|
3469
|
+
}
|
|
3470
|
+
},
|
|
3410
3471
|
})
|
|
3411
3472
|
} else if (!monaco && !monacoErr) {
|
|
3412
3473
|
body = loadingBody(loadStage.message, loadStage.progress)
|
|
@@ -3574,6 +3635,7 @@ export function EditorView(props) {
|
|
|
3574
3635
|
svnChanges,
|
|
3575
3636
|
svnChangeMap: svnChangeMapMemo,
|
|
3576
3637
|
openSvnDiff: (p) => runSvnDiffBase(p),
|
|
3638
|
+
openSvnUpdate: (p) => runSvnUpdate(p),
|
|
3577
3639
|
openSvnLocalPair: runSvnDiffLocalPair,
|
|
3578
3640
|
refreshSvnChanges: () => refreshSvnChanges(sessionId, scope),
|
|
3579
3641
|
openSvnLog: (p) => openSvnLog(p),
|
|
@@ -3726,49 +3788,11 @@ export function EditorView(props) {
|
|
|
3726
3788
|
React.createElement('button', { className: 'edrv-pill edrv-pill-ghost', title: '复制安装命令', onClick: copyInstallCmd }, '复制命令'),
|
|
3727
3789
|
React.createElement('button', { className: 'edrv-side-hint-close', title: '关闭提示', 'aria-label': '关闭提示', onClick: dismissHint }, '×'))
|
|
3728
3790
|
: null
|
|
3729
|
-
/**
|
|
3730
|
-
* SVN 更新结果条(P3):逐条展示 update 的条目级状态,冲突红字高亮,可关闭。
|
|
3731
|
-
* 只在本次 update 有条目明细时渲染(无明细/失败时不占用编辑区高度)。
|
|
3732
|
-
* @author ddj 2026年09月16号
|
|
3733
|
-
* @returns 结果条元素或 null
|
|
3734
|
-
*/
|
|
3735
|
-
const svnResultBar = () => {
|
|
3736
|
-
const result = svnUpdateResult
|
|
3737
|
-
if (!result || !result.entries.length) return null
|
|
3738
|
-
const conflicts = new Set(result.conflicts ?? [])
|
|
3739
|
-
return React.createElement('div', { className: 'edrv-svnres' },
|
|
3740
|
-
React.createElement('span', { className: 'edrv-svnres-head' }, 'SVN 更新'),
|
|
3741
|
-
React.createElement('div', { className: 'edrv-svnres-list' },
|
|
3742
|
-
result.entries.map((entry, idx) => React.createElement('span', {
|
|
3743
|
-
key: entry.path + ':' + idx,
|
|
3744
|
-
className: 'edrv-svnres-item' + (conflicts.has(entry.path) ? ' edrv-svnres-conflict' : ''),
|
|
3745
|
-
title: entry.label + ' ' + entry.path,
|
|
3746
|
-
}, entry.action + ' ' + entry.path))),
|
|
3747
|
-
React.createElement('span', { style: { flex: 1 } }),
|
|
3748
|
-
(conflicts.size
|
|
3749
|
-
? React.createElement('button', {
|
|
3750
|
-
className: 'edrv-svn-act',
|
|
3751
|
-
title: '在工作区中显示第一个冲突文件',
|
|
3752
|
-
onClick: () => {
|
|
3753
|
-
const first = [...conflicts][0]
|
|
3754
|
-
const hit = result.entries.find((entry) => entry.path === first)
|
|
3755
|
-
if (hit?.path) openFile(hit.path, false)
|
|
3756
|
-
},
|
|
3757
|
-
}, '查看冲突文件')
|
|
3758
|
-
: null),
|
|
3759
|
-
React.createElement('button', {
|
|
3760
|
-
className: 'edrv-svn-act',
|
|
3761
|
-
title: '关闭结果条',
|
|
3762
|
-
onClick: () => setSvnUpdateResult(null),
|
|
3763
|
-
}, '✕'))
|
|
3764
|
-
}
|
|
3765
|
-
|
|
3766
3791
|
const mainCol = React.createElement('div', { className: 'edrv-main-col', style: { flex: 1, minWidth: 0, minHeight: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden' } },
|
|
3767
3792
|
pathBar,
|
|
3768
3793
|
tabRow,
|
|
3769
3794
|
sideHintEl,
|
|
3770
3795
|
diskBanner(),
|
|
3771
|
-
svnResultBar(),
|
|
3772
3796
|
editorArea,
|
|
3773
3797
|
statusBar)
|
|
3774
3798
|
// 编辑器根节点按 composer 顶部边界动态限高,底部对话区域继续由 DSH 原生渲染。
|
|
@@ -3856,7 +3880,61 @@ export function EditorView(props) {
|
|
|
3856
3880
|
onComparePair: (revA, revB) => { setSvnLog(null); runSvnDiffPair(svnLog.target || '', revA, revB, svnLog.target || '') },
|
|
3857
3881
|
onCompareWorking: (revision) => { setSvnLog(null); runSvnDiffWorking(svnLog.target || '', revision, svnLog.target || '') },
|
|
3858
3882
|
onOpenFile: (relPath) => { setSvnLog(null); openFile(relPath, false) },
|
|
3859
|
-
onClose: () => {
|
|
3883
|
+
onClose: () => {
|
|
3884
|
+
setSvnLog(null)
|
|
3885
|
+
setSvnLogError('')
|
|
3886
|
+
if (svnUpdateReturn?.from === 'log') {
|
|
3887
|
+
setSvnUpdateDialog(svnUpdateReturn.dialog)
|
|
3888
|
+
setSvnUpdateReturn(null)
|
|
3889
|
+
}
|
|
3890
|
+
},
|
|
3891
|
+
})
|
|
3892
|
+
: null
|
|
3893
|
+
/**
|
|
3894
|
+
* 更新终态只刷新一次目录树与变更缓存,切到日志再返回不重复执行。
|
|
3895
|
+
* @author ddj 2026年09月24号
|
|
3896
|
+
* @param result 已结束的更新任务
|
|
3897
|
+
*/
|
|
3898
|
+
const onSvnUpdateDone = (result) => {
|
|
3899
|
+
if (svnUpdateDoneRef.current.has(result.jobId)) return
|
|
3900
|
+
svnUpdateDoneRef.current.add(result.jobId)
|
|
3901
|
+
const message = result.phase === 'completed' ? 'SVN 更新完成'
|
|
3902
|
+
: result.phase === 'cancelled' ? 'SVN 更新已取消(可能部分完成)' : 'SVN 更新失败:' + result.error
|
|
3903
|
+
setStatus(message)
|
|
3904
|
+
setRecentUpdate({ path: result.target, sessionId, scope, resumeJobId: result.jobId })
|
|
3905
|
+
refreshSvnChanges(sessionId, scope)
|
|
3906
|
+
emitRefresh()
|
|
3907
|
+
}
|
|
3908
|
+
const svnUpdateEl = sameUpdateOwner(svnUpdateDialog, sessionId, scope)
|
|
3909
|
+
? React.createElement(SvnUpdateDialog, {
|
|
3910
|
+
key: 'edrv-svn-update:' + svnUpdateDialog.path + ':' + (svnUpdateDialog.resumeJobId || ''),
|
|
3911
|
+
sessionId, cwd, path: svnUpdateDialog.path, resumeJobId: svnUpdateDialog.resumeJobId,
|
|
3912
|
+
childOverlay: updateOpenWith,
|
|
3913
|
+
onDone: onSvnUpdateDone, onNote: (message) => setStatus(message),
|
|
3914
|
+
onClose: () => setSvnUpdateDialog(null),
|
|
3915
|
+
onShowLog: (target, jobId) => {
|
|
3916
|
+
setSvnUpdateReturn({ from: 'log', dialog: { ...svnUpdateDialog, resumeJobId: jobId } })
|
|
3917
|
+
setSvnUpdateDialog(null)
|
|
3918
|
+
openSvnLog(target)
|
|
3919
|
+
},
|
|
3920
|
+
onCompare: (path, revision, jobId) => runSvnDiffWorking(path, revision, undefined, () => {
|
|
3921
|
+
setSvnUpdateReturn({ from: 'diff', dialog: { ...svnUpdateDialog, resumeJobId: jobId } })
|
|
3922
|
+
setSvnUpdateDialog(null)
|
|
3923
|
+
}),
|
|
3924
|
+
onOpenFile: (path) => openFile(path, false),
|
|
3925
|
+
onOpenWith: (path) => {
|
|
3926
|
+
if (!props.fileOpeners) { setStatus('打开方式不可用'); return }
|
|
3927
|
+
setUpdateOpenWith(true)
|
|
3928
|
+
openWithDialog(props.fileOpeners, { sessionId, cwd: cwd ?? undefined }, path, (opener) => {
|
|
3929
|
+
setUpdateOpenWith(false)
|
|
3930
|
+
if (opener) setStatus('已用「' + opener.label + '」打开:' + baseNameOf(path))
|
|
3931
|
+
})
|
|
3932
|
+
},
|
|
3933
|
+
onOpenParent: (path) => {
|
|
3934
|
+
void revealPathInExplorer(sessionId, path).then((outcome) => {
|
|
3935
|
+
setStatus(outcome.ok ? '已打开父目录' : '打开父目录失败:' + (outcome.error ?? '未知错误'))
|
|
3936
|
+
})
|
|
3937
|
+
},
|
|
3860
3938
|
})
|
|
3861
3939
|
: null
|
|
3862
3940
|
// W2-1 补丁对话框 / W2-2 目录对比对话框:portal 到 body,与日志弹窗同一挂载方式
|
|
@@ -3954,6 +4032,7 @@ export function EditorView(props) {
|
|
|
3954
4032
|
tabMenuEl,
|
|
3955
4033
|
paletteEl,
|
|
3956
4034
|
svnLogEl,
|
|
4035
|
+
svnUpdateEl,
|
|
3957
4036
|
patchDialogEl,
|
|
3958
4037
|
sumDialogEl,
|
|
3959
4038
|
dlogEl,
|
|
@@ -3965,6 +4044,7 @@ export function EditorView(props) {
|
|
|
3965
4044
|
tabMenuEl,
|
|
3966
4045
|
paletteEl,
|
|
3967
4046
|
svnLogEl,
|
|
4047
|
+
svnUpdateEl,
|
|
3968
4048
|
patchDialogEl,
|
|
3969
4049
|
sumDialogEl,
|
|
3970
4050
|
dlogEl,
|