✨ feat(vscode): 代码阅读预览按侧栏筛选算代码差异(未提交的更改对比上一次提交、审查对比 PR 目标分支;兄弟块按名字 / 相似度对齐,卡片内按行 / 值 / 词比对),算好后补发给预览
This commit is contained in:
1 parent
3db44f84ae
commit
2a5806c6b5
23 files changed
+1527
-31
No files matched your search
@@ -1,15 +1,18 @@
|
||||
import type { ExtensionContext, TreeView, WorkspaceFolder } from 'vscode'
|
||||
import type { ExtensionContext, TreeView, Uri, WorkspaceFolder } from 'vscode'
|
||||
import type { GitApi, GitRepository } from '../../git/gitApi'
|
||||
import type { DiffBase } from '../diff/diffBase'
|
||||
import type { ChangedFile } from '../explorer/changedTree'
|
||||
import type { ChangedSection, FileNode, FileTreeProvider, TreeNode } from '../explorer/fileTree'
|
||||
import type { TreeFilter, TreeFilters } from '../explorer/treeFilters'
|
||||
import type { UncommittedRoot } from './uncommittedFiles'
|
||||
import * as path from 'node:path'
|
||||
import { commands, Disposable, window, workspace } from 'vscode'
|
||||
import { fileAtRef } from '../../git/fileAt'
|
||||
import { loadGitApi } from '../../git/gitExtension'
|
||||
import { logger } from '../../logging/logger'
|
||||
import { buildChangedTree } from '../explorer/changedTree'
|
||||
import { uncommittedDescription, uncommittedMessage, uncommittedRoots, UNSTAGED_MARKER, withoutTestFiles, workspaceOrder } from './uncommittedFiles'
|
||||
import { toPathKey } from '../pathMap'
|
||||
import { HEAD_BASE_LABEL, headMissingText, isUntracked, uncommittedDescription, uncommittedMessage, uncommittedRoots, UNSTAGED_MARKER, withoutTestFiles, workspaceOrder } from './uncommittedFiles'
|
||||
|
||||
/** workspaceState:开着「未提交的更改」,重开窗口接着显示。 */
|
||||
const UNCOMMITTED_KEY = 'superpowers.codeReader.uncommitted'
|
||||
@@ -33,7 +36,7 @@ function errorText(err: unknown): string {
|
||||
/**
|
||||
* 侧栏只看未提交的更改:照源代码管理视图分「暂存的更改」「更改」两组(空的不摆),每组下面每个有改动的仓库一个根。
|
||||
* 文件就是工作区里的文件,颜色和 M / A / D 徽标由 VS Code 自带的 git 装饰加上;「更改」组里的文件行上有「暂存」按钮。
|
||||
* 可以隐藏测试文件。开着时盯着 git 状态自动重摆;「显示全部」回到工作区文件树。
|
||||
* 可以隐藏测试文件。开着时盯着 git 状态自动重摆,打开的预览对比上一次提交(diffBase);「显示全部」回到工作区文件树。
|
||||
* 开着没开、隐不隐藏测试文件都按工作区记住;和审查工单互斥,见 TreeFilters。
|
||||
*/
|
||||
export class UncommittedMode implements TreeFilter, Disposable {
|
||||
@@ -123,6 +126,24 @@ export class UncommittedMode implements TreeFilter, Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
/** 开着时,工作区仓库里的文件对比上一次提交(HEAD);不在工作区的仓库里(审查的工作副本、别处的文件)的不比。 */
|
||||
diffBase(uri: Uri): DiffBase | undefined {
|
||||
const repository = this.api?.getRepository(uri)
|
||||
if (!repository || workspaceOrder(repository.rootUri.path, workspace.workspaceFolders ?? []) < 0)
|
||||
return undefined
|
||||
const relative = toPathKey(repository.rootUri.path, uri.path)
|
||||
if (relative === undefined)
|
||||
return undefined
|
||||
const head = repository.state.HEAD?.commit
|
||||
const root = repository.rootUri.fsPath
|
||||
return {
|
||||
label: HEAD_BASE_LABEL,
|
||||
key: `${head ?? ''}:${relative}`,
|
||||
read: () => head ? fileAtRef(root, head, relative) : Promise.resolve(null),
|
||||
missing: headMissingText({ hasCommit: head !== undefined, untracked: isUntracked(repository.state, uri.path) }),
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.stopWatching()
|
||||
for (const disposable of this.disposables)
|
||||
@@ -173,12 +194,18 @@ export class UncommittedMode implements TreeFilter, Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
/** 盯着 git:各仓库的状态变了、开了 / 关了仓库、git 扩展找完仓库、工作区文件夹变了,都合成一次重摆。 */
|
||||
/**
|
||||
* 盯着 git:各仓库的状态变了、开了 / 关了仓库、git 扩展找完仓库、工作区文件夹变了,都合成一次重摆;
|
||||
* 打开着的预览也跟着重新比(提交后 HEAD 动了,对比的上一次提交就换了)。
|
||||
*/
|
||||
private watch(api: GitApi): Disposable {
|
||||
const repositories = new Map<GitRepository, Disposable>()
|
||||
const schedule = (): void => {
|
||||
clearTimeout(this.timer)
|
||||
this.timer = setTimeout(() => this.rebuild(), REBUILD_DELAY_MS)
|
||||
this.timer = setTimeout(() => {
|
||||
this.rebuild()
|
||||
this.filters.baseChanged(this)
|
||||
}, REBUILD_DELAY_MS)
|
||||
}
|
||||
const add = (repository: GitRepository): void => {
|
||||
if (!repositories.has(repository))
|
||||
|
||||
Reference in new issue
Block a user