mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-31 01:00:29 -04:00
479 lines
18 KiB
TypeScript
479 lines
18 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import * as nls from 'vs/nls';
|
|
import { Event } from 'vs/base/common/event';
|
|
import { IDisposable } from 'vs/base/common/lifecycle';
|
|
import { RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
|
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
|
import { URI } from 'vs/base/common/uri';
|
|
import { OperatingSystem } from 'vs/base/common/platform';
|
|
import { IOpenFileRequest } from 'vs/platform/windows/common/windows';
|
|
|
|
export const TERMINAL_PANEL_ID = 'workbench.panel.terminal';
|
|
|
|
/** A context key that is set when there is at least one opened integrated terminal. */
|
|
export const KEYBINDING_CONTEXT_TERMINAL_IS_OPEN = new RawContextKey<boolean>('terminalIsOpen', false);
|
|
/** A context key that is set when the integrated terminal has focus. */
|
|
export const KEYBINDING_CONTEXT_TERMINAL_FOCUS = new RawContextKey<boolean>('terminalFocus', false);
|
|
/** A context key that is set when the integrated terminal does not have focus. */
|
|
export const KEYBINDING_CONTEXT_TERMINAL_NOT_FOCUSED: ContextKeyExpr = KEYBINDING_CONTEXT_TERMINAL_FOCUS.toNegated();
|
|
/** A context key that is set when the user is navigating the accessibility tree */
|
|
export const KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS = new RawContextKey<boolean>('terminalA11yTreeFocus', false);
|
|
|
|
/** A keybinding context key that is set when the integrated terminal has text selected. */
|
|
export const KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED = new RawContextKey<boolean>('terminalTextSelected', false);
|
|
/** A keybinding context key that is set when the integrated terminal does not have text selected. */
|
|
export const KEYBINDING_CONTEXT_TERMINAL_TEXT_NOT_SELECTED: ContextKeyExpr = KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED.toNegated();
|
|
|
|
/** A context key that is set when the find widget in integrated terminal is visible. */
|
|
export const KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE = new RawContextKey<boolean>('terminalFindWidgetVisible', false);
|
|
/** A context key that is set when the find widget in integrated terminal is not visible. */
|
|
export const KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_NOT_VISIBLE: ContextKeyExpr = KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE.toNegated();
|
|
/** A context key that is set when the find widget find input in integrated terminal is focused. */
|
|
export const KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_INPUT_FOCUSED = new RawContextKey<boolean>('terminalFindWidgetInputFocused', false);
|
|
/** A context key that is set when the find widget in integrated terminal is focused. */
|
|
export const KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED = new RawContextKey<boolean>('terminalFindWidgetFocused', false);
|
|
/** A context key that is set when the find widget find input in integrated terminal is not focused. */
|
|
export const KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_INPUT_NOT_FOCUSED: ContextKeyExpr = KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_INPUT_FOCUSED.toNegated();
|
|
|
|
export const IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY = 'terminal.integrated.isWorkspaceShellAllowed';
|
|
export const NEVER_MEASURE_RENDER_TIME_STORAGE_KEY = 'terminal.integrated.neverMeasureRenderTime';
|
|
|
|
// The creation of extension host terminals is delayed by this value (milliseconds). The purpose of
|
|
// this delay is to allow the terminal instance to initialize correctly and have its ID set before
|
|
// trying to create the corressponding object on the ext host.
|
|
export const EXT_HOST_CREATION_DELAY = 100;
|
|
|
|
export const ITerminalNativeService = createDecorator<ITerminalNativeService>('terminalNativeService');
|
|
|
|
export const TerminalCursorStyle = {
|
|
BLOCK: 'block',
|
|
LINE: 'line',
|
|
UNDERLINE: 'underline'
|
|
};
|
|
|
|
export const TERMINAL_CONFIG_SECTION = 'terminal.integrated';
|
|
|
|
export const TERMINAL_ACTION_CATEGORY = nls.localize('terminalCategory', "Terminal");
|
|
|
|
export const DEFAULT_LETTER_SPACING = 0;
|
|
export const MINIMUM_LETTER_SPACING = -5;
|
|
export const DEFAULT_LINE_HEIGHT = 1;
|
|
export const SHELL_PATH_INVALID_EXIT_CODE = -1;
|
|
export const SHELL_PATH_DIRECTORY_EXIT_CODE = -2;
|
|
export const SHELL_CWD_INVALID_EXIT_CODE = -3;
|
|
export const LEGACY_CONSOLE_MODE_EXIT_CODE = 3221225786; // microsoft/vscode#73790
|
|
|
|
export type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
|
|
|
|
export interface ITerminalConfiguration {
|
|
shell: {
|
|
linux: string | null;
|
|
osx: string | null;
|
|
windows: string | null;
|
|
};
|
|
automationShell: {
|
|
linux: string | null;
|
|
osx: string | null;
|
|
windows: string | null;
|
|
};
|
|
shellArgs: {
|
|
linux: string[];
|
|
osx: string[];
|
|
windows: string[];
|
|
};
|
|
macOptionIsMeta: boolean;
|
|
macOptionClickForcesSelection: boolean;
|
|
rendererType: 'auto' | 'canvas' | 'dom' | 'experimentalWebgl';
|
|
rightClickBehavior: 'default' | 'copyPaste' | 'paste' | 'selectWord';
|
|
cursorBlinking: boolean;
|
|
cursorStyle: string;
|
|
cursorWidth: number;
|
|
drawBoldTextInBrightColors: boolean;
|
|
fastScrollSensitivity: number;
|
|
fontFamily: string;
|
|
fontWeight: FontWeight;
|
|
fontWeightBold: FontWeight;
|
|
minimumContrastRatio: number;
|
|
mouseWheelScrollSensitivity: number;
|
|
// fontLigatures: boolean;
|
|
fontSize: number;
|
|
letterSpacing: number;
|
|
lineHeight: number;
|
|
detectLocale: 'auto' | 'off' | 'on';
|
|
scrollback: number;
|
|
commandsToSkipShell: string[];
|
|
allowChords: boolean;
|
|
cwd: string;
|
|
confirmOnExit: boolean;
|
|
enableBell: boolean;
|
|
inheritEnv: boolean;
|
|
env: {
|
|
linux: { [key: string]: string };
|
|
osx: { [key: string]: string };
|
|
windows: { [key: string]: string };
|
|
};
|
|
showExitAlert: boolean;
|
|
splitCwd: 'workspaceRoot' | 'initial' | 'inherited';
|
|
windowsEnableConpty: boolean;
|
|
experimentalRefreshOnResume: boolean;
|
|
experimentalUseTitleEvent: boolean;
|
|
enableFileLinks: boolean;
|
|
unicodeVersion: '6' | '11';
|
|
}
|
|
|
|
export interface ITerminalConfigHelper {
|
|
config: ITerminalConfiguration;
|
|
|
|
onWorkspacePermissionsChanged: Event<boolean>;
|
|
|
|
configFontIsMonospace(): boolean;
|
|
getFont(): ITerminalFont;
|
|
/** Sets whether a workspace shell configuration is allowed or not */
|
|
setWorkspaceShellAllowed(isAllowed: boolean): void;
|
|
checkWorkspaceShellPermissions(osOverride?: OperatingSystem): boolean;
|
|
showRecommendations(shellLaunchConfig: IShellLaunchConfig): void;
|
|
}
|
|
|
|
export interface ITerminalFont {
|
|
fontFamily: string;
|
|
fontSize: number;
|
|
letterSpacing: number;
|
|
lineHeight: number;
|
|
charWidth?: number;
|
|
charHeight?: number;
|
|
}
|
|
|
|
export interface ITerminalEnvironment {
|
|
[key: string]: string | null;
|
|
}
|
|
|
|
export interface IShellLaunchConfig {
|
|
/**
|
|
* The name of the terminal, if this is not set the name of the process will be used.
|
|
*/
|
|
name?: string;
|
|
|
|
/**
|
|
* The shell executable (bash, cmd, etc.).
|
|
*/
|
|
executable?: string;
|
|
|
|
/**
|
|
* The CLI arguments to use with executable, a string[] is in argv format and will be escaped,
|
|
* a string is in "CommandLine" pre-escaped format and will be used as is. The string option is
|
|
* only supported on Windows and will throw an exception if used on macOS or Linux.
|
|
*/
|
|
args?: string[] | string;
|
|
|
|
/**
|
|
* The current working directory of the terminal, this overrides the `terminal.integrated.cwd`
|
|
* settings key.
|
|
*/
|
|
cwd?: string | URI;
|
|
|
|
/**
|
|
* A custom environment for the terminal, if this is not set the environment will be inherited
|
|
* from the VS Code process.
|
|
*/
|
|
env?: ITerminalEnvironment;
|
|
|
|
/**
|
|
* Whether to ignore a custom cwd from the `terminal.integrated.cwd` settings key (e.g. if the
|
|
* shell is being launched by an extension).
|
|
*/
|
|
ignoreConfigurationCwd?: boolean;
|
|
|
|
/** Whether to wait for a key press before closing the terminal. */
|
|
waitOnExit?: boolean | string;
|
|
|
|
/**
|
|
* A string including ANSI escape sequences that will be written to the terminal emulator
|
|
* _before_ the terminal process has launched, a trailing \n is added at the end of the string.
|
|
* This allows for example the terminal instance to display a styled message as the first line
|
|
* of the terminal. Use \x1b over \033 or \e for the escape control character.
|
|
*/
|
|
initialText?: string;
|
|
|
|
/**
|
|
* Whether an extension is controlling the terminal via a `vscode.Pseudoterminal`.
|
|
*/
|
|
isExtensionTerminal?: boolean;
|
|
|
|
/**
|
|
* Whether the terminal process environment should be exactly as provided in
|
|
* `TerminalOptions.env`. When this is false (default), the environment will be based on the
|
|
* window's environment and also apply configured platform settings like
|
|
* `terminal.integrated.windows.env` on top. When this is true, the complete environment must be
|
|
* provided as nothing will be inherited from the process or any configuration.
|
|
*/
|
|
strictEnv?: boolean;
|
|
|
|
/**
|
|
* When enabled the terminal will run the process as normal but not be surfaced to the user
|
|
* until `Terminal.show` is called. The typical usage for this is when you need to run
|
|
* something that may need interactivity but only want to tell the user about it when
|
|
* interaction is needed. Note that the terminals will still be exposed to all extensions
|
|
* as normal.
|
|
*/
|
|
hideFromUser?: boolean;
|
|
}
|
|
|
|
/**
|
|
* Provides access to native or electron APIs to other terminal services.
|
|
*/
|
|
export interface ITerminalNativeService {
|
|
_serviceBrand: undefined;
|
|
|
|
readonly linuxDistro: LinuxDistro;
|
|
|
|
readonly onOpenFileRequest: Event<IOpenFileRequest>;
|
|
readonly onOsResume: Event<void>;
|
|
|
|
getWindowsBuildNumber(): number;
|
|
whenFileDeleted(path: URI): Promise<void>;
|
|
getWslPath(path: string): Promise<string>;
|
|
}
|
|
|
|
export interface IShellDefinition {
|
|
label: string;
|
|
path: string;
|
|
}
|
|
|
|
export interface ITerminalDimensions {
|
|
/**
|
|
* The columns of the terminal.
|
|
*/
|
|
readonly cols: number;
|
|
|
|
/**
|
|
* The rows of the terminal.
|
|
*/
|
|
readonly rows: number;
|
|
}
|
|
|
|
export interface ICommandTracker {
|
|
scrollToPreviousCommand(): void;
|
|
scrollToNextCommand(): void;
|
|
selectToPreviousCommand(): void;
|
|
selectToNextCommand(): void;
|
|
selectToPreviousLine(): void;
|
|
selectToNextLine(): void;
|
|
}
|
|
|
|
export interface INavigationMode {
|
|
exitNavigationMode(): void;
|
|
focusPreviousLine(): void;
|
|
focusNextLine(): void;
|
|
}
|
|
|
|
export interface IBeforeProcessDataEvent {
|
|
/**
|
|
* The data of the event, this can be modified by the event listener to change what gets sent
|
|
* to the terminal.
|
|
*/
|
|
data: string;
|
|
}
|
|
|
|
export interface ITerminalProcessManager extends IDisposable {
|
|
readonly processState: ProcessState;
|
|
readonly ptyProcessReady: Promise<void>;
|
|
readonly shellProcessId: number | undefined;
|
|
readonly remoteAuthority: string | undefined;
|
|
readonly os: OperatingSystem | undefined;
|
|
readonly userHome: string | undefined;
|
|
|
|
readonly onProcessReady: Event<void>;
|
|
readonly onBeforeProcessData: Event<IBeforeProcessDataEvent>;
|
|
readonly onProcessData: Event<string>;
|
|
readonly onProcessTitle: Event<string>;
|
|
readonly onProcessExit: Event<number | undefined>;
|
|
readonly onProcessOverrideDimensions: Event<ITerminalDimensions | undefined>;
|
|
readonly onProcessResolvedShellLaunchConfig: Event<IShellLaunchConfig>;
|
|
|
|
dispose(immediate?: boolean): void;
|
|
createProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number, isScreenReaderModeEnabled: boolean): Promise<void>;
|
|
write(data: string): void;
|
|
setDimensions(cols: number, rows: number): void;
|
|
|
|
getInitialCwd(): Promise<string>;
|
|
getCwd(): Promise<string>;
|
|
getLatency(): Promise<number>;
|
|
}
|
|
|
|
export const enum ProcessState {
|
|
// The process has not been initialized yet.
|
|
UNINITIALIZED,
|
|
// The process is currently launching, the process is marked as launching
|
|
// for a short duration after being created and is helpful to indicate
|
|
// whether the process died as a result of bad shell and args.
|
|
LAUNCHING,
|
|
// The process is running normally.
|
|
RUNNING,
|
|
// The process was killed during launch, likely as a result of bad shell and
|
|
// args.
|
|
KILLED_DURING_LAUNCH,
|
|
// The process was killed by the user (the event originated from VS Code).
|
|
KILLED_BY_USER,
|
|
// The process was killed by itself, for example the shell crashed or `exit`
|
|
// was run.
|
|
KILLED_BY_PROCESS
|
|
}
|
|
|
|
export interface ITerminalProcessExtHostProxy extends IDisposable {
|
|
readonly terminalId: number;
|
|
|
|
emitData(data: string): void;
|
|
emitTitle(title: string): void;
|
|
emitReady(pid: number, cwd: string): void;
|
|
emitExit(exitCode: number | undefined): void;
|
|
emitOverrideDimensions(dimensions: ITerminalDimensions | undefined): void;
|
|
emitResolvedShellLaunchConfig(shellLaunchConfig: IShellLaunchConfig): void;
|
|
emitInitialCwd(initialCwd: string): void;
|
|
emitCwd(cwd: string): void;
|
|
emitLatency(latency: number): void;
|
|
|
|
onInput: Event<string>;
|
|
onResize: Event<{ cols: number, rows: number }>;
|
|
onShutdown: Event<boolean>;
|
|
onRequestInitialCwd: Event<void>;
|
|
onRequestCwd: Event<void>;
|
|
onRequestLatency: Event<void>;
|
|
}
|
|
|
|
export interface ISpawnExtHostProcessRequest {
|
|
proxy: ITerminalProcessExtHostProxy;
|
|
shellLaunchConfig: IShellLaunchConfig;
|
|
activeWorkspaceRootUri: URI | undefined;
|
|
cols: number;
|
|
rows: number;
|
|
isWorkspaceShellAllowed: boolean;
|
|
}
|
|
|
|
export interface IStartExtensionTerminalRequest {
|
|
proxy: ITerminalProcessExtHostProxy;
|
|
cols: number;
|
|
rows: number;
|
|
}
|
|
|
|
export interface IAvailableShellsRequest {
|
|
(shells: IShellDefinition[]): void;
|
|
}
|
|
|
|
export interface IDefaultShellAndArgsRequest {
|
|
useAutomationShell: boolean;
|
|
callback: (shell: string, args: string[] | string | undefined) => void;
|
|
}
|
|
|
|
export enum LinuxDistro {
|
|
Fedora,
|
|
Ubuntu,
|
|
Unknown
|
|
}
|
|
|
|
export enum TitleEventSource {
|
|
/** From the API or the rename command that overrides any other type */
|
|
Api,
|
|
/** From the process name property*/
|
|
Process,
|
|
/** From the VT sequence */
|
|
Sequence
|
|
}
|
|
|
|
export interface IWindowsShellHelper extends IDisposable {
|
|
getShellName(): Promise<string>;
|
|
}
|
|
|
|
/**
|
|
* An interface representing a raw terminal child process, this contains a subset of the
|
|
* child_process.ChildProcess node.js interface.
|
|
*/
|
|
export interface ITerminalChildProcess {
|
|
onProcessData: Event<string>;
|
|
onProcessExit: Event<number | undefined>;
|
|
onProcessReady: Event<{ pid: number, cwd: string }>;
|
|
onProcessTitleChanged: Event<string>;
|
|
onProcessOverrideDimensions?: Event<ITerminalDimensions | undefined>;
|
|
onProcessResolvedShellLaunchConfig?: Event<IShellLaunchConfig>;
|
|
|
|
/**
|
|
* Shutdown the terminal process.
|
|
*
|
|
* @param immediate When true the process will be killed immediately, otherwise the process will
|
|
* be given some time to make sure no additional data comes through.
|
|
*/
|
|
shutdown(immediate: boolean): void;
|
|
input(data: string): void;
|
|
resize(cols: number, rows: number): void;
|
|
|
|
getInitialCwd(): Promise<string>;
|
|
getCwd(): Promise<string>;
|
|
getLatency(): Promise<number>;
|
|
}
|
|
|
|
export const enum TERMINAL_COMMAND_ID {
|
|
FIND_NEXT = 'workbench.action.terminal.findNext',
|
|
FIND_PREVIOUS = 'workbench.action.terminal.findPrevious',
|
|
TOGGLE = 'workbench.action.terminal.toggleTerminal',
|
|
KILL = 'workbench.action.terminal.kill',
|
|
QUICK_KILL = 'workbench.action.terminal.quickKill',
|
|
COPY_SELECTION = 'workbench.action.terminal.copySelection',
|
|
SELECT_ALL = 'workbench.action.terminal.selectAll',
|
|
DELETE_WORD_LEFT = 'workbench.action.terminal.deleteWordLeft',
|
|
DELETE_WORD_RIGHT = 'workbench.action.terminal.deleteWordRight',
|
|
DELETE_TO_LINE_START = 'workbench.action.terminal.deleteToLineStart',
|
|
MOVE_TO_LINE_START = 'workbench.action.terminal.moveToLineStart',
|
|
MOVE_TO_LINE_END = 'workbench.action.terminal.moveToLineEnd',
|
|
NEW = 'workbench.action.terminal.new',
|
|
NEW_WITH_CWD = 'workbench.action.terminal.newWithCwd',
|
|
NEW_LOCAL = 'workbench.action.terminal.newLocal',
|
|
NEW_IN_ACTIVE_WORKSPACE = 'workbench.action.terminal.newInActiveWorkspace',
|
|
SPLIT = 'workbench.action.terminal.split',
|
|
SPLIT_IN_ACTIVE_WORKSPACE = 'workbench.action.terminal.splitInActiveWorkspace',
|
|
FOCUS_PREVIOUS_PANE = 'workbench.action.terminal.focusPreviousPane',
|
|
FOCUS_NEXT_PANE = 'workbench.action.terminal.focusNextPane',
|
|
RESIZE_PANE_LEFT = 'workbench.action.terminal.resizePaneLeft',
|
|
RESIZE_PANE_RIGHT = 'workbench.action.terminal.resizePaneRight',
|
|
RESIZE_PANE_UP = 'workbench.action.terminal.resizePaneUp',
|
|
RESIZE_PANE_DOWN = 'workbench.action.terminal.resizePaneDown',
|
|
FOCUS = 'workbench.action.terminal.focus',
|
|
FOCUS_NEXT = 'workbench.action.terminal.focusNext',
|
|
FOCUS_PREVIOUS = 'workbench.action.terminal.focusPrevious',
|
|
PASTE = 'workbench.action.terminal.paste',
|
|
SELECT_DEFAULT_SHELL = 'workbench.action.terminal.selectDefaultShell',
|
|
RUN_SELECTED_TEXT = 'workbench.action.terminal.runSelectedText',
|
|
RUN_ACTIVE_FILE = 'workbench.action.terminal.runActiveFile',
|
|
SWITCH_TERMINAL = 'workbench.action.terminal.switchTerminal',
|
|
SCROLL_DOWN_LINE = 'workbench.action.terminal.scrollDown',
|
|
SCROLL_DOWN_PAGE = 'workbench.action.terminal.scrollDownPage',
|
|
SCROLL_TO_BOTTOM = 'workbench.action.terminal.scrollToBottom',
|
|
SCROLL_UP_LINE = 'workbench.action.terminal.scrollUp',
|
|
SCROLL_UP_PAGE = 'workbench.action.terminal.scrollUpPage',
|
|
SCROLL_TO_TOP = 'workbench.action.terminal.scrollToTop',
|
|
CLEAR = 'workbench.action.terminal.clear',
|
|
CLEAR_SELECTION = 'workbench.action.terminal.clearSelection',
|
|
MANAGE_WORKSPACE_SHELL_PERMISSIONS = 'workbench.action.terminal.manageWorkspaceShellPermissions',
|
|
RENAME = 'workbench.action.terminal.rename',
|
|
RENAME_WITH_ARG = 'workbench.action.terminal.renameWithArg',
|
|
FIND_WIDGET_FOCUS = 'workbench.action.terminal.focusFindWidget',
|
|
FIND_WIDGET_HIDE = 'workbench.action.terminal.hideFindWidget',
|
|
QUICK_OPEN_TERM = 'workbench.action.quickOpenTerm',
|
|
SCROLL_TO_PREVIOUS_COMMAND = 'workbench.action.terminal.scrollToPreviousCommand',
|
|
SCROLL_TO_NEXT_COMMAND = 'workbench.action.terminal.scrollToNextCommand',
|
|
SELECT_TO_PREVIOUS_COMMAND = 'workbench.action.terminal.selectToPreviousCommand',
|
|
SELECT_TO_NEXT_COMMAND = 'workbench.action.terminal.selectToNextCommand',
|
|
SELECT_TO_PREVIOUS_LINE = 'workbench.action.terminal.selectToPreviousLine',
|
|
SELECT_TO_NEXT_LINE = 'workbench.action.terminal.selectToNextLine',
|
|
TOGGLE_ESCAPE_SEQUENCE_LOGGING = 'toggleEscapeSequenceLogging',
|
|
SEND_SEQUENCE = 'workbench.action.terminal.sendSequence',
|
|
TOGGLE_FIND_REGEX = 'workbench.action.terminal.toggleFindRegex',
|
|
TOGGLE_FIND_WHOLE_WORD = 'workbench.action.terminal.toggleFindWholeWord',
|
|
TOGGLE_FIND_CASE_SENSITIVE = 'workbench.action.terminal.toggleFindCaseSensitive',
|
|
NAVIGATION_MODE_EXIT = 'workbench.action.terminal.navigationModeExit',
|
|
NAVIGATION_MODE_FOCUS_NEXT = 'workbench.action.terminal.navigationModeFocusNext',
|
|
NAVIGATION_MODE_FOCUS_PREVIOUS = 'workbench.action.terminal.navigationModeFocusPrevious'
|
|
}
|