feat!: 合并 Git 面板与文件追踪为统一「文件变动」tab(双视角 + 统一 diff 栈)
在 PR #471(file-trace)基础上的演进: - 合并 tab:git tab(id 保留,兼容持久化布局)升级为「文件变动」双视角 tab——Git 视角(原 GitView 全部能力:staged/unstaged/提交/历史/worktree· 子仓库选择/右键菜单/确认弹窗)+ 本轮文件视角(原 file-trace:会话事件 日志实时折叠的模型读写编辑记录,按文件分组、新增类型筛选 chips、相对 时间);file-trace tab 移除(未随任何版本发布)。 - 统一 diff 组件:新 src/client/diff/ 模块(rows.ts 引擎 + DiffRows/ DiffFiles 渲染器 + highlight.ts 语法着色)——git diff 与会话操作 diff 共用一套渲染:mod 改写配对(del-run/add-run 对半标蓝)、行内字符级 高亮(修复了旧实现旧侧失配不高亮的问题,改为行对象身份键)、上下文 hunk 折叠、git hunk 间未输出区间按行号范围生成不可展开折叠、语法着色 色相落位 diff 三色空档、+n −m 统计 chips、行底色 tint;DiffTab 改用 该栈(git diff tab 从此也有高亮)。 - 交互:两视角共用底部可拖拽预览面板(点击文件/提交/操作即预览,不再 直接开 diff tab;面板可刷新、可键盘/拖拽调高、git 目标可一键展开为 独立 diff tab);视角选择与面板高度持久化在 tab.meta;git 行 XY 徽章 按状态字母着色;选中行高亮。 - i18n:fileTrace* 十键重命名为 changes* 前缀,git 键值更新为「文件 变动」,新增 7 键(视角/筛选/面板操作),全部 21 个词典同步。 - 结构:src/client/changes/(ChangesTab/GitLens/SessionLens/DiffPane/ ops)+ src/client/diff/;GitView/DiffView/filetrace/ 删除;git 样式 从 sidebar.module.css 迁至 changes.module.css。 - 测试:builtins 8→7(git tab 承接 badge pin)、diff-rows(unified 转换/mod 配对/间隙折叠/统计)、changes-tab(壳交互 jsdom)、 diff-files-collapse(原 DiffView 折叠行为钉住)、changes-ops(原 filetrace 数据层)、git-view-worktree 迁移至 GitLens;全量 1122 通过。 - 文档:README ×2 功能矩阵合并、external-plugin-guide §4.4 与内置清单 7 tab、mount e2e 菜单标题同步。
This commit is contained in:
@@ -2177,141 +2177,9 @@ body[data-dsh-sidebar-dragging] .bottomPanel {
|
||||
color: var(--dsw-alias-state-error-primary);
|
||||
}
|
||||
|
||||
/* ── Git ───────────────────────────────────────────────────────────────── */
|
||||
|
||||
.git {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
/* Tab pages never scroll horizontally: content wraps or truncates to the
|
||||
panel width instead of panning sideways. */
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.gitHeader {
|
||||
flex: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
height: 36px;
|
||||
padding: 0 8px 0 12px;
|
||||
}
|
||||
|
||||
.gitWorktreeRow {
|
||||
flex: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 8px 0 12px;
|
||||
}
|
||||
|
||||
.gitWorktreeLabel {
|
||||
flex: none;
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
font: var(--dsw-font-xxxs-11);
|
||||
}
|
||||
|
||||
.gitBranchSelect {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
height: 26px;
|
||||
padding: 0 6px;
|
||||
border: 1px solid var(--dsw-alias-border-l2);
|
||||
border-radius: 6px;
|
||||
background: var(--dsw-alias-bg-base);
|
||||
color: var(--dsw-alias-label-primary);
|
||||
font: var(--dsw-font-xxs-12);
|
||||
}
|
||||
|
||||
.gitSection {
|
||||
border-top: 1px solid var(--dsw-alias-border-l1);
|
||||
}
|
||||
|
||||
.gitSectionHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 6px 12px 4px;
|
||||
font: var(--dsw-font-xxxs-strong-11);
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.gitLink {
|
||||
border: none;
|
||||
background: transparent;
|
||||
font: var(--dsw-font-xxxs-11);
|
||||
color: var(--dsw-alias-brand-primary);
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.gitLink:hover:not(:disabled) {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.gitLink:disabled {
|
||||
opacity: 0.4;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.gitRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
min-height: 34px;
|
||||
margin: 0 6px;
|
||||
padding: 0 8px;
|
||||
border-radius: 8px;
|
||||
animation: dsh-row-in 150ms var(--ds-ease-in-out);
|
||||
}
|
||||
|
||||
.gitRow:hover {
|
||||
background: var(--dsw-alias-interactive-bg-hover);
|
||||
}
|
||||
|
||||
.gitRowSelected {
|
||||
background: var(--dsw-alias-interactive-bg-active);
|
||||
}
|
||||
|
||||
.gitRowMain {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
padding: 3px 0;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.gitBadge {
|
||||
flex: none;
|
||||
width: 20px;
|
||||
height: 16px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
font: var(--dsw-font-xxxs-strong-11);
|
||||
background: var(--dsw-alias-interactive-bg-hover);
|
||||
color: var(--dsw-alias-label-secondary);
|
||||
}
|
||||
|
||||
.gitName {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font: var(--dsw-font-s-14);
|
||||
color: var(--dsw-alias-label-primary);
|
||||
}
|
||||
/* ── Diff tab (generic states + shell; the changes tab owns the rest in
|
||||
changes.module.css, and the diff rows themselves live in
|
||||
diff/diff.module.css) ────────────────────────────────────────────────── */
|
||||
|
||||
.gitEmpty {
|
||||
padding: 4px 12px 8px;
|
||||
@@ -2333,13 +2201,9 @@ body[data-dsh-sidebar-dragging] .bottomPanel {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.gitDiff {
|
||||
border-top: 1px solid var(--dsw-alias-border-l1);
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* The diff tab (a change opened from the git panel, like VSCode's diff
|
||||
editor): header + scrollable diff body, no horizontal panning. */
|
||||
/* The diff tab (a change expanded from the changes tab's preview, like
|
||||
VSCode's diff editor): header + scrollable diff body, no horizontal
|
||||
panning; rows render through the shared diff module. */
|
||||
.gitDiffTab {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
@@ -2370,276 +2234,12 @@ body[data-dsh-sidebar-dragging] .bottomPanel {
|
||||
color: var(--dsw-alias-label-primary);
|
||||
}
|
||||
|
||||
/* One changed file's section: path header, hunk headers, aligned lines. */
|
||||
.gitDiffFile {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 6px;
|
||||
padding: 8px 2px 2px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.gitDiffFile:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.gitDiffFile:hover:not(:disabled) {
|
||||
background: var(--dsw-alias-interactive-bg-hover);
|
||||
}
|
||||
|
||||
.gitDiffFileChevron {
|
||||
flex: none;
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
.gitDiffFileChevronExpanded {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.gitDiffFilePath {
|
||||
font: var(--dsw-font-xxs-strong-12);
|
||||
color: var(--dsw-alias-label-primary);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.gitDiffFileOld {
|
||||
flex: none;
|
||||
font: var(--dsw-font-xxxs-11);
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 40%;
|
||||
}
|
||||
|
||||
.gitDiffFileTag {
|
||||
flex: none;
|
||||
padding: 0 6px;
|
||||
border: 1px solid var(--dsw-alias-border-l2);
|
||||
border-radius: 999px;
|
||||
font: var(--dsw-font-xxxs-strong-11);
|
||||
color: var(--dsw-alias-label-secondary);
|
||||
}
|
||||
|
||||
.gitDiffHunk {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
padding: 3px 2px;
|
||||
font: var(--dsw-font-markdown-code-block-small);
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
}
|
||||
|
||||
.gitDiffHunkHeader {
|
||||
flex: none;
|
||||
color: var(--dsw-alias-label-secondary);
|
||||
}
|
||||
|
||||
.gitDiffHunkSection {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* One aligned diff line: old gutter / new gutter / code. Lines WRAP instead
|
||||
of scrolling horizontally (the tab-page rule: fill the width adaptively),
|
||||
with the long-token fallback breaking anywhere a space never comes. */
|
||||
.gitDiffLine {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
font: var(--dsw-font-markdown-code-block-small);
|
||||
line-height: 20px;
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: anywhere;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.gitDiffNum {
|
||||
flex: none;
|
||||
width: 36px;
|
||||
padding-right: 8px;
|
||||
text-align: right;
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.gitDiffCode {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.gitDiffCtx {
|
||||
color: var(--dsw-alias-label-primary);
|
||||
}
|
||||
|
||||
.gitDiffDel {
|
||||
color: var(--dsw-alias-state-error-primary);
|
||||
background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent);
|
||||
}
|
||||
|
||||
.gitDiffAdd {
|
||||
color: var(--dsw-alias-state-success-primary);
|
||||
background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 12%, transparent);
|
||||
}
|
||||
|
||||
.gitDiffMeta {
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.gitDiffMetaText {
|
||||
font: var(--dsw-font-xxxs-11);
|
||||
font-style: italic;
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
}
|
||||
|
||||
.gitDiffExpand {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 4px 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font: var(--dsw-font-xxs-12);
|
||||
color: var(--dsw-alias-brand-primary);
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.gitDiffExpand:hover {
|
||||
background: var(--dsw-alias-interactive-bg-hover);
|
||||
}
|
||||
|
||||
.gitConfirmDesc {
|
||||
margin: 0;
|
||||
font: var(--dsw-font-s-14);
|
||||
color: var(--dsw-alias-label-primary);
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.gitCommit {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
padding: 8px 12px;
|
||||
border-top: 1px solid var(--dsw-alias-border-l1);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.gitCommitInput {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.gitCommitButton {
|
||||
flex: none;
|
||||
height: 26px;
|
||||
padding: 0 12px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
background: var(--dsw-alias-button-primary-fill);
|
||||
color: var(--dsw-alias-label-primary-inverted);
|
||||
font: var(--dsw-font-xxs-strong-12);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.gitCommitButton:hover:not(:disabled) {
|
||||
background: var(--dsw-alias-button-primary-hover);
|
||||
}
|
||||
|
||||
.gitCommitButton:disabled {
|
||||
opacity: 0.45;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* A history row: line 1 = hash + subject, line 2 = ref badges + author/date
|
||||
(badges live on the second line so they never crowd the subject). */
|
||||
.gitLogRow {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
padding: 5px 12px;
|
||||
cursor: pointer;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.gitLogRow:hover {
|
||||
background: var(--dsw-alias-interactive-bg-hover);
|
||||
}
|
||||
|
||||
.gitLogLine1 {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.gitLogHash {
|
||||
flex: none;
|
||||
font: var(--dsw-font-markdown-code-block-small);
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
}
|
||||
|
||||
.gitLogLine2 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.gitLogRef {
|
||||
flex: none;
|
||||
padding: 0 5px;
|
||||
border: 1px solid var(--dsw-alias-border-l2);
|
||||
border-radius: 999px;
|
||||
font: var(--dsw-font-xxxs-strong-11);
|
||||
color: var(--dsw-alias-brand-primary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.gitLogSubject {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font: var(--dsw-font-s-14);
|
||||
color: var(--dsw-alias-label-primary);
|
||||
}
|
||||
|
||||
.gitLogMeta {
|
||||
font: var(--dsw-font-xxxs-11);
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
}
|
||||
|
||||
.gitLogMore {
|
||||
display: block;
|
||||
width: calc(100% - 24px);
|
||||
margin: 4px 12px 8px;
|
||||
padding: 6px 0;
|
||||
border: 1px solid var(--dsw-alias-border-l2);
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
font: var(--dsw-font-xxs-12);
|
||||
color: var(--dsw-alias-label-secondary);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.gitLogMore:hover:not(:disabled) {
|
||||
background: var(--dsw-alias-interactive-bg-hover);
|
||||
color: var(--dsw-alias-label-primary);
|
||||
}
|
||||
|
||||
.gitLogMore:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* ── Intercepted produced-files row ────────────────────────────────────── */
|
||||
|
||||
@@ -2700,13 +2300,6 @@ body[data-dsh-sidebar-dragging] .bottomPanel {
|
||||
.paneCard:focus-visible,
|
||||
.explorerRow:focus-visible,
|
||||
.explorerRef:focus-visible,
|
||||
.gitRowMain:focus-visible,
|
||||
.gitLink:focus-visible,
|
||||
.gitCommitButton:focus-visible,
|
||||
.gitLogRow:focus-visible,
|
||||
.gitLogMore:focus-visible,
|
||||
.gitDiffFile:focus-visible,
|
||||
.gitDiffExpand:focus-visible,
|
||||
.terminalRetry:focus-visible,
|
||||
.editorModeButton:focus-visible,
|
||||
.editorDownloadLink:focus-visible,
|
||||
@@ -2728,7 +2321,6 @@ body[data-dsh-sidebar-dragging] .bottomPanel {
|
||||
.tabBarPlus,
|
||||
.paneCard,
|
||||
.explorerRow,
|
||||
.gitRow,
|
||||
.divider,
|
||||
.dividerRow::after,
|
||||
.dividerCol::after {
|
||||
|
||||
Reference in New Issue
Block a user