✨ feat(vscode): 代码阅读「了解一块代码」改成按路径列调用树:结果是几条路径(用户的一种操作一条),每条从入口一路调到后端服务、数据表,跨进程的写明怎么连过去(via),结构用扁平的 nodes 加 parent 连成树、不用递归;侧栏路径下面一层层展开节点,回答里用嵌套列表画树;回答和找的过程里的代码位置写成仓库链接,功能对话页上的链接按找代码用的工作区文件夹检查、打开、悬停;旧格式的结果当没有,栏上方提示打开对话重新找;删功能前先弹模态框确认,说清连带删掉调用树和问答记录,点「删除」才删
This commit is contained in:
1 parent
cc445e7123
commit
c6de46ad37
17 files changed
+978
-253
No files matched your search
@@ -17,7 +17,8 @@ import type { BlockFilter } from './blockFilter'
|
||||
import type { FoundLocation } from './definitions'
|
||||
import type { ChatKind, DefinitionPeek, ExtensionToWebview, LineRange, Occurrence, Reveal, SymbolReference, WebviewToExtension } from './messages'
|
||||
import type { TargetSpot } from './openTarget'
|
||||
import type { TopSubject } from './pathPreview'
|
||||
import type { LinkBase, TopSubject } from './pathPreview'
|
||||
import type { RepoEntry } from './repoPath'
|
||||
import { realpath } from 'node:fs/promises'
|
||||
import { commands, EndOfLine, Position, Range, Uri, window, workspace, WorkspaceEdit } from 'vscode'
|
||||
import { logger } from '../../logging/logger'
|
||||
@@ -49,7 +50,7 @@ import { FIND_CONTEXT } from './findCommands'
|
||||
import { NavigationContext, OCCURRENCES_CONTEXT } from './occurrenceNavigation'
|
||||
import { occurrencesOf } from './occurrences'
|
||||
import { languageOf, linesSpot, openingFor, revealOf } from './openTarget'
|
||||
import { PATH_PREVIEW_SCHEME, topSubjectOf } from './pathPreview'
|
||||
import { linkBaseOf, PATH_PREVIEW_SCHEME, topSubjectOf } from './pathPreview'
|
||||
import { ReferenceTargets } from './referenceTargets'
|
||||
import { findRepoSymbol, isRepoImagePath, repoRootOf, resolveRepoEntry } from './repoPath'
|
||||
|
||||
@@ -950,15 +951,11 @@ class Preview {
|
||||
}
|
||||
}
|
||||
|
||||
/** 预览里这批仓库路径,哪些文件或目录不在;这批不带路径的引用,各按写在哪块找,哪些找不到、哪些是语言自带的名字(页面当普通文字)。 */
|
||||
/** 预览里这批仓库路径(从哪儿算见 [linkBaseOf]),哪些文件或目录不在;这批不带路径的引用,各按写在哪块找,哪些找不到、哪些是语言自带的名字(页面当普通文字)。 */
|
||||
private async checkRepoLinks(id: number, paths: string[], references: SymbolReference[]): Promise<void> {
|
||||
const root = await repoRootOf(this.document.uri.fsPath)
|
||||
const base = await linkBaseOf(this.document.uri)
|
||||
const [missing, resolved] = await Promise.all([
|
||||
Promise.all(paths.map(async (rel) => {
|
||||
if (root === undefined || await resolveRepoEntry(root, rel) === undefined)
|
||||
return rel
|
||||
return undefined
|
||||
})),
|
||||
Promise.all(paths.map(async rel => await linkEntry(base, rel) === undefined ? rel : undefined)),
|
||||
Promise.all(references.map(async reference => ({ reference, target: await this.resolveSymbolLink(reference) }))),
|
||||
])
|
||||
this.post({
|
||||
@@ -993,13 +990,13 @@ class Preview {
|
||||
|
||||
/** 这批仓库图片哪些在。在的带回预览里能直接用的地址;不在、不是图片、跑出仓库的没有地址。 */
|
||||
private async checkRepoImages(id: number, paths: string[]): Promise<void> {
|
||||
const root = await repoRootOf(this.document.uri.fsPath)
|
||||
if (root)
|
||||
await this.allowRepoRoot(root)
|
||||
const base = await linkBaseOf(this.document.uri)
|
||||
const images = await Promise.all(paths.map(async (rel) => {
|
||||
if (root === undefined || !isRepoImagePath(rel))
|
||||
const place = isRepoImagePath(rel) ? base(rel) : undefined
|
||||
if (!place)
|
||||
return { path: rel }
|
||||
const entry = await resolveRepoEntry(root, rel)
|
||||
await this.allowRepoRoot(place.root)
|
||||
const entry = await resolveRepoEntry(place.root, place.rel)
|
||||
if (!entry || entry.isDirectory)
|
||||
return { path: rel }
|
||||
const src = this.panel.webview.asWebviewUri(Uri.file(entry.fsPath)).toString()
|
||||
@@ -1032,8 +1029,7 @@ class Preview {
|
||||
}
|
||||
if (rel === undefined)
|
||||
return
|
||||
const root = await repoRootOf(this.document.uri.fsPath)
|
||||
const entry = root === undefined ? undefined : await resolveRepoEntry(root, rel)
|
||||
const entry = await linkEntry(await linkBaseOf(this.document.uri), rel)
|
||||
if (!entry) {
|
||||
this.markRepoLinkBroken(rel)
|
||||
return
|
||||
@@ -1064,8 +1060,7 @@ class Preview {
|
||||
private async symbolTarget(rel: string | undefined, symbol: string, block: string | undefined): Promise<ReferenceTarget> {
|
||||
if (rel === undefined)
|
||||
return this.resolveSymbolLink({ symbol, block })
|
||||
const root = await repoRootOf(this.document.uri.fsPath)
|
||||
const entry = root === undefined ? undefined : await resolveRepoEntry(root, rel)
|
||||
const entry = await linkEntry(await linkBaseOf(this.document.uri), rel)
|
||||
return entry && !entry.isDirectory ? this.locateRepoSymbol(Uri.file(entry.fsPath), symbol) : undefined
|
||||
}
|
||||
|
||||
@@ -1167,6 +1162,12 @@ class Preview {
|
||||
}
|
||||
}
|
||||
|
||||
/** 一条仓库链接指到磁盘上的哪个文件或目录,路径按这一页的算法算(见 [linkBaseOf]);算不出来、不在、跑出根的没有。 */
|
||||
async function linkEntry(base: LinkBase, rel: string): Promise<RepoEntry | undefined> {
|
||||
const place = base(rel)
|
||||
return place && resolveRepoEntry(place.root, place.rel)
|
||||
}
|
||||
|
||||
/** 写回重写好的注释:换掉原来那几行(同块编辑),或在块上面插进新写的几行。 */
|
||||
async function writeCommentEdit(document: TextDocument, edit: CommentEdit): Promise<WriteResult> {
|
||||
if (edit.kind === 'replace')
|
||||
|
||||
Reference in new issue
Block a user