✨ feat(vscode): 代码阅读的注释挂到它讲的代码块上成「注释」一行,重写注释改用技能一句话加结构化结果

- 普通注释不再单独成卡片:同一层挂到后面最近的块(隔空行也算),后面没有挂到前面那块,整层没代码挂到父块;只有文件开头隔着空行的注释、模块 docstring、//!、@file 单独成「文件开头的说明」
- 各语言(Python、TypeScript、Rust、Shell、Dockerfile)建好树后统一调 attachComments;块的编辑范围连着挂上的注释,差异、跳转、钉住卡片都按它
- 宿主统一给每张卡片(语言卡片、翻译插件的属性表、库规则卡片、一行译文的语句卡片)插「注释」一行,排在名称、说明后面
- TypeScript 的 JSDoc 也能当常量、变量的说明;sqlx、React 不再单独处理前面的注释
- 「重写注释」每块都有:提示只发 /ecc:writing-code-comments 路径:起-止,模型只读、按 --json-schema 交 body,没交结构化正文就失败不写;扩展换掉块前面的注释或在块上面新写一段
This commit is contained in:
cruldra committed 2026-10-08 07:51:21 +08:00
1 parent 335cf9ca9f
commit 582ac4c987
49 files changed
+1730 -757

No files matched your search

+51 -19
View File
@@ -17,8 +17,7 @@ function facts(source: string): Promise<Record<number, unknown>> {
/** luffy 桌面端 fetch-runtime.sh 的代码块树(同原型 SHELL_BLOCKS,原型略去的 95-100、116-121 行也在)。 */
const FETCH_TREE: Outline[] = [
{ at: 1, kind: 'interpreter' },
{ at: [2, 13], kind: 'comment' },
{ at: 14, kind: 'options' },
{ at: 14, kind: 'options', notes: [[2, 13]] },
{ at: 16, kind: 'variable' },
{ at: 17, kind: 'variable' },
{ at: 18, kind: 'variable' },
@@ -41,35 +40,28 @@ const FETCH_TREE: Outline[] = [
{ at: 66, kind: 'command' },
{ at: 67, kind: 'command' },
{ at: [68, 71], kind: 'case' },
{ at: 72, kind: 'comment' },
{ at: 73, kind: 'command' },
{ at: [75, 77], kind: 'comment' },
{ at: 78, kind: 'case', kids: [
{ at: 79, kind: 'case', kids: [{ at: 80, kind: 'variable' }, { at: [81, 82], kind: 'command' }, { at: 83, kind: 'comment' }, { at: 84, kind: 'command' }] },
{ at: 86, kind: 'case', kids: [{ at: [87, 88], kind: 'comment' }, { at: 89, kind: 'variable' }, { at: 90, kind: 'command' }, { at: 91, kind: 'command' }] },
{ at: 73, kind: 'command', notes: [72] },
{ at: 78, kind: 'case', notes: [[75, 77]], kids: [
{ at: 79, kind: 'case', kids: [{ at: 80, kind: 'variable' }, { at: [81, 82], kind: 'command' }, { at: 84, kind: 'command', notes: [83] }] },
{ at: 86, kind: 'case', kids: [{ at: 89, kind: 'variable', notes: [[87, 88]] }, { at: 90, kind: 'command' }, { at: 91, kind: 'command' }] },
] },
{ at: [95, 97], kind: 'comment' },
{ at: 98, kind: 'if', kids: [{ at: 99, kind: 'command' }] },
{ at: [102, 104], kind: 'comment' },
{ at: 105, kind: 'if', kids: [
{ at: 98, kind: 'if', notes: [[95, 97]], kids: [{ at: 99, kind: 'command' }] },
{ at: 105, kind: 'if', notes: [[102, 104]], kids: [
{ at: 106, kind: 'variable' },
{ at: [107, 108], kind: 'comment' },
{ at: 109, kind: 'loop', kids: [{ at: 110, kind: 'if' }, { at: [111, 114], kind: 'case' }] },
{ at: 116, kind: 'comment' },
{ at: 117, kind: 'variable' },
{ at: 109, kind: 'loop', notes: [[107, 108]], kids: [{ at: 110, kind: 'if' }, { at: [111, 114], kind: 'case' }] },
{ at: 117, kind: 'variable', notes: [116] },
{ at: 118, kind: 'variable' },
{ at: 119, kind: 'command' },
{ at: 120, kind: 'command' },
{ at: 121, kind: 'command' },
{ at: 122, kind: 'comment' },
{ at: 123, kind: 'pipeline', kids: [{ at: 124, kind: 'command' }, { at: 125, kind: 'command' }] },
{ at: 123, kind: 'pipeline', notes: [122], kids: [{ at: 124, kind: 'command' }, { at: 125, kind: 'command' }] },
] },
{ at: 129, kind: 'command' },
{ at: 130, kind: 'command' },
]
describe('shell 代码块树', () => {
it('fetch-runtime.sh:解释器、选项、变量 / 常量、分情况(短的整条一块,长的每个情况一块子块)、函数(紧贴的注释算进头部)、命令、管道后面的循环主体是子块', async () => {
it('fetch-runtime.sh:解释器、选项、变量 / 常量、分情况(短的整条一块,长的每个情况一块子块)、函数(紧贴的注释算进头部)、命令、管道后面的循环主体是子块;注释挂到后面那块上', async () => {
expect(await tree(FETCH)).toEqual(FETCH_TREE)
})
@@ -218,3 +210,43 @@ describe('shell 命令、名字', () => {
}
})
})
describe('shell 注释挂到它讲的块上', () => {
it('#! 后面隔着空行的是文件的说明;同一层后面最近的那块(隔着空行也算),和函数的说明并存;主体最后的挂到前面那块;文件最后的挂到最后一块', async () => {
const source = [
'#!/usr/bin/env bash',
'# 文件的说明',
'',
'set -e',
'',
'# 讲 fetch:隔着空行',
'',
'# 下载一个文件',
'fetch() {',
' # 先检查',
' if [ -z "$1" ]; then',
' # 只有注释的分支',
' :',
' fi',
' curl -fsSL "$1"',
' # 函数体最后的注释',
'}',
'',
'# 文件最后的注释',
].join('\n')
expect(await tree(source)).toEqual([
{ at: 1, kind: 'interpreter' },
{ at: 2, kind: 'comment' },
{ at: 4, kind: 'options' },
{ at: [8, 9], kind: 'function', notes: [6, 19], kids: [
{ at: 11, kind: 'if', notes: [10], kids: [{ at: 13, kind: 'command', notes: [12] }] },
{ at: 15, kind: 'command', notes: [16] },
] },
])
expect((await facts(source))[8]).toMatchObject({ doc: '# 下载一个文件' })
})
it('#! 后面紧挨着第一块代码的注释挂到它上面', async () => {
expect(await tree('#!/bin/sh\n# 出错就停\nset -e\n')).toEqual([{ at: 1, kind: 'interpreter' }, { at: 3, kind: 'options', notes: [2] }])
})
})