✨ feat(vscode): 代码阅读预览问 AI 的回答里代码位置写成链接、点了能跳:提示词要求写 [名字](路径#符号) 或 [文件名:起-止](路径#L起-L止) 并给出仓库根,仓库链接认 #L 行号(注释里同一套),旧回答里整段是「路径:行」的行内代码也当链接,带行号的在预览里展开、闪包住那几行的块,不支持预览的用文本编辑器选中
This commit is contained in:
1 parent
ceeaad91a7
commit
e401e4aec3
22 files changed
+516
-90
No files matched your search
@@ -15,7 +15,7 @@ import type { ThemeColors } from '../theme/codeColors'
|
||||
import type { IndexFind } from '../workspaceIndex'
|
||||
import type { BlockFilter } from './blockFilter'
|
||||
import type { FoundLocation } from './definitions'
|
||||
import type { ChatKind, DefinitionPeek, ExtensionToWebview, Occurrence, Reveal, SymbolReference, WebviewToExtension } from './messages'
|
||||
import type { ChatKind, DefinitionPeek, ExtensionToWebview, LineRange, Occurrence, Reveal, SymbolReference, WebviewToExtension } from './messages'
|
||||
import type { TargetSpot } from './openTarget'
|
||||
import type { TopSubject } from './pathPreview'
|
||||
import { realpath } from 'node:fs/promises'
|
||||
@@ -47,7 +47,7 @@ import { documentSymbolNodes } from './documentSymbols'
|
||||
import { FIND_CONTEXT } from './findCommands'
|
||||
import { NavigationContext, OCCURRENCES_CONTEXT } from './occurrenceNavigation'
|
||||
import { occurrencesOf } from './occurrences'
|
||||
import { languageOf, openingFor } from './openTarget'
|
||||
import { languageOf, linesSpot, openingFor, revealOf } from './openTarget'
|
||||
import { PATH_PREVIEW_SCHEME, topSubjectOf } from './pathPreview'
|
||||
import { findRepoSymbol, isRepoImagePath, repoRootOf, resolveRepoEntry } from './repoPath'
|
||||
|
||||
@@ -650,7 +650,8 @@ class Preview {
|
||||
return
|
||||
}
|
||||
const at = locateQa(subject.uri)
|
||||
const block = at && this.sent && { path: at.promptPath, languageId: this.document.languageId, blocks: this.sent.blocks, source: this.sent.source, anchor }
|
||||
const repoRoot = await repoRootOf(this.document.uri.fsPath)
|
||||
const block = at && this.sent && { path: at.promptPath, languageId: this.document.languageId, blocks: this.sent.blocks, source: this.sent.source, anchor, ...(repoRoot !== undefined && { repoRoot }) }
|
||||
const prompt = block && askPrompt(block, question)
|
||||
const followUp = block && followUpPrompt(block, question)
|
||||
const refused = prompt === undefined || followUp === undefined
|
||||
@@ -754,7 +755,7 @@ class Preview {
|
||||
await this.findOccurrences(msg.id, msg.version, msg.offset)
|
||||
return
|
||||
case 'openRepoLink':
|
||||
await this.openRepoLink(msg.path, msg.symbol, msg.block)
|
||||
await this.openRepoLink(msg.path, msg.symbol, msg.block, msg.lines)
|
||||
return
|
||||
case 'checkRepoLinks':
|
||||
await this.checkRepoLinks(msg.id, msg.paths, msg.references)
|
||||
@@ -985,10 +986,11 @@ class Preview {
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开注释里的仓库链接:目录在代码阅读侧栏的树上定位,文件用编辑器打开。
|
||||
* 带了符号就按文档符号的名字跳过去;文件或符号没有就不打开。没有路径的是不带路径的引用,按这份文件、从它写在的那块(block)找(见 resolveSymbolLink)。
|
||||
* 打开注释、问 AI 的回答里的仓库链接:目录在代码阅读侧栏的树上定位,文件用编辑器打开。
|
||||
* 带了符号就按文档符号的名字跳过去,带了几行(`lines`)就跳到这几行(见 [linesSpot]);文件或符号没有就不打开。
|
||||
* 没有路径的是不带路径的引用,按这份文件、从它写在的那块(`block`)找(见 [resolveSymbolLink])。
|
||||
*/
|
||||
private async openRepoLink(rel: string | undefined, symbol?: string, block?: string): Promise<void> {
|
||||
private async openRepoLink(rel: string | undefined, symbol?: string, block?: string, lines?: LineRange): Promise<void> {
|
||||
const link = rel ?? `[${symbol}]`
|
||||
try {
|
||||
if (symbol !== undefined) {
|
||||
@@ -1016,7 +1018,8 @@ class Preview {
|
||||
this.markRepoLinkOpened(rel)
|
||||
return
|
||||
}
|
||||
await this.openElsewhere(uri)
|
||||
const spot = lines && await linesSpot(uri, lines)
|
||||
await (spot ? this.showSpot(uri, spot) : this.openElsewhere(uri))
|
||||
this.markRepoLinkOpened(rel)
|
||||
}
|
||||
catch (err) {
|
||||
@@ -1071,14 +1074,19 @@ class Preview {
|
||||
}
|
||||
}
|
||||
|
||||
/** 跳到链接指的符号:在这份文件里就在本预览里滚过去、闪一下;别的文件同 ⌘ + 点击跳到定义(见 openElsewhere)。 */
|
||||
/** 跳到链接指的符号:名字那段是要选中的范围,起点下标是预览要闪的定义处(见 [showSpot])。 */
|
||||
private async showLinkTarget({ uri, selection }: LinkTarget): Promise<void> {
|
||||
if (uri === this.document.uri.toString()) {
|
||||
this.reveal({ line: this.document.positionAt(selection.startIndex).line, definition: selection.startIndex })
|
||||
const doc = uri === this.document.uri.toString() ? this.document : await workspace.openTextDocument(Uri.parse(uri))
|
||||
await this.showSpot(doc.uri, { range: new Range(doc.positionAt(selection.startIndex), doc.positionAt(selection.endIndex)), offset: selection.startIndex })
|
||||
}
|
||||
|
||||
/** 跳到链接指的一处(符号或几行):在这份文件里就在本预览里滚过去、闪一下;别的文件同 ⌘ + 点击跳到定义(见 [openElsewhere])。 */
|
||||
private async showSpot(uri: Uri, spot: TargetSpot): Promise<void> {
|
||||
if (uri.toString() === this.document.uri.toString()) {
|
||||
this.reveal(revealOf(spot))
|
||||
return
|
||||
}
|
||||
const doc = await workspace.openTextDocument(Uri.parse(uri))
|
||||
await this.openElsewhere(doc.uri, { range: new Range(doc.positionAt(selection.startIndex), doc.positionAt(selection.endIndex)), offset: selection.startIndex })
|
||||
await this.openElsewhere(uri, spot)
|
||||
}
|
||||
|
||||
private markRepoLinkBroken(path: string | undefined, symbol?: string, block?: string): void {
|
||||
|
||||
Reference in new issue
Block a user