🐛 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

+25 -7
View File
@@ -102,11 +102,13 @@ interface LineShell {
spaced: boolean
}
/** 一行 `#` 或 `//` 注释:记号、记号后面有没有空格。 */
/** 一行 `#`、`//`、`///`、`//!` 注释:记号、记号后面有没有空格。`///` 和 `//!` 整段都是记号,不能收成 `//`。 */
function lineParts(line: string): LineShell | undefined {
let end = 0
if (line.startsWith('//')) {
end = 2
if (line[end] === '/' || line[end] === '!')
end++
}
else if (line.startsWith('#')) {
while (line[end] === '#')
@@ -337,17 +339,34 @@ export type CommentEdit
* 新正文落到文件里的样子:换掉原来那段注释时套回它的定界符(几段注释中间隔着空行时照第一段的写法写成一段);
* 块还没有注释时用语言的行注释记号新写一段,缩进同块的第一行。认不出定界符、没有行注释记号、正文是空的时没有。
*/
export function commentEdit(target: CommentTarget, lineAt: (line: number) => string, body: string, lineComment: string | undefined): CommentEdit | undefined {
/** 把模型交回的正文套回目标:换掉原来那几行,或按 shell 新写一段。正文是空的、定界符认不出,就不写。 */
export function commentEdit(target: CommentTarget, lineAt: (line: number) => string, body: string): CommentEdit | undefined {
if (target.kind === 'replace') {
const comment = commentSource(Array.from({ length: target.endLine - target.startLine + 1 }, (_, i) => lineAt(target.startLine + i)))
const text = refillComment(comment, body) ?? refillComment(comment.split(/\n[ \t]*\n/)[0], body)
return text === undefined ? undefined : { kind: 'replace', startLine: target.startLine, endLine: target.endLine, text }
}
if (!lineComment)
const text = refillComment(target.shell, body)
if (text === undefined)
return undefined
if (target.breakAt !== undefined)
return splitSameLine(lineAt(target.line), target.line, target.breakAt, text)
const indent = /^[ \t]*/.exec(lineAt(target.line))?.[0] ?? ''
const text = refillComment(`${lineComment} _`, body)
return text === undefined ? undefined : { kind: 'insert', line: target.line, text: text.split('\n').map(line => indent + line).join('\n') }
return { kind: 'insert', line: target.line, text: text.split('\n').map(line => indent + line).join('\n') }
}
/** 声明和主体写在同一行:从 breakAt 那一列拆开,说明插进主体,缩进比声明多一层。交给写回时再补上这一行原来的缩进。 */
function splitSameLine(line: string, atLine: number, breakAt: number, doc: string): CommentEdit | undefined {
if (breakAt < 0 || breakAt > line.length)
return undefined
const base = /^[ \t]*/.exec(line)?.[0] ?? ''
const head = line.slice(base.length, breakAt).trimEnd()
const tail = line.slice(breakAt).trim()
if (!head || !tail)
return undefined
const unit = base.includes('\t') && !base.includes(' ') ? '\t' : ' '
const body = doc.split('\n').map(row => row ? unit + row : '')
return { kind: 'replace', startLine: atLine, endLine: atLine, text: [head, ...body, unit + tail].join('\n') }
}
/** 写回文件的结果:written 写进去了,unchanged 和文件里一样不用写,missing 行号已经不在,rejected 编辑器没接受。 */
@@ -365,7 +384,6 @@ export interface CommentRewriteJob {
startLine: number
endLine: number
path: string
lineComment?: string
}
/** 重写时要用的:读文件现在的行,问模型(拿到结构化结果里的正文,没有正文时 undefined;失败时抛错),出错时给人看的话,写回文件。 */
@@ -403,7 +421,7 @@ export async function rewriteBlockComment(job: CommentRewriteJob, deps: CommentR
return failed('模型没有按要求交回注释正文,没有改文件。')
if (rangeText() !== snapshot)
return failed('这块代码在重写期间变了,没有写回。')
const edit = commentEdit(job.target, deps.lineAt, body, job.lineComment)
const edit = commentEdit(job.target, deps.lineAt, body)
if (!edit)
return failed('这段注释的定界符认不出来,没有改文件。')
const wrote = await deps.write(edit)