✨ feat(vscode): 代码阅读的入口文件和入口块换成绿色播放图标,不再写「入口」二字
This commit is contained in:
1 parent
5827defd51
commit
f6bc217e91
10 files changed
+110
-53
No files matched your search
@@ -4,6 +4,7 @@ import type { LibraryRule } from '../contract'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { packageCommandRules } from '../commands/packageCommands'
|
||||
import { shellCommandRules } from '../commands/shellCommands'
|
||||
import { ENTRY_CONCEPT } from '../entries/entryMarks'
|
||||
import { createBashAdapter } from '../languages/bash'
|
||||
import { createDockerfileAdapter } from '../languages/dockerfile'
|
||||
import { createPythonAdapter } from '../languages/python'
|
||||
@@ -217,26 +218,62 @@ describe('入口文件的预览', () => {
|
||||
].join('\n')
|
||||
|
||||
const nameRow = (block: BlockView): string => 'properties' in block ? propertyLines(block.properties)[0] : ''
|
||||
const firstConcept = (block: BlockView): string => block.concepts[0].id
|
||||
|
||||
it('名字对上的块(变量、函数都算),名称那一行名字后面加浅色的「入口」', async () => {
|
||||
it('名字对上的块(变量、函数都算):概念列表第一个换成入口,名称后面不加字', async () => {
|
||||
const { message } = await documentMessage({ ...doc('python', CLI), entryNames: ['app', 'main'] }, registryWithPython(), runtime, ignore)
|
||||
expect(message.blocks.slice(1).map(nameRow)).toEqual(['名称: app 入口', '名称: main 入口', '名称: helper'])
|
||||
const [, app] = message.blocks
|
||||
expect('properties' in app && app.properties[0].value).toContainEqual({ text: ' 入口', role: 'hint' })
|
||||
const [, app, main, helper] = message.blocks
|
||||
expect([app, main].map(block => block.concepts)).toEqual([[ENTRY_CONCEPT], [ENTRY_CONCEPT]])
|
||||
expect(firstConcept(helper)).toBe('function')
|
||||
expect(message.blocks.slice(1).map(nameRow)).toEqual(['名称: app', '名称: main', '名称: helper'])
|
||||
expect(ENTRY_CONCEPT).toEqual({ id: 'entry', label: '入口', icon: 'play', color: { dark: 'var(--vscode-testing-iconPassed)', light: 'var(--vscode-testing-iconPassed)' } })
|
||||
})
|
||||
|
||||
it('对不上名字、不是入口:什么都不加', async () => {
|
||||
it('种类、筛选属性、属性表都不变,只换概念列表', async () => {
|
||||
const plain = await documentMessage(doc('python', CLI), registryWithPython(), runtime, ignore)
|
||||
const { message } = await documentMessage({ ...doc('python', CLI), entryNames: ['main'] }, registryWithPython(), runtime, ignore)
|
||||
const { concepts: _marked, ...main } = message.blocks[2]
|
||||
const { concepts: _plain, ...before } = plain.message.blocks[2]
|
||||
expect(main).toEqual(before)
|
||||
expect(message.attributes).toEqual(plain.message.attributes)
|
||||
})
|
||||
|
||||
it('库规则的卡片画几个概念图标:入口替掉第一个(种类),后面的照旧', async () => {
|
||||
const API = [
|
||||
'from fastapi import FastAPI',
|
||||
'',
|
||||
'app = FastAPI()',
|
||||
'',
|
||||
'',
|
||||
'@app.get("/")',
|
||||
'def main():',
|
||||
' return {}',
|
||||
'',
|
||||
].join('\n')
|
||||
const plain = await documentMessage(doc('python', API), registryWithPython(fastapiRule), runtime, ignore)
|
||||
const { message } = await documentMessage({ ...doc('python', API), entryNames: ['main'] }, registryWithPython(fastapiRule), runtime, ignore)
|
||||
const before = plain.message.blocks.at(-1)!
|
||||
const after = message.blocks.at(-1)!
|
||||
expect(before.badge).toBeDefined()
|
||||
expect(before.concepts.length).toBeGreaterThan(1)
|
||||
expect(after.concepts).toEqual([ENTRY_CONCEPT, ...before.concepts.slice(1)])
|
||||
expect(after.badge).toEqual(before.badge)
|
||||
expect(after.kind).toBe(before.kind)
|
||||
})
|
||||
|
||||
it('对不上名字、不是入口:什么都不改', async () => {
|
||||
const plain = await documentMessage(doc('python', CLI), registryWithPython(), runtime, ignore)
|
||||
const unmatched = await documentMessage({ ...doc('python', CLI), entryNames: ['run'] }, registryWithPython(), runtime, ignore)
|
||||
expect(unmatched.message.blocks).toEqual(plain.message.blocks)
|
||||
expect(plain.message.blocks.map(nameRow).join('\n')).not.toContain('入口')
|
||||
expect(plain.message.blocks.map(firstConcept)).not.toContain('entry')
|
||||
})
|
||||
|
||||
it('rust:fn main 的名称后面加「入口」', async () => {
|
||||
it('rust:fn main 的概念列表第一个是入口', async () => {
|
||||
const registry = new CodeReaderRegistry({ get: () => undefined, update: async () => {} } as Pick<Memento, 'get' | 'update'>)
|
||||
registry.registerLanguage(createRustAdapter(WASM_DIR))
|
||||
registry.registerTranslator(rustZhTranslator)
|
||||
const { message } = await documentMessage({ ...doc('rust', 'fn main() {\n run();\n}\n\nfn run() {}\n'), entryNames: ['main'] }, registry, runtime, ignore)
|
||||
expect(message.blocks.map(nameRow)).toEqual(['名称: main 入口', '名称: run'])
|
||||
expect(message.blocks.map(firstConcept)).toEqual(['entry', 'function'])
|
||||
expect(message.blocks.map(nameRow)).toEqual(['名称: main', '名称: run'])
|
||||
})
|
||||
})
|
||||
@@ -5,7 +5,7 @@ import type { DocumentMessage } from './messages'
|
||||
import { fileAttributes, mergeAttributeNames } from '../attributes'
|
||||
import { readBlockViews } from '../blockView'
|
||||
import { commandRuleLookup } from '../commandRules'
|
||||
import { markEntryNames } from '../entries/entryMarks'
|
||||
import { markEntryBlocks } from '../entries/entryMarks'
|
||||
import { ruleAttributeNames } from '../libraryRules'
|
||||
|
||||
/** 生成预览数据要读的那点文档信息(TextDocument 的子集)。 */
|
||||
@@ -13,7 +13,7 @@ export interface DocumentSnapshot {
|
||||
languageId: string
|
||||
version: number
|
||||
getText: () => string
|
||||
/** 这份文件是项目写明的入口时,预览里要标「入口」的名字(见 entries/entryPoints.ts) */
|
||||
/** 这份文件是项目写明的入口时,预览里名字对上的块标成入口(见 entries/entryPoints.ts) */
|
||||
entryNames?: readonly string[]
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export interface DocumentRead {
|
||||
* 当前文档 → 发给预览的 document 消息;语言不支持或解析失败时带 error,blocks 为空。库规则出错不算失败,交给 report 记下;
|
||||
* 规则查名字的定义时问 lookup(RuleContext.lookup),翻译插件问调用的名字定义成哪种块时问 calleeKind(SourceDocument.calleeKind)。
|
||||
* 筛选属性和值的名字先取翻译插件的,没给的再取库规则的(LibraryRule.attributeNames)。
|
||||
* 入口文件里名字对上的块,名称那一行在翻译好的结果上加「入口」(markEntryNames)。
|
||||
* 入口文件里名字对上的块,概念列表的第一个换成入口(markEntryBlocks)。
|
||||
*/
|
||||
export async function documentMessage(
|
||||
document: DocumentSnapshot,
|
||||
@@ -70,7 +70,7 @@ export async function documentMessage(
|
||||
},
|
||||
})
|
||||
const names = mergeAttributeNames([translator?.attributeNames, ...ruleAttributeNames(rules, translator?.displayLanguage, report)])
|
||||
return { message: { ...message, blocks: markEntryNames(blocks, source, document.entryNames ?? []), attributes: fileAttributes(blocks, names) }, displayNames, symbols }
|
||||
return { message: { ...message, blocks: markEntryBlocks(blocks, source, document.entryNames ?? []), attributes: fileAttributes(blocks, names) }, displayNames, symbols }
|
||||
}
|
||||
catch (err) {
|
||||
return { message: { ...message, error: err instanceof Error ? err.message : String(err) }, displayNames: [], symbols: [] }
|
||||
|
||||
@@ -77,7 +77,7 @@ export class PreviewEditorProvider implements CustomTextEditorProvider {
|
||||
readonly indexed: (index: WorkspaceIndex, key: string) => Promise<IndexedEntry[]>,
|
||||
/** 预览标差异时对比什么 */
|
||||
readonly diffBases: DiffBases,
|
||||
/** 哪些文件是项目写明的入口、预览里标哪些名字 */
|
||||
/** 哪些文件是项目写明的入口、预览里哪些名字的块标成入口 */
|
||||
readonly entries: Pick<WorkspaceEntries, 'namesOf' | 'onDidChange'>,
|
||||
) {}
|
||||
|
||||
@@ -256,7 +256,7 @@ class Preview {
|
||||
if (this.ready)
|
||||
this.post({ type: 'filter', ...state })
|
||||
}),
|
||||
// 项目的入口变了:重新发文档,名称那一行的「入口」跟着变
|
||||
// 项目的入口变了:重新发文档,卡片左边的入口图标跟着变
|
||||
owner.entries.onDidChange((uris) => {
|
||||
if (uris.some(uri => uri.toString() === document.uri.toString()))
|
||||
this.schedulePush()
|
||||
@@ -352,7 +352,7 @@ class Preview {
|
||||
|
||||
/**
|
||||
* 对比基准里的旧版本排成视图数据:和这份文档同一种语言、同一个翻译插件和库规则;规则查定义、调用的种类用这份文档眼下查到的答案,
|
||||
* 两边同样的写法翻得一样,不会因为答案晚到被当成改了;项目入口也按眼下的标,「入口」两边都有。旧版本里规则出的错不记(记的是现在这份的)。
|
||||
* 两边同样的写法翻得一样,不会因为答案晚到被当成改了;项目入口也按眼下的标,两边的入口块一样。旧版本里规则出的错不记(记的是现在这份的)。
|
||||
*/
|
||||
private async readOld(source: string): Promise<OldDocument | undefined> {
|
||||
const { message } = await documentMessage(
|
||||
|
||||
Reference in new issue
Block a user