✨ 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:
1 parent
335cf9ca9f
commit
582ac4c987
49 files changed
+1730
-757
No files matched your search
@@ -22,8 +22,7 @@ const SAMPLE: Outline[] = [
|
||||
{ at: 6, kind: 'const' },
|
||||
{ at: 7, kind: 'variable' },
|
||||
{ at: [10, 11], kind: 'function', kids: [
|
||||
{ at: 12, kind: 'comment' },
|
||||
{ at: 13, kind: 'variable' },
|
||||
{ at: 13, kind: 'variable', notes: [12] },
|
||||
{ at: 14, kind: 'if', kids: [{ at: 15, kind: 'return' }] },
|
||||
{ at: 16, kind: 'else', kids: [{ at: 17, kind: 'variable' }] },
|
||||
{ at: 18, kind: 'else', kids: [{ at: 19, kind: 'statement' }] },
|
||||
@@ -51,7 +50,7 @@ describe('python 代码块树', () => {
|
||||
expect(await tree(readFixture('sample.py'))).toEqual(SAMPLE)
|
||||
})
|
||||
|
||||
it('装饰器算进头部;冒号后、主体前的注释归子块;循环的 else 是兄弟块;match 的 case 是子块 if', async () => {
|
||||
it('装饰器算进头部;冒号后、主体前的注释挂到主体第一条语句上;循环的 else 是兄弟块;match 的 case 是子块 if', async () => {
|
||||
const source = [
|
||||
'@cache',
|
||||
'def load(key):',
|
||||
@@ -68,8 +67,7 @@ describe('python 代码块树', () => {
|
||||
].join('\n')
|
||||
expect(await tree(source)).toEqual([
|
||||
{ at: [1, 2], kind: 'function', kids: [
|
||||
{ at: 3, kind: 'comment' },
|
||||
{ at: 4, kind: 'loop', kids: [{ at: 5, kind: 'variable' }] },
|
||||
{ at: 4, kind: 'loop', notes: [3], kids: [{ at: 5, kind: 'variable' }] },
|
||||
{ at: 6, kind: 'else', kids: [{ at: 7, kind: 'statement' }] },
|
||||
{ at: 8, kind: 'if', kids: [
|
||||
{ at: 9, kind: 'if', kids: [{ at: 10, kind: 'return' }] },
|
||||
@@ -79,7 +77,7 @@ describe('python 代码块树', () => {
|
||||
])
|
||||
})
|
||||
|
||||
it('docstring 只认主体开头;不是开头、也没挂到赋值上的字符串是注释块,f-string、字节串照旧是语句', async () => {
|
||||
it('docstring 只认主体开头;不是开头、也没挂到赋值上的字符串是注释,挂到后面那条语句上,f-string、字节串照旧是语句', async () => {
|
||||
const source = [
|
||||
'def f():',
|
||||
' x = 1',
|
||||
@@ -92,9 +90,7 @@ describe('python 代码块树', () => {
|
||||
expect(await tree(source)).toEqual([
|
||||
{ at: 1, kind: 'function', kids: [
|
||||
{ at: 2, kind: 'variable' },
|
||||
{ at: 3, kind: 'comment' },
|
||||
{ at: 4, kind: 'comment' },
|
||||
{ at: 5, kind: 'statement' },
|
||||
{ at: 5, kind: 'statement', notes: [3, 4] },
|
||||
{ at: 6, kind: 'statement' },
|
||||
{ at: 7, kind: 'statement' },
|
||||
] },
|
||||
@@ -116,21 +112,18 @@ describe('python 属性 docstring', () => {
|
||||
})
|
||||
}
|
||||
|
||||
it('attributeDocs.py:模块、类主体里紧跟在赋值后面的字符串并进那块,头部延到字符串结尾;隔着注释、不跟在赋值后面的是注释块', async () => {
|
||||
it('attributeDocs.py:模块、类主体里紧跟在赋值后面的字符串并进那块,头部延到字符串结尾;隔着注释、不跟在赋值后面的是注释,挂到讲的块上', async () => {
|
||||
expect(await tree(readFixture('attributeDocs.py'))).toEqual([
|
||||
{ at: 1, kind: 'comment' },
|
||||
{ at: [3, 4], kind: 'const' },
|
||||
{ at: [6, 8], kind: 'variable' },
|
||||
{ at: [11, 12], kind: 'class', kids: [
|
||||
{ at: [14, 15], kind: 'variable' },
|
||||
{ at: [17, 19], kind: 'field' },
|
||||
{ at: 21, kind: 'comment' },
|
||||
{ at: 22, kind: 'comment' },
|
||||
{ at: [17, 19], kind: 'field', notes: [21, 22] },
|
||||
] },
|
||||
{ at: 25, kind: 'function', kids: [
|
||||
{ at: 26, kind: 'variable' },
|
||||
{ at: [27, 30], kind: 'comment' },
|
||||
{ at: 31, kind: 'statement' },
|
||||
{ at: 31, kind: 'statement', notes: [[27, 30]] },
|
||||
{ at: 32, kind: 'statement' },
|
||||
{ at: 33, kind: 'return' },
|
||||
] },
|
||||
@@ -158,8 +151,8 @@ describe('python 属性 docstring', () => {
|
||||
' """不算"""',
|
||||
].join('\n')
|
||||
expect(await tree(source)).toEqual([
|
||||
{ at: 1, kind: 'class', kids: [{ at: [2, 3], kind: 'field' }, { at: 4, kind: 'comment' }] },
|
||||
{ at: 5, kind: 'if', kids: [{ at: 6, kind: 'variable' }, { at: 7, kind: 'comment' }] },
|
||||
{ at: 1, kind: 'class', kids: [{ at: [2, 3], kind: 'field', notes: [4] }] },
|
||||
{ at: 5, kind: 'if', kids: [{ at: 6, kind: 'variable', notes: [7] }] },
|
||||
])
|
||||
expect(await fieldDocs(source)).toEqual({ 2: '"A" "B"' })
|
||||
})
|
||||
@@ -180,12 +173,11 @@ describe('python 函数、类的 docstring', () => {
|
||||
'def g(): "单行"',
|
||||
].join('\n')
|
||||
|
||||
it('算进函数、类头部、不单独成块,它前面的注释也在头部里;后面的注释照旧成块', async () => {
|
||||
it('算进函数、类头部、不单独成块,它前面的注释也在头部里;后面的注释挂到后面那条语句上', async () => {
|
||||
expect(await tree(source)).toEqual([
|
||||
{ at: [1, 2], kind: 'class', kids: [
|
||||
{ at: [3, 8], kind: 'function', kids: [
|
||||
{ at: 9, kind: 'comment' },
|
||||
{ at: 10, kind: 'return' },
|
||||
{ at: 10, kind: 'return', notes: [9] },
|
||||
] },
|
||||
] },
|
||||
{ at: 11, kind: 'function' },
|
||||
@@ -513,3 +505,55 @@ describe('python 调用', () => {
|
||||
expect(await calls('@cache\nclass A(Base):\n pass')).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('python 注释挂到它讲的块上', () => {
|
||||
it('同一层后面最近的那块(隔着空行也算);主体最后的挂到前面那块;主体里只有注释时挂到父块;文件最后的挂到最后一块', async () => {
|
||||
const source = [
|
||||
'"""模块说明。"""',
|
||||
'',
|
||||
'import os',
|
||||
'',
|
||||
'',
|
||||
'# 讲 load:隔着空行',
|
||||
'def load(path):',
|
||||
' """读出来。"""',
|
||||
' # 先检查',
|
||||
' if not path:',
|
||||
' return None',
|
||||
' return path',
|
||||
' # 函数体最后的注释',
|
||||
'',
|
||||
'',
|
||||
'class Empty:',
|
||||
' """只有说明。"""',
|
||||
' # 只有注释的主体',
|
||||
'',
|
||||
'',
|
||||
'# 文件最后的注释',
|
||||
].join('\n')
|
||||
expect(await tree(source)).toEqual([
|
||||
{ at: 1, kind: 'comment' },
|
||||
{ at: 3, kind: 'import' },
|
||||
{ at: [7, 8], kind: 'function', notes: [6], kids: [
|
||||
{ at: 10, kind: 'if', notes: [9], kids: [{ at: 11, kind: 'return' }] },
|
||||
{ at: 12, kind: 'return', notes: [13] },
|
||||
] },
|
||||
{ at: [16, 17], kind: 'class', notes: [18, 21] },
|
||||
])
|
||||
})
|
||||
|
||||
it('文件开头的注释和第一块代码隔着空行是文件的说明,紧挨着就挂到它上面;#! 和写编码的那行总是文件的', async () => {
|
||||
expect(await tree('# 文件的说明\n\nimport os\n')).toEqual([{ at: 1, kind: 'comment' }, { at: 3, kind: 'import' }])
|
||||
expect(await tree('# 讲导入\nimport os\n')).toEqual([{ at: 2, kind: 'import', notes: [1] }])
|
||||
expect(await tree('#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n# 讲导入\nimport os\n')).toEqual([
|
||||
{ at: [1, 2], kind: 'comment' },
|
||||
{ at: 4, kind: 'import', notes: [3] },
|
||||
])
|
||||
})
|
||||
|
||||
it('luffy 的 acquisition/repository.py:导入后面隔着两个空行的注释挂到类上,是类卡片的「注释」一行,类的编辑范围连着这几行', async () => {
|
||||
const source = readFixture('acquisitionRepository.py')
|
||||
const [klass] = (await tree(source)).filter(block => block.kind === 'class')
|
||||
expect(klass).toMatchObject({ at: [19, 21], notes: [[13, 16]] })
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user