✨ feat(vscode): 代码阅读函数块默认折叠,函数说明进属性表「说明」行

This commit is contained in:
cruldra committed 2026-09-25 13:09:53 +08:00
1 parent 62f48fe67c
commit 9b32d4b5a8
17 files changed
+489 -100

No files matched your search

@@ -1,4 +1,5 @@
import type { Access, FactBlock, FunctionFacts, ImportFacts, ImportItem, Node, PropertyRow, Segment, SourceSpan, TextBlock, TokenRole, Translator, VariableBlock } from '../contract'
import { commonIndent, splitLines } from '../editText'
/** 按所在语法节点区分译法的关键字,例如 Python 的 else:if 后「否则」,for / while 后「未中断时」。 */
export interface ContextualWord {
@@ -100,6 +101,16 @@ function oneLine(text: string): string {
return text.replace(/\s*\n\s*/g, ' ')
}
/**
* 说明文字排版:去掉行尾空白、首尾空行和共同缩进,保留换行(段落之间的空行也留着)。
* 第一行紧跟在引号 / 注释符号后面,本来就没有缩进,不参与算共同缩进(同 PEP 257 的做法)。
*/
function docText(raw: string): string {
const [first = '', ...rest] = splitLines(raw).map(line => line.trimEnd())
const indent = commonIndent(rest).length
return [first.trim(), ...rest.map(line => line.slice(indent))].join('\n').replace(/^\n+|\n+$/g, '')
}
/** 模板槽位引用的子节点;注释是语法之外的节点,不占具名子节点序号。 */
function slotChild(node: Node, slot: Exclude<TemplatePart, string>): Node | null | undefined {
if ('field' in slot)
@@ -287,6 +298,10 @@ export function createZhTemplateTranslator(table: ZhTable): Translator {
// 点分模块名逐节照抄,每一节各自能跳到定义,和 VS Code 里一样
module: node => stringNodes.has(node.type) ? [segment(node.text, 'string', offsetOf(node))] : verbatim(node, source, 'type'),
name: (node, role) => [segment(node.text, role, offsetOf(node))],
doc: (node) => {
const text = docText(table.commentText(node))
return text ? [{ text, role: 'comment' }] : []
},
}
switch (block.kind) {
case 'function':
@@ -347,6 +362,8 @@ interface Phrases {
module: (node: Node) => Segment[]
/** 源码里的一个名字原样照抄、按 role 着色(函数名称)。 */
name: (node: Node, role: TokenRole) => Segment[]
/** 函数的说明(JSDoc、docstring):去掉注释符号、引号和共同缩进,保留换行,按注释着色;没有文字时是空的。 */
doc: (node: Node) => Segment[]
}
const ACCESS_ZH: Record<Access, string> = { public: '公共', private: '私有', protected: '受保护' }
@@ -380,8 +397,10 @@ function aliased(item: Segment[], alias: Node | undefined, say: Phrases): Segmen
/** 函数:名称 / 访问级别 / 异步 / 装饰器 / 输入参数(每个参数一行:名称、类型、默认值)/ 输出参数。 */
function functionRows(facts: FunctionFacts, say: Phrases): PropertyRow[] {
const decorators = facts.decorators.map(say.verbatim)
const doc = facts.doc ? say.doc(facts.doc) : []
return [
{ label: '名称', value: facts.name ? say.name(facts.name, 'function') : [hint('匿名')] },
...(doc.length > 0 ? [{ label: '说明', value: doc }] : []),
...accessRows(facts.access),
{ label: '异步', value: yesNo(facts.async) },
...(decorators.length > 0 ? [{ label: '装饰器', value: joined(decorators, '\n') }] : []),