123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
- };
- import * as browser from '../../../base/browser/browser.js';
- import * as platform from '../../../base/common/platform.js';
- import { CopyOptions, InMemoryClipboardMetadataManager } from '../../browser/controller/textAreaInput.js';
- import { EditorAction, MultiCommand, registerEditorAction } from '../../browser/editorExtensions.js';
- import { ICodeEditorService } from '../../browser/services/codeEditorService.js';
- import { EditorContextKeys } from '../../common/editorContextKeys.js';
- import * as nls from '../../../nls.js';
- import { MenuId, MenuRegistry } from '../../../platform/actions/common/actions.js';
- import { IClipboardService } from '../../../platform/clipboard/common/clipboardService.js';
- const CLIPBOARD_CONTEXT_MENU_GROUP = '9_cutcopypaste';
- const supportsCut = (platform.isNative || document.queryCommandSupported('cut'));
- const supportsCopy = (platform.isNative || document.queryCommandSupported('copy'));
- // Firefox only supports navigator.clipboard.readText() in browser extensions.
- // See https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText#Browser_compatibility
- // When loading over http, navigator.clipboard can be undefined. See https://github.com/microsoft/monaco-editor/issues/2313
- const supportsPaste = (typeof navigator.clipboard === 'undefined' || browser.isFirefox) ? document.queryCommandSupported('paste') : true;
- function registerCommand(command) {
- command.register();
- return command;
- }
- export const CutAction = supportsCut ? registerCommand(new MultiCommand({
- id: 'editor.action.clipboardCutAction',
- precondition: undefined,
- kbOpts: (
- // Do not bind cut keybindings in the browser,
- // since browsers do that for us and it avoids security prompts
- platform.isNative ? {
- primary: 2048 /* CtrlCmd */ | 54 /* KeyX */,
- win: { primary: 2048 /* CtrlCmd */ | 54 /* KeyX */, secondary: [1024 /* Shift */ | 20 /* Delete */] },
- weight: 100 /* EditorContrib */
- } : undefined),
- menuOpts: [{
- menuId: MenuId.MenubarEditMenu,
- group: '2_ccp',
- title: nls.localize({ key: 'miCut', comment: ['&& denotes a mnemonic'] }, "Cu&&t"),
- order: 1
- }, {
- menuId: MenuId.EditorContext,
- group: CLIPBOARD_CONTEXT_MENU_GROUP,
- title: nls.localize('actions.clipboard.cutLabel', "Cut"),
- when: EditorContextKeys.writable,
- order: 1,
- }, {
- menuId: MenuId.CommandPalette,
- group: '',
- title: nls.localize('actions.clipboard.cutLabel', "Cut"),
- order: 1
- }, {
- menuId: MenuId.SimpleEditorContext,
- group: CLIPBOARD_CONTEXT_MENU_GROUP,
- title: nls.localize('actions.clipboard.cutLabel', "Cut"),
- when: EditorContextKeys.writable,
- order: 1,
- }]
- })) : undefined;
- export const CopyAction = supportsCopy ? registerCommand(new MultiCommand({
- id: 'editor.action.clipboardCopyAction',
- precondition: undefined,
- kbOpts: (
- // Do not bind copy keybindings in the browser,
- // since browsers do that for us and it avoids security prompts
- platform.isNative ? {
- primary: 2048 /* CtrlCmd */ | 33 /* KeyC */,
- win: { primary: 2048 /* CtrlCmd */ | 33 /* KeyC */, secondary: [2048 /* CtrlCmd */ | 19 /* Insert */] },
- weight: 100 /* EditorContrib */
- } : undefined),
- menuOpts: [{
- menuId: MenuId.MenubarEditMenu,
- group: '2_ccp',
- title: nls.localize({ key: 'miCopy', comment: ['&& denotes a mnemonic'] }, "&&Copy"),
- order: 2
- }, {
- menuId: MenuId.EditorContext,
- group: CLIPBOARD_CONTEXT_MENU_GROUP,
- title: nls.localize('actions.clipboard.copyLabel', "Copy"),
- order: 2,
- }, {
- menuId: MenuId.CommandPalette,
- group: '',
- title: nls.localize('actions.clipboard.copyLabel', "Copy"),
- order: 1
- }, {
- menuId: MenuId.SimpleEditorContext,
- group: CLIPBOARD_CONTEXT_MENU_GROUP,
- title: nls.localize('actions.clipboard.copyLabel', "Copy"),
- order: 2,
- }]
- })) : undefined;
- MenuRegistry.appendMenuItem(MenuId.MenubarEditMenu, { submenu: MenuId.MenubarCopy, title: { value: nls.localize('copy as', "Copy As"), original: 'Copy As', }, group: '2_ccp', order: 3 });
- MenuRegistry.appendMenuItem(MenuId.EditorContext, { submenu: MenuId.EditorContextCopy, title: { value: nls.localize('copy as', "Copy As"), original: 'Copy As', }, group: CLIPBOARD_CONTEXT_MENU_GROUP, order: 3 });
- export const PasteAction = supportsPaste ? registerCommand(new MultiCommand({
- id: 'editor.action.clipboardPasteAction',
- precondition: undefined,
- kbOpts: (
- // Do not bind paste keybindings in the browser,
- // since browsers do that for us and it avoids security prompts
- platform.isNative ? {
- primary: 2048 /* CtrlCmd */ | 52 /* KeyV */,
- win: { primary: 2048 /* CtrlCmd */ | 52 /* KeyV */, secondary: [1024 /* Shift */ | 19 /* Insert */] },
- linux: { primary: 2048 /* CtrlCmd */ | 52 /* KeyV */, secondary: [1024 /* Shift */ | 19 /* Insert */] },
- weight: 100 /* EditorContrib */
- } : undefined),
- menuOpts: [{
- menuId: MenuId.MenubarEditMenu,
- group: '2_ccp',
- title: nls.localize({ key: 'miPaste', comment: ['&& denotes a mnemonic'] }, "&&Paste"),
- order: 4
- }, {
- menuId: MenuId.EditorContext,
- group: CLIPBOARD_CONTEXT_MENU_GROUP,
- title: nls.localize('actions.clipboard.pasteLabel', "Paste"),
- when: EditorContextKeys.writable,
- order: 4,
- }, {
- menuId: MenuId.CommandPalette,
- group: '',
- title: nls.localize('actions.clipboard.pasteLabel', "Paste"),
- order: 1
- }, {
- menuId: MenuId.SimpleEditorContext,
- group: CLIPBOARD_CONTEXT_MENU_GROUP,
- title: nls.localize('actions.clipboard.pasteLabel', "Paste"),
- when: EditorContextKeys.writable,
- order: 4,
- }]
- })) : undefined;
- class ExecCommandCopyWithSyntaxHighlightingAction extends EditorAction {
- constructor() {
- super({
- id: 'editor.action.clipboardCopyWithSyntaxHighlightingAction',
- label: nls.localize('actions.clipboard.copyWithSyntaxHighlightingLabel', "Copy With Syntax Highlighting"),
- alias: 'Copy With Syntax Highlighting',
- precondition: undefined,
- kbOpts: {
- kbExpr: EditorContextKeys.textInputFocus,
- primary: 0,
- weight: 100 /* EditorContrib */
- }
- });
- }
- run(accessor, editor) {
- if (!editor.hasModel()) {
- return;
- }
- const emptySelectionClipboard = editor.getOption(32 /* emptySelectionClipboard */);
- if (!emptySelectionClipboard && editor.getSelection().isEmpty()) {
- return;
- }
- CopyOptions.forceCopyWithSyntaxHighlighting = true;
- editor.focus();
- document.execCommand('copy');
- CopyOptions.forceCopyWithSyntaxHighlighting = false;
- }
- }
- function registerExecCommandImpl(target, browserCommand) {
- if (!target) {
- return;
- }
- // 1. handle case when focus is in editor.
- target.addImplementation(10000, 'code-editor', (accessor, args) => {
- // Only if editor text focus (i.e. not if editor has widget focus).
- const focusedEditor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
- if (focusedEditor && focusedEditor.hasTextFocus()) {
- // Do not execute if there is no selection and empty selection clipboard is off
- const emptySelectionClipboard = focusedEditor.getOption(32 /* emptySelectionClipboard */);
- const selection = focusedEditor.getSelection();
- if (selection && selection.isEmpty() && !emptySelectionClipboard) {
- return true;
- }
- document.execCommand(browserCommand);
- return true;
- }
- return false;
- });
- // 2. (default) handle case when focus is somewhere else.
- target.addImplementation(0, 'generic-dom', (accessor, args) => {
- document.execCommand(browserCommand);
- return true;
- });
- }
- registerExecCommandImpl(CutAction, 'cut');
- registerExecCommandImpl(CopyAction, 'copy');
- if (PasteAction) {
- // 1. Paste: handle case when focus is in editor.
- PasteAction.addImplementation(10000, 'code-editor', (accessor, args) => {
- const codeEditorService = accessor.get(ICodeEditorService);
- const clipboardService = accessor.get(IClipboardService);
- // Only if editor text focus (i.e. not if editor has widget focus).
- const focusedEditor = codeEditorService.getFocusedCodeEditor();
- if (focusedEditor && focusedEditor.hasTextFocus()) {
- const result = document.execCommand('paste');
- // Use the clipboard service if document.execCommand('paste') was not successful
- if (!result && platform.isWeb) {
- return (() => __awaiter(void 0, void 0, void 0, function* () {
- const clipboardText = yield clipboardService.readText();
- if (clipboardText !== '') {
- const metadata = InMemoryClipboardMetadataManager.INSTANCE.get(clipboardText);
- let pasteOnNewLine = false;
- let multicursorText = null;
- let mode = null;
- if (metadata) {
- pasteOnNewLine = (focusedEditor.getOption(32 /* emptySelectionClipboard */) && !!metadata.isFromEmptySelection);
- multicursorText = (typeof metadata.multicursorText !== 'undefined' ? metadata.multicursorText : null);
- mode = metadata.mode;
- }
- focusedEditor.trigger('keyboard', "paste" /* Paste */, {
- text: clipboardText,
- pasteOnNewLine,
- multicursorText,
- mode
- });
- }
- }))();
- }
- return true;
- }
- return false;
- });
- // 2. Paste: (default) handle case when focus is somewhere else.
- PasteAction.addImplementation(0, 'generic-dom', (accessor, args) => {
- document.execCommand('paste');
- return true;
- });
- }
- if (supportsCopy) {
- registerEditorAction(ExecCommandCopyWithSyntaxHighlightingAction);
- }
|