mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-24 17:07:34 +01:00
terminal: allow the find widget to work in detached terminals (#197678)
- Abstracts some methods to an `IAnyTerminalInstance` interface that is common between attached and detached terminal instances. - Some minor changes in the find contribution to make it work with detached instances after that. - Make the find widget track the `activeFindWidget` since commands previously depended on the active terminal, which is not tracked for detached terminals (the alternative would be making the active terminal instance tracker also track detached terminals) And then it 'just works' in the test results terminal
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { Delayer } from 'vs/base/common/async';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
@@ -19,11 +20,13 @@ import { XtermTerminal } from 'vs/workbench/contrib/terminal/browser/xterm/xterm
|
||||
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||
import { ITerminalProcessInfo, ProcessState } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
|
||||
export class DeatachedTerminal extends Disposable implements IDetachedTerminalInstance {
|
||||
export class DetachedTerminal extends Disposable implements IDetachedTerminalInstance {
|
||||
private readonly _widgets = this._register(new TerminalWidgetManager());
|
||||
public readonly capabilities = new TerminalCapabilityStore();
|
||||
private readonly _contributions: Map<string, ITerminalContribution> = new Map();
|
||||
|
||||
public domElement?: HTMLElement;
|
||||
|
||||
public get xterm(): IDetachedXtermTerminal {
|
||||
return this._xterm;
|
||||
}
|
||||
@@ -66,10 +69,41 @@ export class DeatachedTerminal extends Disposable implements IDetachedTerminalIn
|
||||
});
|
||||
}
|
||||
|
||||
get selection(): string | undefined {
|
||||
return this._xterm && this.hasSelection() ? this._xterm.raw.getSelection() : undefined;
|
||||
}
|
||||
|
||||
hasSelection(): boolean {
|
||||
return this._xterm.hasSelection();
|
||||
}
|
||||
|
||||
clearSelection(): void {
|
||||
this._xterm.clearSelection();
|
||||
}
|
||||
|
||||
focus(force?: boolean): void {
|
||||
if (force || !dom.getActiveWindow().getSelection()?.toString()) {
|
||||
this.xterm.focus();
|
||||
}
|
||||
}
|
||||
|
||||
attachToElement(container: HTMLElement, options?: Partial<IXtermAttachToElementOptions> | undefined): void {
|
||||
this.domElement = container;
|
||||
const screenElement = this._xterm.attachToElement(container, options);
|
||||
this._widgets.attachToElement(screenElement);
|
||||
}
|
||||
|
||||
forceScrollbarVisibility(): void {
|
||||
this.domElement?.classList.add('force-scrollbar');
|
||||
}
|
||||
|
||||
resetScrollbarVisibility(): void {
|
||||
this.domElement?.classList.remove('force-scrollbar');
|
||||
}
|
||||
|
||||
getContribution<T extends ITerminalContribution>(id: string): T | null {
|
||||
return this._contributions.get(id) as T | null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -149,15 +149,66 @@ export interface IDetachedXTermOptions {
|
||||
processInfo: ITerminalProcessInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic interface implemented in both the {@link ITerminalInstance} (an
|
||||
* interface used for terminals attached to the terminal panel or editor) and
|
||||
* {@link IDetachedTerminalInstance} (a terminal used elsewhere in VS Code UI).
|
||||
*/
|
||||
export interface IBaseTerminalInstance {
|
||||
readonly capabilities: ITerminalCapabilityStore;
|
||||
|
||||
/**
|
||||
* DOM element the terminal is mounted in.
|
||||
*/
|
||||
readonly domElement?: HTMLElement;
|
||||
|
||||
/**
|
||||
* Current selection in the terminal.
|
||||
*/
|
||||
readonly selection: string | undefined;
|
||||
|
||||
/**
|
||||
* Check if anything is selected in terminal.
|
||||
*/
|
||||
hasSelection(): boolean;
|
||||
|
||||
/**
|
||||
* Clear current selection.
|
||||
*/
|
||||
clearSelection(): void;
|
||||
|
||||
/**
|
||||
* Focuses the terminal instance if it's able to (the xterm.js instance must exist).
|
||||
*
|
||||
* @param force Force focus even if there is a selection.
|
||||
*/
|
||||
focus(force?: boolean): void;
|
||||
|
||||
/**
|
||||
* Force the scroll bar to be visible until {@link resetScrollbarVisibility} is called.
|
||||
*/
|
||||
forceScrollbarVisibility(): void;
|
||||
|
||||
/**
|
||||
* Resets the scroll bar to only be visible when needed, this does nothing unless
|
||||
* {@link forceScrollbarVisibility} was called.
|
||||
*/
|
||||
resetScrollbarVisibility(): void;
|
||||
|
||||
/**
|
||||
* Gets a terminal contribution by its ID.
|
||||
*/
|
||||
getContribution<T extends ITerminalContribution>(id: string): T | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link ITerminalInstance}-like object that emulates a subset of
|
||||
* capabilities. This instance is returned from {@link ITerminalService.createDetachedTerminal}
|
||||
* to represent terminals that appear in other parts of the VS Code UI outside
|
||||
* of the "Terminal" view or editors.
|
||||
*/
|
||||
export interface IDetachedTerminalInstance extends IDisposable {
|
||||
export interface IDetachedTerminalInstance extends IDisposable, IBaseTerminalInstance {
|
||||
readonly xterm: IDetachedXtermTerminal;
|
||||
readonly capabilities: ITerminalCapabilityStore;
|
||||
|
||||
/**
|
||||
* Attached the terminal to the given element. This should be preferred over
|
||||
@@ -178,7 +229,7 @@ export interface ITerminalService extends ITerminalInstanceHost {
|
||||
/** Gets all terminal instances, including editor and terminal view (group) instances. */
|
||||
readonly instances: readonly ITerminalInstance[];
|
||||
/** Gets detached terminal instances created via {@link createDetachedXterm}. */
|
||||
readonly detachedXterms: Iterable<IXtermTerminal>;
|
||||
readonly detachedInstances: Iterable<IDetachedTerminalInstance>;
|
||||
readonly configHelper: ITerminalConfigHelper;
|
||||
readonly defaultLocation: TerminalLocation;
|
||||
|
||||
@@ -478,7 +529,7 @@ export interface ISearchOptions {
|
||||
incremental?: boolean;
|
||||
}
|
||||
|
||||
export interface ITerminalInstance {
|
||||
export interface ITerminalInstance extends IBaseTerminalInstance {
|
||||
/**
|
||||
* The ID of the terminal instance, this is an arbitrary number only used to uniquely identify
|
||||
* terminal instances within a window.
|
||||
@@ -510,7 +561,6 @@ export interface ITerminalInstance {
|
||||
readonly cwd?: string;
|
||||
readonly initialCwd?: string;
|
||||
readonly os?: OperatingSystem;
|
||||
readonly capabilities: ITerminalCapabilityStore;
|
||||
readonly usedShellIntegrationInjection: boolean;
|
||||
readonly injectedArgs: string[] | undefined;
|
||||
readonly extEnvironmentVariableCollection: IMergedEnvironmentVariableCollection | undefined;
|
||||
@@ -749,39 +799,17 @@ export interface ITerminalInstance {
|
||||
*/
|
||||
detachProcessAndDispose(reason: TerminalExitReason): Promise<void>;
|
||||
|
||||
/**
|
||||
* Check if anything is selected in terminal.
|
||||
*/
|
||||
hasSelection(): boolean;
|
||||
|
||||
/**
|
||||
* Copies the terminal selection to the clipboard.
|
||||
*/
|
||||
copySelection(asHtml?: boolean, command?: ITerminalCommand): Promise<void>;
|
||||
|
||||
/**
|
||||
* Current selection in the terminal.
|
||||
*/
|
||||
readonly selection: string | undefined;
|
||||
|
||||
/**
|
||||
* Clear current selection.
|
||||
*/
|
||||
clearSelection(): void;
|
||||
|
||||
/**
|
||||
* When the panel is hidden or a terminal in the editor area becomes inactive, reset the focus context key
|
||||
* to avoid issues like #147180.
|
||||
*/
|
||||
resetFocusContextKey(): void;
|
||||
|
||||
/**
|
||||
* Focuses the terminal instance if it's able to (the xterm.js instance must exist).
|
||||
*
|
||||
* @param force Force focus even if there is a selection.
|
||||
*/
|
||||
focus(force?: boolean): void;
|
||||
|
||||
/**
|
||||
* Focuses the terminal instance when it's ready (the xterm.js instance much exist). This is the
|
||||
* best focus call when the terminal is being shown for example.
|
||||
@@ -977,22 +1005,6 @@ export interface ITerminalInstance {
|
||||
* Hides the suggest widget.
|
||||
*/
|
||||
hideSuggestWidget(): void;
|
||||
|
||||
/**
|
||||
* Force the scroll bar to be visible until {@link resetScrollbarVisibility} is called.
|
||||
*/
|
||||
forceScrollbarVisibility(): void;
|
||||
|
||||
/**
|
||||
* Resets the scroll bar to only be visible when needed, this does nothing unless
|
||||
* {@link forceScrollbarVisibility} was called.
|
||||
*/
|
||||
resetScrollbarVisibility(): void;
|
||||
|
||||
/**
|
||||
* Gets a terminal contribution by its ID.
|
||||
*/
|
||||
getContribution<T extends ITerminalContribution>(id: string): T | null;
|
||||
}
|
||||
|
||||
export const enum XtermTerminalConstants {
|
||||
|
||||
@@ -32,7 +32,7 @@ import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspac
|
||||
import { PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands';
|
||||
import { CLOSE_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands';
|
||||
import { ResourceContextKey } from 'vs/workbench/common/contextkeys';
|
||||
import { Direction, ICreateTerminalOptions, ITerminalEditorService, ITerminalGroupService, ITerminalInstance, ITerminalInstanceService, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { Direction, ICreateTerminalOptions, IDetachedTerminalInstance, ITerminalEditorService, ITerminalGroupService, ITerminalInstance, ITerminalInstanceService, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { TerminalQuickAccessProvider } from 'vs/workbench/contrib/terminal/browser/terminalQuickAccess';
|
||||
import { IRemoteTerminalAttachTarget, ITerminalConfigHelper, ITerminalProfileResolverService, ITerminalProfileService, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey';
|
||||
@@ -251,15 +251,15 @@ export function registerActiveInstanceAction(
|
||||
* This includes detached xterm terminals that are not managed by an {@link ITerminalInstance}.
|
||||
*/
|
||||
export function registerActiveXtermAction(
|
||||
options: IAction2Options & { run: (activeTerminal: IXtermTerminal, accessor: ServicesAccessor, instance?: ITerminalInstance, args?: unknown) => void | Promise<unknown> }
|
||||
options: IAction2Options & { run: (activeTerminal: IXtermTerminal, accessor: ServicesAccessor, instance: ITerminalInstance | IDetachedTerminalInstance, args?: unknown) => void | Promise<unknown> }
|
||||
): IDisposable {
|
||||
const originalRun = options.run;
|
||||
return registerTerminalAction({
|
||||
...options,
|
||||
run: (c, accessor, args) => {
|
||||
const activeDetached = Iterable.find(c.service.detachedXterms, d => d.isFocused);
|
||||
const activeDetached = Iterable.find(c.service.detachedInstances, d => d.xterm.isFocused);
|
||||
if (activeDetached) {
|
||||
return originalRun(activeDetached, accessor, undefined, args);
|
||||
return originalRun(activeDetached.xterm, accessor, activeDetached, args);
|
||||
}
|
||||
|
||||
const activeInstance = c.service.activeInstance;
|
||||
|
||||
@@ -88,7 +88,6 @@ import { ISimpleSelectedSuggestion } from 'vs/workbench/services/suggest/browser
|
||||
import type { IMarker, Terminal as XTermTerminal } from '@xterm/xterm';
|
||||
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
|
||||
import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings';
|
||||
import { $window } from 'vs/base/browser/window';
|
||||
|
||||
const enum Constants {
|
||||
/**
|
||||
@@ -1211,7 +1210,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
||||
if (!this.xterm) {
|
||||
return;
|
||||
}
|
||||
if (force || !$window.getSelection()?.toString()) {
|
||||
if (force || !dom.getActiveWindow().getSelection()?.toString()) {
|
||||
this.xterm.raw.focus();
|
||||
this._onDidRequestFocus.fire();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import { ThemeIcon } from 'vs/base/common/themables';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { VirtualWorkspaceContext } from 'vs/workbench/common/contextkeys';
|
||||
import { IEditableData, IViewsService } from 'vs/workbench/common/views';
|
||||
import { ICreateTerminalOptions, IDetachedTerminalInstance, IDetachedXTermOptions, IRequestAddInstanceToGroupEvent, ITerminalEditorService, ITerminalGroup, ITerminalGroupService, ITerminalInstance, ITerminalInstanceHost, ITerminalInstanceService, ITerminalLocationOptions, ITerminalService, ITerminalServiceNativeDelegate, IXtermTerminal, TerminalConnectionState, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { ICreateTerminalOptions, IDetachedTerminalInstance, IDetachedXTermOptions, IRequestAddInstanceToGroupEvent, ITerminalEditorService, ITerminalGroup, ITerminalGroupService, ITerminalInstance, ITerminalInstanceHost, ITerminalInstanceService, ITerminalLocationOptions, ITerminalService, ITerminalServiceNativeDelegate, TerminalConnectionState, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { getCwdForSplit } from 'vs/workbench/contrib/terminal/browser/terminalActions';
|
||||
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
|
||||
import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput';
|
||||
@@ -52,7 +52,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { TerminalCapabilityStore } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore';
|
||||
import { ITimerService } from 'vs/workbench/services/timer/browser/timerService';
|
||||
import { mark } from 'vs/base/common/performance';
|
||||
import { DeatachedTerminal } from 'vs/workbench/contrib/terminal/browser/detachedTerminal';
|
||||
import { DetachedTerminal } from 'vs/workbench/contrib/terminal/browser/detachedTerminal';
|
||||
import { ITerminalCapabilityImplMap, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities';
|
||||
import { createInstanceCapabilityEventMultiplexer } from 'vs/workbench/contrib/terminal/browser/terminalEvents';
|
||||
import { mainWindow } from 'vs/base/browser/window';
|
||||
@@ -62,7 +62,7 @@ export class TerminalService extends Disposable implements ITerminalService {
|
||||
|
||||
private _hostActiveTerminals: Map<ITerminalInstanceHost, ITerminalInstance | undefined> = new Map();
|
||||
|
||||
private _detachedXterms = new Set<IXtermTerminal>();
|
||||
private _detachedXterms = new Set<IDetachedTerminalInstance>();
|
||||
private _terminalEditorActive: IContextKey<boolean>;
|
||||
private readonly _terminalShellTypeContextKey: IContextKey<string>;
|
||||
|
||||
@@ -95,7 +95,7 @@ export class TerminalService extends Disposable implements ITerminalService {
|
||||
get instances(): ITerminalInstance[] {
|
||||
return this._terminalGroupService.instances.concat(this._terminalEditorService.instances);
|
||||
}
|
||||
get detachedXterms(): Iterable<IXtermTerminal> {
|
||||
get detachedInstances(): Iterable<IDetachedTerminalInstance> {
|
||||
return this._detachedXterms;
|
||||
}
|
||||
|
||||
@@ -1023,13 +1023,14 @@ export class TerminalService extends Disposable implements ITerminalService {
|
||||
xterm.raw.attachCustomKeyEventHandler(() => false);
|
||||
}
|
||||
|
||||
this._detachedXterms.add(xterm);
|
||||
const instance = new DetachedTerminal(xterm, options, this._instantiationService);
|
||||
this._detachedXterms.add(instance);
|
||||
const l = xterm.onDidDispose(() => {
|
||||
this._detachedXterms.delete(xterm);
|
||||
this._detachedXterms.delete(instance);
|
||||
l.dispose();
|
||||
});
|
||||
|
||||
return new DeatachedTerminal(xterm, options, this._instantiationService);
|
||||
return instance;
|
||||
}
|
||||
|
||||
private async _resolveCwd(shellLaunchConfig: IShellLaunchConfig, splitActiveTerminal: boolean, options?: ICreateTerminalOptions): Promise<void> {
|
||||
|
||||
+62
-38
@@ -12,11 +12,11 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { findInFilesCommand } from 'vs/workbench/contrib/search/browser/searchActionsFind';
|
||||
import { ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { registerActiveInstanceAction } from 'vs/workbench/contrib/terminal/browser/terminalActions';
|
||||
import { IDetachedTerminalInstance, ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTerminal, isDetachedTerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { registerActiveInstanceAction, registerActiveXtermAction } from 'vs/workbench/contrib/terminal/browser/terminalActions';
|
||||
import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions';
|
||||
import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager';
|
||||
import { ITerminalProcessManager, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { ITerminalProcessInfo, ITerminalProcessManager, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey';
|
||||
import { TerminalFindWidget } from 'vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget';
|
||||
import type { Terminal as RawXtermTerminal } from '@xterm/xterm';
|
||||
@@ -24,7 +24,13 @@ import type { Terminal as RawXtermTerminal } from '@xterm/xterm';
|
||||
class TerminalFindContribution extends Disposable implements ITerminalContribution {
|
||||
static readonly ID = 'terminal.find';
|
||||
|
||||
static get(instance: ITerminalInstance): TerminalFindContribution | null {
|
||||
/**
|
||||
* Currently focused find widget. This is used to track action context since
|
||||
* 'active terminals' are only tracked for non-detached terminal instanecs.
|
||||
*/
|
||||
static activeFindWidget?: TerminalFindContribution;
|
||||
|
||||
static get(instance: ITerminalInstance | IDetachedTerminalInstance): TerminalFindContribution | null {
|
||||
return instance.getContribution<TerminalFindContribution>(TerminalFindContribution.ID);
|
||||
}
|
||||
|
||||
@@ -34,8 +40,8 @@ class TerminalFindContribution extends Disposable implements ITerminalContributi
|
||||
get findWidget(): TerminalFindWidget { return this._findWidget.value; }
|
||||
|
||||
constructor(
|
||||
private readonly _instance: ITerminalInstance,
|
||||
processManager: ITerminalProcessManager,
|
||||
private readonly _instance: ITerminalInstance | IDetachedTerminalInstance,
|
||||
processManager: ITerminalProcessManager | ITerminalProcessInfo,
|
||||
widgetManager: TerminalWidgetManager,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@ITerminalService terminalService: ITerminalService
|
||||
@@ -47,14 +53,22 @@ class TerminalFindContribution extends Disposable implements ITerminalContributi
|
||||
|
||||
// Track focus and set state so we can force the scroll bar to be visible
|
||||
findWidget.focusTracker.onDidFocus(() => {
|
||||
TerminalFindContribution.activeFindWidget = this;
|
||||
this._instance.forceScrollbarVisibility();
|
||||
terminalService.setActiveInstance(this._instance);
|
||||
if (!isDetachedTerminalInstance(this._instance)) {
|
||||
terminalService.setActiveInstance(this._instance);
|
||||
}
|
||||
});
|
||||
findWidget.focusTracker.onDidBlur(() => {
|
||||
TerminalFindContribution.activeFindWidget = undefined;
|
||||
this._instance.resetScrollbarVisibility();
|
||||
});
|
||||
|
||||
this._instance.domElement.appendChild(findWidget.getDomNode());
|
||||
if (!this._instance.domElement) {
|
||||
throw new Error('FindWidget expected terminal DOM to be initialized');
|
||||
}
|
||||
|
||||
this._instance.domElement?.appendChild(findWidget.getDomNode());
|
||||
if (this._lastLayoutDimensions) {
|
||||
findWidget.layout(this._lastLayoutDimensions.width);
|
||||
}
|
||||
@@ -63,7 +77,7 @@ class TerminalFindContribution extends Disposable implements ITerminalContributi
|
||||
});
|
||||
}
|
||||
|
||||
layout(xterm: IXtermTerminal & { raw: RawXtermTerminal }, dimension: IDimension): void {
|
||||
layout(_xterm: IXtermTerminal & { raw: RawXtermTerminal }, dimension: IDimension): void {
|
||||
this._lastLayoutDimensions = dimension;
|
||||
this._findWidget.rawValue?.layout(dimension.width);
|
||||
}
|
||||
@@ -73,98 +87,106 @@ class TerminalFindContribution extends Disposable implements ITerminalContributi
|
||||
}
|
||||
|
||||
override dispose() {
|
||||
if (TerminalFindContribution.activeFindWidget === this) {
|
||||
TerminalFindContribution.activeFindWidget = undefined;
|
||||
}
|
||||
super.dispose();
|
||||
this._findWidget.rawValue?.dispose();
|
||||
}
|
||||
|
||||
}
|
||||
registerTerminalContribution(TerminalFindContribution.ID, TerminalFindContribution);
|
||||
registerTerminalContribution(TerminalFindContribution.ID, TerminalFindContribution, true);
|
||||
|
||||
registerActiveInstanceAction({
|
||||
registerActiveXtermAction({
|
||||
id: TerminalCommandId.FindFocus,
|
||||
title: { value: localize('workbench.action.terminal.focusFind', "Focus Find"), original: 'Focus Find' },
|
||||
keybinding: {
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KeyF,
|
||||
when: ContextKeyExpr.or(TerminalContextKeys.findFocus, TerminalContextKeys.focus),
|
||||
when: ContextKeyExpr.or(TerminalContextKeys.findFocus, TerminalContextKeys.focusInAny),
|
||||
weight: KeybindingWeight.WorkbenchContrib
|
||||
},
|
||||
precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
|
||||
run: (activeInstance) => {
|
||||
TerminalFindContribution.get(activeInstance)?.findWidget.reveal();
|
||||
run: (_xterm, _accessor, activeInstance) => {
|
||||
const contr = TerminalFindContribution.activeFindWidget || TerminalFindContribution.get(activeInstance);
|
||||
contr?.findWidget.reveal();
|
||||
}
|
||||
});
|
||||
|
||||
registerActiveInstanceAction({
|
||||
registerActiveXtermAction({
|
||||
id: TerminalCommandId.FindHide,
|
||||
title: { value: localize('workbench.action.terminal.hideFind', "Hide Find"), original: 'Hide Find' },
|
||||
keybinding: {
|
||||
primary: KeyCode.Escape,
|
||||
secondary: [KeyMod.Shift | KeyCode.Escape],
|
||||
when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.findVisible),
|
||||
when: ContextKeyExpr.and(TerminalContextKeys.focusInAny, TerminalContextKeys.findVisible),
|
||||
weight: KeybindingWeight.WorkbenchContrib
|
||||
},
|
||||
precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
|
||||
run: (activeInstance) => {
|
||||
TerminalFindContribution.get(activeInstance)?.findWidget.hide();
|
||||
run: (_xterm, _accessor, activeInstance) => {
|
||||
const contr = TerminalFindContribution.activeFindWidget || TerminalFindContribution.get(activeInstance);
|
||||
contr?.findWidget.hide();
|
||||
}
|
||||
});
|
||||
|
||||
registerActiveInstanceAction({
|
||||
registerActiveXtermAction({
|
||||
id: TerminalCommandId.ToggleFindRegex,
|
||||
title: { value: localize('workbench.action.terminal.toggleFindRegex', "Toggle Find Using Regex"), original: 'Toggle Find Using Regex' },
|
||||
keybinding: {
|
||||
primary: KeyMod.Alt | KeyCode.KeyR,
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyR },
|
||||
when: ContextKeyExpr.or(TerminalContextKeys.focus, TerminalContextKeys.findFocus),
|
||||
when: ContextKeyExpr.or(TerminalContextKeys.focusInAny, TerminalContextKeys.findFocus),
|
||||
weight: KeybindingWeight.WorkbenchContrib
|
||||
},
|
||||
precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
|
||||
run: (activeInstance) => {
|
||||
const state = TerminalFindContribution.get(activeInstance)?.findWidget.state;
|
||||
run: (_xterm, _accessor, activeInstance) => {
|
||||
const contr = TerminalFindContribution.activeFindWidget || TerminalFindContribution.get(activeInstance);
|
||||
const state = contr?.findWidget.state;
|
||||
state?.change({ isRegex: !state.isRegex }, false);
|
||||
}
|
||||
});
|
||||
|
||||
registerActiveInstanceAction({
|
||||
registerActiveXtermAction({
|
||||
id: TerminalCommandId.ToggleFindWholeWord,
|
||||
title: { value: localize('workbench.action.terminal.toggleFindWholeWord', "Toggle Find Using Whole Word"), original: 'Toggle Find Using Whole Word' },
|
||||
keybinding: {
|
||||
primary: KeyMod.Alt | KeyCode.KeyW,
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyW },
|
||||
when: ContextKeyExpr.or(TerminalContextKeys.focus, TerminalContextKeys.findFocus),
|
||||
when: ContextKeyExpr.or(TerminalContextKeys.focusInAny, TerminalContextKeys.findFocus),
|
||||
weight: KeybindingWeight.WorkbenchContrib
|
||||
},
|
||||
precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
|
||||
run: (activeInstance) => {
|
||||
const state = TerminalFindContribution.get(activeInstance)?.findWidget.state;
|
||||
run: (_xterm, _accessor, activeInstance) => {
|
||||
const contr = TerminalFindContribution.activeFindWidget || TerminalFindContribution.get(activeInstance);
|
||||
const state = contr?.findWidget.state;
|
||||
state?.change({ wholeWord: !state.wholeWord }, false);
|
||||
}
|
||||
});
|
||||
|
||||
registerActiveInstanceAction({
|
||||
registerActiveXtermAction({
|
||||
id: TerminalCommandId.ToggleFindCaseSensitive,
|
||||
title: { value: localize('workbench.action.terminal.toggleFindCaseSensitive', "Toggle Find Using Case Sensitive"), original: 'Toggle Find Using Case Sensitive' },
|
||||
keybinding: {
|
||||
primary: KeyMod.Alt | KeyCode.KeyC,
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyC },
|
||||
when: ContextKeyExpr.or(TerminalContextKeys.focus, TerminalContextKeys.findFocus),
|
||||
when: ContextKeyExpr.or(TerminalContextKeys.focusInAny, TerminalContextKeys.findFocus),
|
||||
weight: KeybindingWeight.WorkbenchContrib
|
||||
},
|
||||
precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
|
||||
run: (activeInstance) => {
|
||||
const state = TerminalFindContribution.get(activeInstance)?.findWidget.state;
|
||||
run: (_xterm, _accessor, activeInstance) => {
|
||||
const contr = TerminalFindContribution.activeFindWidget || TerminalFindContribution.get(activeInstance);
|
||||
const state = contr?.findWidget.state;
|
||||
state?.change({ matchCase: !state.matchCase }, false);
|
||||
}
|
||||
});
|
||||
|
||||
registerActiveInstanceAction({
|
||||
registerActiveXtermAction({
|
||||
id: TerminalCommandId.FindNext,
|
||||
title: { value: localize('workbench.action.terminal.findNext', "Find Next"), original: 'Find Next' },
|
||||
keybinding: [
|
||||
{
|
||||
primary: KeyCode.F3,
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyCode.KeyG, secondary: [KeyCode.F3] },
|
||||
when: ContextKeyExpr.or(TerminalContextKeys.focus, TerminalContextKeys.findFocus),
|
||||
when: ContextKeyExpr.or(TerminalContextKeys.focusInAny, TerminalContextKeys.findFocus),
|
||||
weight: KeybindingWeight.WorkbenchContrib
|
||||
},
|
||||
{
|
||||
@@ -174,8 +196,9 @@ registerActiveInstanceAction({
|
||||
}
|
||||
],
|
||||
precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
|
||||
run: (activeInstance) => {
|
||||
const widget = TerminalFindContribution.get(activeInstance)?.findWidget;
|
||||
run: (_xterm, _accessor, activeInstance) => {
|
||||
const contr = TerminalFindContribution.activeFindWidget || TerminalFindContribution.get(activeInstance);
|
||||
const widget = contr?.findWidget;
|
||||
if (widget) {
|
||||
widget.show();
|
||||
widget.find(false);
|
||||
@@ -183,14 +206,14 @@ registerActiveInstanceAction({
|
||||
}
|
||||
});
|
||||
|
||||
registerActiveInstanceAction({
|
||||
registerActiveXtermAction({
|
||||
id: TerminalCommandId.FindPrevious,
|
||||
title: { value: localize('workbench.action.terminal.findPrevious', "Find Previous"), original: 'Find Previous' },
|
||||
keybinding: [
|
||||
{
|
||||
primary: KeyMod.Shift | KeyCode.F3,
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyG, secondary: [KeyMod.Shift | KeyCode.F3] },
|
||||
when: ContextKeyExpr.or(TerminalContextKeys.focus, TerminalContextKeys.findFocus),
|
||||
when: ContextKeyExpr.or(TerminalContextKeys.focusInAny, TerminalContextKeys.findFocus),
|
||||
weight: KeybindingWeight.WorkbenchContrib
|
||||
},
|
||||
{
|
||||
@@ -200,8 +223,9 @@ registerActiveInstanceAction({
|
||||
}
|
||||
],
|
||||
precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
|
||||
run: (activeInstance) => {
|
||||
const widget = TerminalFindContribution.get(activeInstance)?.findWidget;
|
||||
run: (_xterm, _accessor, activeInstance) => {
|
||||
const contr = TerminalFindContribution.activeFindWidget || TerminalFindContribution.get(activeInstance);
|
||||
const widget = contr?.findWidget;
|
||||
if (widget) {
|
||||
widget.show();
|
||||
widget.find(true);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { SimpleFindWidget } from 'vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget';
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ITerminalInstance, IXtermTerminal, XtermTerminalConstants } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { IDetachedTerminalInstance, ITerminalInstance, IXtermTerminal, XtermTerminalConstants } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
@@ -23,7 +23,7 @@ export class TerminalFindWidget extends SimpleFindWidget {
|
||||
private _findWidgetVisible: IContextKey<boolean>;
|
||||
|
||||
constructor(
|
||||
private _instance: ITerminalInstance,
|
||||
private _instance: ITerminalInstance | IDetachedTerminalInstance,
|
||||
@IContextViewService _contextViewService: IContextViewService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
|
||||
|
||||
Reference in New Issue
Block a user