✨ feat(vscode): 代码阅读侧栏给目录、文件记注释

This commit is contained in:
cruldra committed 2026-09-25 19:21:03 +08:00
1 parent beabffdf2c
commit 05c4bec56b
14 files changed
+703 -23

No files matched your search

@@ -0,0 +1,53 @@
import { readFileSync } from 'node:fs'
import * as path from 'node:path'
import { describe, expect, it } from 'vitest'
import { entryContext } from '../explorer/fileEntries'
import { escapeMarkdown, noteDecoration } from './noteItem'
describe('树上的一行', () => {
it('没有注释的行保持原样', () => {
expect(noteDecoration('file', 'src/a.ts', undefined)).toBeUndefined()
})
it('有注释:名字后面灰字是注释,contextValue 加 noted,提示里粗体路径下一行注释全文', () => {
expect(noteDecoration('file', 'campaign/order_bonus.py', '下单返利:订单完成后按活动规则发积分')).toEqual({
description: '下单返利:订单完成后按活动规则发积分',
tooltip: '**campaign\\/order\\_bonus\\.py** \n下单返利:订单完成后按活动规则发积分',
contextValue: 'file noted',
})
expect(noteDecoration('folder', 'campaign', '营销活动')?.contextValue).toBe('folder noted')
})
it('注释里的 Markdown 符号原样显示', () => {
expect(escapeMarkdown('**别加粗** <b>x</b> [链接](command:x) `代码` # 标题 $(icon)'))
.toBe('\\*\\*别加粗\\*\\* \\<b\\>x\\<\\/b\\> \\[链接\\]\\(command\\:x\\) \\`代码\\` \\# 标题 \\$\\(icon\\)')
})
})
describe('菜单按 contextValue 挂按钮', () => {
interface MenuItem { command: string, when: string, group: string }
const menus = (JSON.parse(readFileSync(path.resolve(__dirname, '../../../package.json'), 'utf8')) as {
contributes: { menus: Record<string, MenuItem[]> }
}).contributes.menus['view/item/context']
/** 这一行在某个组(行尾按钮 inline / 右键菜单)里有哪些注释命令 */
function commandsFor(contextValue: string, group: string): string[] {
return menus
.filter(item => item.group === group && item.when.includes('view == superpowers.codeReader.files'))
.filter((item) => {
const pattern = /viewItem =~ \/(.+)\/$/.exec(item.when)?.[1]
return pattern !== undefined && new RegExp(pattern).test(contextValue)
})
.map(item => item.command)
}
const noted = (context: string): string => noteDecoration(context, 'x', '注释')!.contextValue
it.each(['inline', 'notes'])('%s:没注释的目录 / 文件只有「添加注释」,有注释的只有「编辑注释」,工作区根都没有', (group) => {
for (const context of [entryContext({ isDirectory: false, isRoot: false }), entryContext({ isDirectory: true, isRoot: false })]) {
expect(commandsFor(context, group)).toEqual(['superpowers.codeReader.addNote'])
expect(commandsFor(noted(context), group)).toEqual(['superpowers.codeReader.editNote'])
}
expect(commandsFor(entryContext({ isDirectory: true, isRoot: true }), group)).toEqual([])
})
})