✨ feat(vscode): 代码阅读认出代码里起的中文名(Annotated[…, Comment("…")]、@Comment 装饰器、行尾 # @Comment、docstring / JSDoc 的参数说明),预览里定义和用到它的各处都写中文名,悬停看原名,定义处后面淡淡写原名

This commit is contained in:
cruldra committed 2026-09-27 00:56:39 +08:00
1 parent 1b1299dc1f
commit 44c221ea2b
45 files changed
+1685 -128

No files matched your search

+38 -27
View File
@@ -1,11 +1,13 @@
import type { ReactElement } from 'react'
import type { BlockTreeState } from './BlockTree'
import type { NameMap, VersionNames } from './displayNames'
import type { DocumentMessage, Excluded, Reveal } from './types'
import type { OccurrencePage } from './useOccurrences'
import type { ViewState } from './viewState'
import { TriangleAlert } from 'lucide-react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { BlockLevel } from './BlockTree'
import { acceptNames, DisplayNameContext, documentNames } from './displayNames'
import { coveredByEditing, startEditing } from './editing'
import { applyFilter, keptWhileEditing } from './filter'
import { FilterBar } from './FilterBar'
@@ -20,6 +22,7 @@ import { onMessage, postMessage, viewState } from './vscode'
type BlockModes = Pick<ViewState, 'editing' | 'folds'>
const NONE: ReadonlySet<string> = new Set()
const NO_NAMES: NameMap = new Map()
function savedBlockModes(): BlockModes {
const { editing, folds } = viewState.get()
@@ -38,6 +41,8 @@ export function App(): ReactElement | null {
const [excluded, setExcluded] = useState<Excluded>({})
/** 跳到定义时临时露出来的块(目标和它的各层祖先),筛选一变、文档一刷新就回到筛选状态 */
const [keep, setKeep] = useState<ReadonlySet<string>>(NONE)
/** 页面上这个文档版本的中文名:文档带来的,扩展端查到了再换 */
const [names, setNames] = useState<VersionNames | undefined>()
/** 收到消息时读眼下哪些块在编辑(消息回调只在挂载时注册一次) */
const editing = useRef(view.editing)
const collapsed = useMemo(() => collapsedIds(doc?.blocks ?? [], view.folds), [doc, view.folds])
@@ -69,6 +74,7 @@ export function App(): ReactElement | null {
switch (msg.type) {
case 'document':
setDoc(msg)
setNames(documentNames(msg.version, msg.names))
setKeep(prev => keptWhileEditing(prev, editing.current))
if (msg.reveal)
setReveal(msg.reveal)
@@ -76,6 +82,9 @@ export function App(): ReactElement | null {
case 'reveal':
setReveal({ line: msg.line, definition: msg.definition })
return
case 'displayNames':
setNames(prev => acceptNames(prev, msg.version, msg.names))
return
case 'filter':
setExcluded(msg.excluded)
setKeep(NONE)
@@ -119,35 +128,37 @@ export function App(): ReactElement | null {
return (
<HighlightContext value={highlight}>
<FilterBar
attributes={doc.attributes}
excluded={excluded}
view={filter}
highlight={highlight}
onChange={next => postMessage({ type: 'setFilter', excluded: next })}
translators={doc.translators}
translatorId={doc.translatorId}
onSelectTranslator={id => postMessage({ type: 'selectTranslator', id })}
/>
<div className="mx-auto box-content max-w-[880px] px-6 py-5">
{doc.error !== undefined && (
<div className="mb-3 flex items-start gap-2 rounded-lg border border-[var(--vscode-inputValidation-errorBorder)] bg-[var(--vscode-inputValidation-errorBackground)] px-3 py-2">
<TriangleAlert size={16} strokeWidth={1.8} className="mt-px shrink-0 text-[var(--vscode-errorForeground)]" />
<div className="min-w-0">
<div className="break-words">
解析失败:
{doc.error}
<DisplayNameContext value={names?.names ?? NO_NAMES}>
<FilterBar
attributes={doc.attributes}
excluded={excluded}
view={filter}
highlight={highlight}
onChange={next => postMessage({ type: 'setFilter', excluded: next })}
translators={doc.translators}
translatorId={doc.translatorId}
onSelectTranslator={id => postMessage({ type: 'selectTranslator', id })}
/>
<div className="mx-auto box-content max-w-[880px] px-6 py-5">
{doc.error !== undefined && (
<div className="mb-3 flex items-start gap-2 rounded-lg border border-[var(--vscode-inputValidation-errorBorder)] bg-[var(--vscode-inputValidation-errorBackground)] px-3 py-2">
<TriangleAlert size={16} strokeWidth={1.8} className="mt-px shrink-0 text-[var(--vscode-errorForeground)]" />
<div className="min-w-0">
<div className="break-words">
解析失败:
{doc.error}
</div>
<div className="mt-0.5 text-xs text-[var(--vscode-descriptionForeground)]">点编辑器右上角的「编辑」查看源码。</div>
</div>
<div className="mt-0.5 text-xs text-[var(--vscode-descriptionForeground)]">点编辑器右上角的「编辑」查看源码。</div>
</div>
</div>
)}
{doc.blocks.length === 0
? doc.error === undefined && <div className="text-[var(--vscode-descriptionForeground)]">这个文件里没有代码。</div>
: doc.blocks.some(block => !filter.hidden.has(block.id))
? <BlockLevel blocks={doc.blocks} tree={tree} />
: <div className="text-[var(--vscode-descriptionForeground)]">所有块都被筛选隐藏了。</div>}
</div>
)}
{doc.blocks.length === 0
? doc.error === undefined && <div className="text-[var(--vscode-descriptionForeground)]">这个文件里没有代码。</div>
: doc.blocks.some(block => !filter.hidden.has(block.id))
? <BlockLevel blocks={doc.blocks} tree={tree} />
: <div className="text-[var(--vscode-descriptionForeground)]">所有块都被筛选隐藏了。</div>}
</div>
</DisplayNameContext>
</HighlightContext>
)
}