diff --git a/packages/output/src/browser/output-contribution.ts b/packages/output/src/browser/output-contribution.ts index 0041d6acf246b..8f371b8ed24c0 100644 --- a/packages/output/src/browser/output-contribution.ts +++ b/packages/output/src/browser/output-contribution.ts @@ -14,16 +14,17 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { injectable } from 'inversify'; +import { injectable, inject } from 'inversify'; import URI from '@theia/core/lib/common/uri'; import { Widget } from '@theia/core/lib/browser/widgets/widget'; import { MaybePromise } from '@theia/core/lib/common/types'; -import { CommonCommands, quickCommand, OpenHandler, OpenerOptions } from '@theia/core/lib/browser'; +import { CommonCommands, quickCommand, OpenHandler, OpenerOptions, KeybindingRegistry } from '@theia/core/lib/browser'; import { Command, CommandRegistry, MenuModelRegistry } from '@theia/core/lib/common'; import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution'; import { OutputWidget } from './output-widget'; import { OutputContextMenu } from './output-context-menu'; import { OutputUri } from '../common/output-uri'; +import { ClipboardService } from '@theia/core/lib/browser/clipboard-service'; export namespace OutputCommands { @@ -100,11 +101,19 @@ export namespace OutputCommands { category: OUTPUT_CATEGORY }; + export const COPY_ALL: Command = { + id: 'output:copy-all', + label: 'Copy all', + category: OUTPUT_CATEGORY, + }; } @injectable() export class OutputContribution extends AbstractViewContribution implements OpenHandler { + @inject(ClipboardService) + protected readonly clipboardService: ClipboardService; + readonly id: string = `${OutputWidget.ID}-opener`; constructor() { @@ -136,6 +145,20 @@ export class OutputContribution extends AbstractViewContribution i isVisible: widget => this.withWidget(widget, output => output.isLocked), execute: () => this.widget.then(widget => widget.unlock()) }); + registry.registerCommand(OutputCommands.COPY_ALL, { + execute: () => { + this.widget.then(async widget => { + this.clipboardService.writeText(widget.getText()); + }); + } + }); + } + + registerKeybindings(registry: KeybindingRegistry): void { + registry.registerKeybinding({ + command: OutputCommands.COPY_ALL.id, + keybinding: 'ctrlcmd+shift+c' + }); } registerMenus(registry: MenuModelRegistry): void { @@ -143,6 +166,9 @@ export class OutputContribution extends AbstractViewContribution i registry.registerMenuAction(OutputContextMenu.TEXT_EDIT_GROUP, { commandId: CommonCommands.COPY.id }); + registry.registerMenuAction(OutputContextMenu.TEXT_EDIT_GROUP, { + commandId: OutputCommands.COPY_ALL.id + }); registry.registerMenuAction(OutputContextMenu.COMMAND_GROUP, { commandId: quickCommand.id, label: 'Find Command...' diff --git a/packages/output/src/browser/output-widget.tsx b/packages/output/src/browser/output-widget.tsx index 0d137c3bd3dcd..021af088f0d4e 100644 --- a/packages/output/src/browser/output-widget.tsx +++ b/packages/output/src/browser/output-widget.tsx @@ -220,6 +220,17 @@ export class OutputWidget extends BaseWidget implements StatefulWidget { return undefined; } + getText(): string { + const editor = this.editor; + if (editor) { + const model = editor.getControl().getModel(); + if (model) { + return model.getValue(); + } + } + return ''; + } + } export namespace OutputWidget {