提交 7688ec07 编写于 作者: D Daniel Imms 提交者: GitHub

Merge pull request #28388 from Microsoft/tyriar/9958

Integrate xterm.js's new terminal selection feature
......@@ -440,9 +440,9 @@
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.0.tgz"
},
"xterm": {
"version": "2.6.0",
"from": "Tyriar/xterm.js#vscode-release/1.13",
"resolved": "git+https://github.com/Tyriar/xterm.js.git#55e0399c1b3ccf06c5d677bf7945b9b2d598fc16"
"version": "2.7.0",
"from": "Tyriar/xterm.js#vscode-release/1.14",
"resolved": "git+https://github.com/Tyriar/xterm.js.git#1d7007669dec1f60e5878aa102a36473d8cbd97f"
},
"yauzl": {
"version": "2.3.1",
......
......@@ -137,7 +137,7 @@ export const focusBorder = registerColor('focusBorder', { dark: Color.fromHex('#
export const contrastBorder = registerColor('contrastBorder', { light: null, dark: null, hc: '#6FC3DF' }, nls.localize('contrastBorder', "An extra border around elements to separate them from others for greater contrast."));
export const activeContrastBorder = registerColor('contrastActiveBorder', { light: null, dark: null, hc: focusBorder }, nls.localize('activeContrastBorder', "An extra border around active elements to separate them from others for greater contrast."));
export const selectionBackground = registerColor('selection.background', { light: null, dark: null, hc: null }, nls.localize('selectionBackground', "The background color of text selections in the workbench (e.g. for input fields or text areas). Note that this does not apply to selections within the editor and the terminal."));
export const selectionBackground = registerColor('selection.background', { light: null, dark: null, hc: null }, nls.localize('selectionBackground', "The background color of text selections in the workbench (e.g. for input fields or text areas). Note that this does not apply to selections within the editor."));
// ------ text colors
......
......@@ -230,6 +230,11 @@ export interface ITerminalInstance {
*/
clearSelection(): void;
/**
* Select all text in the terminal.
*/
selectAll(): void;
/**
* Focuses the terminal instance.
*
......
......@@ -6,6 +6,7 @@
.monaco-workbench .panel.integrated-terminal .xterm {
position: relative;
height: 100%;
user-select: none;
}
.monaco-workbench .panel.integrated-terminal .xterm:focus {
......@@ -126,6 +127,22 @@
left: -9999em;
}
.monaco-workbench .panel.integrated-terminal .xterm.enable-mouse-events {
/* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
cursor: default;
}
.monaco-workbench .panel.integrated-terminal .xterm .xterm-selection {
position: absolute;
left: 0;
bottom: 0;
}
.monaco-workbench .panel.integrated-terminal .xterm .xterm-selection div {
position: absolute;
opacity: 0.5;
}
.monaco-workbench .panel.integrated-terminal .xterm .xterm-bold {
font-weight: bold;
}
......@@ -157,23 +174,6 @@
display: block;
}
/* Base selection colors */
.monaco-workbench .panel.integrated-terminal .xterm ::selection {
color: #FFF;
background-color: rgba(51, 51, 51, 0.996);
}
.vs-dark .monaco-workbench .panel.integrated-terminal .xterm ::selection {
color: #1e1e1e;
background-color: rgba(204, 204, 204, 0.996);
}
.hc-black .monaco-workbench .panel.integrated-terminal .xterm ::selection {
color: #000;
background-color: rgba(255, 255, 255, 0.996);
}
/* Terminal colors 16-255 */
.monaco-workbench .panel.integrated-terminal .xterm .xterm-color-16 {
......
......@@ -18,7 +18,7 @@ import { TERMINAL_DEFAULT_SHELL_LINUX, TERMINAL_DEFAULT_SHELL_OSX, TERMINAL_DEFA
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actionRegistry';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { KillTerminalAction, CopyTerminalSelectionAction, CreateNewTerminalAction, FocusActiveTerminalAction, FocusNextTerminalAction, FocusPreviousTerminalAction, FocusTerminalAtIndexAction, SelectDefaultShellWindowsTerminalAction, RunSelectedTextInTerminalAction, RunActiveFileInTerminalAction, ScrollDownTerminalAction, ScrollDownPageTerminalAction, ScrollToBottomTerminalAction, ScrollUpTerminalAction, ScrollUpPageTerminalAction, ScrollToTopTerminalAction, TerminalPasteAction, ToggleTerminalAction, ClearTerminalAction, AllowWorkspaceShellTerminalCommand, DisallowWorkspaceShellTerminalCommand } from 'vs/workbench/parts/terminal/electron-browser/terminalActions';
import { KillTerminalAction, CopyTerminalSelectionAction, CreateNewTerminalAction, FocusActiveTerminalAction, FocusNextTerminalAction, FocusPreviousTerminalAction, FocusTerminalAtIndexAction, SelectDefaultShellWindowsTerminalAction, RunSelectedTextInTerminalAction, RunActiveFileInTerminalAction, ScrollDownTerminalAction, ScrollDownPageTerminalAction, ScrollToBottomTerminalAction, ScrollUpTerminalAction, ScrollUpPageTerminalAction, ScrollToTopTerminalAction, TerminalPasteAction, ToggleTerminalAction, ClearTerminalAction, AllowWorkspaceShellTerminalCommand, DisallowWorkspaceShellTerminalCommand, SelectAllTerminalAction } from 'vs/workbench/parts/terminal/electron-browser/terminalActions';
import { Registry } from 'vs/platform/platform';
import { ShowAllCommandsAction } from 'vs/workbench/parts/quickopen/browser/commandsHandler';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
......@@ -185,7 +185,8 @@ configurationRegistry.registerConfiguration({
OpenPreviousRecentlyUsedEditorInGroupAction.ID,
FocusFirstGroupAction.ID,
FocusSecondGroupAction.ID,
FocusThirdGroupAction.ID
FocusThirdGroupAction.ID,
SelectAllTerminalAction.ID
].sort()
}
}
......@@ -209,9 +210,7 @@ let actionRegistry = <IWorkbenchActionRegistry>Registry.as(ActionExtensions.Work
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(KillTerminalAction, KillTerminalAction.ID, KillTerminalAction.LABEL), 'Terminal: Kill the Active Terminal Instance', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CopyTerminalSelectionAction, CopyTerminalSelectionAction.ID, CopyTerminalSelectionAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.KEY_C,
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C },
// Don't apply to Mac since cmd+c works
mac: { primary: null }
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C }
}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, KEYBINDING_CONTEXT_TERMINAL_FOCUS)), 'Terminal: Copy Selection', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CreateNewTerminalAction, CreateNewTerminalAction.ID, CreateNewTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_BACKTICK,
......@@ -229,6 +228,15 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TerminalPasteAct
// Don't apply to Mac since cmd+v works
mac: { primary: null }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Paste into Active Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectAllTerminalAction, SelectAllTerminalAction.ID, SelectAllTerminalAction.LABEL, {
// Don't use ctrl+a by default as that would override the common go to start
// of prompt shell binding
primary: null,
// Technically this doesn't need to be here as it will fall back to this
// behavior anyway when handed to xterm.js, having this handled by VS Code
// makes it easier for users to see how it works though.
mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_A }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Select All', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RunSelectedTextInTerminalAction, RunSelectedTextInTerminalAction.ID, RunSelectedTextInTerminalAction.LABEL), 'Terminal: Run Selected Text In Active Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RunActiveFileInTerminalAction, RunActiveFileInTerminalAction.ID, RunActiveFileInTerminalAction.LABEL), 'Terminal: Run Active File In Active Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleTerminalAction, ToggleTerminalAction.ID, ToggleTerminalAction.LABEL, {
......
......@@ -93,6 +93,27 @@ export class CopyTerminalSelectionAction extends Action {
}
}
export class SelectAllTerminalAction extends Action {
public static ID = 'workbench.action.terminal.selectAll';
public static LABEL = nls.localize('workbench.action.terminal.selectAll', "Select All");
constructor(
id: string, label: string,
@ITerminalService private terminalService: ITerminalService
) {
super(id, label);
}
public run(event?: any): TPromise<any> {
let terminalInstance = this.terminalService.getActiveInstance();
if (terminalInstance) {
terminalInstance.selectAll();
}
return TPromise.as(void 0);
}
}
export class CreateNewTerminalAction extends Action {
public static ID = 'workbench.action.terminal.new';
......
......@@ -31,7 +31,8 @@ import { TerminalLinkHandler } from 'vs/workbench/parts/terminal/electron-browse
import { TerminalWidgetManager } from 'vs/workbench/parts/terminal/browser/terminalWidgetManager';
import { registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { scrollbarSliderBackground, scrollbarSliderHoverBackground, scrollbarSliderActiveBackground } from 'vs/platform/theme/common/colorRegistry';
import { TPromise } from "vs/base/common/winjs.base";
import { TPromise } from 'vs/base/common/winjs.base';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
/** The amount of time to consider terminal errors to be related to the launch */
const LAUNCHING_DURATION = 500;
......@@ -99,7 +100,8 @@ export class TerminalInstance implements ITerminalInstance {
@IPanelService private _panelService: IPanelService,
@IWorkspaceContextService private _contextService: IWorkspaceContextService,
@IWorkbenchEditorService private _editorService: IWorkbenchEditorService,
@IInstantiationService private _instantiationService: IInstantiationService
@IInstantiationService private _instantiationService: IInstantiationService,
@IClipboardService private _clipboardService: IClipboardService
) {
this._instanceDisposables = [];
this._processDisposables = [];
......@@ -323,19 +325,23 @@ export class TerminalInstance implements ITerminalInstance {
}
public hasSelection(): boolean {
return !document.getSelection().isCollapsed;
return this._xterm.hasSelection();
}
public copySelection(): void {
if (document.activeElement.classList.contains('xterm')) {
document.execCommand('copy');
if (this.hasSelection()) {
this._clipboardService.writeText(this._xterm.getSelection());
} else {
this._messageService.show(Severity.Warning, nls.localize('terminal.integrated.copySelection.noSelection', 'Cannot copy terminal selection when terminal does not have focus'));
this._messageService.show(Severity.Warning, nls.localize('terminal.integrated.copySelection.noSelection', 'The terminal has no selection to copy'));
}
}
public clearSelection(): void {
window.getSelection().empty();
this._xterm.clearSelection();
}
public selectAll(): void {
this._xterm.selectAll();
}
public dispose(): void {
......@@ -439,8 +445,8 @@ export class TerminalInstance implements ITerminalInstance {
private _refreshSelectionContextKey() {
const activePanel = this._panelService.getActivePanel();
const isFocused = activePanel && activePanel.getId() === TERMINAL_PANEL_ID;
this._terminalHasTextContextKey.set(isFocused && !window.getSelection().isCollapsed);
const isActive = activePanel && activePanel.getId() === TERMINAL_PANEL_ID;
this._terminalHasTextContextKey.set(isActive && this.hasSelection());
}
private _sanitizeInput(data: any) {
......
......@@ -16,7 +16,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ITerminalService, ITerminalFont, TERMINAL_PANEL_ID } from 'vs/workbench/parts/terminal/common/terminal';
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_FOREGROUND_COLOR } from './terminalColorRegistry';
import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry';
import { ColorIdentifier, selectionBackground } from 'vs/platform/theme/common/colorRegistry';
import { KillTerminalAction, CreateNewTerminalAction, SwitchTerminalInstanceAction, SwitchTerminalInstanceActionItem, CopyTerminalSelectionAction, TerminalPasteAction, ClearTerminalAction } from 'vs/workbench/parts/terminal/electron-browser/terminalActions';
import { Panel } from 'vs/workbench/browser/panel';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
......@@ -243,13 +243,8 @@ export class TerminalPanel extends Panel {
ansiColorIdentifiers.forEach((colorId: ColorIdentifier, index: number) => {
if (colorId) { // should not happen, all indices should have a color defined.
let color = theme.getColor(colorId);
let rgba = color.transparent(0.996);
css += `.monaco-workbench .panel.integrated-terminal .xterm .xterm-color-${index} { color: ${color}; }` +
`.monaco-workbench .panel.integrated-terminal .xterm .xterm-color-${index}::selection,` +
`.monaco-workbench .panel.integrated-terminal .xterm .xterm-color-${index} *::selection { background-color: ${rgba}; }` +
`.monaco-workbench .panel.integrated-terminal .xterm .xterm-bg-color-${index} { background-color: ${color}; }` +
`.monaco-workbench .panel.integrated-terminal .xterm .xterm-bg-color-${index}::selection,` +
`.monaco-workbench .panel.integrated-terminal .xterm .xterm-bg-color-${index} *::selection { color: ${color}; }`;
`.monaco-workbench .panel.integrated-terminal .xterm .xterm-bg-color-${index} { background-color: ${color}; }`;
}
});
const bgColor = theme.getColor(TERMINAL_BACKGROUND_COLOR);
......@@ -267,6 +262,12 @@ export class TerminalPanel extends Panel {
`.monaco-workbench .panel.integrated-terminal .xterm.xterm-cursor-style-bar.focus.xterm-cursor-blink .terminal-cursor::before,` +
`.monaco-workbench .panel.integrated-terminal .xterm.xterm-cursor-style-underline.focus.xterm-cursor-blink .terminal-cursor::before { background-color: ${fgColor}; }`;
}
// Use selection.background as the terminal selection, this is temporary
// until proper color inverting is implemented to ensure contrast.
const selectionColor = theme.getColor(selectionBackground);
if (selectionColor) {
css += `.monaco-workbench .panel.integrated-terminal .xterm .xterm-selection div { background-color: ${selectionColor}; }`;
}
this._themeStyleElement.innerHTML = css;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册