import { inject, injectable } from '@theia/core/shared/inversify'; import { CommonCommands } from '@theia/core/lib/browser/common-frontend-contribution'; import { ClipboardService } from '@theia/core/lib/browser/clipboard-service'; import { MonacoEditorService } from '@theia/monaco/lib/browser/monaco-editor-service'; import { Contribution, Command, MenuModelRegistry, KeybindingRegistry, CommandRegistry, } from './contribution'; import { ArduinoMenus } from '../menu/arduino-menus'; import { nls } from '@theia/core/lib/common'; import type { ICodeEditor } from '@theia/monaco-editor-core/esm/vs/editor/browser/editorBrowser'; import type { StandaloneCodeEditor } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneCodeEditor'; // TODO: [macOS]: to remove `Start Dictation...` and `Emoji & Symbol` see this thread: https://github.com/electron/electron/issues/8283#issuecomment-269522072 // Depends on https://github.com/eclipse-theia/theia/pull/7964 @injectable() export class EditContributions extends Contribution { @inject(MonacoEditorService) private readonly codeEditorService: MonacoEditorService; @inject(ClipboardService) private readonly clipboardService: ClipboardService; override registerCommands(registry: CommandRegistry): void { registry.registerCommand(EditContributions.Commands.GO_TO_LINE, { execute: () => this.run('editor.action.gotoLine'), }); registry.registerCommand(EditContributions.Commands.TOGGLE_COMMENT, { execute: () => this.run('editor.action.commentLine'), }); registry.registerCommand(EditContributions.Commands.INDENT_LINES, { execute: () => this.run('editor.action.indentLines'), }); registry.registerCommand(EditContributions.Commands.OUTDENT_LINES, { execute: () => this.run('editor.action.outdentLines'), }); registry.registerCommand(EditContributions.Commands.FIND, { execute: () => this.run('actions.find'), }); registry.registerCommand(EditContributions.Commands.FIND_NEXT, { execute: () => this.run('editor.action.nextMatchFindAction'), }); registry.registerCommand(EditContributions.Commands.FIND_PREVIOUS, { execute: () => this.run('editor.action.previousMatchFindAction'), }); registry.registerCommand(EditContributions.Commands.USE_FOR_FIND, { execute: () => this.run('editor.action.previousSelectionMatchFindAction'), }); /* Tools */ registry.registerCommand( EditContributions.Commands.AUTO_FORMAT, { execute: () => this.run('editor.action.formatDocument') } ); registry.registerCommand(EditContributions.Commands.COPY_FOR_FORUM, { execute: async () => { const value = await this.currentValue(); if (value !== undefined) { this.clipboardService.writeText(`\`\`\`cpp ${value} \`\`\``); } }, }); } override registerMenus(registry: MenuModelRegistry): void { registry.registerMenuAction(ArduinoMenus.EDIT__TEXT_CONTROL_GROUP, { commandId: CommonCommands.CUT.id, order: '0', }); registry.registerMenuAction(ArduinoMenus.EDIT__TEXT_CONTROL_GROUP, { commandId: CommonCommands.COPY.id, order: '1', }); registry.registerMenuAction(ArduinoMenus.EDIT__TEXT_CONTROL_GROUP, { commandId: EditContributions.Commands.COPY_FOR_FORUM.id, label: nls.localize( 'arduino/editor/copyForForum', 'Copy for Forum (Markdown)' ), order: '2', }); registry.registerMenuAction(ArduinoMenus.EDIT__TEXT_CONTROL_GROUP, { commandId: CommonCommands.PASTE.id, order: '3', }); registry.registerMenuAction(ArduinoMenus.EDIT__TEXT_CONTROL_GROUP, { commandId: CommonCommands.SELECT_ALL.id, order: '4', }); registry.registerMenuAction(ArduinoMenus.EDIT__TEXT_CONTROL_GROUP, { commandId: EditContributions.Commands.GO_TO_LINE.id, label: nls.localize( 'vscode/standaloneStrings/gotoLineActionLabel', 'Go to Line...' ), order: '5', }); registry.registerMenuAction(ArduinoMenus.EDIT__CODE_CONTROL_GROUP, { commandId: EditContributions.Commands.TOGGLE_COMMENT.id, label: nls.localize( 'arduino/editor/commentUncomment', 'Comment/Uncomment' ), order: '0', }); registry.registerMenuAction(ArduinoMenus.EDIT__CODE_CONTROL_GROUP, { commandId: EditContributions.Commands.INDENT_LINES.id, label: nls.localize('arduino/editor/increaseIndent', 'Increase Indent'), order: '1', }); registry.registerMenuAction(ArduinoMenus.EDIT__CODE_CONTROL_GROUP, { commandId: EditContributions.Commands.OUTDENT_LINES.id, label: nls.localize('arduino/editor/decreaseIndent', 'Decrease Indent'), order: '2', }); registry.registerMenuAction(ArduinoMenus.EDIT__CODE_CONTROL_GROUP, { commandId: EditContributions.Commands.AUTO_FORMAT.id, label: nls.localize('arduino/editor/autoFormat', 'Auto Format'), order: '3', }); registry.registerMenuAction(ArduinoMenus.EDIT__FIND_GROUP, { commandId: EditContributions.Commands.FIND.id, label: nls.localize('vscode/findController/startFindAction', 'Find'), order: '0', }); registry.registerMenuAction(ArduinoMenus.EDIT__FIND_GROUP, { commandId: EditContributions.Commands.FIND_NEXT.id, label: nls.localize( 'vscode/findController/findNextMatchAction', 'Find Next' ), order: '1', }); registry.registerMenuAction(ArduinoMenus.EDIT__FIND_GROUP, { commandId: EditContributions.Commands.FIND_PREVIOUS.id, label: nls.localize( 'vscode/findController/findPreviousMatchAction', 'Find Previous' ), order: '2', }); registry.registerMenuAction(ArduinoMenus.EDIT__FIND_GROUP, { commandId: EditContributions.Commands.USE_FOR_FIND.id, label: nls.localize( 'vscode/findController/startFindWithSelectionAction', 'Use Selection for Find' ), // XXX: The Java IDE uses `Use Selection For Find`. order: '3', }); // `Tools` registry.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, { commandId: EditContributions.Commands.AUTO_FORMAT.id, label: nls.localize('arduino/editor/autoFormat', 'Auto Format'), // XXX: The Java IDE uses `Use Selection For Find`. order: '0', }); } override registerKeybindings(registry: KeybindingRegistry): void { registry.registerKeybinding({ command: EditContributions.Commands.COPY_FOR_FORUM.id, keybinding: 'CtrlCmd+Shift+C', when: 'editorFocus', }); registry.registerKeybinding({ command: EditContributions.Commands.GO_TO_LINE.id, keybinding: 'CtrlCmd+L', when: 'editorFocus', }); registry.registerKeybinding({ command: EditContributions.Commands.TOGGLE_COMMENT.id, keybinding: 'CtrlCmd+/', when: 'editorFocus', }); registry.registerKeybinding({ command: EditContributions.Commands.FIND.id, keybinding: 'CtrlCmd+F', }); registry.registerKeybinding({ command: EditContributions.Commands.FIND_NEXT.id, keybinding: 'CtrlCmd+G', }); registry.registerKeybinding({ command: EditContributions.Commands.FIND_PREVIOUS.id, keybinding: 'CtrlCmd+Shift+G', }); registry.registerKeybinding({ command: EditContributions.Commands.USE_FOR_FIND.id, keybinding: 'CtrlCmd+E', }); // `Tools` registry.registerKeybinding({ command: EditContributions.Commands.AUTO_FORMAT.id, keybinding: 'CtrlCmd+T', }); } protected async current(): Promise< ICodeEditor | StandaloneCodeEditor | undefined > { return ( this.codeEditorService.getFocusedCodeEditor() || this.codeEditorService.getActiveCodeEditor() || undefined ); } protected async currentValue(): Promise { const currentEditor = await this.current(); if (currentEditor) { const selection = currentEditor.getSelection(); if (!selection || selection.isEmpty()) { return currentEditor.getValue(); } return currentEditor.getModel()?.getValueInRange(selection); } return undefined; } protected async run(commandId: string): Promise { const editor = await this.current(); if (editor) { const action = editor.getAction(commandId); if (action) { return action.run(); } } } } export namespace EditContributions { export namespace Commands { export const COPY_FOR_FORUM: Command = { id: 'arduino-copy-for-forum', }; export const GO_TO_LINE: Command = { id: 'arduino-go-to-line', }; export const TOGGLE_COMMENT: Command = { id: 'arduino-toggle-comment', }; export const INDENT_LINES: Command = { id: 'arduino-indent-lines', }; export const OUTDENT_LINES: Command = { id: 'arduino-outdent-lines', }; export const FIND: Command = { id: 'arduino-find', }; export const FIND_NEXT: Command = { id: 'arduino-find-next', }; export const FIND_PREVIOUS: Command = { id: 'arduino-find-previous', }; export const USE_FOR_FIND: Command = { id: 'arduino-for-find', }; export const AUTO_FORMAT: Command = { id: 'arduino-auto-format', // `Auto Format` should belong to `Tool`. }; } }