✨ feat(vscode): 代码阅读侧栏行加复制菜单,块按钮只留图标,筛选菜单加全选 / 取消全选
This commit is contained in:
1 parent
631699a570
commit
c84e21ff57
16 files changed
+555
-119
No files matched your search
@@ -0,0 +1,104 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import * as path from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { noteDecoration } from '../notes/noteItem'
|
||||
import { COPY_COMMANDS } from './copyText'
|
||||
import { entryContext } from './fileEntries'
|
||||
|
||||
interface MenuItem { command?: string, submenu?: string, when: string, group?: string }
|
||||
interface Manifest {
|
||||
contributes: {
|
||||
commands: { command: string, title: string, icon?: string }[]
|
||||
submenus: { id: string, label: string, icon?: string }[]
|
||||
menus: Record<string, MenuItem[]>
|
||||
}
|
||||
}
|
||||
|
||||
const { commands, submenus, menus } = (JSON.parse(readFileSync(path.resolve(__dirname, '../../../package.json'), 'utf8')) as Manifest).contributes
|
||||
|
||||
const COPY_MENU = 'superpowers.codeReader.copy'
|
||||
const ADD_NOTE = 'superpowers.codeReader.addNote'
|
||||
const EDIT_NOTE = 'superpowers.codeReader.editNote'
|
||||
|
||||
const file = entryContext({ isDirectory: false, isRoot: false })
|
||||
const folder = entryContext({ isDirectory: true, isRoot: false })
|
||||
const root = entryContext({ isDirectory: true, isRoot: true })
|
||||
const noted = (context: string): string => noteDecoration(context, 'x', '注释')!.contextValue
|
||||
|
||||
const orderOf = (item: MenuItem): number => Number(item.group?.split('@')[1] ?? 0)
|
||||
|
||||
/** 某个菜单的某一组(行尾按钮 inline / 右键菜单的 copy、notes)对这一行显示哪些命令或子菜单,照 `@序号` 排 */
|
||||
function itemsFor(menu: string, group: string, contextValue: string): string[] {
|
||||
return menus[menu]
|
||||
.filter(item => item.group?.split('@')[0] === 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)
|
||||
})
|
||||
.sort((a, b) => orderOf(a) - orderOf(b))
|
||||
.map(item => item.command ?? item.submenu ?? '')
|
||||
}
|
||||
|
||||
const FILE_COPIES = [
|
||||
'superpowers.codeReader.copyFileName',
|
||||
'superpowers.codeReader.copyFileStem',
|
||||
'superpowers.codeReader.copyRelativePath',
|
||||
'superpowers.codeReader.copyAbsolutePath',
|
||||
]
|
||||
const FOLDER_COPIES = [
|
||||
'superpowers.codeReader.copyFolderName',
|
||||
'superpowers.codeReader.copyRelativePath',
|
||||
'superpowers.codeReader.copyAbsolutePath',
|
||||
]
|
||||
|
||||
describe('侧栏行尾按钮', () => {
|
||||
it('先「复制」再注释:没注释的是「添加注释」,有注释的是「编辑注释」;工作区根都没有', () => {
|
||||
for (const context of [file, folder]) {
|
||||
expect(itemsFor('view/item/context', 'inline', context)).toEqual([COPY_MENU, ADD_NOTE])
|
||||
expect(itemsFor('view/item/context', 'inline', noted(context))).toEqual([COPY_MENU, EDIT_NOTE])
|
||||
}
|
||||
expect(itemsFor('view/item/context', 'inline', root)).toEqual([])
|
||||
})
|
||||
|
||||
it('「复制」是带 copy 图标的子菜单(VS Code 画成点开的下拉按钮),注释按钮的图标是 note / edit', () => {
|
||||
expect(submenus.find(item => item.id === COPY_MENU)).toEqual({ id: COPY_MENU, label: '复制', icon: '$(copy)' })
|
||||
expect(commands.find(item => item.command === ADD_NOTE)?.icon).toBe('$(note)')
|
||||
expect(commands.find(item => item.command === EDIT_NOTE)?.icon).toBe('$(edit)')
|
||||
})
|
||||
})
|
||||
|
||||
describe('复制菜单', () => {
|
||||
it.each([COPY_MENU, 'view/item/context'])('%s:文件四项、文件夹没有「不带后缀」,有没有注释都一样', (menu) => {
|
||||
for (const context of [file, noted(file)])
|
||||
expect(itemsFor(menu, 'copy', context)).toEqual(FILE_COPIES)
|
||||
for (const context of [folder, noted(folder)])
|
||||
expect(itemsFor(menu, 'copy', context)).toEqual(FOLDER_COPIES)
|
||||
expect(itemsFor(menu, 'copy', root)).toEqual([])
|
||||
})
|
||||
|
||||
it('菜单上的字', () => {
|
||||
const title = (id: string): string | undefined => commands.find(item => item.command === id)?.title
|
||||
expect(FILE_COPIES.map(title)).toEqual(['复制文件名', '复制文件名(不带后缀)', '复制相对路径', '复制绝对路径'])
|
||||
expect(title('superpowers.codeReader.copyFolderName')).toBe('复制文件夹名')
|
||||
})
|
||||
|
||||
it('命令都登记了、都有注册,命令面板里藏起来', () => {
|
||||
const palette = new Map(menus.commandPalette.map(item => [item.command, item.when]))
|
||||
for (const id of [...new Set([...FILE_COPIES, ...FOLDER_COPIES])]) {
|
||||
expect(id in COPY_COMMANDS).toBe(true)
|
||||
expect(commands.some(item => item.command === id)).toBe(true)
|
||||
expect(palette.get(id)).toBe('false')
|
||||
}
|
||||
expect(Object.keys(COPY_COMMANDS).sort()).toEqual([...new Set([...FILE_COPIES, ...FOLDER_COPIES])].sort())
|
||||
})
|
||||
})
|
||||
|
||||
describe('右键菜单的注释', () => {
|
||||
it('没注释的目录 / 文件只有「添加注释」,有注释的只有「编辑注释」,工作区根没有', () => {
|
||||
for (const context of [file, folder]) {
|
||||
expect(itemsFor('view/item/context', 'notes', context)).toEqual([ADD_NOTE])
|
||||
expect(itemsFor('view/item/context', 'notes', noted(context))).toEqual([EDIT_NOTE])
|
||||
}
|
||||
expect(itemsFor('view/item/context', 'notes', root)).toEqual([])
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user