✨ feat(vscode): 代码阅读契约加命令规则(按命令名注册、读一条命令)、按位置的参数 / 输出 / 返回、解释器和选项块、分情况 / 命令 / 管道种类、常量色;模板引擎加节点读法;没有定义、高亮提供者的语言用语言插件认的同一文件里的名字跳转、高亮
This commit is contained in:
1 parent
cf09c24730
commit
ff2a44f080
17 files changed
+555
-60
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import type { CustomTextEditorProvider, Disposable, TextDocument, TextDocumentShowOptions, Uri, WebviewPanel } from 'vscode'
|
||||
import type { ClaudeImage } from '../../cc/spawnClaude'
|
||||
import type { BlockView } from '../blockView'
|
||||
import type { BlockKind, RuleLocation, RuleReference, WorkspaceIndex } from '../contract'
|
||||
import type { BlockKind, LocalSymbol, RuleLocation, RuleReference, WorkspaceIndex } from '../contract'
|
||||
import type { DefinitionStart, IndexedName, NameSources } from '../nameResolution'
|
||||
import type { CodeQa } from '../qa/codeQa'
|
||||
import type { CodeReaderRegistry } from '../registry'
|
||||
@@ -10,13 +10,14 @@ import type { TreeSitterRuntime } from '../runtime'
|
||||
import type { IndexedEntry } from '../workspaceIndex'
|
||||
import type { BlockFilter } from './blockFilter'
|
||||
import type { Definition, FoundLocation } from './definitions'
|
||||
import type { ExtensionToWebview, Reveal, WebviewToExtension } from './messages'
|
||||
import type { ExtensionToWebview, Occurrence, Reveal, WebviewToExtension } from './messages'
|
||||
import { commands, Range, window, workspace, WorkspaceEdit } from 'vscode'
|
||||
import { logger } from '../../logging/logger'
|
||||
import { webviewHtml, webviewUiRoot } from '../../webview/html'
|
||||
import { DocumentCallees } from '../calleeKinds'
|
||||
import { blockReplacement } from '../editText'
|
||||
import { locate } from '../folderStore'
|
||||
import { definitionFor, symbolAt, symbolOccurrences } from '../localSymbols'
|
||||
import { DocumentNames, resolveNames } from '../nameResolution'
|
||||
import { askPrompt, followUpPrompt } from '../qa/prompt'
|
||||
import { DocumentLookups } from '../ruleLookups'
|
||||
@@ -128,6 +129,8 @@ class Preview {
|
||||
visibleLine: number | undefined
|
||||
/** 最近一次发出去的块树和它的源码:问 AI 时按块的记号在里面找那块代码 */
|
||||
private sent: { blocks: BlockView[], source: string } | undefined
|
||||
/** 最近一次发出去的文档里语言插件自己认得出的名字(LanguageAdapter.symbols):语言扩展查不到定义、各处出现时用 */
|
||||
private symbols: { version: number, list: LocalSymbol[] } | undefined
|
||||
/** 这份文档各版本显示成中文名的名字 */
|
||||
private readonly names: DocumentNames
|
||||
/** 库规则问的名字的定义查到了什么:查到的变了就重发文档 */
|
||||
@@ -150,7 +153,10 @@ class Preview {
|
||||
) {
|
||||
this.definitions = new DefinitionSources({
|
||||
rule: async reference => ruleDefinitions(await owner.resolveReference(reference)),
|
||||
language: offset => languageDefinitions(document.uri, document.positionAt(offset)),
|
||||
language: async (offset) => {
|
||||
const found = await languageDefinitions(document.uri, document.positionAt(offset))
|
||||
return found.length > 0 ? found : this.localDefinitions(offset)
|
||||
},
|
||||
})
|
||||
this.names = new DocumentNames((version, names) => {
|
||||
if (this.ready && version === document.version)
|
||||
@@ -228,13 +234,14 @@ class Preview {
|
||||
const source = this.document.getText()
|
||||
const session = this.lookups.session()
|
||||
const callees = this.callees.session()
|
||||
const { message, displayNames } = await documentMessage({ languageId, version, getText: () => source }, this.registry, this.runtime, (text) => {
|
||||
const { message, displayNames, symbols } = await documentMessage({ languageId, version, getText: () => source }, this.registry, this.runtime, (text) => {
|
||||
logger.add({ level: 'warn', source: 'codeReader', message: `${this.document.uri.fsPath}:${text}` })
|
||||
}, session.lookup, callees.calleeKind)
|
||||
if (request !== this.latest || !this.ready)
|
||||
return
|
||||
this.definitions.remember(message.version, message.blocks)
|
||||
this.sent = { blocks: message.blocks, source }
|
||||
this.symbols = { version, list: symbols }
|
||||
const reveal = this.pendingReveal
|
||||
this.pendingReveal = undefined
|
||||
this.post({ ...message, names: this.names.known(version), ...(reveal && { reveal }) })
|
||||
@@ -260,6 +267,28 @@ class Preview {
|
||||
return null
|
||||
}
|
||||
|
||||
/** 这份文档里语言插件自己认得出、盖住 offset 的名字(只认最近一次发出去的那个版本)。 */
|
||||
private localSymbol(offset: number): LocalSymbol | undefined {
|
||||
return this.symbols?.version === this.document.version ? symbolAt(this.symbols.list, offset) : undefined
|
||||
}
|
||||
|
||||
/** 语言扩展查不到定义时:语言插件自己认得出的名字的定义(见 definitionFor)。 */
|
||||
private localDefinitions(offset: number): FoundLocation[] {
|
||||
const symbol = this.localSymbol(offset)
|
||||
const target = symbol && definitionFor(symbol, offset)
|
||||
if (!target)
|
||||
return []
|
||||
const { document } = this
|
||||
return [{ uri: document.uri, range: new Range(document.positionAt(target.startIndex), document.positionAt(target.endIndex)) }]
|
||||
}
|
||||
|
||||
/** offset 处名字的各处出现:先问语言扩展,它答不上来时用语言插件自己认得出的名字(见 symbolOccurrences)。 */
|
||||
private async occurrences(offset: number): Promise<Occurrence[]> {
|
||||
const found = await occurrencesOf(this.document, offset)
|
||||
const symbol = found.length > 0 ? undefined : this.localSymbol(offset)
|
||||
return symbol ? symbolOccurrences(symbol) : found
|
||||
}
|
||||
|
||||
/** 这份文档里 offset 处名字的定义(语言扩展查的)落在哪儿。 */
|
||||
private async definitionStarts(offset: number): Promise<DefinitionStart[]> {
|
||||
const { document } = this
|
||||
@@ -272,7 +301,7 @@ class Preview {
|
||||
const { document } = this
|
||||
return {
|
||||
uri: document.uri.toString(),
|
||||
occurrences: async offset => (await occurrencesOf(document, offset)).map(({ start, end }) => ({ start, end })),
|
||||
occurrences: async offset => (await this.occurrences(offset)).map(({ start, end }) => ({ start, end })),
|
||||
definitions: offset => this.definitionStarts(offset),
|
||||
indexed: name => this.owner.indexedNames(document.languageId, name),
|
||||
}
|
||||
@@ -403,7 +432,7 @@ class Preview {
|
||||
const { document } = this
|
||||
if (version !== document.version)
|
||||
return
|
||||
const occurrences = await occurrencesOf(document, offset)
|
||||
const occurrences = await this.occurrences(offset)
|
||||
if (version === document.version && this.ready)
|
||||
this.post({ type: 'occurrencesFound', id, occurrences })
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user