🐛 fix(vscode): 写注释时改已有说明,不再在声明上面另插一行

This commit is contained in:
cruldra committed 2026-10-08 09:55:36 +08:00
1 parent 63dfb658e9
commit 7f39345d03
11 files changed
+196 -36

No files matched your search

+17 -6
View File
@@ -5,7 +5,7 @@ import type { ImportedName } from './symbolLinks'
import { blockAttributes } from './attributes'
import { KIND_ICONS } from './contract'
import { commonIndent, splitLines } from './editText'
import { isCommentBlock } from './languages/shared'
import { explanationSpan, isCommentBlock } from './languages/shared'
import { activeRules, claimBlock, importsIn } from './libraryRules'
import { BlockAnchors } from './qa/anchor'
import { importedNames } from './symbolLinks'
@@ -38,7 +38,7 @@ interface BlockViewBase {
* 同一个 id 只留第一个。项目入口那一块的第一个换成入口(见 entries/entryMarks.ts)。webview 按这个画图标,不自己用种类查。
*/
concepts: BlockConcept[]
/** 「重写注释」写到哪(见 CommentTarget);不能写注释的块(嵌着的代码里的、语言没说行注释怎么写又还没有注释的)没有。 */
/** 「重写注释」写到哪(见 CommentTarget);不能写注释的块(嵌着的代码里的、语言没给出新写的办法又还没有注释的)没有。 */
commentTarget?: CommentTarget
/** 库规则的卡片才有:筛选栏里这个种类的名字,卡片边框的颜色(RuleCard.badge)。图标在 concepts 里。预览同类块一样默认收起它的子块。 */
badge?: KindBadge
@@ -54,12 +54,14 @@ export interface BlockSlot {
}
/**
* 「重写注释」写到哪,行号 0 起:replace 是换掉 startLine..endLine 这几行(块前面那几段普通注释;文件开头的说明卡片是它自己),
* insert 是块还没有注释,新写一段插在 line 这一行上面(块的第一行),缩进同这一行。
* 「重写注释」写到哪,行号 0 起。
* replace 换掉这几行:块的说明(docstring、JSDoc、`///`),没有说明时是块前面的普通注释,文件开头的说明卡片是它自己。
* insert 是都没有,新写一段插在 line 这一行上面。shell 是带定界符的空壳(正文占位 `_`),缩进同这一行。
* breakAt 是主体和声明写在同一行:从这一行的这一列拆开,说明插进主体里。
*/
export type CommentTarget
= | { kind: 'replace', startLine: number, endLine: number }
| { kind: 'insert', line: number }
| { kind: 'insert', line: number, shell: string, breakAt?: number }
/**
* 发给 webview 的一块(可序列化):函数、类、枚举、异常、导入、常量、变量块和库规则的卡片预览时是属性表,文件开头的说明是 Markdown,其余是一行译文。
@@ -394,17 +396,26 @@ export function toBlockViews(
return { properties: row ? withCommentRow(rows, row) : rows }
}
/** 「重写注释」写到哪(见 CommentTarget):块前面的普通注释换掉,没有就新写在块上面。 */
/** 「重写注释」写到哪:有说明就换说明,否则换块前面的普通注释,都没有就按这门语言的说明新写。 */
function commentTarget(block: CodeBlock): Pick<BlockView, 'commentTarget'> {
if (!writable)
return {}
if (isCommentBlock(block))
return { commentTarget: { kind: 'replace', startLine: block.header.startRow, endLine: block.header.endRow } }
const leading = (block.comments ?? []).filter(comment => comment.header.startIndex < block.header.startIndex)
const doc = explanationSpan(block)
const covered = doc !== undefined && leading.some(comment => comment.header.startIndex <= doc.startIndex && comment.header.endIndex >= doc.endIndex)
if (doc && !covered)
return { commentTarget: { kind: 'replace', startLine: doc.startRow, endLine: doc.endRow } }
const [first] = leading
const last = leading.at(-1)
if (first && last)
return { commentTarget: { kind: 'replace', startLine: first.header.startRow, endLine: last.header.endRow } }
return layerDocument.language.lineComment ? { commentTarget: { kind: 'insert', line: block.header.startRow } } : {}
const fresh = layerDocument.language.freshDoc?.(block)
if (fresh)
return { commentTarget: { kind: 'insert', line: fresh.line, shell: fresh.shell, ...(fresh.breakAt !== undefined && { breakAt: fresh.breakAt }) } }
const marker = layerDocument.language.lineComment
return marker ? { commentTarget: { kind: 'insert', line: block.header.startRow, shell: `${marker} _` } } : {}
}
/** 一行译文的卡片:译文、实参表、说明,有注释时下面再排「注释」一行。 */
function textCard(block: TextBlock): ReturnType<typeof textView> & { rows?: PropertyRow[] } {