|
| 1 | +import { isDefined } from '@internal/common-utils'; |
1 | 2 | import { createDisposableList } from 'utils-disposables';
|
2 |
| -import type { Disposable, QuickPickItem, Uri } from 'vscode'; |
| 3 | +import type { Disposable, QuickPickItem } from 'vscode'; |
3 | 4 | import vscode from 'vscode';
|
4 | 5 |
|
5 |
| -export function registerQuickMenu(): Disposable { |
| 6 | +import { knownCommands } from './commands.mjs'; |
| 7 | +import { logErrors } from './util/errors.js'; |
| 8 | + |
| 9 | +export interface ActionsMenuOptions { |
| 10 | + areIssuesVisible: () => boolean; |
| 11 | +} |
| 12 | + |
| 13 | +export function registerActionsMenu(options: ActionsMenuOptions): Disposable { |
6 | 14 | const dList = createDisposableList();
|
7 |
| - dList.push(vscode.commands.registerCommand('cspell.quickMenu.show', quickPickMenu)); |
| 15 | + dList.push(vscode.commands.registerCommand('cspell.showActionsMenu', () => quickPickMenu(options))); |
8 | 16 | return dList;
|
9 | 17 | }
|
10 | 18 |
|
11 |
| -export class MessageItem implements QuickPickItem { |
12 |
| - label: string; |
13 |
| - description = ''; |
14 |
| - detail: string; |
| 19 | +interface ActionMenuItem extends QuickPickItem { |
| 20 | + action?: (() => void | Promise<void>) | undefined; |
| 21 | +} |
| 22 | + |
| 23 | +export class MenuItem implements ActionMenuItem { |
| 24 | + #action?: (() => void | Promise<void>) | undefined; |
| 25 | + kind?: QuickPickItem['kind'] | undefined; |
| 26 | + detail?: string | undefined; |
| 27 | + picked?: boolean | undefined; |
| 28 | + iconPath?: QuickPickItem['iconPath'] | undefined; |
| 29 | + alwaysShow?: boolean | undefined; |
| 30 | + buttons?: readonly vscode.QuickInputButton[] | undefined; |
| 31 | + constructor( |
| 32 | + public label: string, |
| 33 | + public description?: string, |
| 34 | + action?: (() => void | Promise<void>) | undefined, |
| 35 | + ) { |
| 36 | + this.#action = action; |
| 37 | + } |
| 38 | + |
| 39 | + action() { |
| 40 | + return this.#action?.(); |
| 41 | + } |
| 42 | +} |
15 | 43 |
|
| 44 | +export class CommandMenuItem extends MenuItem { |
16 | 45 | constructor(
|
17 |
| - public base: Uri, |
18 |
| - public message: string, |
| 46 | + readonly command: vscode.Command, |
| 47 | + public description?: string, |
19 | 48 | ) {
|
20 |
| - this.label = message.replace(/\r?\n/g, ' '); |
21 |
| - this.detail = base.fsPath; |
| 49 | + super(command.title, description); |
22 | 50 | }
|
| 51 | + |
| 52 | + async action() { |
| 53 | + await vscode.commands.executeCommand(this.command.command, ...(this.command.arguments || [])); |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +async function quickPickMenu(options: ActionsMenuOptions) { |
| 58 | + const items: QuickPickItem[] = [ |
| 59 | + menuItem('Item 1', 'Description for Item 1'), |
| 60 | + menuItem('Item 2', 'Description for Item 2'), |
| 61 | + { label: '', kind: vscode.QuickPickItemKind.Separator }, |
| 62 | + itemIssuesShowHide(options), |
| 63 | + menuItem({ label: '$(book) Dictionaries...' }), |
| 64 | + itemCommand({ title: '$(file) Show File Info...', command: knownCommands['cSpell.openFileInfoView'] }), |
| 65 | + itemCommand({ title: '$(console) Open Spell Checker REPL Console.', command: knownCommands['cSpell.createCSpellTerminal'] }), |
| 66 | + itemCommand({ title: '$(issues) Open Spelling Issues Panel.', command: 'cSpell.openIssuesPanel' }), |
| 67 | + itemSeparator(), |
| 68 | + itemCommand({ |
| 69 | + title: '$(keyboard) Edit Keyboard Shortcuts...', |
| 70 | + command: 'workbench.action.openGlobalKeybindings', |
| 71 | + arguments: ['Spell:'], |
| 72 | + }), |
| 73 | + itemCommand({ title: '$(gear) Edit Settings...', command: 'workbench.action.openSettings', arguments: ['cSpell'] }), |
| 74 | + ].filter(isDefined); |
| 75 | + const quickPick = vscode.window.createQuickPick<QuickPickItem>(); |
| 76 | + quickPick.title = 'Spell Checker Actions Menu'; |
| 77 | + quickPick.items = items; |
| 78 | + quickPick.onDidChangeSelection((selection) => { |
| 79 | + console.log('onDidChangeSelection', selection); |
| 80 | + }); |
| 81 | + quickPick.onDidChangeActive((active) => { |
| 82 | + console.log('onDidChangeActive', active); |
| 83 | + }); |
| 84 | + quickPick.onDidAccept(() => { |
| 85 | + console.log('onDidAccept', quickPick.activeItems); |
| 86 | + const item = quickPick.activeItems[0]; |
| 87 | + if (item instanceof MenuItem && item.action) { |
| 88 | + logErrors(Promise.resolve(item.action()), 'quickPickMenu'); |
| 89 | + } |
| 90 | + quickPick.dispose(); |
| 91 | + }); |
| 92 | + quickPick.onDidHide(() => { |
| 93 | + console.log('onDidHide'); |
| 94 | + }); |
| 95 | + quickPick.show(); |
| 96 | +} |
| 97 | + |
| 98 | +function menuItem(item: QuickPickItem): MenuItem; |
| 99 | +function menuItem(label: string, description?: string): MenuItem; |
| 100 | +function menuItem(labelOrItem: string | QuickPickItem, description?: string): MenuItem { |
| 101 | + if (typeof labelOrItem === 'string') return new MenuItem(labelOrItem, description); |
| 102 | + const item = new MenuItem(labelOrItem.label, labelOrItem.description); |
| 103 | + item.kind = labelOrItem.kind; |
| 104 | + item.iconPath = labelOrItem.iconPath; |
| 105 | + item.alwaysShow = labelOrItem.alwaysShow; |
| 106 | + item.buttons = labelOrItem.buttons; |
| 107 | + item.detail = labelOrItem.detail; |
| 108 | + item.picked = labelOrItem.picked; |
| 109 | + return item; |
| 110 | +} |
| 111 | + |
| 112 | +function itemCommand(command: vscode.Command, description?: string) { |
| 113 | + return new CommandMenuItem(command, description); |
| 114 | +} |
| 115 | + |
| 116 | +function itemSeparator(): QuickPickItem { |
| 117 | + return { label: '', kind: vscode.QuickPickItemKind.Separator }; |
23 | 118 | }
|
24 | 119 |
|
25 |
| -async function quickPickMenu() { |
26 |
| - // const items: QuickPickItem[] = [ |
27 |
| - // { label: 'Item 1', description: 'Description for Item 1' }, |
28 |
| - // { label: 'Item 2', description: 'Description for Item 2' }, |
29 |
| - // { label: 'Item 3', description: 'Description for Item 3' }, |
30 |
| - // ]; |
31 |
| - // const quickPick = vscode.window.createQuickPick<QuickPickItem>(); |
32 |
| - // quickPick.items = items; |
33 |
| - // quickPick.onDidChangeSelection((selection) => { |
34 |
| - // console.log('onDidChangeSelection', selection); |
35 |
| - // }); |
36 |
| - // quickPick.onDidChangeActive((active) => { |
37 |
| - // console.log('onDidChangeActive', active); |
38 |
| - // }); |
39 |
| - // quickPick.onDidAccept(() => { |
40 |
| - // console.log('onDidAccept'); |
41 |
| - // }); |
42 |
| - // quickPick.onDidHide(() => { |
43 |
| - // console.log('onDidHide'); |
44 |
| - // }); |
45 |
| - // quickPick.show(); |
| 120 | +function itemIssuesShowHide(options: Pick<ActionsMenuOptions, 'areIssuesVisible'>) { |
| 121 | + const visible = options.areIssuesVisible(); |
| 122 | + return visible |
| 123 | + ? itemCommand({ title: '$(eye-closed) Hide Spelling Issues', command: 'cSpell.hide' }) |
| 124 | + : itemCommand({ title: '$(eye) Show Spelling Issues', command: 'cSpell.show' }); |
46 | 125 | }
|
0 commit comments