monaco-editor-core
Version:
A browser based code editor
1,137 lines • 75.3 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from '../../nls.js';
import { isFirefox } from '../../base/browser/browser.js';
import * as types from '../../base/common/types.js';
import { status } from '../../base/browser/ui/aria/aria.js';
import { Command, EditorCommand, registerEditorCommand, UndoCommand, RedoCommand, SelectAllCommand } from './editorExtensions.js';
import { ICodeEditorService } from './services/codeEditorService.js';
import { ColumnSelection } from '../common/cursor/cursorColumnSelection.js';
import { CursorState } from '../common/cursorCommon.js';
import { DeleteOperations } from '../common/cursor/cursorDeleteOperations.js';
import { CursorMove as CursorMove_, CursorMoveCommands } from '../common/cursor/cursorMoveCommands.js';
import { TypeOperations } from '../common/cursor/cursorTypeOperations.js';
import { Position } from '../common/core/position.js';
import { Range } from '../common/core/range.js';
import { EditorContextKeys } from '../common/editorContextKeys.js';
import { ContextKeyExpr } from '../../platform/contextkey/common/contextkey.js';
import { KeybindingsRegistry } from '../../platform/keybinding/common/keybindingsRegistry.js';
import { getActiveElement } from '../../base/browser/dom.js';
import { EnterOperation } from '../common/cursor/cursorTypeEditOperations.js';
const CORE_WEIGHT = 0 /* KeybindingWeight.EditorCore */;
export class CoreEditorCommand extends EditorCommand {
runEditorCommand(accessor, editor, args) {
const viewModel = editor._getViewModel();
if (!viewModel) {
// the editor has no view => has no cursors
return;
}
this.runCoreEditorCommand(viewModel, args || {});
}
}
export var EditorScroll_;
(function (EditorScroll_) {
const isEditorScrollArgs = function (arg) {
if (!types.isObject(arg)) {
return false;
}
const scrollArg = arg;
if (!types.isString(scrollArg.to)) {
return false;
}
if (!types.isUndefined(scrollArg.by) && !types.isString(scrollArg.by)) {
return false;
}
if (!types.isUndefined(scrollArg.value) && !types.isNumber(scrollArg.value)) {
return false;
}
if (!types.isUndefined(scrollArg.revealCursor) && !types.isBoolean(scrollArg.revealCursor)) {
return false;
}
return true;
};
EditorScroll_.metadata = {
description: 'Scroll editor in the given direction',
args: [
{
name: 'Editor scroll argument object',
description: `Property-value pairs that can be passed through this argument:
* 'to': A mandatory direction value.
\`\`\`
'up', 'down'
\`\`\`
* 'by': Unit to move. Default is computed based on 'to' value.
\`\`\`
'line', 'wrappedLine', 'page', 'halfPage', 'editor'
\`\`\`
* 'value': Number of units to move. Default is '1'.
* 'revealCursor': If 'true' reveals the cursor if it is outside view port.
`,
constraint: isEditorScrollArgs,
schema: {
'type': 'object',
'required': ['to'],
'properties': {
'to': {
'type': 'string',
'enum': ['up', 'down']
},
'by': {
'type': 'string',
'enum': ['line', 'wrappedLine', 'page', 'halfPage', 'editor']
},
'value': {
'type': 'number',
'default': 1
},
'revealCursor': {
'type': 'boolean',
}
}
}
}
]
};
/**
* Directions in the view for editor scroll command.
*/
EditorScroll_.RawDirection = {
Up: 'up',
Right: 'right',
Down: 'down',
Left: 'left'
};
/**
* Units for editor scroll 'by' argument
*/
EditorScroll_.RawUnit = {
Line: 'line',
WrappedLine: 'wrappedLine',
Page: 'page',
HalfPage: 'halfPage',
Editor: 'editor',
Column: 'column'
};
function parse(args) {
let direction;
switch (args.to) {
case EditorScroll_.RawDirection.Up:
direction = 1 /* Direction.Up */;
break;
case EditorScroll_.RawDirection.Right:
direction = 2 /* Direction.Right */;
break;
case EditorScroll_.RawDirection.Down:
direction = 3 /* Direction.Down */;
break;
case EditorScroll_.RawDirection.Left:
direction = 4 /* Direction.Left */;
break;
default:
// Illegal arguments
return null;
}
let unit;
switch (args.by) {
case EditorScroll_.RawUnit.Line:
unit = 1 /* Unit.Line */;
break;
case EditorScroll_.RawUnit.WrappedLine:
unit = 2 /* Unit.WrappedLine */;
break;
case EditorScroll_.RawUnit.Page:
unit = 3 /* Unit.Page */;
break;
case EditorScroll_.RawUnit.HalfPage:
unit = 4 /* Unit.HalfPage */;
break;
case EditorScroll_.RawUnit.Editor:
unit = 5 /* Unit.Editor */;
break;
case EditorScroll_.RawUnit.Column:
unit = 6 /* Unit.Column */;
break;
default:
unit = 2 /* Unit.WrappedLine */;
}
const value = Math.floor(args.value || 1);
const revealCursor = !!args.revealCursor;
return {
direction: direction,
unit: unit,
value: value,
revealCursor: revealCursor,
select: (!!args.select)
};
}
EditorScroll_.parse = parse;
})(EditorScroll_ || (EditorScroll_ = {}));
export var RevealLine_;
(function (RevealLine_) {
const isRevealLineArgs = function (arg) {
if (!types.isObject(arg)) {
return false;
}
const reveaLineArg = arg;
if (!types.isNumber(reveaLineArg.lineNumber) && !types.isString(reveaLineArg.lineNumber)) {
return false;
}
if (!types.isUndefined(reveaLineArg.at) && !types.isString(reveaLineArg.at)) {
return false;
}
return true;
};
RevealLine_.metadata = {
description: 'Reveal the given line at the given logical position',
args: [
{
name: 'Reveal line argument object',
description: `Property-value pairs that can be passed through this argument:
* 'lineNumber': A mandatory line number value.
* 'at': Logical position at which line has to be revealed.
\`\`\`
'top', 'center', 'bottom'
\`\`\`
`,
constraint: isRevealLineArgs,
schema: {
'type': 'object',
'required': ['lineNumber'],
'properties': {
'lineNumber': {
'type': ['number', 'string'],
},
'at': {
'type': 'string',
'enum': ['top', 'center', 'bottom']
}
}
}
}
]
};
/**
* Values for reveal line 'at' argument
*/
RevealLine_.RawAtArgument = {
Top: 'top',
Center: 'center',
Bottom: 'bottom'
};
})(RevealLine_ || (RevealLine_ = {}));
class EditorOrNativeTextInputCommand {
constructor(target) {
// 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()) {
return this._runEditorCommand(accessor, focusedEditor, args);
}
return false;
});
// 2. handle case when focus is in some other `input` / `textarea`.
target.addImplementation(1000, 'generic-dom-input-textarea', (accessor, args) => {
// Only if focused on an element that allows for entering text
const activeElement = getActiveElement();
if (activeElement && ['input', 'textarea'].indexOf(activeElement.tagName.toLowerCase()) >= 0) {
this.runDOMCommand(activeElement);
return true;
}
return false;
});
// 3. (default) handle case when focus is somewhere else.
target.addImplementation(0, 'generic-dom', (accessor, args) => {
// Redirecting to active editor
const activeEditor = accessor.get(ICodeEditorService).getActiveCodeEditor();
if (activeEditor) {
activeEditor.focus();
return this._runEditorCommand(accessor, activeEditor, args);
}
return false;
});
}
_runEditorCommand(accessor, editor, args) {
const result = this.runEditorCommand(accessor, editor, args);
if (result) {
return result;
}
return true;
}
}
export var CoreNavigationCommands;
(function (CoreNavigationCommands) {
class BaseMoveToCommand extends CoreEditorCommand {
constructor(opts) {
super(opts);
this._inSelectionMode = opts.inSelectionMode;
}
runCoreEditorCommand(viewModel, args) {
if (!args.position) {
return;
}
viewModel.model.pushStackElement();
const cursorStateChanged = viewModel.setCursorStates(args.source, 3 /* CursorChangeReason.Explicit */, [
CursorMoveCommands.moveTo(viewModel, viewModel.getPrimaryCursorState(), this._inSelectionMode, args.position, args.viewPosition)
]);
if (cursorStateChanged && args.revealType !== 2 /* NavigationCommandRevealType.None */) {
viewModel.revealAllCursors(args.source, true, true);
}
}
}
CoreNavigationCommands.MoveTo = registerEditorCommand(new BaseMoveToCommand({
id: '_moveTo',
inSelectionMode: false,
precondition: undefined
}));
CoreNavigationCommands.MoveToSelect = registerEditorCommand(new BaseMoveToCommand({
id: '_moveToSelect',
inSelectionMode: true,
precondition: undefined
}));
class ColumnSelectCommand extends CoreEditorCommand {
runCoreEditorCommand(viewModel, args) {
viewModel.model.pushStackElement();
const result = this._getColumnSelectResult(viewModel, viewModel.getPrimaryCursorState(), viewModel.getCursorColumnSelectData(), args);
if (result === null) {
// invalid arguments
return;
}
viewModel.setCursorStates(args.source, 3 /* CursorChangeReason.Explicit */, result.viewStates.map((viewState) => CursorState.fromViewState(viewState)));
viewModel.setCursorColumnSelectData({
isReal: true,
fromViewLineNumber: result.fromLineNumber,
fromViewVisualColumn: result.fromVisualColumn,
toViewLineNumber: result.toLineNumber,
toViewVisualColumn: result.toVisualColumn
});
if (result.reversed) {
viewModel.revealTopMostCursor(args.source);
}
else {
viewModel.revealBottomMostCursor(args.source);
}
}
}
CoreNavigationCommands.ColumnSelect = registerEditorCommand(new class extends ColumnSelectCommand {
constructor() {
super({
id: 'columnSelect',
precondition: undefined
});
}
_getColumnSelectResult(viewModel, primary, prevColumnSelectData, args) {
if (typeof args.position === 'undefined' || typeof args.viewPosition === 'undefined' || typeof args.mouseColumn === 'undefined') {
return null;
}
// validate `args`
const validatedPosition = viewModel.model.validatePosition(args.position);
const validatedViewPosition = viewModel.coordinatesConverter.validateViewPosition(new Position(args.viewPosition.lineNumber, args.viewPosition.column), validatedPosition);
const fromViewLineNumber = args.doColumnSelect ? prevColumnSelectData.fromViewLineNumber : validatedViewPosition.lineNumber;
const fromViewVisualColumn = args.doColumnSelect ? prevColumnSelectData.fromViewVisualColumn : args.mouseColumn - 1;
return ColumnSelection.columnSelect(viewModel.cursorConfig, viewModel, fromViewLineNumber, fromViewVisualColumn, validatedViewPosition.lineNumber, args.mouseColumn - 1);
}
});
CoreNavigationCommands.CursorColumnSelectLeft = registerEditorCommand(new class extends ColumnSelectCommand {
constructor() {
super({
id: 'cursorColumnSelectLeft',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 512 /* KeyMod.Alt */ | 15 /* KeyCode.LeftArrow */,
linux: { primary: 0 }
}
});
}
_getColumnSelectResult(viewModel, primary, prevColumnSelectData, args) {
return ColumnSelection.columnSelectLeft(viewModel.cursorConfig, viewModel, prevColumnSelectData);
}
});
CoreNavigationCommands.CursorColumnSelectRight = registerEditorCommand(new class extends ColumnSelectCommand {
constructor() {
super({
id: 'cursorColumnSelectRight',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 512 /* KeyMod.Alt */ | 17 /* KeyCode.RightArrow */,
linux: { primary: 0 }
}
});
}
_getColumnSelectResult(viewModel, primary, prevColumnSelectData, args) {
return ColumnSelection.columnSelectRight(viewModel.cursorConfig, viewModel, prevColumnSelectData);
}
});
class ColumnSelectUpCommand extends ColumnSelectCommand {
constructor(opts) {
super(opts);
this._isPaged = opts.isPaged;
}
_getColumnSelectResult(viewModel, primary, prevColumnSelectData, args) {
return ColumnSelection.columnSelectUp(viewModel.cursorConfig, viewModel, prevColumnSelectData, this._isPaged);
}
}
CoreNavigationCommands.CursorColumnSelectUp = registerEditorCommand(new ColumnSelectUpCommand({
isPaged: false,
id: 'cursorColumnSelectUp',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 512 /* KeyMod.Alt */ | 16 /* KeyCode.UpArrow */,
linux: { primary: 0 }
}
}));
CoreNavigationCommands.CursorColumnSelectPageUp = registerEditorCommand(new ColumnSelectUpCommand({
isPaged: true,
id: 'cursorColumnSelectPageUp',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 512 /* KeyMod.Alt */ | 11 /* KeyCode.PageUp */,
linux: { primary: 0 }
}
}));
class ColumnSelectDownCommand extends ColumnSelectCommand {
constructor(opts) {
super(opts);
this._isPaged = opts.isPaged;
}
_getColumnSelectResult(viewModel, primary, prevColumnSelectData, args) {
return ColumnSelection.columnSelectDown(viewModel.cursorConfig, viewModel, prevColumnSelectData, this._isPaged);
}
}
CoreNavigationCommands.CursorColumnSelectDown = registerEditorCommand(new ColumnSelectDownCommand({
isPaged: false,
id: 'cursorColumnSelectDown',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 512 /* KeyMod.Alt */ | 18 /* KeyCode.DownArrow */,
linux: { primary: 0 }
}
}));
CoreNavigationCommands.CursorColumnSelectPageDown = registerEditorCommand(new ColumnSelectDownCommand({
isPaged: true,
id: 'cursorColumnSelectPageDown',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 512 /* KeyMod.Alt */ | 12 /* KeyCode.PageDown */,
linux: { primary: 0 }
}
}));
class CursorMoveImpl extends CoreEditorCommand {
constructor() {
super({
id: 'cursorMove',
precondition: undefined,
metadata: CursorMove_.metadata
});
}
runCoreEditorCommand(viewModel, args) {
const parsed = CursorMove_.parse(args);
if (!parsed) {
// illegal arguments
return;
}
this._runCursorMove(viewModel, args.source, parsed);
}
_runCursorMove(viewModel, source, args) {
viewModel.model.pushStackElement();
viewModel.setCursorStates(source, 3 /* CursorChangeReason.Explicit */, CursorMoveImpl._move(viewModel, viewModel.getCursorStates(), args));
viewModel.revealAllCursors(source, true);
}
static _move(viewModel, cursors, args) {
const inSelectionMode = args.select;
const value = args.value;
switch (args.direction) {
case 0 /* CursorMove_.Direction.Left */:
case 1 /* CursorMove_.Direction.Right */:
case 2 /* CursorMove_.Direction.Up */:
case 3 /* CursorMove_.Direction.Down */:
case 4 /* CursorMove_.Direction.PrevBlankLine */:
case 5 /* CursorMove_.Direction.NextBlankLine */:
case 6 /* CursorMove_.Direction.WrappedLineStart */:
case 7 /* CursorMove_.Direction.WrappedLineFirstNonWhitespaceCharacter */:
case 8 /* CursorMove_.Direction.WrappedLineColumnCenter */:
case 9 /* CursorMove_.Direction.WrappedLineEnd */:
case 10 /* CursorMove_.Direction.WrappedLineLastNonWhitespaceCharacter */:
return CursorMoveCommands.simpleMove(viewModel, cursors, args.direction, inSelectionMode, value, args.unit);
case 11 /* CursorMove_.Direction.ViewPortTop */:
case 13 /* CursorMove_.Direction.ViewPortBottom */:
case 12 /* CursorMove_.Direction.ViewPortCenter */:
case 14 /* CursorMove_.Direction.ViewPortIfOutside */:
return CursorMoveCommands.viewportMove(viewModel, cursors, args.direction, inSelectionMode, value);
default:
return null;
}
}
}
CoreNavigationCommands.CursorMoveImpl = CursorMoveImpl;
CoreNavigationCommands.CursorMove = registerEditorCommand(new CursorMoveImpl());
class CursorMoveBasedCommand extends CoreEditorCommand {
constructor(opts) {
super(opts);
this._staticArgs = opts.args;
}
runCoreEditorCommand(viewModel, dynamicArgs) {
let args = this._staticArgs;
if (this._staticArgs.value === -1 /* Constants.PAGE_SIZE_MARKER */) {
// -1 is a marker for page size
args = {
direction: this._staticArgs.direction,
unit: this._staticArgs.unit,
select: this._staticArgs.select,
value: dynamicArgs.pageSize || viewModel.cursorConfig.pageSize
};
}
viewModel.model.pushStackElement();
viewModel.setCursorStates(dynamicArgs.source, 3 /* CursorChangeReason.Explicit */, CursorMoveCommands.simpleMove(viewModel, viewModel.getCursorStates(), args.direction, args.select, args.value, args.unit));
viewModel.revealAllCursors(dynamicArgs.source, true);
}
}
CoreNavigationCommands.CursorLeft = registerEditorCommand(new CursorMoveBasedCommand({
args: {
direction: 0 /* CursorMove_.Direction.Left */,
unit: 0 /* CursorMove_.Unit.None */,
select: false,
value: 1
},
id: 'cursorLeft',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 15 /* KeyCode.LeftArrow */,
mac: { primary: 15 /* KeyCode.LeftArrow */, secondary: [256 /* KeyMod.WinCtrl */ | 32 /* KeyCode.KeyB */] }
}
}));
CoreNavigationCommands.CursorLeftSelect = registerEditorCommand(new CursorMoveBasedCommand({
args: {
direction: 0 /* CursorMove_.Direction.Left */,
unit: 0 /* CursorMove_.Unit.None */,
select: true,
value: 1
},
id: 'cursorLeftSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 1024 /* KeyMod.Shift */ | 15 /* KeyCode.LeftArrow */
}
}));
CoreNavigationCommands.CursorRight = registerEditorCommand(new CursorMoveBasedCommand({
args: {
direction: 1 /* CursorMove_.Direction.Right */,
unit: 0 /* CursorMove_.Unit.None */,
select: false,
value: 1
},
id: 'cursorRight',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 17 /* KeyCode.RightArrow */,
mac: { primary: 17 /* KeyCode.RightArrow */, secondary: [256 /* KeyMod.WinCtrl */ | 36 /* KeyCode.KeyF */] }
}
}));
CoreNavigationCommands.CursorRightSelect = registerEditorCommand(new CursorMoveBasedCommand({
args: {
direction: 1 /* CursorMove_.Direction.Right */,
unit: 0 /* CursorMove_.Unit.None */,
select: true,
value: 1
},
id: 'cursorRightSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 1024 /* KeyMod.Shift */ | 17 /* KeyCode.RightArrow */
}
}));
CoreNavigationCommands.CursorUp = registerEditorCommand(new CursorMoveBasedCommand({
args: {
direction: 2 /* CursorMove_.Direction.Up */,
unit: 2 /* CursorMove_.Unit.WrappedLine */,
select: false,
value: 1
},
id: 'cursorUp',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 16 /* KeyCode.UpArrow */,
mac: { primary: 16 /* KeyCode.UpArrow */, secondary: [256 /* KeyMod.WinCtrl */ | 46 /* KeyCode.KeyP */] }
}
}));
CoreNavigationCommands.CursorUpSelect = registerEditorCommand(new CursorMoveBasedCommand({
args: {
direction: 2 /* CursorMove_.Direction.Up */,
unit: 2 /* CursorMove_.Unit.WrappedLine */,
select: true,
value: 1
},
id: 'cursorUpSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 1024 /* KeyMod.Shift */ | 16 /* KeyCode.UpArrow */,
secondary: [2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 16 /* KeyCode.UpArrow */],
mac: { primary: 1024 /* KeyMod.Shift */ | 16 /* KeyCode.UpArrow */ },
linux: { primary: 1024 /* KeyMod.Shift */ | 16 /* KeyCode.UpArrow */ }
}
}));
CoreNavigationCommands.CursorPageUp = registerEditorCommand(new CursorMoveBasedCommand({
args: {
direction: 2 /* CursorMove_.Direction.Up */,
unit: 2 /* CursorMove_.Unit.WrappedLine */,
select: false,
value: -1 /* Constants.PAGE_SIZE_MARKER */
},
id: 'cursorPageUp',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 11 /* KeyCode.PageUp */
}
}));
CoreNavigationCommands.CursorPageUpSelect = registerEditorCommand(new CursorMoveBasedCommand({
args: {
direction: 2 /* CursorMove_.Direction.Up */,
unit: 2 /* CursorMove_.Unit.WrappedLine */,
select: true,
value: -1 /* Constants.PAGE_SIZE_MARKER */
},
id: 'cursorPageUpSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 1024 /* KeyMod.Shift */ | 11 /* KeyCode.PageUp */
}
}));
CoreNavigationCommands.CursorDown = registerEditorCommand(new CursorMoveBasedCommand({
args: {
direction: 3 /* CursorMove_.Direction.Down */,
unit: 2 /* CursorMove_.Unit.WrappedLine */,
select: false,
value: 1
},
id: 'cursorDown',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 18 /* KeyCode.DownArrow */,
mac: { primary: 18 /* KeyCode.DownArrow */, secondary: [256 /* KeyMod.WinCtrl */ | 44 /* KeyCode.KeyN */] }
}
}));
CoreNavigationCommands.CursorDownSelect = registerEditorCommand(new CursorMoveBasedCommand({
args: {
direction: 3 /* CursorMove_.Direction.Down */,
unit: 2 /* CursorMove_.Unit.WrappedLine */,
select: true,
value: 1
},
id: 'cursorDownSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 1024 /* KeyMod.Shift */ | 18 /* KeyCode.DownArrow */,
secondary: [2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 18 /* KeyCode.DownArrow */],
mac: { primary: 1024 /* KeyMod.Shift */ | 18 /* KeyCode.DownArrow */ },
linux: { primary: 1024 /* KeyMod.Shift */ | 18 /* KeyCode.DownArrow */ }
}
}));
CoreNavigationCommands.CursorPageDown = registerEditorCommand(new CursorMoveBasedCommand({
args: {
direction: 3 /* CursorMove_.Direction.Down */,
unit: 2 /* CursorMove_.Unit.WrappedLine */,
select: false,
value: -1 /* Constants.PAGE_SIZE_MARKER */
},
id: 'cursorPageDown',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 12 /* KeyCode.PageDown */
}
}));
CoreNavigationCommands.CursorPageDownSelect = registerEditorCommand(new CursorMoveBasedCommand({
args: {
direction: 3 /* CursorMove_.Direction.Down */,
unit: 2 /* CursorMove_.Unit.WrappedLine */,
select: true,
value: -1 /* Constants.PAGE_SIZE_MARKER */
},
id: 'cursorPageDownSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 1024 /* KeyMod.Shift */ | 12 /* KeyCode.PageDown */
}
}));
CoreNavigationCommands.CreateCursor = registerEditorCommand(new class extends CoreEditorCommand {
constructor() {
super({
id: 'createCursor',
precondition: undefined
});
}
runCoreEditorCommand(viewModel, args) {
if (!args.position) {
return;
}
let newState;
if (args.wholeLine) {
newState = CursorMoveCommands.line(viewModel, viewModel.getPrimaryCursorState(), false, args.position, args.viewPosition);
}
else {
newState = CursorMoveCommands.moveTo(viewModel, viewModel.getPrimaryCursorState(), false, args.position, args.viewPosition);
}
const states = viewModel.getCursorStates();
// Check if we should remove a cursor (sort of like a toggle)
if (states.length > 1) {
const newModelPosition = (newState.modelState ? newState.modelState.position : null);
const newViewPosition = (newState.viewState ? newState.viewState.position : null);
for (let i = 0, len = states.length; i < len; i++) {
const state = states[i];
if (newModelPosition && !state.modelState.selection.containsPosition(newModelPosition)) {
continue;
}
if (newViewPosition && !state.viewState.selection.containsPosition(newViewPosition)) {
continue;
}
// => Remove the cursor
states.splice(i, 1);
viewModel.model.pushStackElement();
viewModel.setCursorStates(args.source, 3 /* CursorChangeReason.Explicit */, states);
return;
}
}
// => Add the new cursor
states.push(newState);
viewModel.model.pushStackElement();
viewModel.setCursorStates(args.source, 3 /* CursorChangeReason.Explicit */, states);
}
});
CoreNavigationCommands.LastCursorMoveToSelect = registerEditorCommand(new class extends CoreEditorCommand {
constructor() {
super({
id: '_lastCursorMoveToSelect',
precondition: undefined
});
}
runCoreEditorCommand(viewModel, args) {
if (!args.position) {
return;
}
const lastAddedCursorIndex = viewModel.getLastAddedCursorIndex();
const states = viewModel.getCursorStates();
const newStates = states.slice(0);
newStates[lastAddedCursorIndex] = CursorMoveCommands.moveTo(viewModel, states[lastAddedCursorIndex], true, args.position, args.viewPosition);
viewModel.model.pushStackElement();
viewModel.setCursorStates(args.source, 3 /* CursorChangeReason.Explicit */, newStates);
}
});
class HomeCommand extends CoreEditorCommand {
constructor(opts) {
super(opts);
this._inSelectionMode = opts.inSelectionMode;
}
runCoreEditorCommand(viewModel, args) {
viewModel.model.pushStackElement();
viewModel.setCursorStates(args.source, 3 /* CursorChangeReason.Explicit */, CursorMoveCommands.moveToBeginningOfLine(viewModel, viewModel.getCursorStates(), this._inSelectionMode));
viewModel.revealAllCursors(args.source, true);
}
}
CoreNavigationCommands.CursorHome = registerEditorCommand(new HomeCommand({
inSelectionMode: false,
id: 'cursorHome',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 14 /* KeyCode.Home */,
mac: { primary: 14 /* KeyCode.Home */, secondary: [2048 /* KeyMod.CtrlCmd */ | 15 /* KeyCode.LeftArrow */] }
}
}));
CoreNavigationCommands.CursorHomeSelect = registerEditorCommand(new HomeCommand({
inSelectionMode: true,
id: 'cursorHomeSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 1024 /* KeyMod.Shift */ | 14 /* KeyCode.Home */,
mac: { primary: 1024 /* KeyMod.Shift */ | 14 /* KeyCode.Home */, secondary: [2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 15 /* KeyCode.LeftArrow */] }
}
}));
class LineStartCommand extends CoreEditorCommand {
constructor(opts) {
super(opts);
this._inSelectionMode = opts.inSelectionMode;
}
runCoreEditorCommand(viewModel, args) {
viewModel.model.pushStackElement();
viewModel.setCursorStates(args.source, 3 /* CursorChangeReason.Explicit */, this._exec(viewModel.getCursorStates()));
viewModel.revealAllCursors(args.source, true);
}
_exec(cursors) {
const result = [];
for (let i = 0, len = cursors.length; i < len; i++) {
const cursor = cursors[i];
const lineNumber = cursor.modelState.position.lineNumber;
result[i] = CursorState.fromModelState(cursor.modelState.move(this._inSelectionMode, lineNumber, 1, 0));
}
return result;
}
}
CoreNavigationCommands.CursorLineStart = registerEditorCommand(new LineStartCommand({
inSelectionMode: false,
id: 'cursorLineStart',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 0,
mac: { primary: 256 /* KeyMod.WinCtrl */ | 31 /* KeyCode.KeyA */ }
}
}));
CoreNavigationCommands.CursorLineStartSelect = registerEditorCommand(new LineStartCommand({
inSelectionMode: true,
id: 'cursorLineStartSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 0,
mac: { primary: 256 /* KeyMod.WinCtrl */ | 1024 /* KeyMod.Shift */ | 31 /* KeyCode.KeyA */ }
}
}));
class EndCommand extends CoreEditorCommand {
constructor(opts) {
super(opts);
this._inSelectionMode = opts.inSelectionMode;
}
runCoreEditorCommand(viewModel, args) {
viewModel.model.pushStackElement();
viewModel.setCursorStates(args.source, 3 /* CursorChangeReason.Explicit */, CursorMoveCommands.moveToEndOfLine(viewModel, viewModel.getCursorStates(), this._inSelectionMode, args.sticky || false));
viewModel.revealAllCursors(args.source, true);
}
}
CoreNavigationCommands.CursorEnd = registerEditorCommand(new EndCommand({
inSelectionMode: false,
id: 'cursorEnd',
precondition: undefined,
kbOpts: {
args: { sticky: false },
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 13 /* KeyCode.End */,
mac: { primary: 13 /* KeyCode.End */, secondary: [2048 /* KeyMod.CtrlCmd */ | 17 /* KeyCode.RightArrow */] }
},
metadata: {
description: `Go to End`,
args: [{
name: 'args',
schema: {
type: 'object',
properties: {
'sticky': {
description: nls.localize('stickydesc', "Stick to the end even when going to longer lines"),
type: 'boolean',
default: false
}
}
}
}]
}
}));
CoreNavigationCommands.CursorEndSelect = registerEditorCommand(new EndCommand({
inSelectionMode: true,
id: 'cursorEndSelect',
precondition: undefined,
kbOpts: {
args: { sticky: false },
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 1024 /* KeyMod.Shift */ | 13 /* KeyCode.End */,
mac: { primary: 1024 /* KeyMod.Shift */ | 13 /* KeyCode.End */, secondary: [2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 17 /* KeyCode.RightArrow */] }
},
metadata: {
description: `Select to End`,
args: [{
name: 'args',
schema: {
type: 'object',
properties: {
'sticky': {
description: nls.localize('stickydesc', "Stick to the end even when going to longer lines"),
type: 'boolean',
default: false
}
}
}
}]
}
}));
class LineEndCommand extends CoreEditorCommand {
constructor(opts) {
super(opts);
this._inSelectionMode = opts.inSelectionMode;
}
runCoreEditorCommand(viewModel, args) {
viewModel.model.pushStackElement();
viewModel.setCursorStates(args.source, 3 /* CursorChangeReason.Explicit */, this._exec(viewModel, viewModel.getCursorStates()));
viewModel.revealAllCursors(args.source, true);
}
_exec(viewModel, cursors) {
const result = [];
for (let i = 0, len = cursors.length; i < len; i++) {
const cursor = cursors[i];
const lineNumber = cursor.modelState.position.lineNumber;
const maxColumn = viewModel.model.getLineMaxColumn(lineNumber);
result[i] = CursorState.fromModelState(cursor.modelState.move(this._inSelectionMode, lineNumber, maxColumn, 0));
}
return result;
}
}
CoreNavigationCommands.CursorLineEnd = registerEditorCommand(new LineEndCommand({
inSelectionMode: false,
id: 'cursorLineEnd',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 0,
mac: { primary: 256 /* KeyMod.WinCtrl */ | 35 /* KeyCode.KeyE */ }
}
}));
CoreNavigationCommands.CursorLineEndSelect = registerEditorCommand(new LineEndCommand({
inSelectionMode: true,
id: 'cursorLineEndSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 0,
mac: { primary: 256 /* KeyMod.WinCtrl */ | 1024 /* KeyMod.Shift */ | 35 /* KeyCode.KeyE */ }
}
}));
class TopCommand extends CoreEditorCommand {
constructor(opts) {
super(opts);
this._inSelectionMode = opts.inSelectionMode;
}
runCoreEditorCommand(viewModel, args) {
viewModel.model.pushStackElement();
viewModel.setCursorStates(args.source, 3 /* CursorChangeReason.Explicit */, CursorMoveCommands.moveToBeginningOfBuffer(viewModel, viewModel.getCursorStates(), this._inSelectionMode));
viewModel.revealAllCursors(args.source, true);
}
}
CoreNavigationCommands.CursorTop = registerEditorCommand(new TopCommand({
inSelectionMode: false,
id: 'cursorTop',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 2048 /* KeyMod.CtrlCmd */ | 14 /* KeyCode.Home */,
mac: { primary: 2048 /* KeyMod.CtrlCmd */ | 16 /* KeyCode.UpArrow */ }
}
}));
CoreNavigationCommands.CursorTopSelect = registerEditorCommand(new TopCommand({
inSelectionMode: true,
id: 'cursorTopSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 14 /* KeyCode.Home */,
mac: { primary: 2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 16 /* KeyCode.UpArrow */ }
}
}));
class BottomCommand extends CoreEditorCommand {
constructor(opts) {
super(opts);
this._inSelectionMode = opts.inSelectionMode;
}
runCoreEditorCommand(viewModel, args) {
viewModel.model.pushStackElement();
viewModel.setCursorStates(args.source, 3 /* CursorChangeReason.Explicit */, CursorMoveCommands.moveToEndOfBuffer(viewModel, viewModel.getCursorStates(), this._inSelectionMode));
viewModel.revealAllCursors(args.source, true);
}
}
CoreNavigationCommands.CursorBottom = registerEditorCommand(new BottomCommand({
inSelectionMode: false,
id: 'cursorBottom',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 2048 /* KeyMod.CtrlCmd */ | 13 /* KeyCode.End */,
mac: { primary: 2048 /* KeyMod.CtrlCmd */ | 18 /* KeyCode.DownArrow */ }
}
}));
CoreNavigationCommands.CursorBottomSelect = registerEditorCommand(new BottomCommand({
inSelectionMode: true,
id: 'cursorBottomSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 13 /* KeyCode.End */,
mac: { primary: 2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 18 /* KeyCode.DownArrow */ }
}
}));
class EditorScrollImpl extends CoreEditorCommand {
constructor() {
super({
id: 'editorScroll',
precondition: undefined,
metadata: EditorScroll_.metadata
});
}
determineScrollMethod(args) {
const horizontalUnits = [6 /* EditorScroll_.Unit.Column */];
const verticalUnits = [
1 /* EditorScroll_.Unit.Line */,
2 /* EditorScroll_.Unit.WrappedLine */,
3 /* EditorScroll_.Unit.Page */,
4 /* EditorScroll_.Unit.HalfPage */,
5 /* EditorScroll_.Unit.Editor */,
6 /* EditorScroll_.Unit.Column */
];
const horizontalDirections = [4 /* EditorScroll_.Direction.Left */, 2 /* EditorScroll_.Direction.Right */];
const verticalDirections = [1 /* EditorScroll_.Direction.Up */, 3 /* EditorScroll_.Direction.Down */];
if (horizontalUnits.includes(args.unit) && horizontalDirections.includes(args.direction)) {
return this._runHorizontalEditorScroll.bind(this);
}
if (verticalUnits.includes(args.unit) && verticalDirections.includes(args.direction)) {
return this._runVerticalEditorScroll.bind(this);
}
return null;
}
runCoreEditorCommand(viewModel, args) {
const parsed = EditorScroll_.parse(args);
if (!parsed) {
// illegal arguments
return;
}
const runEditorScroll = this.determineScrollMethod(parsed);
if (!runEditorScroll) {
// Incompatible unit and direction
return;
}
runEditorScroll(viewModel, args.source, parsed);
}
_runVerticalEditorScroll(viewModel, source, args) {
const desiredScrollTop = this._computeDesiredScrollTop(viewModel, args);
if (args.revealCursor) {
// must ensure cursor is in new visible range
const desiredVisibleViewRange = viewModel.getCompletelyVisibleViewRangeAtScrollTop(desiredScrollTop);
viewModel.setCursorStates(source, 3 /* CursorChangeReason.Explicit */, [
CursorMoveCommands.findPositionInViewportIfOutside(viewModel, viewModel.getPrimaryCursorState(), desiredVisibleViewRange, args.select)
]);
}
viewModel.viewLayout.setScrollPosition({ scrollTop: desiredScrollTop }, 0 /* ScrollType.Smooth */);
}
_computeDesiredScrollTop(viewModel, args) {
if (args.unit === 1 /* EditorScroll_.Unit.Line */) {
// scrolling by model lines
const futureViewport = viewModel.viewLayout.getFutureViewport();
const visibleViewRange = viewModel.getCompletelyVisibleViewRangeAtScrollTop(futureViewport.top);
const visibleModelRange = viewModel.coordinatesConverter.convertViewRangeToModelRange(visibleViewRange);
let desiredTopModelLineNumber;
if (args.direction === 1 /* EditorScroll_.Direction.Up */) {
// must go x model lines up
desiredTopModelLineNumber = Math.max(1, visibleModelRange.startLineNumber - args.value);
}
else {
// must go x model lines down
desiredTopModelLineNumber = Math.min(viewModel.model.getLineCount(), visibleModelRange.startLineNumber + args.value);
}
const viewPosition = viewModel.coordinatesConverter.convertModelPositionToViewPosition(new Position(desiredTopModelLineNumber, 1));
return viewModel.viewLayout.getVerticalOffsetForLineNumber(viewPosition.lineNumber);
}
if (args.unit === 5 /* EditorScroll_.Unit.Editor */) {
let desiredTopModelLineNumber = 0;
if (args.direction === 3 /* EditorScroll_.Direction.Down */) {
desiredTopModelLineNumber = viewModel.model.getLineCount() - viewModel.cursorConfig.pageSize;
}
return viewModel.viewLayout.getVerticalOffsetForLineNumber(desiredTopModelLineNumber);
}
let noOfLines;
if (args.unit === 3 /* EditorScroll_.Unit.Page */) {
noOfLines = viewModel.cursorConfig.pageSize * args.value;
}
else if (args.unit === 4 /* EditorScroll_.Unit.HalfPage */) {
noOfLines = Math.round(viewModel.cursorConfig.pageSize / 2) * args.value;
}
else {
noOfLines = args.value;
}
const deltaLines = (args.direction === 1 /* EditorScroll_.Direction.Up */ ? -1 : 1) * noOfLines;
return viewModel.viewLayout.getCurrentScrollTop() + deltaLines * viewModel.cursorConfig.lineHeight;
}
_runHorizontalEditorScroll(viewModel, source, args) {
const desiredScrollLeft = this._computeDesiredScrollLeft(viewModel, args);
viewModel.viewLayout.setScrollPosition({ scrollLeft: desiredScrollLeft }, 0 /* ScrollType.Smooth */);
}
_computeDesiredScrollLeft(viewModel, args) {
const deltaColumns = (args.direction === 4 /* EditorScroll_.Direction.Left */ ? -1 : 1) * args.value;
return viewModel.viewLayout.getCurrentScrollLeft() + deltaColumns * viewModel.cursorConfig.typicalHalfwidthCharacterWidth;
}
}
CoreNavigationCommands.EditorScrollImpl = EditorScrollImpl;
CoreNavigationCommands.EditorScroll = registerEditorCommand(new EditorScrollImpl());
CoreNavigationCommands.ScrollLineUp = registerEditorCommand(new class extends CoreEditorCommand {
constructor() {
super({
id: 'scrollLineUp',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 2048 /* KeyMod.CtrlCmd */ | 16 /* KeyCode.UpArrow */,
mac: { primary: 256 /* KeyMod.WinCtrl */ | 11 /* KeyCode.PageUp */ }
}
});
}
runCoreEditorCommand(viewModel, args) {
CoreNavigationCommands.EditorScroll.runCoreEditorCommand(viewModel, {
to: EditorScroll_.RawDirection.Up,
by: EditorScroll_.RawUnit.WrappedLine,
value: 1,
revealCursor: false,
select: false,
source: args.source
});
}
});
CoreNavigationCommands.ScrollPageUp = registerEditorCommand(new class extends CoreEditorCommand {
constructor() {
super({
id: 'scrollPageUp',
precondition: undefined,
kbOp