monaco-editor-core 0.56.0-dev-20251218 → 0.56.0-dev-20251220

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/esm/nls.messages.cs.js +1 -1
  2. package/esm/nls.messages.de.js +1 -1
  3. package/esm/nls.messages.es.js +1 -1
  4. package/esm/nls.messages.fr.js +1 -1
  5. package/esm/nls.messages.it.js +1 -1
  6. package/esm/nls.messages.ja.js +1 -1
  7. package/esm/nls.messages.ko.js +1 -1
  8. package/esm/nls.messages.pl.js +1 -1
  9. package/esm/nls.messages.pt-br.js +1 -1
  10. package/esm/nls.messages.ru.js +1 -1
  11. package/esm/nls.messages.tr.js +1 -1
  12. package/esm/nls.messages.zh-cn.js +1 -1
  13. package/esm/nls.messages.zh-tw.js +1 -1
  14. package/esm/vs/base/common/fuzzyScorer.js +3 -2
  15. package/esm/vs/base/common/fuzzyScorer.js.map +1 -1
  16. package/esm/vs/editor/common/cursor/cursorTypeEditOperations.js +3 -3
  17. package/esm/vs/editor/common/cursor/cursorTypeEditOperations.js.map +1 -1
  18. package/esm/vs/editor/common/viewModel/viewModelImpl.js +4 -15
  19. package/esm/vs/editor/common/viewModel/viewModelImpl.js.map +1 -1
  20. package/esm/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsModel.js +2 -1
  21. package/esm/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsModel.js.map +1 -1
  22. package/esm/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsSource.js +1 -1
  23. package/esm/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsSource.js.map +1 -1
  24. package/esm/vs/editor/contrib/inlineCompletions/browser/model/renameSymbolProcessor.js +2 -2
  25. package/esm/vs/editor/contrib/inlineCompletions/browser/model/renameSymbolProcessor.js.map +1 -1
  26. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.js +6 -6
  27. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.js.map +1 -1
  28. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsModel.js +1 -1
  29. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsModel.js.map +1 -1
  30. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsView.js +13 -11
  31. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsView.js.map +1 -1
  32. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsCustomView.js +5 -7
  33. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsCustomView.js.map +1 -1
  34. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsDeletionView.js +6 -5
  35. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsDeletionView.js.map +1 -1
  36. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsInsertionView.js +6 -5
  37. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsInsertionView.js.map +1 -1
  38. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsLineReplacementView.js +9 -7
  39. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsLineReplacementView.js.map +1 -1
  40. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsSideBySideView.js +14 -9
  41. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsSideBySideView.js.map +1 -1
  42. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordReplacementView.js +9 -7
  43. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordReplacementView.js.map +1 -1
  44. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/inlineEditsLongDistanceHint.js +5 -4
  45. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/inlineEditsLongDistanceHint.js.map +1 -1
  46. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/originalEditorInlineDiffView.js +2 -1
  47. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/originalEditorInlineDiffView.js.map +1 -1
  48. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/theme.js +20 -1
  49. package/esm/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/theme.js.map +1 -1
  50. package/esm/vs/platform/quickinput/browser/quickInput.js +3 -37
  51. package/esm/vs/platform/quickinput/browser/quickInput.js.map +1 -1
  52. package/esm/vs/platform/quickinput/browser/quickInputController.js +1 -0
  53. package/esm/vs/platform/quickinput/browser/quickInputController.js.map +1 -1
  54. package/esm/vs/platform/quickinput/browser/quickInputUtils.js +1 -1
  55. package/esm/vs/platform/quickinput/browser/quickInputUtils.js.map +1 -1
  56. package/esm/vs/platform/quickinput/common/quickInput.js.map +1 -1
  57. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/editor/common/cursor/cursorTypeEditOperations.ts","vs/editor/common/cursor/cursorTypeEditOperations.ts"],"names":[],"mappings":"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","file":"cursorTypeEditOperations.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { CharCode } from '../../../base/common/charCode.js';\nimport { onUnexpectedError } from '../../../base/common/errors.js';\nimport * as strings from '../../../base/common/strings.js';\nimport { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, ReplaceOvertypeCommandOnCompositionEnd } from '../commands/replaceCommand.js';\nimport { ShiftCommand } from '../commands/shiftCommand.js';\nimport { SurroundSelectionCommand } from '../commands/surroundSelectionCommand.js';\nimport { CursorConfiguration, EditOperationResult, EditOperationType, ICursorSimpleModel, isQuote } from '../cursorCommon.js';\nimport { WordCharacterClass, getMapForWordSeparators } from '../core/wordCharacterClassifier.js';\nimport { Range } from '../core/range.js';\nimport { Selection } from '../core/selection.js';\nimport { Position } from '../core/position.js';\nimport { ICommand, ICursorStateComputerData, IEditOperationBuilder } from '../editorCommon.js';\nimport { ITextModel } from '../model.js';\nimport { EnterAction, IndentAction, StandardAutoClosingPairConditional } from '../languages/languageConfiguration.js';\nimport { getIndentationAtPosition } from '../languages/languageConfigurationRegistry.js';\nimport { IElectricAction } from '../languages/supports/electricCharacter.js';\nimport { EditorAutoClosingStrategy, EditorAutoIndentStrategy } from '../config/editorOptions.js';\nimport { createScopedLineTokens } from '../languages/supports.js';\nimport { getIndentActionForType, getIndentForEnter, getInheritIndentForLine } from '../languages/autoIndent.js';\nimport { getEnterAction } from '../languages/enterAction.js';\nimport { CompositionOutcome } from './cursorTypeOperations.js';\n\nexport class AutoIndentOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition && this._isAutoIndentType(config, model, selections)) {\n\t\t\tconst indentationForSelections: { selection: Selection; indentation: string }[] = [];\n\t\t\tfor (const selection of selections) {\n\t\t\t\tconst indentation = this._findActualIndentationForSelection(config, model, selection, ch);\n\t\t\t\tif (indentation === null) {\n\t\t\t\t\t// Auto indentation failed\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tindentationForSelections.push({ selection, indentation });\n\t\t\t}\n\t\t\tconst autoClosingPairClose = AutoClosingOpenCharTypeOperation.getAutoClosingPairClose(config, model, selections, ch, false);\n\t\t\treturn this._getIndentationAndAutoClosingPairEdits(config, model, indentationForSelections, ch, autoClosingPairClose);\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _isAutoIndentType(config: CursorConfiguration, model: ITextModel, selections: Selection[]): boolean {\n\t\tif (config.autoIndent < EditorAutoIndentStrategy.Full) {\n\t\t\treturn false;\n\t\t}\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tif (!model.tokenization.isCheapToTokenize(selections[i].getEndPosition().lineNumber)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate static _findActualIndentationForSelection(config: CursorConfiguration, model: ITextModel, selection: Selection, ch: string): string | null {\n\t\tconst actualIndentation = getIndentActionForType(config, model, selection, ch, {\n\t\t\tshiftIndent: (indentation) => {\n\t\t\t\treturn shiftIndent(config, indentation);\n\t\t\t},\n\t\t\tunshiftIndent: (indentation) => {\n\t\t\t\treturn unshiftIndent(config, indentation);\n\t\t\t},\n\t\t}, config.languageConfigurationService);\n\n\t\tif (actualIndentation === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst currentIndentation = getIndentationAtPosition(model, selection.startLineNumber, selection.startColumn);\n\t\tif (actualIndentation === config.normalizeIndentation(currentIndentation)) {\n\t\t\treturn null;\n\t\t}\n\t\treturn actualIndentation;\n\t}\n\n\tprivate static _getIndentationAndAutoClosingPairEdits(config: CursorConfiguration, model: ITextModel, indentationForSelections: { selection: Selection; indentation: string }[], ch: string, autoClosingPairClose: string | null): EditOperationResult {\n\t\tconst commands: ICommand[] = indentationForSelections.map(({ selection, indentation }) => {\n\t\t\tif (autoClosingPairClose !== null) {\n\t\t\t\t// Apply both auto closing pair edits and auto indentation edits\n\t\t\t\tconst indentationEdit = this._getEditFromIndentationAndSelection(config, model, indentation, selection, ch, false);\n\t\t\t\treturn new TypeWithIndentationAndAutoClosingCommand(indentationEdit, selection, ch, autoClosingPairClose);\n\t\t\t} else {\n\t\t\t\t// Apply only auto indentation edits\n\t\t\t\tconst indentationEdit = this._getEditFromIndentationAndSelection(config, model, indentation, selection, ch, true);\n\t\t\t\treturn typeCommand(indentationEdit.range, indentationEdit.text, false);\n\t\t\t}\n\t\t});\n\t\tconst editOptions = { shouldPushStackElementBefore: true, shouldPushStackElementAfter: false };\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, editOptions);\n\t}\n\n\tprivate static _getEditFromIndentationAndSelection(config: CursorConfiguration, model: ITextModel, indentation: string, selection: Selection, ch: string, includeChInEdit: boolean = true): { range: Range; text: string } {\n\t\tconst startLineNumber = selection.startLineNumber;\n\t\tconst firstNonWhitespaceColumn = model.getLineFirstNonWhitespaceColumn(startLineNumber);\n\t\tlet text: string = config.normalizeIndentation(indentation);\n\t\tif (firstNonWhitespaceColumn !== 0) {\n\t\t\tconst startLine = model.getLineContent(startLineNumber);\n\t\t\ttext += startLine.substring(firstNonWhitespaceColumn - 1, selection.startColumn - 1);\n\t\t}\n\t\ttext += includeChInEdit ? ch : '';\n\t\tconst range = new Range(startLineNumber, 1, selection.endLineNumber, selection.endColumn);\n\t\treturn { range, text };\n\t}\n}\n\nexport class AutoClosingOvertypeOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult | undefined {\n\t\tif (isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) {\n\t\t\treturn this._runAutoClosingOvertype(prevEditOperationType, selections, ch);\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _runAutoClosingOvertype(prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tconst position = selection.getPosition();\n\t\t\tconst typeSelection = new Range(position.lineNumber, position.column, position.lineNumber, position.column + 1);\n\t\t\tcommands[i] = new ReplaceCommand(typeSelection, ch);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, EditOperationType.TypingOther),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class AutoClosingOvertypeWithInterceptorsOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult | undefined {\n\t\tif (isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) {\n\t\t\t// Unfortunately, the close character is at this point \"doubled\", so we need to delete it...\n\t\t\tconst commands = selections.map(s => new ReplaceCommand(new Range(s.positionLineNumber, s.positionColumn, s.positionLineNumber, s.positionColumn + 1), '', false));\n\t\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\t\tshouldPushStackElementBefore: true,\n\t\t\t\tshouldPushStackElementAfter: false\n\t\t\t});\n\t\t}\n\t\treturn;\n\t}\n}\n\nexport class AutoClosingOpenCharTypeOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, chIsAlreadyTyped: boolean, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition) {\n\t\t\tconst autoClosingPairClose = this.getAutoClosingPairClose(config, model, selections, ch, chIsAlreadyTyped);\n\t\t\tif (autoClosingPairClose !== null) {\n\t\t\t\treturn this._runAutoClosingOpenCharType(selections, ch, chIsAlreadyTyped, autoClosingPairClose);\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _runAutoClosingOpenCharType(selections: Selection[], ch: string, chIsAlreadyTyped: boolean, autoClosingPairClose: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tcommands[i] = new TypeWithAutoClosingCommand(selection, ch, !chIsAlreadyTyped, autoClosingPairClose);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n\n\tpublic static getAutoClosingPairClose(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, chIsAlreadyTyped: boolean): string | null {\n\t\tfor (const selection of selections) {\n\t\t\tif (!selection.isEmpty()) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\t// This method is called both when typing (regularly) and when composition ends\n\t\t// This means that we need to work with a text buffer where sometimes `ch` is not\n\t\t// there (it is being typed right now) or with a text buffer where `ch` has already been typed\n\t\t//\n\t\t// In order to avoid adding checks for `chIsAlreadyTyped` in all places, we will work\n\t\t// with two conceptual positions, the position before `ch` and the position after `ch`\n\t\t//\n\t\tconst positions: { lineNumber: number; beforeColumn: number; afterColumn: number }[] = selections.map((s) => {\n\t\t\tconst position = s.getPosition();\n\t\t\tif (chIsAlreadyTyped) {\n\t\t\t\treturn { lineNumber: position.lineNumber, beforeColumn: position.column - ch.length, afterColumn: position.column };\n\t\t\t} else {\n\t\t\t\treturn { lineNumber: position.lineNumber, beforeColumn: position.column, afterColumn: position.column };\n\t\t\t}\n\t\t});\n\t\t// Find the longest auto-closing open pair in case of multiple ending in `ch`\n\t\t// e.g. when having [f\",\"] and [\",\"], it picks [f\",\"] if the character before is f\n\t\tconst pair = this._findAutoClosingPairOpen(config, model, positions.map(p => new Position(p.lineNumber, p.beforeColumn)), ch);\n\t\tif (!pair) {\n\t\t\treturn null;\n\t\t}\n\t\tlet autoCloseConfig: EditorAutoClosingStrategy;\n\t\tlet shouldAutoCloseBefore: (ch: string) => boolean;\n\n\t\tconst chIsQuote = isQuote(ch);\n\t\tif (chIsQuote) {\n\t\t\tautoCloseConfig = config.autoClosingQuotes;\n\t\t\tshouldAutoCloseBefore = config.shouldAutoCloseBefore.quote;\n\t\t} else {\n\t\t\tconst pairIsForComments = config.blockCommentStartToken ? pair.open.includes(config.blockCommentStartToken) : false;\n\t\t\tif (pairIsForComments) {\n\t\t\t\tautoCloseConfig = config.autoClosingComments;\n\t\t\t\tshouldAutoCloseBefore = config.shouldAutoCloseBefore.comment;\n\t\t\t} else {\n\t\t\t\tautoCloseConfig = config.autoClosingBrackets;\n\t\t\t\tshouldAutoCloseBefore = config.shouldAutoCloseBefore.bracket;\n\t\t\t}\n\t\t}\n\t\tif (autoCloseConfig === 'never') {\n\t\t\treturn null;\n\t\t}\n\t\t// Sometimes, it is possible to have two auto-closing pairs that have a containment relationship\n\t\t// e.g. when having [(,)] and [(*,*)]\n\t\t// - when typing (, the resulting state is (|)\n\t\t// - when typing *, the desired resulting state is (*|*), not (*|*))\n\t\tconst containedPair = this._findContainedAutoClosingPair(config, pair);\n\t\tconst containedPairClose = containedPair ? containedPair.close : '';\n\t\tlet isContainedPairPresent = true;\n\n\t\tfor (const position of positions) {\n\t\t\tconst { lineNumber, beforeColumn, afterColumn } = position;\n\t\t\tconst lineText = model.getLineContent(lineNumber);\n\t\t\tconst lineBefore = lineText.substring(0, beforeColumn - 1);\n\t\t\tconst lineAfter = lineText.substring(afterColumn - 1);\n\n\t\t\tif (!lineAfter.startsWith(containedPairClose)) {\n\t\t\t\tisContainedPairPresent = false;\n\t\t\t}\n\t\t\t// Only consider auto closing the pair if an allowed character follows or if another autoclosed pair closing brace follows\n\t\t\tif (lineAfter.length > 0) {\n\t\t\t\tconst characterAfter = lineAfter.charAt(0);\n\t\t\t\tconst isBeforeCloseBrace = this._isBeforeClosingBrace(config, lineAfter);\n\t\t\t\tif (!isBeforeCloseBrace && !shouldAutoCloseBefore(characterAfter)) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Do not auto-close ' or \" after a word character\n\t\t\tif (pair.open.length === 1 && (ch === '\\'' || ch === '\"') && autoCloseConfig !== 'always') {\n\t\t\t\tconst wordSeparators = getMapForWordSeparators(config.wordSeparators, []);\n\t\t\t\tif (lineBefore.length > 0) {\n\t\t\t\t\tconst characterBefore = lineBefore.charCodeAt(lineBefore.length - 1);\n\t\t\t\t\tif (wordSeparators.get(characterBefore) === WordCharacterClass.Regular) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!model.tokenization.isCheapToTokenize(lineNumber)) {\n\t\t\t\t// Do not force tokenization\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tmodel.tokenization.forceTokenization(lineNumber);\n\t\t\tconst lineTokens = model.tokenization.getLineTokens(lineNumber);\n\t\t\tconst scopedLineTokens = createScopedLineTokens(lineTokens, beforeColumn - 1);\n\t\t\tif (!pair.shouldAutoClose(scopedLineTokens, beforeColumn - scopedLineTokens.firstCharOffset)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\t// Typing for example a quote could either start a new string, in which case auto-closing is desirable\n\t\t\t// or it could end a previously started string, in which case auto-closing is not desirable\n\t\t\t//\n\t\t\t// In certain cases, it is really not possible to look at the previous token to determine\n\t\t\t// what would happen. That's why we do something really unusual, we pretend to type a different\n\t\t\t// character and ask the tokenizer what the outcome of doing that is: after typing a neutral\n\t\t\t// character, are we in a string (i.e. the quote would most likely end a string) or not?\n\t\t\t//\n\t\t\tconst neutralCharacter = pair.findNeutralCharacter();\n\t\t\tif (neutralCharacter) {\n\t\t\t\tconst tokenType = model.tokenization.getTokenTypeIfInsertingCharacter(lineNumber, beforeColumn, neutralCharacter);\n\t\t\t\tif (!pair.isOK(tokenType)) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (isContainedPairPresent) {\n\t\t\treturn pair.close.substring(0, pair.close.length - containedPairClose.length);\n\t\t} else {\n\t\t\treturn pair.close;\n\t\t}\n\t}\n\n\t/**\n\t * Find another auto-closing pair that is contained by the one passed in.\n\t *\n\t * e.g. when having [(,)] and [(*,*)] as auto-closing pairs\n\t * this method will find [(,)] as a containment pair for [(*,*)]\n\t */\n\tprivate static _findContainedAutoClosingPair(config: CursorConfiguration, pair: StandardAutoClosingPairConditional): StandardAutoClosingPairConditional | null {\n\t\tif (pair.open.length <= 1) {\n\t\t\treturn null;\n\t\t}\n\t\tconst lastChar = pair.close.charAt(pair.close.length - 1);\n\t\t// get candidates with the same last character as close\n\t\tconst candidates = config.autoClosingPairs.autoClosingPairsCloseByEnd.get(lastChar) || [];\n\t\tlet result: StandardAutoClosingPairConditional | null = null;\n\t\tfor (const candidate of candidates) {\n\t\t\tif (candidate.open !== pair.open && pair.open.includes(candidate.open) && pair.close.endsWith(candidate.close)) {\n\t\t\t\tif (!result || candidate.open.length > result.open.length) {\n\t\t\t\t\tresult = candidate;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Determine if typing `ch` at all `positions` in the `model` results in an\n\t * auto closing open sequence being typed.\n\t *\n\t * Auto closing open sequences can consist of multiple characters, which\n\t * can lead to ambiguities. In such a case, the longest auto-closing open\n\t * sequence is returned.\n\t */\n\tprivate static _findAutoClosingPairOpen(config: CursorConfiguration, model: ITextModel, positions: Position[], ch: string): StandardAutoClosingPairConditional | null {\n\t\tconst candidates = config.autoClosingPairs.autoClosingPairsOpenByEnd.get(ch);\n\t\tif (!candidates) {\n\t\t\treturn null;\n\t\t}\n\t\t// Determine which auto-closing pair it is\n\t\tlet result: StandardAutoClosingPairConditional | null = null;\n\t\tfor (const candidate of candidates) {\n\t\t\tif (result === null || candidate.open.length > result.open.length) {\n\t\t\t\tlet candidateIsMatch = true;\n\t\t\t\tfor (const position of positions) {\n\t\t\t\t\tconst relevantText = model.getValueInRange(new Range(position.lineNumber, position.column - candidate.open.length + 1, position.lineNumber, position.column));\n\t\t\t\t\tif (relevantText + ch !== candidate.open) {\n\t\t\t\t\t\tcandidateIsMatch = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (candidateIsMatch) {\n\t\t\t\t\tresult = candidate;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate static _isBeforeClosingBrace(config: CursorConfiguration, lineAfter: string) {\n\t\t// If the start of lineAfter can be interpretted as both a starting or ending brace, default to returning false\n\t\tconst nextChar = lineAfter.charAt(0);\n\t\tconst potentialStartingBraces = config.autoClosingPairs.autoClosingPairsOpenByStart.get(nextChar) || [];\n\t\tconst potentialClosingBraces = config.autoClosingPairs.autoClosingPairsCloseByStart.get(nextChar) || [];\n\n\t\tconst isBeforeStartingBrace = potentialStartingBraces.some(x => lineAfter.startsWith(x.open));\n\t\tconst isBeforeClosingBrace = potentialClosingBraces.some(x => lineAfter.startsWith(x.close));\n\n\t\treturn !isBeforeStartingBrace && isBeforeClosingBrace;\n\t}\n}\n\nexport class CompositionEndOvertypeOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, compositions: CompositionOutcome[]): EditOperationResult | null {\n\t\tconst isOvertypeMode = config.inputMode === 'overtype';\n\t\tif (!isOvertypeMode) {\n\t\t\treturn null;\n\t\t}\n\t\tconst commands = compositions.map(composition => new ReplaceOvertypeCommandOnCompositionEnd(composition.insertedTextRange));\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class SurroundSelectionOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition && this._isSurroundSelectionType(config, model, selections, ch)) {\n\t\t\treturn this._runSurroundSelectionType(config, selections, ch);\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _runSurroundSelectionType(config: CursorConfiguration, selections: Selection[], ch: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tconst closeCharacter = config.surroundingPairs[ch];\n\t\t\tcommands[i] = new SurroundSelectionCommand(selection, ch, closeCharacter);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.Other, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: true\n\t\t});\n\t}\n\n\tprivate static _isSurroundSelectionType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean {\n\t\tif (!shouldSurroundChar(config, ch) || !config.surroundingPairs.hasOwnProperty(ch)) {\n\t\t\treturn false;\n\t\t}\n\t\tconst isTypingAQuoteCharacter = isQuote(ch);\n\t\tfor (const selection of selections) {\n\t\t\tif (selection.isEmpty()) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tlet selectionContainsOnlyWhitespace = true;\n\t\t\tfor (let lineNumber = selection.startLineNumber; lineNumber <= selection.endLineNumber; lineNumber++) {\n\t\t\t\tconst lineText = model.getLineContent(lineNumber);\n\t\t\t\tconst startIndex = (lineNumber === selection.startLineNumber ? selection.startColumn - 1 : 0);\n\t\t\t\tconst endIndex = (lineNumber === selection.endLineNumber ? selection.endColumn - 1 : lineText.length);\n\t\t\t\tconst selectedText = lineText.substring(startIndex, endIndex);\n\t\t\t\tif (/[^ \\t]/.test(selectedText)) {\n\t\t\t\t\t// this selected text contains something other than whitespace\n\t\t\t\t\tselectionContainsOnlyWhitespace = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (selectionContainsOnlyWhitespace) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (isTypingAQuoteCharacter && selection.startLineNumber === selection.endLineNumber && selection.startColumn + 1 === selection.endColumn) {\n\t\t\t\tconst selectionText = model.getValueInRange(selection);\n\t\t\t\tif (isQuote(selectionText)) {\n\t\t\t\t\t// Typing a quote character on top of another quote character\n\t\t\t\t\t// => disable surround selection type\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}\n\nexport class InterceptorElectricCharOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\t// Electric characters make sense only when dealing with a single cursor,\n\t\t// as multiple cursors typing brackets for example would interfer with bracket matching\n\t\tif (!isDoingComposition && this._isTypeInterceptorElectricChar(config, model, selections)) {\n\t\t\tconst r = this._typeInterceptorElectricChar(prevEditOperationType, config, model, selections[0], ch);\n\t\t\tif (r) {\n\t\t\t\treturn r;\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _isTypeInterceptorElectricChar(config: CursorConfiguration, model: ITextModel, selections: Selection[]) {\n\t\tif (selections.length === 1 && model.tokenization.isCheapToTokenize(selections[0].getEndPosition().lineNumber)) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate static _typeInterceptorElectricChar(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selection: Selection, ch: string): EditOperationResult | null {\n\t\tif (!config.electricChars.hasOwnProperty(ch) || !selection.isEmpty()) {\n\t\t\treturn null;\n\t\t}\n\t\tconst position = selection.getPosition();\n\t\tmodel.tokenization.forceTokenization(position.lineNumber);\n\t\tconst lineTokens = model.tokenization.getLineTokens(position.lineNumber);\n\t\tlet electricAction: IElectricAction | null;\n\t\ttry {\n\t\t\telectricAction = config.onElectricCharacter(ch, lineTokens, position.column);\n\t\t} catch (e) {\n\t\t\tonUnexpectedError(e);\n\t\t\treturn null;\n\t\t}\n\t\tif (!electricAction) {\n\t\t\treturn null;\n\t\t}\n\t\tif (electricAction.matchOpenBracket) {\n\t\t\tconst endColumn = (lineTokens.getLineContent() + ch).lastIndexOf(electricAction.matchOpenBracket) + 1;\n\t\t\tconst match = model.bracketPairs.findMatchingBracketUp(electricAction.matchOpenBracket, {\n\t\t\t\tlineNumber: position.lineNumber,\n\t\t\t\tcolumn: endColumn\n\t\t\t}, 500 /* give at most 500ms to compute */);\n\t\t\tif (match) {\n\t\t\t\tif (match.startLineNumber === position.lineNumber) {\n\t\t\t\t\t// matched something on the same line => no change in indentation\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst matchLine = model.getLineContent(match.startLineNumber);\n\t\t\t\tconst matchLineIndentation = strings.getLeadingWhitespace(matchLine);\n\t\t\t\tconst newIndentation = config.normalizeIndentation(matchLineIndentation);\n\t\t\t\tconst lineText = model.getLineContent(position.lineNumber);\n\t\t\t\tconst lineFirstNonBlankColumn = model.getLineFirstNonWhitespaceColumn(position.lineNumber) || position.column;\n\t\t\t\tconst prefix = lineText.substring(lineFirstNonBlankColumn - 1, position.column - 1);\n\t\t\t\tconst typeText = newIndentation + prefix + ch;\n\t\t\t\tconst typeSelection = new Range(position.lineNumber, 1, position.lineNumber, position.column);\n\t\t\t\tconst command = new ReplaceCommand(typeSelection, typeText);\n\t\t\t\treturn new EditOperationResult(getTypingOperation(typeText, prevEditOperationType), [command], {\n\t\t\t\t\tshouldPushStackElementBefore: false,\n\t\t\t\t\tshouldPushStackElementAfter: true\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n}\n\nexport class SimpleCharacterTypeOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, prevEditOperationType: EditOperationType, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult {\n\t\t// A simple character type\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst ChosenReplaceCommand = config.inputMode === 'overtype' && !isDoingComposition ? ReplaceOvertypeCommand : ReplaceCommand;\n\t\t\tcommands[i] = new ChosenReplaceCommand(selections[i], ch);\n\t\t}\n\n\t\tconst opType = getTypingOperation(ch, prevEditOperationType);\n\t\treturn new EditOperationResult(opType, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, opType),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class EnterOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition && ch === '\\n') {\n\t\t\tconst commands: ICommand[] = [];\n\t\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\t\tcommands[i] = this._enter(config, model, false, selections[i]);\n\t\t\t}\n\t\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\t\tshouldPushStackElementBefore: true,\n\t\t\t\tshouldPushStackElementAfter: false,\n\t\t\t});\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _enter(config: CursorConfiguration, model: ITextModel, keepPosition: boolean, range: Range): ICommand {\n\t\tif (config.autoIndent === EditorAutoIndentStrategy.None) {\n\t\t\treturn typeCommand(range, '\\n', keepPosition);\n\t\t}\n\t\tif (!model.tokenization.isCheapToTokenize(range.getStartPosition().lineNumber) || config.autoIndent === EditorAutoIndentStrategy.Keep) {\n\t\t\tconst lineText = model.getLineContent(range.startLineNumber);\n\t\t\tconst indentation = strings.getLeadingWhitespace(lineText).substring(0, range.startColumn - 1);\n\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(indentation), keepPosition);\n\t\t}\n\t\tconst r = getEnterAction(config.autoIndent, model, range, config.languageConfigurationService);\n\t\tif (r) {\n\t\t\tif (r.indentAction === IndentAction.None) {\n\t\t\t\t// Nothing special\n\t\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(r.indentation + r.appendText), keepPosition);\n\n\t\t\t} else if (r.indentAction === IndentAction.Indent) {\n\t\t\t\t// Indent once\n\t\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(r.indentation + r.appendText), keepPosition);\n\n\t\t\t} else if (r.indentAction === IndentAction.IndentOutdent) {\n\t\t\t\t// Ultra special\n\t\t\t\tconst normalIndent = config.normalizeIndentation(r.indentation);\n\t\t\t\tconst increasedIndent = config.normalizeIndentation(r.indentation + r.appendText);\n\t\t\t\tconst typeText = '\\n' + increasedIndent + '\\n' + normalIndent;\n\t\t\t\tif (keepPosition) {\n\t\t\t\t\treturn new ReplaceCommandWithoutChangingPosition(range, typeText, true);\n\t\t\t\t} else {\n\t\t\t\t\treturn new ReplaceCommandWithOffsetCursorState(range, typeText, -1, increasedIndent.length - normalIndent.length, true);\n\t\t\t\t}\n\t\t\t} else if (r.indentAction === IndentAction.Outdent) {\n\t\t\t\tconst actualIndentation = unshiftIndent(config, r.indentation);\n\t\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(actualIndentation + r.appendText), keepPosition);\n\t\t\t}\n\t\t}\n\n\t\tconst lineText = model.getLineContent(range.startLineNumber);\n\t\tconst indentation = strings.getLeadingWhitespace(lineText).substring(0, range.startColumn - 1);\n\n\t\tif (config.autoIndent >= EditorAutoIndentStrategy.Full) {\n\t\t\tconst ir = getIndentForEnter(config.autoIndent, model, range, {\n\t\t\t\tunshiftIndent: (indent) => {\n\t\t\t\t\treturn unshiftIndent(config, indent);\n\t\t\t\t},\n\t\t\t\tshiftIndent: (indent) => {\n\t\t\t\t\treturn shiftIndent(config, indent);\n\t\t\t\t},\n\t\t\t\tnormalizeIndentation: (indent) => {\n\t\t\t\t\treturn config.normalizeIndentation(indent);\n\t\t\t\t}\n\t\t\t}, config.languageConfigurationService);\n\n\t\t\tif (ir) {\n\t\t\t\tlet oldEndViewColumn = config.visibleColumnFromColumn(model, range.getEndPosition());\n\t\t\t\tconst oldEndColumn = range.endColumn;\n\t\t\t\tconst newLineContent = model.getLineContent(range.endLineNumber);\n\t\t\t\tconst firstNonWhitespace = strings.firstNonWhitespaceIndex(newLineContent);\n\t\t\t\tif (firstNonWhitespace >= 0) {\n\t\t\t\t\trange = range.setEndPosition(range.endLineNumber, Math.max(range.endColumn, firstNonWhitespace + 1));\n\t\t\t\t} else {\n\t\t\t\t\trange = range.setEndPosition(range.endLineNumber, model.getLineMaxColumn(range.endLineNumber));\n\t\t\t\t}\n\t\t\t\tif (keepPosition) {\n\t\t\t\t\treturn new ReplaceCommandWithoutChangingPosition(range, '\\n' + config.normalizeIndentation(ir.afterEnter), true);\n\t\t\t\t} else {\n\t\t\t\t\tlet offset = 0;\n\t\t\t\t\tif (oldEndColumn <= firstNonWhitespace + 1) {\n\t\t\t\t\t\tif (!config.insertSpaces) {\n\t\t\t\t\t\t\toldEndViewColumn = Math.ceil(oldEndViewColumn / config.indentSize);\n\t\t\t\t\t\t}\n\t\t\t\t\t\toffset = Math.min(oldEndViewColumn + 1 - config.normalizeIndentation(ir.afterEnter).length - 1, 0);\n\t\t\t\t\t}\n\t\t\t\t\treturn new ReplaceCommandWithOffsetCursorState(range, '\\n' + config.normalizeIndentation(ir.afterEnter), 0, offset, true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(indentation), keepPosition);\n\t}\n\n\n\tpublic static lineInsertBefore(config: CursorConfiguration, model: ITextModel | null, selections: Selection[] | null): ICommand[] {\n\t\tif (model === null || selections === null) {\n\t\t\treturn [];\n\t\t}\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tlet lineNumber = selections[i].positionLineNumber;\n\t\t\tif (lineNumber === 1) {\n\t\t\t\tcommands[i] = new ReplaceCommandWithoutChangingPosition(new Range(1, 1, 1, 1), '\\n');\n\t\t\t} else {\n\t\t\t\tlineNumber--;\n\t\t\t\tconst column = model.getLineMaxColumn(lineNumber);\n\n\t\t\t\tcommands[i] = this._enter(config, model, false, new Range(lineNumber, column, lineNumber, column));\n\t\t\t}\n\t\t}\n\t\treturn commands;\n\t}\n\n\tpublic static lineInsertAfter(config: CursorConfiguration, model: ITextModel | null, selections: Selection[] | null): ICommand[] {\n\t\tif (model === null || selections === null) {\n\t\t\treturn [];\n\t\t}\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst lineNumber = selections[i].positionLineNumber;\n\t\t\tconst column = model.getLineMaxColumn(lineNumber);\n\t\t\tcommands[i] = this._enter(config, model, false, new Range(lineNumber, column, lineNumber, column));\n\t\t}\n\t\treturn commands;\n\t}\n\n\tpublic static lineBreakInsert(config: CursorConfiguration, model: ITextModel, selections: Selection[]): ICommand[] {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tcommands[i] = this._enter(config, model, true, selections[i]);\n\t\t}\n\t\treturn commands;\n\t}\n}\n\nexport class PasteOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]) {\n\t\tconst distributedPaste = this._distributePasteToCursors(config, selections, text, pasteOnNewLine, multicursorText);\n\t\tif (distributedPaste) {\n\t\t\tselections = selections.sort(Range.compareRangesUsingStarts);\n\t\t\treturn this._distributedPaste(config, model, selections, distributedPaste);\n\t\t} else {\n\t\t\treturn this._simplePaste(config, model, selections, text, pasteOnNewLine);\n\t\t}\n\t}\n\n\tprivate static _distributePasteToCursors(config: CursorConfiguration, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]): string[] | null {\n\t\tif (pasteOnNewLine) {\n\t\t\treturn null;\n\t\t}\n\t\tif (selections.length === 1) {\n\t\t\treturn null;\n\t\t}\n\t\tif (multicursorText && multicursorText.length === selections.length) {\n\t\t\treturn multicursorText;\n\t\t}\n\t\tif (config.multiCursorPaste === 'spread') {\n\t\t\t// Try to spread the pasted text in case the line count matches the cursor count\n\t\t\t// Remove trailing \\n if present\n\t\t\tif (text.charCodeAt(text.length - 1) === CharCode.LineFeed) {\n\t\t\t\ttext = text.substring(0, text.length - 1);\n\t\t\t}\n\t\t\t// Remove trailing \\r if present\n\t\t\tif (text.charCodeAt(text.length - 1) === CharCode.CarriageReturn) {\n\t\t\t\ttext = text.substring(0, text.length - 1);\n\t\t\t}\n\t\t\tconst lines = strings.splitLines(text);\n\t\t\tif (lines.length === selections.length) {\n\t\t\t\treturn lines;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate static _distributedPaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string[]): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst shouldOvertypeOnPaste = config.overtypeOnPaste && config.inputMode === 'overtype';\n\t\t\tconst ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommand : ReplaceCommand;\n\t\t\tcommands[i] = new ChosenReplaceCommand(selections[i], text[i]);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.Other, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: true\n\t\t});\n\t}\n\n\tprivate static _simplePaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tconst position = selection.getPosition();\n\t\t\tif (pasteOnNewLine && !selection.isEmpty()) {\n\t\t\t\tpasteOnNewLine = false;\n\t\t\t}\n\t\t\tif (pasteOnNewLine && text.indexOf('\\n') !== text.length - 1) {\n\t\t\t\tpasteOnNewLine = false;\n\t\t\t}\n\t\t\tif (pasteOnNewLine) {\n\t\t\t\t// Paste entire line at the beginning of line\n\t\t\t\tconst typeSelection = new Range(position.lineNumber, 1, position.lineNumber, 1);\n\t\t\t\tcommands[i] = new ReplaceCommandThatPreservesSelection(typeSelection, text, selection, true);\n\t\t\t} else {\n\t\t\t\tconst shouldOvertypeOnPaste = config.overtypeOnPaste && config.inputMode === 'overtype';\n\t\t\t\tconst ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommand : ReplaceCommand;\n\t\t\t\tcommands[i] = new ChosenReplaceCommand(selection, text);\n\t\t\t}\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.Other, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: true\n\t\t});\n\t}\n}\n\nexport class CompositionOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number) {\n\t\tconst commands = selections.map(selection => this._compositionType(model, selection, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta));\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, EditOperationType.TypingOther),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n\n\tprivate static _compositionType(model: ITextModel, selection: Selection, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number): ICommand | null {\n\t\tif (!selection.isEmpty()) {\n\t\t\t// looks like https://github.com/microsoft/vscode/issues/2773\n\t\t\t// where a cursor operation occurred before a canceled composition\n\t\t\t// => ignore composition\n\t\t\treturn null;\n\t\t}\n\t\tconst pos = selection.getPosition();\n\t\tconst startColumn = Math.max(1, pos.column - replacePrevCharCnt);\n\t\tconst endColumn = Math.min(model.getLineMaxColumn(pos.lineNumber), pos.column + replaceNextCharCnt);\n\t\tconst range = new Range(pos.lineNumber, startColumn, pos.lineNumber, endColumn);\n\t\treturn new ReplaceCommandWithOffsetCursorState(range, text, 0, positionDelta);\n\t}\n}\n\nexport class TypeWithoutInterceptorsOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], str: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tcommands[i] = new ReplaceCommand(selections[i], str);\n\t\t}\n\t\tconst opType = getTypingOperation(str, prevEditOperationType);\n\t\treturn new EditOperationResult(opType, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, opType),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class TabOperation {\n\n\tpublic static getCommands(config: CursorConfiguration, model: ITextModel, selections: Selection[]) {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tif (selection.isEmpty()) {\n\t\t\t\tconst lineText = model.getLineContent(selection.startLineNumber);\n\t\t\t\tif (/^\\s*$/.test(lineText) && model.tokenization.isCheapToTokenize(selection.startLineNumber)) {\n\t\t\t\t\tlet goodIndent = this._goodIndentForLine(config, model, selection.startLineNumber);\n\t\t\t\t\tgoodIndent = goodIndent || '\\t';\n\t\t\t\t\tconst possibleTypeText = config.normalizeIndentation(goodIndent);\n\t\t\t\t\tif (!lineText.startsWith(possibleTypeText)) {\n\t\t\t\t\t\tcommands[i] = new ReplaceCommand(new Range(selection.startLineNumber, 1, selection.startLineNumber, lineText.length + 1), possibleTypeText, true);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcommands[i] = this._replaceJumpToNextIndent(config, model, selection, true);\n\t\t\t} else {\n\t\t\t\tif (selection.startLineNumber === selection.endLineNumber) {\n\t\t\t\t\tconst lineMaxColumn = model.getLineMaxColumn(selection.startLineNumber);\n\t\t\t\t\tif (selection.startColumn !== 1 || selection.endColumn !== lineMaxColumn) {\n\t\t\t\t\t\t// This is a single line selection that is not the entire line\n\t\t\t\t\t\tcommands[i] = this._replaceJumpToNextIndent(config, model, selection, false);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcommands[i] = new ShiftCommand(selection, {\n\t\t\t\t\tisUnshift: false,\n\t\t\t\t\ttabSize: config.tabSize,\n\t\t\t\t\tindentSize: config.indentSize,\n\t\t\t\t\tinsertSpaces: config.insertSpaces,\n\t\t\t\t\tuseTabStops: config.useTabStops,\n\t\t\t\t\tautoIndent: config.autoIndent\n\t\t\t\t}, config.languageConfigurationService);\n\t\t\t}\n\t\t}\n\t\treturn commands;\n\t}\n\n\tprivate static _goodIndentForLine(config: CursorConfiguration, model: ITextModel, lineNumber: number): string | null {\n\t\tlet action: IndentAction | EnterAction | null = null;\n\t\tlet indentation: string = '';\n\t\tconst expectedIndentAction = getInheritIndentForLine(config.autoIndent, model, lineNumber, false, config.languageConfigurationService);\n\t\tif (expectedIndentAction) {\n\t\t\taction = expectedIndentAction.action;\n\t\t\tindentation = expectedIndentAction.indentation;\n\t\t} else if (lineNumber > 1) {\n\t\t\tlet lastLineNumber: number;\n\t\t\tfor (lastLineNumber = lineNumber - 1; lastLineNumber >= 1; lastLineNumber--) {\n\t\t\t\tconst lineText = model.getLineContent(lastLineNumber);\n\t\t\t\tconst nonWhitespaceIdx = strings.lastNonWhitespaceIndex(lineText);\n\t\t\t\tif (nonWhitespaceIdx >= 0) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (lastLineNumber < 1) {\n\t\t\t\t// No previous line with content found\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst maxColumn = model.getLineMaxColumn(lastLineNumber);\n\t\t\tconst expectedEnterAction = getEnterAction(config.autoIndent, model, new Range(lastLineNumber, maxColumn, lastLineNumber, maxColumn), config.languageConfigurationService);\n\t\t\tif (expectedEnterAction) {\n\t\t\t\tindentation = expectedEnterAction.indentation + expectedEnterAction.appendText;\n\t\t\t}\n\t\t}\n\t\tif (action) {\n\t\t\tif (action === IndentAction.Indent) {\n\t\t\t\tindentation = shiftIndent(config, indentation);\n\t\t\t}\n\t\t\tif (action === IndentAction.Outdent) {\n\t\t\t\tindentation = unshiftIndent(config, indentation);\n\t\t\t}\n\t\t\tindentation = config.normalizeIndentation(indentation);\n\t\t}\n\t\tif (!indentation) {\n\t\t\treturn null;\n\t\t}\n\t\treturn indentation;\n\t}\n\n\tprivate static _replaceJumpToNextIndent(config: CursorConfiguration, model: ICursorSimpleModel, selection: Selection, insertsAutoWhitespace: boolean): ReplaceCommand {\n\t\tlet typeText = '';\n\t\tconst position = selection.getStartPosition();\n\t\tif (config.insertSpaces) {\n\t\t\tconst visibleColumnFromColumn = config.visibleColumnFromColumn(model, position);\n\t\t\tconst indentSize = config.indentSize;\n\t\t\tconst spacesCnt = indentSize - (visibleColumnFromColumn % indentSize);\n\t\t\tfor (let i = 0; i < spacesCnt; i++) {\n\t\t\t\ttypeText += ' ';\n\t\t\t}\n\t\t} else {\n\t\t\ttypeText = '\\t';\n\t\t}\n\t\treturn new ReplaceCommand(selection, typeText, insertsAutoWhitespace);\n\t}\n}\n\nexport class BaseTypeWithAutoClosingCommand extends ReplaceCommandWithOffsetCursorState {\n\n\tprivate readonly _openCharacter: string;\n\tprivate readonly _closeCharacter: string;\n\tpublic closeCharacterRange: Range | null;\n\tpublic enclosingRange: Range | null;\n\n\tconstructor(selection: Selection, text: string, lineNumberDeltaOffset: number, columnDeltaOffset: number, openCharacter: string, closeCharacter: string) {\n\t\tsuper(selection, text, lineNumberDeltaOffset, columnDeltaOffset);\n\t\tthis._openCharacter = openCharacter;\n\t\tthis._closeCharacter = closeCharacter;\n\t\tthis.closeCharacterRange = null;\n\t\tthis.enclosingRange = null;\n\t}\n\n\tprotected _computeCursorStateWithRange(model: ITextModel, range: Range, helper: ICursorStateComputerData): Selection {\n\t\tthis.closeCharacterRange = new Range(range.startLineNumber, range.endColumn - this._closeCharacter.length, range.endLineNumber, range.endColumn);\n\t\tthis.enclosingRange = new Range(range.startLineNumber, range.endColumn - this._openCharacter.length - this._closeCharacter.length, range.endLineNumber, range.endColumn);\n\t\treturn super.computeCursorState(model, helper);\n\t}\n}\n\nclass TypeWithAutoClosingCommand extends BaseTypeWithAutoClosingCommand {\n\n\tconstructor(selection: Selection, openCharacter: string, insertOpenCharacter: boolean, closeCharacter: string) {\n\t\tconst text = (insertOpenCharacter ? openCharacter : '') + closeCharacter;\n\t\tconst lineNumberDeltaOffset = 0;\n\t\tconst columnDeltaOffset = -closeCharacter.length;\n\t\tsuper(selection, text, lineNumberDeltaOffset, columnDeltaOffset, openCharacter, closeCharacter);\n\t}\n\n\tpublic override computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {\n\t\tconst inverseEditOperations = helper.getInverseEditOperations();\n\t\tconst range = inverseEditOperations[0].range;\n\t\treturn this._computeCursorStateWithRange(model, range, helper);\n\t}\n}\n\nclass TypeWithIndentationAndAutoClosingCommand extends BaseTypeWithAutoClosingCommand {\n\n\tprivate readonly _autoIndentationEdit: { range: Range; text: string };\n\tprivate readonly _autoClosingEdit: { range: Range; text: string };\n\n\tconstructor(autoIndentationEdit: { range: Range; text: string }, selection: Selection, openCharacter: string, closeCharacter: string) {\n\t\tconst text = openCharacter + closeCharacter;\n\t\tconst lineNumberDeltaOffset = 0;\n\t\tconst columnDeltaOffset = openCharacter.length;\n\t\tsuper(selection, text, lineNumberDeltaOffset, columnDeltaOffset, openCharacter, closeCharacter);\n\t\tthis._autoIndentationEdit = autoIndentationEdit;\n\t\tthis._autoClosingEdit = { range: selection, text };\n\t}\n\n\tpublic override getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {\n\t\tbuilder.addTrackedEditOperation(this._autoIndentationEdit.range, this._autoIndentationEdit.text);\n\t\tbuilder.addTrackedEditOperation(this._autoClosingEdit.range, this._autoClosingEdit.text);\n\t}\n\n\tpublic override computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {\n\t\tconst inverseEditOperations = helper.getInverseEditOperations();\n\t\tif (inverseEditOperations.length !== 2) {\n\t\t\tthrow new Error('There should be two inverse edit operations!');\n\t\t}\n\t\tconst range1 = inverseEditOperations[0].range;\n\t\tconst range2 = inverseEditOperations[1].range;\n\t\tconst range = range1.plusRange(range2);\n\t\treturn this._computeCursorStateWithRange(model, range, helper);\n\t}\n}\n\nfunction getTypingOperation(typedText: string, previousTypingOperation: EditOperationType): EditOperationType {\n\tif (typedText === ' ') {\n\t\treturn previousTypingOperation === EditOperationType.TypingFirstSpace\n\t\t\t|| previousTypingOperation === EditOperationType.TypingConsecutiveSpace\n\t\t\t? EditOperationType.TypingConsecutiveSpace\n\t\t\t: EditOperationType.TypingFirstSpace;\n\t}\n\n\treturn EditOperationType.TypingOther;\n}\n\nfunction shouldPushStackElementBetween(previousTypingOperation: EditOperationType, typingOperation: EditOperationType): boolean {\n\tif (isTypingOperation(previousTypingOperation) && !isTypingOperation(typingOperation)) {\n\t\t// Always set an undo stop before non-type operations\n\t\treturn true;\n\t}\n\tif (previousTypingOperation === EditOperationType.TypingFirstSpace) {\n\t\t// `abc |d`: No undo stop\n\t\t// `abc |d`: Undo stop\n\t\treturn false;\n\t}\n\t// Insert undo stop between different operation types\n\treturn normalizeOperationType(previousTypingOperation) !== normalizeOperationType(typingOperation);\n}\n\nfunction normalizeOperationType(type: EditOperationType): EditOperationType | 'space' {\n\treturn (type === EditOperationType.TypingConsecutiveSpace || type === EditOperationType.TypingFirstSpace)\n\t\t? 'space'\n\t\t: type;\n}\n\nfunction isTypingOperation(type: EditOperationType): boolean {\n\treturn type === EditOperationType.TypingOther\n\t\t|| type === EditOperationType.TypingFirstSpace\n\t\t|| type === EditOperationType.TypingConsecutiveSpace;\n}\n\nfunction isAutoClosingOvertype(config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): boolean {\n\tif (config.autoClosingOvertype === 'never') {\n\t\treturn false;\n\t}\n\tif (!config.autoClosingPairs.autoClosingPairsCloseSingleChar.has(ch)) {\n\t\treturn false;\n\t}\n\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\tconst selection = selections[i];\n\t\tif (!selection.isEmpty()) {\n\t\t\treturn false;\n\t\t}\n\t\tconst position = selection.getPosition();\n\t\tconst lineText = model.getLineContent(position.lineNumber);\n\t\tconst afterCharacter = lineText.charAt(position.column - 1);\n\t\tif (afterCharacter !== ch) {\n\t\t\treturn false;\n\t\t}\n\t\t// Do not over-type quotes after a backslash\n\t\tconst chIsQuote = isQuote(ch);\n\t\tconst beforeCharacter = position.column > 2 ? lineText.charCodeAt(position.column - 2) : CharCode.Null;\n\t\tif (beforeCharacter === CharCode.Backslash && chIsQuote) {\n\t\t\treturn false;\n\t\t}\n\t\t// Must over-type a closing character typed by the editor\n\t\tif (config.autoClosingOvertype === 'auto') {\n\t\t\tlet found = false;\n\t\t\tfor (let j = 0, lenJ = autoClosedCharacters.length; j < lenJ; j++) {\n\t\t\t\tconst autoClosedCharacter = autoClosedCharacters[j];\n\t\t\t\tif (position.lineNumber === autoClosedCharacter.startLineNumber && position.column === autoClosedCharacter.startColumn) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction typeCommand(range: Range, text: string, keepPosition: boolean): ICommand {\n\tif (keepPosition) {\n\t\treturn new ReplaceCommandWithoutChangingPosition(range, text, true);\n\t} else {\n\t\treturn new ReplaceCommand(range, text, true);\n\t}\n}\n\nexport function shiftIndent(config: CursorConfiguration, indentation: string, count?: number): string {\n\tcount = count || 1;\n\treturn ShiftCommand.shiftIndent(indentation, indentation.length + count, config.tabSize, config.indentSize, config.insertSpaces);\n}\n\nexport function unshiftIndent(config: CursorConfiguration, indentation: string, count?: number): string {\n\tcount = count || 1;\n\treturn ShiftCommand.unshiftIndent(indentation, indentation.length + count, config.tabSize, config.indentSize, config.insertSpaces);\n}\n\nexport function shouldSurroundChar(config: CursorConfiguration, ch: string): boolean {\n\tif (isQuote(ch)) {\n\t\treturn (config.autoSurround === 'quotes' || config.autoSurround === 'languageDefined');\n\t} else {\n\t\t// Character is a bracket\n\t\treturn (config.autoSurround === 'brackets' || config.autoSurround === 'languageDefined');\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { CharCode } from '../../../base/common/charCode.js';\nimport { onUnexpectedError } from '../../../base/common/errors.js';\nimport * as strings from '../../../base/common/strings.js';\nimport { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, ReplaceOvertypeCommandOnCompositionEnd } from '../commands/replaceCommand.js';\nimport { ShiftCommand } from '../commands/shiftCommand.js';\nimport { SurroundSelectionCommand } from '../commands/surroundSelectionCommand.js';\nimport { CursorConfiguration, EditOperationResult, EditOperationType, ICursorSimpleModel, isQuote } from '../cursorCommon.js';\nimport { WordCharacterClass, getMapForWordSeparators } from '../core/wordCharacterClassifier.js';\nimport { Range } from '../core/range.js';\nimport { Selection } from '../core/selection.js';\nimport { Position } from '../core/position.js';\nimport { ICommand, ICursorStateComputerData, IEditOperationBuilder } from '../editorCommon.js';\nimport { ITextModel } from '../model.js';\nimport { EnterAction, IndentAction, StandardAutoClosingPairConditional } from '../languages/languageConfiguration.js';\nimport { getIndentationAtPosition } from '../languages/languageConfigurationRegistry.js';\nimport { IElectricAction } from '../languages/supports/electricCharacter.js';\nimport { EditorAutoClosingStrategy, EditorAutoIndentStrategy } from '../config/editorOptions.js';\nimport { createScopedLineTokens } from '../languages/supports.js';\nimport { getIndentActionForType, getIndentForEnter, getInheritIndentForLine } from '../languages/autoIndent.js';\nimport { getEnterAction } from '../languages/enterAction.js';\nimport { CompositionOutcome } from './cursorTypeOperations.js';\n\nexport class AutoIndentOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition && this._isAutoIndentType(config, model, selections)) {\n\t\t\tconst indentationForSelections: { selection: Selection; indentation: string }[] = [];\n\t\t\tfor (const selection of selections) {\n\t\t\t\tconst indentation = this._findActualIndentationForSelection(config, model, selection, ch);\n\t\t\t\tif (indentation === null) {\n\t\t\t\t\t// Auto indentation failed\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tindentationForSelections.push({ selection, indentation });\n\t\t\t}\n\t\t\tconst autoClosingPairClose = AutoClosingOpenCharTypeOperation.getAutoClosingPairClose(config, model, selections, ch, false);\n\t\t\treturn this._getIndentationAndAutoClosingPairEdits(config, model, indentationForSelections, ch, autoClosingPairClose);\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _isAutoIndentType(config: CursorConfiguration, model: ITextModel, selections: Selection[]): boolean {\n\t\tif (config.autoIndent < EditorAutoIndentStrategy.Full) {\n\t\t\treturn false;\n\t\t}\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tif (!model.tokenization.isCheapToTokenize(selections[i].getEndPosition().lineNumber)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate static _findActualIndentationForSelection(config: CursorConfiguration, model: ITextModel, selection: Selection, ch: string): string | null {\n\t\tconst actualIndentation = getIndentActionForType(config, model, selection, ch, {\n\t\t\tshiftIndent: (indentation) => {\n\t\t\t\treturn shiftIndent(config, indentation);\n\t\t\t},\n\t\t\tunshiftIndent: (indentation) => {\n\t\t\t\treturn unshiftIndent(config, indentation);\n\t\t\t},\n\t\t}, config.languageConfigurationService);\n\n\t\tif (actualIndentation === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst currentIndentation = getIndentationAtPosition(model, selection.startLineNumber, selection.startColumn);\n\t\tif (actualIndentation === config.normalizeIndentation(currentIndentation)) {\n\t\t\treturn null;\n\t\t}\n\t\treturn actualIndentation;\n\t}\n\n\tprivate static _getIndentationAndAutoClosingPairEdits(config: CursorConfiguration, model: ITextModel, indentationForSelections: { selection: Selection; indentation: string }[], ch: string, autoClosingPairClose: string | null): EditOperationResult {\n\t\tconst commands: ICommand[] = indentationForSelections.map(({ selection, indentation }) => {\n\t\t\tif (autoClosingPairClose !== null) {\n\t\t\t\t// Apply both auto closing pair edits and auto indentation edits\n\t\t\t\tconst indentationEdit = this._getEditFromIndentationAndSelection(config, model, indentation, selection, ch, false);\n\t\t\t\treturn new TypeWithIndentationAndAutoClosingCommand(indentationEdit, selection, ch, autoClosingPairClose);\n\t\t\t} else {\n\t\t\t\t// Apply only auto indentation edits\n\t\t\t\tconst indentationEdit = this._getEditFromIndentationAndSelection(config, model, indentation, selection, ch, true);\n\t\t\t\treturn typeCommand(indentationEdit.range, indentationEdit.text, false);\n\t\t\t}\n\t\t});\n\t\tconst editOptions = { shouldPushStackElementBefore: true, shouldPushStackElementAfter: false };\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, editOptions);\n\t}\n\n\tprivate static _getEditFromIndentationAndSelection(config: CursorConfiguration, model: ITextModel, indentation: string, selection: Selection, ch: string, includeChInEdit: boolean = true): { range: Range; text: string } {\n\t\tconst startLineNumber = selection.startLineNumber;\n\t\tconst firstNonWhitespaceColumn = model.getLineFirstNonWhitespaceColumn(startLineNumber);\n\t\tlet text: string = config.normalizeIndentation(indentation);\n\t\tif (firstNonWhitespaceColumn !== 0) {\n\t\t\tconst startLine = model.getLineContent(startLineNumber);\n\t\t\ttext += startLine.substring(firstNonWhitespaceColumn - 1, selection.startColumn - 1);\n\t\t}\n\t\ttext += includeChInEdit ? ch : '';\n\t\tconst range = new Range(startLineNumber, 1, selection.endLineNumber, selection.endColumn);\n\t\treturn { range, text };\n\t}\n}\n\nexport class AutoClosingOvertypeOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult | undefined {\n\t\tif (isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) {\n\t\t\treturn this._runAutoClosingOvertype(prevEditOperationType, selections, ch);\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _runAutoClosingOvertype(prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tconst position = selection.getPosition();\n\t\t\tconst typeSelection = new Range(position.lineNumber, position.column, position.lineNumber, position.column + 1);\n\t\t\tcommands[i] = new ReplaceCommand(typeSelection, ch);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, EditOperationType.TypingOther),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class AutoClosingOvertypeWithInterceptorsOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult | undefined {\n\t\tif (isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) {\n\t\t\t// Unfortunately, the close character is at this point \"doubled\", so we need to delete it...\n\t\t\tconst commands = selections.map(s => new ReplaceCommand(new Range(s.positionLineNumber, s.positionColumn, s.positionLineNumber, s.positionColumn + 1), '', false));\n\t\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\t\tshouldPushStackElementBefore: true,\n\t\t\t\tshouldPushStackElementAfter: false\n\t\t\t});\n\t\t}\n\t\treturn;\n\t}\n}\n\nexport class AutoClosingOpenCharTypeOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, chIsAlreadyTyped: boolean, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition) {\n\t\t\tconst autoClosingPairClose = this.getAutoClosingPairClose(config, model, selections, ch, chIsAlreadyTyped);\n\t\t\tif (autoClosingPairClose !== null) {\n\t\t\t\treturn this._runAutoClosingOpenCharType(selections, ch, chIsAlreadyTyped, autoClosingPairClose);\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _runAutoClosingOpenCharType(selections: Selection[], ch: string, chIsAlreadyTyped: boolean, autoClosingPairClose: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tcommands[i] = new TypeWithAutoClosingCommand(selection, ch, !chIsAlreadyTyped, autoClosingPairClose);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n\n\tpublic static getAutoClosingPairClose(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, chIsAlreadyTyped: boolean): string | null {\n\t\tfor (const selection of selections) {\n\t\t\tif (!selection.isEmpty()) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\t// This method is called both when typing (regularly) and when composition ends\n\t\t// This means that we need to work with a text buffer where sometimes `ch` is not\n\t\t// there (it is being typed right now) or with a text buffer where `ch` has already been typed\n\t\t//\n\t\t// In order to avoid adding checks for `chIsAlreadyTyped` in all places, we will work\n\t\t// with two conceptual positions, the position before `ch` and the position after `ch`\n\t\t//\n\t\tconst positions: { lineNumber: number; beforeColumn: number; afterColumn: number }[] = selections.map((s) => {\n\t\t\tconst position = s.getPosition();\n\t\t\tif (chIsAlreadyTyped) {\n\t\t\t\treturn { lineNumber: position.lineNumber, beforeColumn: position.column - ch.length, afterColumn: position.column };\n\t\t\t} else {\n\t\t\t\treturn { lineNumber: position.lineNumber, beforeColumn: position.column, afterColumn: position.column };\n\t\t\t}\n\t\t});\n\t\t// Find the longest auto-closing open pair in case of multiple ending in `ch`\n\t\t// e.g. when having [f\",\"] and [\",\"], it picks [f\",\"] if the character before is f\n\t\tconst pair = this._findAutoClosingPairOpen(config, model, positions.map(p => new Position(p.lineNumber, p.beforeColumn)), ch);\n\t\tif (!pair) {\n\t\t\treturn null;\n\t\t}\n\t\tlet autoCloseConfig: EditorAutoClosingStrategy;\n\t\tlet shouldAutoCloseBefore: (ch: string) => boolean;\n\n\t\tconst chIsQuote = isQuote(ch);\n\t\tif (chIsQuote) {\n\t\t\tautoCloseConfig = config.autoClosingQuotes;\n\t\t\tshouldAutoCloseBefore = config.shouldAutoCloseBefore.quote;\n\t\t} else {\n\t\t\tconst pairIsForComments = config.blockCommentStartToken ? pair.open.includes(config.blockCommentStartToken) : false;\n\t\t\tif (pairIsForComments) {\n\t\t\t\tautoCloseConfig = config.autoClosingComments;\n\t\t\t\tshouldAutoCloseBefore = config.shouldAutoCloseBefore.comment;\n\t\t\t} else {\n\t\t\t\tautoCloseConfig = config.autoClosingBrackets;\n\t\t\t\tshouldAutoCloseBefore = config.shouldAutoCloseBefore.bracket;\n\t\t\t}\n\t\t}\n\t\tif (autoCloseConfig === 'never') {\n\t\t\treturn null;\n\t\t}\n\t\t// Sometimes, it is possible to have two auto-closing pairs that have a containment relationship\n\t\t// e.g. when having [(,)] and [(*,*)]\n\t\t// - when typing (, the resulting state is (|)\n\t\t// - when typing *, the desired resulting state is (*|*), not (*|*))\n\t\tconst containedPair = this._findContainedAutoClosingPair(config, pair);\n\t\tconst containedPairClose = containedPair ? containedPair.close : '';\n\t\tlet isContainedPairPresent = true;\n\n\t\tfor (const position of positions) {\n\t\t\tconst { lineNumber, beforeColumn, afterColumn } = position;\n\t\t\tconst lineText = model.getLineContent(lineNumber);\n\t\t\tconst lineBefore = lineText.substring(0, beforeColumn - 1);\n\t\t\tconst lineAfter = lineText.substring(afterColumn - 1);\n\n\t\t\tif (!lineAfter.startsWith(containedPairClose)) {\n\t\t\t\tisContainedPairPresent = false;\n\t\t\t}\n\t\t\t// Only consider auto closing the pair if an allowed character follows or if another autoclosed pair closing brace follows\n\t\t\tif (lineAfter.length > 0) {\n\t\t\t\tconst characterAfter = lineAfter.charAt(0);\n\t\t\t\tconst isBeforeCloseBrace = this._isBeforeClosingBrace(config, lineAfter);\n\t\t\t\tif (!isBeforeCloseBrace && !shouldAutoCloseBefore(characterAfter)) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Do not auto-close ' or \" after a word character\n\t\t\tif (pair.open.length === 1 && (ch === '\\'' || ch === '\"') && autoCloseConfig !== 'always') {\n\t\t\t\tconst wordSeparators = getMapForWordSeparators(config.wordSeparators, []);\n\t\t\t\tif (lineBefore.length > 0) {\n\t\t\t\t\tconst characterBefore = lineBefore.charCodeAt(lineBefore.length - 1);\n\t\t\t\t\tif (wordSeparators.get(characterBefore) === WordCharacterClass.Regular) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!model.tokenization.isCheapToTokenize(lineNumber)) {\n\t\t\t\t// Do not force tokenization\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tmodel.tokenization.forceTokenization(lineNumber);\n\t\t\tconst lineTokens = model.tokenization.getLineTokens(lineNumber);\n\t\t\tconst scopedLineTokens = createScopedLineTokens(lineTokens, beforeColumn - 1);\n\t\t\tif (!pair.shouldAutoClose(scopedLineTokens, beforeColumn - scopedLineTokens.firstCharOffset)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\t// Typing for example a quote could either start a new string, in which case auto-closing is desirable\n\t\t\t// or it could end a previously started string, in which case auto-closing is not desirable\n\t\t\t//\n\t\t\t// In certain cases, it is really not possible to look at the previous token to determine\n\t\t\t// what would happen. That's why we do something really unusual, we pretend to type a different\n\t\t\t// character and ask the tokenizer what the outcome of doing that is: after typing a neutral\n\t\t\t// character, are we in a string (i.e. the quote would most likely end a string) or not?\n\t\t\t//\n\t\t\tconst neutralCharacter = pair.findNeutralCharacter();\n\t\t\tif (neutralCharacter) {\n\t\t\t\tconst tokenType = model.tokenization.getTokenTypeIfInsertingCharacter(lineNumber, beforeColumn, neutralCharacter);\n\t\t\t\tif (!pair.isOK(tokenType)) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (isContainedPairPresent) {\n\t\t\treturn pair.close.substring(0, pair.close.length - containedPairClose.length);\n\t\t} else {\n\t\t\treturn pair.close;\n\t\t}\n\t}\n\n\t/**\n\t * Find another auto-closing pair that is contained by the one passed in.\n\t *\n\t * e.g. when having [(,)] and [(*,*)] as auto-closing pairs\n\t * this method will find [(,)] as a containment pair for [(*,*)]\n\t */\n\tprivate static _findContainedAutoClosingPair(config: CursorConfiguration, pair: StandardAutoClosingPairConditional): StandardAutoClosingPairConditional | null {\n\t\tif (pair.open.length <= 1) {\n\t\t\treturn null;\n\t\t}\n\t\tconst lastChar = pair.close.charAt(pair.close.length - 1);\n\t\t// get candidates with the same last character as close\n\t\tconst candidates = config.autoClosingPairs.autoClosingPairsCloseByEnd.get(lastChar) || [];\n\t\tlet result: StandardAutoClosingPairConditional | null = null;\n\t\tfor (const candidate of candidates) {\n\t\t\tif (candidate.open !== pair.open && pair.open.includes(candidate.open) && pair.close.endsWith(candidate.close)) {\n\t\t\t\tif (!result || candidate.open.length > result.open.length) {\n\t\t\t\t\tresult = candidate;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Determine if typing `ch` at all `positions` in the `model` results in an\n\t * auto closing open sequence being typed.\n\t *\n\t * Auto closing open sequences can consist of multiple characters, which\n\t * can lead to ambiguities. In such a case, the longest auto-closing open\n\t * sequence is returned.\n\t */\n\tprivate static _findAutoClosingPairOpen(config: CursorConfiguration, model: ITextModel, positions: Position[], ch: string): StandardAutoClosingPairConditional | null {\n\t\tconst candidates = config.autoClosingPairs.autoClosingPairsOpenByEnd.get(ch);\n\t\tif (!candidates) {\n\t\t\treturn null;\n\t\t}\n\t\t// Determine which auto-closing pair it is\n\t\tlet result: StandardAutoClosingPairConditional | null = null;\n\t\tfor (const candidate of candidates) {\n\t\t\tif (result === null || candidate.open.length > result.open.length) {\n\t\t\t\tlet candidateIsMatch = true;\n\t\t\t\tfor (const position of positions) {\n\t\t\t\t\tconst relevantText = model.getValueInRange(new Range(position.lineNumber, position.column - candidate.open.length + 1, position.lineNumber, position.column));\n\t\t\t\t\tif (relevantText + ch !== candidate.open) {\n\t\t\t\t\t\tcandidateIsMatch = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (candidateIsMatch) {\n\t\t\t\t\tresult = candidate;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate static _isBeforeClosingBrace(config: CursorConfiguration, lineAfter: string) {\n\t\t// If the start of lineAfter can be interpretted as both a starting or ending brace, default to returning false\n\t\tconst nextChar = lineAfter.charAt(0);\n\t\tconst potentialStartingBraces = config.autoClosingPairs.autoClosingPairsOpenByStart.get(nextChar) || [];\n\t\tconst potentialClosingBraces = config.autoClosingPairs.autoClosingPairsCloseByStart.get(nextChar) || [];\n\n\t\tconst isBeforeStartingBrace = potentialStartingBraces.some(x => lineAfter.startsWith(x.open));\n\t\tconst isBeforeClosingBrace = potentialClosingBraces.some(x => lineAfter.startsWith(x.close));\n\n\t\treturn !isBeforeStartingBrace && isBeforeClosingBrace;\n\t}\n}\n\nexport class CompositionEndOvertypeOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, compositions: CompositionOutcome[]): EditOperationResult | null {\n\t\tconst isOvertypeMode = config.inputMode === 'overtype';\n\t\tif (!isOvertypeMode) {\n\t\t\treturn null;\n\t\t}\n\t\tconst commands = compositions.map(composition => new ReplaceOvertypeCommandOnCompositionEnd(composition.insertedTextRange));\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class SurroundSelectionOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition && this._isSurroundSelectionType(config, model, selections, ch)) {\n\t\t\treturn this._runSurroundSelectionType(config, selections, ch);\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _runSurroundSelectionType(config: CursorConfiguration, selections: Selection[], ch: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tconst closeCharacter = config.surroundingPairs[ch];\n\t\t\tcommands[i] = new SurroundSelectionCommand(selection, ch, closeCharacter);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.Other, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: true\n\t\t});\n\t}\n\n\tprivate static _isSurroundSelectionType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean {\n\t\tif (!shouldSurroundChar(config, ch) || !config.surroundingPairs.hasOwnProperty(ch)) {\n\t\t\treturn false;\n\t\t}\n\t\tconst isTypingAQuoteCharacter = isQuote(ch);\n\t\tfor (const selection of selections) {\n\t\t\tif (selection.isEmpty()) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tlet selectionContainsOnlyWhitespace = true;\n\t\t\tfor (let lineNumber = selection.startLineNumber; lineNumber <= selection.endLineNumber; lineNumber++) {\n\t\t\t\tconst lineText = model.getLineContent(lineNumber);\n\t\t\t\tconst startIndex = (lineNumber === selection.startLineNumber ? selection.startColumn - 1 : 0);\n\t\t\t\tconst endIndex = (lineNumber === selection.endLineNumber ? selection.endColumn - 1 : lineText.length);\n\t\t\t\tconst selectedText = lineText.substring(startIndex, endIndex);\n\t\t\t\tif (/[^ \\t]/.test(selectedText)) {\n\t\t\t\t\t// this selected text contains something other than whitespace\n\t\t\t\t\tselectionContainsOnlyWhitespace = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (selectionContainsOnlyWhitespace) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (isTypingAQuoteCharacter && selection.startLineNumber === selection.endLineNumber && selection.startColumn + 1 === selection.endColumn) {\n\t\t\t\tconst selectionText = model.getValueInRange(selection);\n\t\t\t\tif (isQuote(selectionText)) {\n\t\t\t\t\t// Typing a quote character on top of another quote character\n\t\t\t\t\t// => disable surround selection type\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}\n\nexport class InterceptorElectricCharOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\t// Electric characters make sense only when dealing with a single cursor,\n\t\t// as multiple cursors typing brackets for example would interfer with bracket matching\n\t\tif (!isDoingComposition && this._isTypeInterceptorElectricChar(config, model, selections)) {\n\t\t\tconst r = this._typeInterceptorElectricChar(prevEditOperationType, config, model, selections[0], ch);\n\t\t\tif (r) {\n\t\t\t\treturn r;\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _isTypeInterceptorElectricChar(config: CursorConfiguration, model: ITextModel, selections: Selection[]) {\n\t\tif (selections.length === 1 && model.tokenization.isCheapToTokenize(selections[0].getEndPosition().lineNumber)) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate static _typeInterceptorElectricChar(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selection: Selection, ch: string): EditOperationResult | null {\n\t\tif (!config.electricChars.hasOwnProperty(ch) || !selection.isEmpty()) {\n\t\t\treturn null;\n\t\t}\n\t\tconst position = selection.getPosition();\n\t\tmodel.tokenization.forceTokenization(position.lineNumber);\n\t\tconst lineTokens = model.tokenization.getLineTokens(position.lineNumber);\n\t\tlet electricAction: IElectricAction | null;\n\t\ttry {\n\t\t\telectricAction = config.onElectricCharacter(ch, lineTokens, position.column);\n\t\t} catch (e) {\n\t\t\tonUnexpectedError(e);\n\t\t\treturn null;\n\t\t}\n\t\tif (!electricAction) {\n\t\t\treturn null;\n\t\t}\n\t\tif (electricAction.matchOpenBracket) {\n\t\t\tconst endColumn = (lineTokens.getLineContent() + ch).lastIndexOf(electricAction.matchOpenBracket) + 1;\n\t\t\tconst match = model.bracketPairs.findMatchingBracketUp(electricAction.matchOpenBracket, {\n\t\t\t\tlineNumber: position.lineNumber,\n\t\t\t\tcolumn: endColumn\n\t\t\t}, 500 /* give at most 500ms to compute */);\n\t\t\tif (match) {\n\t\t\t\tif (match.startLineNumber === position.lineNumber) {\n\t\t\t\t\t// matched something on the same line => no change in indentation\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst matchLine = model.getLineContent(match.startLineNumber);\n\t\t\t\tconst matchLineIndentation = strings.getLeadingWhitespace(matchLine);\n\t\t\t\tconst newIndentation = config.normalizeIndentation(matchLineIndentation);\n\t\t\t\tconst lineText = model.getLineContent(position.lineNumber);\n\t\t\t\tconst lineFirstNonBlankColumn = model.getLineFirstNonWhitespaceColumn(position.lineNumber) || position.column;\n\t\t\t\tconst prefix = lineText.substring(lineFirstNonBlankColumn - 1, position.column - 1);\n\t\t\t\tconst typeText = newIndentation + prefix + ch;\n\t\t\t\tconst typeSelection = new Range(position.lineNumber, 1, position.lineNumber, position.column);\n\t\t\t\tconst command = new ReplaceCommand(typeSelection, typeText);\n\t\t\t\treturn new EditOperationResult(getTypingOperation(typeText, prevEditOperationType), [command], {\n\t\t\t\t\tshouldPushStackElementBefore: false,\n\t\t\t\t\tshouldPushStackElementAfter: true\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n}\n\nexport class SimpleCharacterTypeOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, prevEditOperationType: EditOperationType, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult {\n\t\t// A simple character type\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst ChosenReplaceCommand = config.inputMode === 'overtype' && !isDoingComposition ? ReplaceOvertypeCommand : ReplaceCommand;\n\t\t\tcommands[i] = new ChosenReplaceCommand(selections[i], ch);\n\t\t}\n\n\t\tconst opType = getTypingOperation(ch, prevEditOperationType);\n\t\treturn new EditOperationResult(opType, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, opType),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class EnterOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition && ch === '\\n') {\n\t\t\tconst commands: ICommand[] = [];\n\t\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\t\tcommands[i] = this._enter(config, model, false, selections[i]);\n\t\t\t}\n\t\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\t\tshouldPushStackElementBefore: true,\n\t\t\t\tshouldPushStackElementAfter: false,\n\t\t\t});\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _enter(config: CursorConfiguration, model: ITextModel, keepPosition: boolean, range: Range): ICommand {\n\t\tif (config.autoIndent === EditorAutoIndentStrategy.None) {\n\t\t\treturn typeCommand(range, '\\n', keepPosition);\n\t\t}\n\t\tif (!model.tokenization.isCheapToTokenize(range.getStartPosition().lineNumber) || config.autoIndent === EditorAutoIndentStrategy.Keep) {\n\t\t\tconst lineText = model.getLineContent(range.startLineNumber);\n\t\t\tconst indentation = strings.getLeadingWhitespace(lineText).substring(0, range.startColumn - 1);\n\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(indentation), keepPosition);\n\t\t}\n\t\tconst r = getEnterAction(config.autoIndent, model, range, config.languageConfigurationService);\n\t\tif (r) {\n\t\t\tif (r.indentAction === IndentAction.None) {\n\t\t\t\t// Nothing special\n\t\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(r.indentation + r.appendText), keepPosition);\n\n\t\t\t} else if (r.indentAction === IndentAction.Indent) {\n\t\t\t\t// Indent once\n\t\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(r.indentation + r.appendText), keepPosition);\n\n\t\t\t} else if (r.indentAction === IndentAction.IndentOutdent) {\n\t\t\t\t// Ultra special\n\t\t\t\tconst normalIndent = config.normalizeIndentation(r.indentation);\n\t\t\t\tconst increasedIndent = config.normalizeIndentation(r.indentation + r.appendText);\n\t\t\t\tconst typeText = '\\n' + increasedIndent + '\\n' + normalIndent;\n\t\t\t\tif (keepPosition) {\n\t\t\t\t\treturn new ReplaceCommandWithoutChangingPosition(range, typeText, true);\n\t\t\t\t} else {\n\t\t\t\t\treturn new ReplaceCommandWithOffsetCursorState(range, typeText, -1, increasedIndent.length - normalIndent.length, true);\n\t\t\t\t}\n\t\t\t} else if (r.indentAction === IndentAction.Outdent) {\n\t\t\t\tconst actualIndentation = unshiftIndent(config, r.indentation);\n\t\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(actualIndentation + r.appendText), keepPosition);\n\t\t\t}\n\t\t}\n\n\t\tconst lineText = model.getLineContent(range.startLineNumber);\n\t\tconst indentation = strings.getLeadingWhitespace(lineText).substring(0, range.startColumn - 1);\n\n\t\tif (config.autoIndent >= EditorAutoIndentStrategy.Full) {\n\t\t\tconst ir = getIndentForEnter(config.autoIndent, model, range, {\n\t\t\t\tunshiftIndent: (indent) => {\n\t\t\t\t\treturn unshiftIndent(config, indent);\n\t\t\t\t},\n\t\t\t\tshiftIndent: (indent) => {\n\t\t\t\t\treturn shiftIndent(config, indent);\n\t\t\t\t},\n\t\t\t\tnormalizeIndentation: (indent) => {\n\t\t\t\t\treturn config.normalizeIndentation(indent);\n\t\t\t\t}\n\t\t\t}, config.languageConfigurationService);\n\n\t\t\tif (ir) {\n\t\t\t\tlet oldEndViewColumn = config.visibleColumnFromColumn(model, range.getEndPosition());\n\t\t\t\tconst oldEndColumn = range.endColumn;\n\t\t\t\tconst newLineContent = model.getLineContent(range.endLineNumber);\n\t\t\t\tconst firstNonWhitespace = strings.firstNonWhitespaceIndex(newLineContent);\n\t\t\t\tif (firstNonWhitespace >= 0) {\n\t\t\t\t\trange = range.setEndPosition(range.endLineNumber, Math.max(range.endColumn, firstNonWhitespace + 1));\n\t\t\t\t} else {\n\t\t\t\t\trange = range.setEndPosition(range.endLineNumber, model.getLineMaxColumn(range.endLineNumber));\n\t\t\t\t}\n\t\t\t\tif (keepPosition) {\n\t\t\t\t\treturn new ReplaceCommandWithoutChangingPosition(range, '\\n' + config.normalizeIndentation(ir.afterEnter), true);\n\t\t\t\t} else {\n\t\t\t\t\tlet offset = 0;\n\t\t\t\t\tif (oldEndColumn <= firstNonWhitespace + 1) {\n\t\t\t\t\t\tif (!config.insertSpaces) {\n\t\t\t\t\t\t\toldEndViewColumn = Math.ceil(oldEndViewColumn / config.indentSize);\n\t\t\t\t\t\t}\n\t\t\t\t\t\toffset = Math.min(oldEndViewColumn + 1 - config.normalizeIndentation(ir.afterEnter).length - 1, 0);\n\t\t\t\t\t}\n\t\t\t\t\treturn new ReplaceCommandWithOffsetCursorState(range, '\\n' + config.normalizeIndentation(ir.afterEnter), 0, offset, true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(indentation), keepPosition);\n\t}\n\n\n\tpublic static lineInsertBefore(config: CursorConfiguration, model: ITextModel | null, selections: Selection[] | null): ICommand[] {\n\t\tif (model === null || selections === null) {\n\t\t\treturn [];\n\t\t}\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tlet lineNumber = selections[i].positionLineNumber;\n\t\t\tif (lineNumber === 1) {\n\t\t\t\tcommands[i] = new ReplaceCommandWithoutChangingPosition(new Range(1, 1, 1, 1), '\\n');\n\t\t\t} else {\n\t\t\t\tlineNumber--;\n\t\t\t\tconst column = model.getLineMaxColumn(lineNumber);\n\n\t\t\t\tcommands[i] = this._enter(config, model, false, new Range(lineNumber, column, lineNumber, column));\n\t\t\t}\n\t\t}\n\t\treturn commands;\n\t}\n\n\tpublic static lineInsertAfter(config: CursorConfiguration, model: ITextModel | null, selections: Selection[] | null): ICommand[] {\n\t\tif (model === null || selections === null) {\n\t\t\treturn [];\n\t\t}\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst lineNumber = selections[i].positionLineNumber;\n\t\t\tconst column = model.getLineMaxColumn(lineNumber);\n\t\t\tcommands[i] = this._enter(config, model, false, new Range(lineNumber, column, lineNumber, column));\n\t\t}\n\t\treturn commands;\n\t}\n\n\tpublic static lineBreakInsert(config: CursorConfiguration, model: ITextModel, selections: Selection[]): ICommand[] {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tcommands[i] = this._enter(config, model, true, selections[i]);\n\t\t}\n\t\treturn commands;\n\t}\n}\n\nexport class PasteOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]) {\n\t\tconst distributedPaste = this._distributePasteToCursors(config, selections, text, pasteOnNewLine, multicursorText);\n\t\tif (distributedPaste) {\n\t\t\tselections = selections.sort(Range.compareRangesUsingStarts);\n\t\t\treturn this._distributedPaste(config, model, selections, distributedPaste);\n\t\t} else {\n\t\t\treturn this._simplePaste(config, model, selections, text, pasteOnNewLine);\n\t\t}\n\t}\n\n\tprivate static _distributePasteToCursors(config: CursorConfiguration, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]): string[] | null {\n\t\tif (pasteOnNewLine) {\n\t\t\treturn null;\n\t\t}\n\t\tif (selections.length === 1) {\n\t\t\treturn null;\n\t\t}\n\t\tif (multicursorText && multicursorText.length === selections.length) {\n\t\t\treturn multicursorText;\n\t\t}\n\t\tif (config.multiCursorPaste === 'spread') {\n\t\t\t// Try to spread the pasted text in case the line count matches the cursor count\n\t\t\t// Remove trailing \\n if present\n\t\t\tif (text.charCodeAt(text.length - 1) === CharCode.LineFeed) {\n\t\t\t\ttext = text.substring(0, text.length - 1);\n\t\t\t}\n\t\t\t// Remove trailing \\r if present\n\t\t\tif (text.charCodeAt(text.length - 1) === CharCode.CarriageReturn) {\n\t\t\t\ttext = text.substring(0, text.length - 1);\n\t\t\t}\n\t\t\tconst lines = strings.splitLines(text);\n\t\t\tif (lines.length === selections.length) {\n\t\t\t\treturn lines;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate static _distributedPaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string[]): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst shouldOvertypeOnPaste = config.overtypeOnPaste && config.inputMode === 'overtype';\n\t\t\tconst ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommand : ReplaceCommand;\n\t\t\tcommands[i] = new ChosenReplaceCommand(selections[i], text[i]);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.Other, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: true\n\t\t});\n\t}\n\n\tprivate static _simplePaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tconst position = selection.getPosition();\n\t\t\tif (pasteOnNewLine && !selection.isEmpty()) {\n\t\t\t\tpasteOnNewLine = false;\n\t\t\t}\n\t\t\tif (pasteOnNewLine && text.indexOf('\\n') !== text.length - 1) {\n\t\t\t\tpasteOnNewLine = false;\n\t\t\t}\n\t\t\tif (pasteOnNewLine) {\n\t\t\t\t// Paste entire line at the beginning of line\n\t\t\t\tconst typeSelection = new Range(position.lineNumber, 1, position.lineNumber, 1);\n\t\t\t\tcommands[i] = new ReplaceCommandThatPreservesSelection(typeSelection, text, selection, true);\n\t\t\t} else {\n\t\t\t\tconst shouldOvertypeOnPaste = config.overtypeOnPaste && config.inputMode === 'overtype';\n\t\t\t\tconst ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommand : ReplaceCommand;\n\t\t\t\tcommands[i] = new ChosenReplaceCommand(selection, text);\n\t\t\t}\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.Other, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: true\n\t\t});\n\t}\n}\n\nexport class CompositionOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number) {\n\t\tconst commands = selections.map(selection => this._compositionType(model, selection, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta));\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, EditOperationType.TypingOther),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n\n\tprivate static _compositionType(model: ITextModel, selection: Selection, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number): ICommand | null {\n\t\tif (!selection.isEmpty()) {\n\t\t\t// looks like https://github.com/microsoft/vscode/issues/2773\n\t\t\t// where a cursor operation occurred before a canceled composition\n\t\t\t// => ignore composition\n\t\t\treturn null;\n\t\t}\n\t\tconst pos = selection.getPosition();\n\t\tconst startColumn = Math.max(1, pos.column - replacePrevCharCnt);\n\t\tconst endColumn = Math.min(model.getLineMaxColumn(pos.lineNumber), pos.column + replaceNextCharCnt);\n\t\tconst range = new Range(pos.lineNumber, startColumn, pos.lineNumber, endColumn);\n\t\treturn new ReplaceCommandWithOffsetCursorState(range, text, 0, positionDelta);\n\t}\n}\n\nexport class TypeWithoutInterceptorsOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], str: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tcommands[i] = new ReplaceCommand(selections[i], str);\n\t\t}\n\t\tconst opType = getTypingOperation(str, prevEditOperationType);\n\t\treturn new EditOperationResult(opType, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, opType),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class TabOperation {\n\n\tpublic static getCommands(config: CursorConfiguration, model: ITextModel, selections: Selection[]) {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tif (selection.isEmpty()) {\n\t\t\t\tconst lineText = model.getLineContent(selection.startLineNumber);\n\t\t\t\tif (/^\\s*$/.test(lineText) && model.tokenization.isCheapToTokenize(selection.startLineNumber)) {\n\t\t\t\t\tlet goodIndent = this._goodIndentForLine(config, model, selection.startLineNumber);\n\t\t\t\t\tgoodIndent = goodIndent || '\\t';\n\t\t\t\t\tconst possibleTypeText = config.normalizeIndentation(goodIndent);\n\t\t\t\t\tif (!lineText.startsWith(possibleTypeText)) {\n\t\t\t\t\t\tcommands[i] = new ReplaceCommand(new Range(selection.startLineNumber, 1, selection.startLineNumber, lineText.length + 1), possibleTypeText, true);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcommands[i] = this._replaceJumpToNextIndent(config, model, selection, true);\n\t\t\t} else {\n\t\t\t\tif (selection.startLineNumber === selection.endLineNumber) {\n\t\t\t\t\tconst lineMaxColumn = model.getLineMaxColumn(selection.startLineNumber);\n\t\t\t\t\tif (selection.startColumn !== 1 || selection.endColumn !== lineMaxColumn) {\n\t\t\t\t\t\t// This is a single line selection that is not the entire line\n\t\t\t\t\t\tcommands[i] = this._replaceJumpToNextIndent(config, model, selection, false);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcommands[i] = new ShiftCommand(selection, {\n\t\t\t\t\tisUnshift: false,\n\t\t\t\t\ttabSize: config.tabSize,\n\t\t\t\t\tindentSize: config.indentSize,\n\t\t\t\t\tinsertSpaces: config.insertSpaces,\n\t\t\t\t\tuseTabStops: config.useTabStops,\n\t\t\t\t\tautoIndent: config.autoIndent\n\t\t\t\t}, config.languageConfigurationService);\n\t\t\t}\n\t\t}\n\t\treturn commands;\n\t}\n\n\tprivate static _goodIndentForLine(config: CursorConfiguration, model: ITextModel, lineNumber: number): string | null {\n\t\tlet action: IndentAction | EnterAction | null = null;\n\t\tlet indentation: string = '';\n\t\tconst expectedIndentAction = getInheritIndentForLine(config.autoIndent, model, lineNumber, false, config.languageConfigurationService);\n\t\tif (expectedIndentAction) {\n\t\t\taction = expectedIndentAction.action;\n\t\t\tindentation = expectedIndentAction.indentation;\n\t\t} else if (lineNumber > 1) {\n\t\t\tlet lastLineNumber: number;\n\t\t\tfor (lastLineNumber = lineNumber - 1; lastLineNumber >= 1; lastLineNumber--) {\n\t\t\t\tconst lineText = model.getLineContent(lastLineNumber);\n\t\t\t\tconst nonWhitespaceIdx = strings.lastNonWhitespaceIndex(lineText);\n\t\t\t\tif (nonWhitespaceIdx >= 0) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (lastLineNumber < 1) {\n\t\t\t\t// No previous line with content found\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst maxColumn = model.getLineMaxColumn(lastLineNumber);\n\t\t\tconst expectedEnterAction = getEnterAction(config.autoIndent, model, new Range(lastLineNumber, maxColumn, lastLineNumber, maxColumn), config.languageConfigurationService);\n\t\t\tif (expectedEnterAction) {\n\t\t\t\tindentation = expectedEnterAction.indentation + expectedEnterAction.appendText;\n\t\t\t}\n\t\t}\n\t\tif (action) {\n\t\t\tif (action === IndentAction.Indent) {\n\t\t\t\tindentation = shiftIndent(config, indentation);\n\t\t\t}\n\t\t\tif (action === IndentAction.Outdent) {\n\t\t\t\tindentation = unshiftIndent(config, indentation);\n\t\t\t}\n\t\t\tindentation = config.normalizeIndentation(indentation);\n\t\t}\n\t\tif (!indentation) {\n\t\t\treturn null;\n\t\t}\n\t\treturn indentation;\n\t}\n\n\tprivate static _replaceJumpToNextIndent(config: CursorConfiguration, model: ICursorSimpleModel, selection: Selection, insertsAutoWhitespace: boolean): ReplaceCommand {\n\t\tlet typeText = '';\n\t\tconst position = selection.getStartPosition();\n\t\tif (config.insertSpaces) {\n\t\t\tconst visibleColumnFromColumn = config.visibleColumnFromColumn(model, position);\n\t\t\tconst indentSize = config.indentSize;\n\t\t\tconst spacesCnt = indentSize - (visibleColumnFromColumn % indentSize);\n\t\t\tfor (let i = 0; i < spacesCnt; i++) {\n\t\t\t\ttypeText += ' ';\n\t\t\t}\n\t\t} else {\n\t\t\ttypeText = '\\t';\n\t\t}\n\t\treturn new ReplaceCommand(selection, typeText, insertsAutoWhitespace);\n\t}\n}\n\nexport class BaseTypeWithAutoClosingCommand extends ReplaceCommandWithOffsetCursorState {\n\n\tprivate readonly _openCharacter: string;\n\tprivate readonly _closeCharacter: string;\n\tpublic closeCharacterRange: Range | null;\n\tpublic enclosingRange: Range | null;\n\n\tconstructor(selection: Selection, text: string, lineNumberDeltaOffset: number, columnDeltaOffset: number, openCharacter: string, closeCharacter: string) {\n\t\tsuper(selection, text, lineNumberDeltaOffset, columnDeltaOffset);\n\t\tthis._openCharacter = openCharacter;\n\t\tthis._closeCharacter = closeCharacter;\n\t\tthis.closeCharacterRange = null;\n\t\tthis.enclosingRange = null;\n\t}\n\n\tprotected _computeCursorStateWithRange(model: ITextModel, range: Range, helper: ICursorStateComputerData): Selection {\n\t\tthis.closeCharacterRange = new Range(range.startLineNumber, range.endColumn - this._closeCharacter.length, range.endLineNumber, range.endColumn);\n\t\tthis.enclosingRange = new Range(range.startLineNumber, range.endColumn - this._openCharacter.length - this._closeCharacter.length, range.endLineNumber, range.endColumn);\n\t\treturn super.computeCursorState(model, helper);\n\t}\n}\n\nclass TypeWithAutoClosingCommand extends BaseTypeWithAutoClosingCommand {\n\n\tconstructor(selection: Selection, openCharacter: string, insertOpenCharacter: boolean, closeCharacter: string) {\n\t\tconst text = (insertOpenCharacter ? openCharacter : '') + closeCharacter;\n\t\tconst lineNumberDeltaOffset = 0;\n\t\tconst columnDeltaOffset = -closeCharacter.length;\n\t\tsuper(selection, text, lineNumberDeltaOffset, columnDeltaOffset, openCharacter, closeCharacter);\n\t}\n\n\tpublic override computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {\n\t\tconst inverseEditOperations = helper.getInverseEditOperations();\n\t\tconst range = inverseEditOperations[0].range;\n\t\treturn this._computeCursorStateWithRange(model, range, helper);\n\t}\n}\n\nclass TypeWithIndentationAndAutoClosingCommand extends BaseTypeWithAutoClosingCommand {\n\n\tprivate readonly _autoIndentationEdit: { range: Range; text: string };\n\tprivate readonly _autoClosingEdit: { range: Range; text: string };\n\n\tconstructor(autoIndentationEdit: { range: Range; text: string }, selection: Selection, openCharacter: string, closeCharacter: string) {\n\t\tconst text = openCharacter + closeCharacter;\n\t\tconst lineNumberDeltaOffset = 0;\n\t\tconst columnDeltaOffset = openCharacter.length;\n\t\tsuper(selection, text, lineNumberDeltaOffset, columnDeltaOffset, openCharacter, closeCharacter);\n\t\tthis._autoIndentationEdit = autoIndentationEdit;\n\t\tthis._autoClosingEdit = { range: selection, text };\n\t}\n\n\tpublic override getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {\n\t\tbuilder.addTrackedEditOperation(this._autoIndentationEdit.range, this._autoIndentationEdit.text);\n\t\tbuilder.addTrackedEditOperation(this._autoClosingEdit.range, this._autoClosingEdit.text);\n\t}\n\n\tpublic override computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {\n\t\tconst inverseEditOperations = helper.getInverseEditOperations();\n\t\tif (inverseEditOperations.length !== 2) {\n\t\t\tthrow new Error('There should be two inverse edit operations!');\n\t\t}\n\t\tconst range1 = inverseEditOperations[0].range;\n\t\tconst range2 = inverseEditOperations[1].range;\n\t\tconst range = range1.plusRange(range2);\n\t\treturn this._computeCursorStateWithRange(model, range, helper);\n\t}\n}\n\nfunction getTypingOperation(typedText: string, previousTypingOperation: EditOperationType): EditOperationType {\n\tif (typedText === ' ') {\n\t\treturn previousTypingOperation === EditOperationType.TypingFirstSpace\n\t\t\t|| previousTypingOperation === EditOperationType.TypingConsecutiveSpace\n\t\t\t? EditOperationType.TypingConsecutiveSpace\n\t\t\t: EditOperationType.TypingFirstSpace;\n\t}\n\n\treturn EditOperationType.TypingOther;\n}\n\nfunction shouldPushStackElementBetween(previousTypingOperation: EditOperationType, typingOperation: EditOperationType): boolean {\n\tif (isTypingOperation(previousTypingOperation) && !isTypingOperation(typingOperation)) {\n\t\t// Always set an undo stop before non-type operations\n\t\treturn true;\n\t}\n\tif (previousTypingOperation === EditOperationType.TypingFirstSpace) {\n\t\t// `abc |d`: No undo stop\n\t\t// `abc |d`: Undo stop\n\t\treturn false;\n\t}\n\t// Insert undo stop between different operation types\n\treturn normalizeOperationType(previousTypingOperation) !== normalizeOperationType(typingOperation);\n}\n\nfunction normalizeOperationType(type: EditOperationType): EditOperationType | 'space' {\n\treturn (type === EditOperationType.TypingConsecutiveSpace || type === EditOperationType.TypingFirstSpace)\n\t\t? 'space'\n\t\t: type;\n}\n\nfunction isTypingOperation(type: EditOperationType): boolean {\n\treturn type === EditOperationType.TypingOther\n\t\t|| type === EditOperationType.TypingFirstSpace\n\t\t|| type === EditOperationType.TypingConsecutiveSpace;\n}\n\nfunction isAutoClosingOvertype(config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): boolean {\n\tif (config.autoClosingOvertype === 'never') {\n\t\treturn false;\n\t}\n\tif (!config.autoClosingPairs.autoClosingPairsCloseSingleChar.has(ch)) {\n\t\treturn false;\n\t}\n\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\tconst selection = selections[i];\n\t\tif (!selection.isEmpty()) {\n\t\t\treturn false;\n\t\t}\n\t\tconst position = selection.getPosition();\n\t\tconst lineText = model.getLineContent(position.lineNumber);\n\t\tconst afterCharacter = lineText.charAt(position.column - 1);\n\t\tif (afterCharacter !== ch) {\n\t\t\treturn false;\n\t\t}\n\t\t// Do not over-type quotes after a backslash\n\t\tconst chIsQuote = isQuote(ch);\n\t\tconst beforeCharacter = position.column > 2 ? lineText.charCodeAt(position.column - 2) : CharCode.Null;\n\t\tif (beforeCharacter === CharCode.Backslash && chIsQuote) {\n\t\t\treturn false;\n\t\t}\n\t\t// Must over-type a closing character typed by the editor\n\t\tif (config.autoClosingOvertype === 'auto') {\n\t\t\tlet found = false;\n\t\t\tfor (let j = 0, lenJ = autoClosedCharacters.length; j < lenJ; j++) {\n\t\t\t\tconst autoClosedCharacter = autoClosedCharacters[j];\n\t\t\t\tif (position.lineNumber === autoClosedCharacter.startLineNumber && position.column === autoClosedCharacter.startColumn) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction typeCommand(range: Range, text: string, keepPosition: boolean): ICommand {\n\tif (keepPosition) {\n\t\treturn new ReplaceCommandWithoutChangingPosition(range, text, true);\n\t} else {\n\t\treturn new ReplaceCommand(range, text, true);\n\t}\n}\n\nexport function shiftIndent(config: CursorConfiguration, indentation: string, count?: number): string {\n\tcount = count || 1;\n\treturn ShiftCommand.shiftIndent(indentation, indentation.length + count, config.tabSize, config.indentSize, config.insertSpaces);\n}\n\nexport function unshiftIndent(config: CursorConfiguration, indentation: string, count?: number): string {\n\tcount = count || 1;\n\treturn ShiftCommand.unshiftIndent(indentation, indentation.length + count, config.tabSize, config.indentSize, config.insertSpaces);\n}\n\nexport function shouldSurroundChar(config: CursorConfiguration, ch: string): boolean {\n\tif (isQuote(ch)) {\n\t\treturn (config.autoSurround === 'quotes' || config.autoSurround === 'languageDefined');\n\t} else {\n\t\t// Character is a bracket\n\t\treturn (config.autoSurround === 'brackets' || config.autoSurround === 'languageDefined');\n\t}\n}\n"]}
1
+ {"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/editor/common/cursor/cursorTypeEditOperations.ts","vs/editor/common/cursor/cursorTypeEditOperations.ts"],"names":[],"mappings":"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","file":"cursorTypeEditOperations.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { CharCode } from '../../../base/common/charCode.js';\nimport { onUnexpectedError } from '../../../base/common/errors.js';\nimport * as strings from '../../../base/common/strings.js';\nimport { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, ReplaceOvertypeCommandOnCompositionEnd } from '../commands/replaceCommand.js';\nimport { ShiftCommand } from '../commands/shiftCommand.js';\nimport { SurroundSelectionCommand } from '../commands/surroundSelectionCommand.js';\nimport { CursorConfiguration, EditOperationResult, EditOperationType, ICursorSimpleModel, isQuote } from '../cursorCommon.js';\nimport { WordCharacterClass, getMapForWordSeparators } from '../core/wordCharacterClassifier.js';\nimport { Range } from '../core/range.js';\nimport { Selection } from '../core/selection.js';\nimport { Position } from '../core/position.js';\nimport { ICommand, ICursorStateComputerData, IEditOperationBuilder } from '../editorCommon.js';\nimport { ITextModel } from '../model.js';\nimport { EnterAction, IndentAction, StandardAutoClosingPairConditional } from '../languages/languageConfiguration.js';\nimport { getIndentationAtPosition } from '../languages/languageConfigurationRegistry.js';\nimport { IElectricAction } from '../languages/supports/electricCharacter.js';\nimport { EditorAutoClosingStrategy, EditorAutoIndentStrategy } from '../config/editorOptions.js';\nimport { createScopedLineTokens } from '../languages/supports.js';\nimport { getIndentActionForType, getIndentForEnter, getInheritIndentForLine } from '../languages/autoIndent.js';\nimport { getEnterAction } from '../languages/enterAction.js';\nimport { CompositionOutcome } from './cursorTypeOperations.js';\n\nexport class AutoIndentOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition && this._isAutoIndentType(config, model, selections)) {\n\t\t\tconst indentationForSelections: { selection: Selection; indentation: string }[] = [];\n\t\t\tfor (const selection of selections) {\n\t\t\t\tconst indentation = this._findActualIndentationForSelection(config, model, selection, ch);\n\t\t\t\tif (indentation === null) {\n\t\t\t\t\t// Auto indentation failed\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tindentationForSelections.push({ selection, indentation });\n\t\t\t}\n\t\t\tconst autoClosingPairClose = AutoClosingOpenCharTypeOperation.getAutoClosingPairClose(config, model, selections, ch, false);\n\t\t\treturn this._getIndentationAndAutoClosingPairEdits(config, model, indentationForSelections, ch, autoClosingPairClose);\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _isAutoIndentType(config: CursorConfiguration, model: ITextModel, selections: Selection[]): boolean {\n\t\tif (config.autoIndent < EditorAutoIndentStrategy.Full) {\n\t\t\treturn false;\n\t\t}\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tif (!model.tokenization.isCheapToTokenize(selections[i].getEndPosition().lineNumber)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate static _findActualIndentationForSelection(config: CursorConfiguration, model: ITextModel, selection: Selection, ch: string): string | null {\n\t\tconst actualIndentation = getIndentActionForType(config, model, selection, ch, {\n\t\t\tshiftIndent: (indentation) => {\n\t\t\t\treturn shiftIndent(config, indentation);\n\t\t\t},\n\t\t\tunshiftIndent: (indentation) => {\n\t\t\t\treturn unshiftIndent(config, indentation);\n\t\t\t},\n\t\t}, config.languageConfigurationService);\n\n\t\tif (actualIndentation === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst currentIndentation = getIndentationAtPosition(model, selection.startLineNumber, selection.startColumn);\n\t\tif (actualIndentation === config.normalizeIndentation(currentIndentation)) {\n\t\t\treturn null;\n\t\t}\n\t\treturn actualIndentation;\n\t}\n\n\tprivate static _getIndentationAndAutoClosingPairEdits(config: CursorConfiguration, model: ITextModel, indentationForSelections: { selection: Selection; indentation: string }[], ch: string, autoClosingPairClose: string | null): EditOperationResult {\n\t\tconst commands: ICommand[] = indentationForSelections.map(({ selection, indentation }) => {\n\t\t\tif (autoClosingPairClose !== null) {\n\t\t\t\t// Apply both auto closing pair edits and auto indentation edits\n\t\t\t\tconst indentationEdit = this._getEditFromIndentationAndSelection(config, model, indentation, selection, ch, false);\n\t\t\t\treturn new TypeWithIndentationAndAutoClosingCommand(indentationEdit, selection, ch, autoClosingPairClose);\n\t\t\t} else {\n\t\t\t\t// Apply only auto indentation edits\n\t\t\t\tconst indentationEdit = this._getEditFromIndentationAndSelection(config, model, indentation, selection, ch, true);\n\t\t\t\treturn typeCommand(indentationEdit.range, indentationEdit.text, false);\n\t\t\t}\n\t\t});\n\t\tconst editOptions = { shouldPushStackElementBefore: true, shouldPushStackElementAfter: false };\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, editOptions);\n\t}\n\n\tprivate static _getEditFromIndentationAndSelection(config: CursorConfiguration, model: ITextModel, indentation: string, selection: Selection, ch: string, includeChInEdit: boolean = true): { range: Range; text: string } {\n\t\tconst startLineNumber = selection.startLineNumber;\n\t\tconst firstNonWhitespaceColumn = model.getLineFirstNonWhitespaceColumn(startLineNumber);\n\t\tlet text: string = config.normalizeIndentation(indentation);\n\t\tif (firstNonWhitespaceColumn !== 0) {\n\t\t\tconst startLine = model.getLineContent(startLineNumber);\n\t\t\ttext += startLine.substring(firstNonWhitespaceColumn - 1, selection.startColumn - 1);\n\t\t}\n\t\ttext += includeChInEdit ? ch : '';\n\t\tconst range = new Range(startLineNumber, 1, selection.endLineNumber, selection.endColumn);\n\t\treturn { range, text };\n\t}\n}\n\nexport class AutoClosingOvertypeOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult | undefined {\n\t\tif (isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) {\n\t\t\treturn this._runAutoClosingOvertype(prevEditOperationType, selections, ch);\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _runAutoClosingOvertype(prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tconst position = selection.getPosition();\n\t\t\tconst typeSelection = new Range(position.lineNumber, position.column, position.lineNumber, position.column + 1);\n\t\t\tcommands[i] = new ReplaceCommand(typeSelection, ch);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, EditOperationType.TypingOther),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class AutoClosingOvertypeWithInterceptorsOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult | undefined {\n\t\tif (isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) {\n\t\t\t// Unfortunately, the close character is at this point \"doubled\", so we need to delete it...\n\t\t\tconst commands = selections.map(s => new ReplaceCommand(new Range(s.positionLineNumber, s.positionColumn, s.positionLineNumber, s.positionColumn + 1), '', false));\n\t\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\t\tshouldPushStackElementBefore: true,\n\t\t\t\tshouldPushStackElementAfter: false\n\t\t\t});\n\t\t}\n\t\treturn;\n\t}\n}\n\nexport class AutoClosingOpenCharTypeOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, chIsAlreadyTyped: boolean, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition) {\n\t\t\tconst autoClosingPairClose = this.getAutoClosingPairClose(config, model, selections, ch, chIsAlreadyTyped);\n\t\t\tif (autoClosingPairClose !== null) {\n\t\t\t\treturn this._runAutoClosingOpenCharType(selections, ch, chIsAlreadyTyped, autoClosingPairClose);\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _runAutoClosingOpenCharType(selections: Selection[], ch: string, chIsAlreadyTyped: boolean, autoClosingPairClose: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tcommands[i] = new TypeWithAutoClosingCommand(selection, ch, !chIsAlreadyTyped, autoClosingPairClose);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n\n\tpublic static getAutoClosingPairClose(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, chIsAlreadyTyped: boolean): string | null {\n\t\tfor (const selection of selections) {\n\t\t\tif (!selection.isEmpty()) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\t// This method is called both when typing (regularly) and when composition ends\n\t\t// This means that we need to work with a text buffer where sometimes `ch` is not\n\t\t// there (it is being typed right now) or with a text buffer where `ch` has already been typed\n\t\t//\n\t\t// In order to avoid adding checks for `chIsAlreadyTyped` in all places, we will work\n\t\t// with two conceptual positions, the position before `ch` and the position after `ch`\n\t\t//\n\t\tconst positions: { lineNumber: number; beforeColumn: number; afterColumn: number }[] = selections.map((s) => {\n\t\t\tconst position = s.getPosition();\n\t\t\tif (chIsAlreadyTyped) {\n\t\t\t\treturn { lineNumber: position.lineNumber, beforeColumn: position.column - ch.length, afterColumn: position.column };\n\t\t\t} else {\n\t\t\t\treturn { lineNumber: position.lineNumber, beforeColumn: position.column, afterColumn: position.column };\n\t\t\t}\n\t\t});\n\t\t// Find the longest auto-closing open pair in case of multiple ending in `ch`\n\t\t// e.g. when having [f\",\"] and [\",\"], it picks [f\",\"] if the character before is f\n\t\tconst pair = this._findAutoClosingPairOpen(config, model, positions.map(p => new Position(p.lineNumber, p.beforeColumn)), ch);\n\t\tif (!pair) {\n\t\t\treturn null;\n\t\t}\n\t\tlet autoCloseConfig: EditorAutoClosingStrategy;\n\t\tlet shouldAutoCloseBefore: (ch: string) => boolean;\n\n\t\tconst chIsQuote = isQuote(ch);\n\t\tif (chIsQuote) {\n\t\t\tautoCloseConfig = config.autoClosingQuotes;\n\t\t\tshouldAutoCloseBefore = config.shouldAutoCloseBefore.quote;\n\t\t} else {\n\t\t\tconst pairIsForComments = config.blockCommentStartToken ? pair.open.includes(config.blockCommentStartToken) : false;\n\t\t\tif (pairIsForComments) {\n\t\t\t\tautoCloseConfig = config.autoClosingComments;\n\t\t\t\tshouldAutoCloseBefore = config.shouldAutoCloseBefore.comment;\n\t\t\t} else {\n\t\t\t\tautoCloseConfig = config.autoClosingBrackets;\n\t\t\t\tshouldAutoCloseBefore = config.shouldAutoCloseBefore.bracket;\n\t\t\t}\n\t\t}\n\t\tif (autoCloseConfig === 'never') {\n\t\t\treturn null;\n\t\t}\n\t\t// Sometimes, it is possible to have two auto-closing pairs that have a containment relationship\n\t\t// e.g. when having [(,)] and [(*,*)]\n\t\t// - when typing (, the resulting state is (|)\n\t\t// - when typing *, the desired resulting state is (*|*), not (*|*))\n\t\tconst containedPair = this._findContainedAutoClosingPair(config, pair);\n\t\tconst containedPairClose = containedPair ? containedPair.close : '';\n\t\tlet isContainedPairPresent = true;\n\n\t\tfor (const position of positions) {\n\t\t\tconst { lineNumber, beforeColumn, afterColumn } = position;\n\t\t\tconst lineText = model.getLineContent(lineNumber);\n\t\t\tconst lineBefore = lineText.substring(0, beforeColumn - 1);\n\t\t\tconst lineAfter = lineText.substring(afterColumn - 1);\n\n\t\t\tif (!lineAfter.startsWith(containedPairClose)) {\n\t\t\t\tisContainedPairPresent = false;\n\t\t\t}\n\t\t\t// Only consider auto closing the pair if an allowed character follows or if another autoclosed pair closing brace follows\n\t\t\tif (lineAfter.length > 0) {\n\t\t\t\tconst characterAfter = lineAfter.charAt(0);\n\t\t\t\tconst isBeforeCloseBrace = this._isBeforeClosingBrace(config, lineAfter);\n\t\t\t\tif (!isBeforeCloseBrace && !shouldAutoCloseBefore(characterAfter)) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Do not auto-close ' or \" after a word character\n\t\t\tif (pair.open.length === 1 && (ch === '\\'' || ch === '\"') && autoCloseConfig !== 'always') {\n\t\t\t\tconst wordSeparators = getMapForWordSeparators(config.wordSeparators, []);\n\t\t\t\tif (lineBefore.length > 0) {\n\t\t\t\t\tconst characterBefore = lineBefore.charCodeAt(lineBefore.length - 1);\n\t\t\t\t\tif (wordSeparators.get(characterBefore) === WordCharacterClass.Regular) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!model.tokenization.isCheapToTokenize(lineNumber)) {\n\t\t\t\t// Do not force tokenization\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tmodel.tokenization.forceTokenization(lineNumber);\n\t\t\tconst lineTokens = model.tokenization.getLineTokens(lineNumber);\n\t\t\tconst scopedLineTokens = createScopedLineTokens(lineTokens, beforeColumn - 1);\n\t\t\tif (!pair.shouldAutoClose(scopedLineTokens, beforeColumn - scopedLineTokens.firstCharOffset)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\t// Typing for example a quote could either start a new string, in which case auto-closing is desirable\n\t\t\t// or it could end a previously started string, in which case auto-closing is not desirable\n\t\t\t//\n\t\t\t// In certain cases, it is really not possible to look at the previous token to determine\n\t\t\t// what would happen. That's why we do something really unusual, we pretend to type a different\n\t\t\t// character and ask the tokenizer what the outcome of doing that is: after typing a neutral\n\t\t\t// character, are we in a string (i.e. the quote would most likely end a string) or not?\n\t\t\t//\n\t\t\tconst neutralCharacter = pair.findNeutralCharacter();\n\t\t\tif (neutralCharacter) {\n\t\t\t\tconst tokenType = model.tokenization.getTokenTypeIfInsertingCharacter(lineNumber, beforeColumn, neutralCharacter);\n\t\t\t\tif (!pair.isOK(tokenType)) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (isContainedPairPresent) {\n\t\t\treturn pair.close.substring(0, pair.close.length - containedPairClose.length);\n\t\t} else {\n\t\t\treturn pair.close;\n\t\t}\n\t}\n\n\t/**\n\t * Find another auto-closing pair that is contained by the one passed in.\n\t *\n\t * e.g. when having [(,)] and [(*,*)] as auto-closing pairs\n\t * this method will find [(,)] as a containment pair for [(*,*)]\n\t */\n\tprivate static _findContainedAutoClosingPair(config: CursorConfiguration, pair: StandardAutoClosingPairConditional): StandardAutoClosingPairConditional | null {\n\t\tif (pair.open.length <= 1) {\n\t\t\treturn null;\n\t\t}\n\t\tconst lastChar = pair.close.charAt(pair.close.length - 1);\n\t\t// get candidates with the same last character as close\n\t\tconst candidates = config.autoClosingPairs.autoClosingPairsCloseByEnd.get(lastChar) || [];\n\t\tlet result: StandardAutoClosingPairConditional | null = null;\n\t\tfor (const candidate of candidates) {\n\t\t\tif (candidate.open !== pair.open && pair.open.includes(candidate.open) && pair.close.endsWith(candidate.close)) {\n\t\t\t\tif (!result || candidate.open.length > result.open.length) {\n\t\t\t\t\tresult = candidate;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Determine if typing `ch` at all `positions` in the `model` results in an\n\t * auto closing open sequence being typed.\n\t *\n\t * Auto closing open sequences can consist of multiple characters, which\n\t * can lead to ambiguities. In such a case, the longest auto-closing open\n\t * sequence is returned.\n\t */\n\tprivate static _findAutoClosingPairOpen(config: CursorConfiguration, model: ITextModel, positions: Position[], ch: string): StandardAutoClosingPairConditional | null {\n\t\tconst candidates = config.autoClosingPairs.autoClosingPairsOpenByEnd.get(ch);\n\t\tif (!candidates) {\n\t\t\treturn null;\n\t\t}\n\t\t// Determine which auto-closing pair it is\n\t\tlet result: StandardAutoClosingPairConditional | null = null;\n\t\tfor (const candidate of candidates) {\n\t\t\tif (result === null || candidate.open.length > result.open.length) {\n\t\t\t\tlet candidateIsMatch = true;\n\t\t\t\tfor (const position of positions) {\n\t\t\t\t\tconst relevantText = model.getValueInRange(new Range(position.lineNumber, position.column - candidate.open.length + 1, position.lineNumber, position.column));\n\t\t\t\t\tif (relevantText + ch !== candidate.open) {\n\t\t\t\t\t\tcandidateIsMatch = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (candidateIsMatch) {\n\t\t\t\t\tresult = candidate;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate static _isBeforeClosingBrace(config: CursorConfiguration, lineAfter: string) {\n\t\t// If the start of lineAfter can be interpretted as both a starting or ending brace, default to returning false\n\t\tconst nextChar = lineAfter.charAt(0);\n\t\tconst potentialStartingBraces = config.autoClosingPairs.autoClosingPairsOpenByStart.get(nextChar) || [];\n\t\tconst potentialClosingBraces = config.autoClosingPairs.autoClosingPairsCloseByStart.get(nextChar) || [];\n\n\t\tconst isBeforeStartingBrace = potentialStartingBraces.some(x => lineAfter.startsWith(x.open));\n\t\tconst isBeforeClosingBrace = potentialClosingBraces.some(x => lineAfter.startsWith(x.close));\n\n\t\treturn !isBeforeStartingBrace && isBeforeClosingBrace;\n\t}\n}\n\nexport class CompositionEndOvertypeOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, compositions: CompositionOutcome[]): EditOperationResult | null {\n\t\tconst isOvertypeMode = config.inputMode === 'overtype';\n\t\tif (!isOvertypeMode) {\n\t\t\treturn null;\n\t\t}\n\t\tconst commands = compositions.map(composition => new ReplaceOvertypeCommandOnCompositionEnd(composition.insertedTextRange));\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class SurroundSelectionOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition && this._isSurroundSelectionType(config, model, selections, ch)) {\n\t\t\treturn this._runSurroundSelectionType(config, selections, ch);\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _runSurroundSelectionType(config: CursorConfiguration, selections: Selection[], ch: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tconst closeCharacter = config.surroundingPairs[ch];\n\t\t\tcommands[i] = new SurroundSelectionCommand(selection, ch, closeCharacter);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.Other, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: true\n\t\t});\n\t}\n\n\tprivate static _isSurroundSelectionType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean {\n\t\tif (!shouldSurroundChar(config, ch) || !config.surroundingPairs.hasOwnProperty(ch)) {\n\t\t\treturn false;\n\t\t}\n\t\tconst isTypingAQuoteCharacter = isQuote(ch);\n\t\tfor (const selection of selections) {\n\t\t\tif (selection.isEmpty()) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tlet selectionContainsOnlyWhitespace = true;\n\t\t\tfor (let lineNumber = selection.startLineNumber; lineNumber <= selection.endLineNumber; lineNumber++) {\n\t\t\t\tconst lineText = model.getLineContent(lineNumber);\n\t\t\t\tconst startIndex = (lineNumber === selection.startLineNumber ? selection.startColumn - 1 : 0);\n\t\t\t\tconst endIndex = (lineNumber === selection.endLineNumber ? selection.endColumn - 1 : lineText.length);\n\t\t\t\tconst selectedText = lineText.substring(startIndex, endIndex);\n\t\t\t\tif (/[^ \\t]/.test(selectedText)) {\n\t\t\t\t\t// this selected text contains something other than whitespace\n\t\t\t\t\tselectionContainsOnlyWhitespace = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (selectionContainsOnlyWhitespace) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (isTypingAQuoteCharacter && selection.startLineNumber === selection.endLineNumber && selection.startColumn + 1 === selection.endColumn) {\n\t\t\t\tconst selectionText = model.getValueInRange(selection);\n\t\t\t\tif (isQuote(selectionText)) {\n\t\t\t\t\t// Typing a quote character on top of another quote character\n\t\t\t\t\t// => disable surround selection type\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}\n\nexport class InterceptorElectricCharOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\t// Electric characters make sense only when dealing with a single cursor,\n\t\t// as multiple cursors typing brackets for example would interfer with bracket matching\n\t\tif (!isDoingComposition && this._isTypeInterceptorElectricChar(config, model, selections)) {\n\t\t\tconst r = this._typeInterceptorElectricChar(prevEditOperationType, config, model, selections[0], ch);\n\t\t\tif (r) {\n\t\t\t\treturn r;\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _isTypeInterceptorElectricChar(config: CursorConfiguration, model: ITextModel, selections: Selection[]) {\n\t\tif (selections.length === 1 && model.tokenization.isCheapToTokenize(selections[0].getEndPosition().lineNumber)) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate static _typeInterceptorElectricChar(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selection: Selection, ch: string): EditOperationResult | null {\n\t\tif (!config.electricChars.hasOwnProperty(ch) || !selection.isEmpty()) {\n\t\t\treturn null;\n\t\t}\n\t\tconst position = selection.getPosition();\n\t\tmodel.tokenization.forceTokenization(position.lineNumber);\n\t\tconst lineTokens = model.tokenization.getLineTokens(position.lineNumber);\n\t\tlet electricAction: IElectricAction | null;\n\t\ttry {\n\t\t\telectricAction = config.onElectricCharacter(ch, lineTokens, position.column);\n\t\t} catch (e) {\n\t\t\tonUnexpectedError(e);\n\t\t\treturn null;\n\t\t}\n\t\tif (!electricAction) {\n\t\t\treturn null;\n\t\t}\n\t\tif (electricAction.matchOpenBracket) {\n\t\t\tconst endColumn = (lineTokens.getLineContent() + ch).lastIndexOf(electricAction.matchOpenBracket) + 1;\n\t\t\tconst match = model.bracketPairs.findMatchingBracketUp(electricAction.matchOpenBracket, {\n\t\t\t\tlineNumber: position.lineNumber,\n\t\t\t\tcolumn: endColumn\n\t\t\t}, 500 /* give at most 500ms to compute */);\n\t\t\tif (match) {\n\t\t\t\tif (match.startLineNumber === position.lineNumber) {\n\t\t\t\t\t// matched something on the same line => no change in indentation\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst matchLine = model.getLineContent(match.startLineNumber);\n\t\t\t\tconst matchLineIndentation = strings.getLeadingWhitespace(matchLine);\n\t\t\t\tconst newIndentation = config.normalizeIndentation(matchLineIndentation);\n\t\t\t\tconst lineText = model.getLineContent(position.lineNumber);\n\t\t\t\tconst lineFirstNonBlankColumn = model.getLineFirstNonWhitespaceColumn(position.lineNumber) || position.column;\n\t\t\t\tconst prefix = lineText.substring(lineFirstNonBlankColumn - 1, position.column - 1);\n\t\t\t\tconst typeText = newIndentation + prefix + ch;\n\t\t\t\tconst typeSelection = new Range(position.lineNumber, 1, position.lineNumber, position.column);\n\t\t\t\tconst command = new ReplaceCommand(typeSelection, typeText);\n\t\t\t\treturn new EditOperationResult(getTypingOperation(typeText, prevEditOperationType), [command], {\n\t\t\t\t\tshouldPushStackElementBefore: false,\n\t\t\t\t\tshouldPushStackElementAfter: true\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n}\n\nexport class SimpleCharacterTypeOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, prevEditOperationType: EditOperationType, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult {\n\t\t// A simple character type\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst ChosenReplaceCommand = config.inputMode === 'overtype' && !isDoingComposition ? ReplaceOvertypeCommand : ReplaceCommand;\n\t\t\tcommands[i] = new ChosenReplaceCommand(selections[i], ch);\n\t\t}\n\n\t\tconst opType = getTypingOperation(ch, prevEditOperationType);\n\t\treturn new EditOperationResult(opType, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, opType),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class EnterOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition && ch === '\\n') {\n\t\t\tconst commands: ICommand[] = [];\n\t\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\t\tcommands[i] = this._enter(config, model, false, selections[i]);\n\t\t\t}\n\t\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\t\tshouldPushStackElementBefore: true,\n\t\t\t\tshouldPushStackElementAfter: false,\n\t\t\t});\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _enter(config: CursorConfiguration, model: ITextModel, keepPosition: boolean, range: Range): ICommand {\n\t\tif (config.autoIndent === EditorAutoIndentStrategy.None) {\n\t\t\treturn typeCommand(range, '\\n', keepPosition);\n\t\t}\n\t\tif (!model.tokenization.isCheapToTokenize(range.getStartPosition().lineNumber) || config.autoIndent === EditorAutoIndentStrategy.Keep) {\n\t\t\tconst lineText = model.getLineContent(range.startLineNumber);\n\t\t\tconst indentation = strings.getLeadingWhitespace(lineText).substring(0, range.startColumn - 1);\n\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(indentation), keepPosition);\n\t\t}\n\t\tconst r = getEnterAction(config.autoIndent, model, range, config.languageConfigurationService);\n\t\tif (r) {\n\t\t\tif (r.indentAction === IndentAction.None) {\n\t\t\t\t// Nothing special\n\t\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(r.indentation + r.appendText), keepPosition);\n\n\t\t\t} else if (r.indentAction === IndentAction.Indent) {\n\t\t\t\t// Indent once\n\t\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(r.indentation + r.appendText), keepPosition);\n\n\t\t\t} else if (r.indentAction === IndentAction.IndentOutdent) {\n\t\t\t\t// Ultra special\n\t\t\t\tconst normalIndent = config.normalizeIndentation(r.indentation);\n\t\t\t\tconst increasedIndent = config.normalizeIndentation(r.indentation + r.appendText);\n\t\t\t\tconst typeText = '\\n' + increasedIndent + '\\n' + normalIndent;\n\t\t\t\tif (keepPosition) {\n\t\t\t\t\treturn new ReplaceCommandWithoutChangingPosition(range, typeText, true);\n\t\t\t\t} else {\n\t\t\t\t\treturn new ReplaceCommandWithOffsetCursorState(range, typeText, -1, increasedIndent.length - normalIndent.length, true);\n\t\t\t\t}\n\t\t\t} else if (r.indentAction === IndentAction.Outdent) {\n\t\t\t\tconst actualIndentation = unshiftIndent(config, r.indentation);\n\t\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(actualIndentation + r.appendText), keepPosition);\n\t\t\t}\n\t\t}\n\n\t\tconst lineText = model.getLineContent(range.startLineNumber);\n\t\tconst indentation = strings.getLeadingWhitespace(lineText).substring(0, range.startColumn - 1);\n\n\t\tif (config.autoIndent >= EditorAutoIndentStrategy.Full) {\n\t\t\tconst ir = getIndentForEnter(config.autoIndent, model, range, {\n\t\t\t\tunshiftIndent: (indent) => {\n\t\t\t\t\treturn unshiftIndent(config, indent);\n\t\t\t\t},\n\t\t\t\tshiftIndent: (indent) => {\n\t\t\t\t\treturn shiftIndent(config, indent);\n\t\t\t\t},\n\t\t\t\tnormalizeIndentation: (indent) => {\n\t\t\t\t\treturn config.normalizeIndentation(indent);\n\t\t\t\t}\n\t\t\t}, config.languageConfigurationService);\n\n\t\t\tif (ir) {\n\t\t\t\tlet oldEndViewColumn = config.visibleColumnFromColumn(model, range.getEndPosition());\n\t\t\t\tconst oldEndColumn = range.endColumn;\n\t\t\t\tconst newLineContent = model.getLineContent(range.endLineNumber);\n\t\t\t\tconst firstNonWhitespace = strings.firstNonWhitespaceIndex(newLineContent);\n\t\t\t\tif (firstNonWhitespace >= 0) {\n\t\t\t\t\trange = range.setEndPosition(range.endLineNumber, Math.max(range.endColumn, firstNonWhitespace + 1));\n\t\t\t\t} else {\n\t\t\t\t\trange = range.setEndPosition(range.endLineNumber, model.getLineMaxColumn(range.endLineNumber));\n\t\t\t\t}\n\t\t\t\tif (keepPosition) {\n\t\t\t\t\treturn new ReplaceCommandWithoutChangingPosition(range, '\\n' + config.normalizeIndentation(ir.afterEnter), true);\n\t\t\t\t} else {\n\t\t\t\t\tlet offset = 0;\n\t\t\t\t\tif (oldEndColumn <= firstNonWhitespace + 1) {\n\t\t\t\t\t\tif (!config.insertSpaces) {\n\t\t\t\t\t\t\toldEndViewColumn = Math.ceil(oldEndViewColumn / config.indentSize);\n\t\t\t\t\t\t}\n\t\t\t\t\t\toffset = Math.min(oldEndViewColumn + 1 - config.normalizeIndentation(ir.afterEnter).length - 1, 0);\n\t\t\t\t\t}\n\t\t\t\t\treturn new ReplaceCommandWithOffsetCursorState(range, '\\n' + config.normalizeIndentation(ir.afterEnter), 0, offset, true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(indentation), keepPosition);\n\t}\n\n\n\tpublic static lineInsertBefore(config: CursorConfiguration, model: ITextModel | null, selections: Selection[] | null): ICommand[] {\n\t\tif (model === null || selections === null) {\n\t\t\treturn [];\n\t\t}\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tlet lineNumber = selections[i].positionLineNumber;\n\t\t\tif (lineNumber === 1) {\n\t\t\t\tcommands[i] = new ReplaceCommandWithoutChangingPosition(new Range(1, 1, 1, 1), '\\n');\n\t\t\t} else {\n\t\t\t\tlineNumber--;\n\t\t\t\tconst column = model.getLineMaxColumn(lineNumber);\n\n\t\t\t\tcommands[i] = this._enter(config, model, false, new Range(lineNumber, column, lineNumber, column));\n\t\t\t}\n\t\t}\n\t\treturn commands;\n\t}\n\n\tpublic static lineInsertAfter(config: CursorConfiguration, model: ITextModel | null, selections: Selection[] | null): ICommand[] {\n\t\tif (model === null || selections === null) {\n\t\t\treturn [];\n\t\t}\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst lineNumber = selections[i].positionLineNumber;\n\t\t\tconst column = model.getLineMaxColumn(lineNumber);\n\t\t\tcommands[i] = this._enter(config, model, false, new Range(lineNumber, column, lineNumber, column));\n\t\t}\n\t\treturn commands;\n\t}\n\n\tpublic static lineBreakInsert(config: CursorConfiguration, model: ITextModel, selections: Selection[]): ICommand[] {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tcommands[i] = this._enter(config, model, true, selections[i]);\n\t\t}\n\t\treturn commands;\n\t}\n}\n\nexport class PasteOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]) {\n\t\tconst distributedPaste = this._distributePasteToCursors(config, selections, text, pasteOnNewLine, multicursorText);\n\t\tif (distributedPaste) {\n\t\t\tselections = selections.sort(Range.compareRangesUsingStarts);\n\t\t\treturn this._distributedPaste(config, model, selections, distributedPaste);\n\t\t} else {\n\t\t\treturn this._simplePaste(config, model, selections, text, pasteOnNewLine);\n\t\t}\n\t}\n\n\tprivate static _distributePasteToCursors(config: CursorConfiguration, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]): string[] | null {\n\t\tif (selections.length === 1) {\n\t\t\treturn null;\n\t\t}\n\t\tif (multicursorText && multicursorText.length === selections.length) {\n\t\t\treturn multicursorText;\n\t\t}\n\t\tif (pasteOnNewLine) {\n\t\t\treturn null;\n\t\t}\n\t\tif (config.multiCursorPaste === 'spread') {\n\t\t\t// Try to spread the pasted text in case the line count matches the cursor count\n\t\t\t// Remove trailing \\n if present\n\t\t\tif (text.charCodeAt(text.length - 1) === CharCode.LineFeed) {\n\t\t\t\ttext = text.substring(0, text.length - 1);\n\t\t\t}\n\t\t\t// Remove trailing \\r if present\n\t\t\tif (text.charCodeAt(text.length - 1) === CharCode.CarriageReturn) {\n\t\t\t\ttext = text.substring(0, text.length - 1);\n\t\t\t}\n\t\t\tconst lines = strings.splitLines(text);\n\t\t\tif (lines.length === selections.length) {\n\t\t\t\treturn lines;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate static _distributedPaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string[]): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst shouldOvertypeOnPaste = config.overtypeOnPaste && config.inputMode === 'overtype';\n\t\t\tconst ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommand : ReplaceCommand;\n\t\t\tcommands[i] = new ChosenReplaceCommand(selections[i], text[i]);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.Other, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: true\n\t\t});\n\t}\n\n\tprivate static _simplePaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tconst position = selection.getPosition();\n\t\t\tif (pasteOnNewLine && !selection.isEmpty()) {\n\t\t\t\tpasteOnNewLine = false;\n\t\t\t}\n\t\t\tif (pasteOnNewLine && text.indexOf('\\n') !== text.length - 1) {\n\t\t\t\tpasteOnNewLine = false;\n\t\t\t}\n\t\t\tif (pasteOnNewLine) {\n\t\t\t\t// Paste entire line at the beginning of line\n\t\t\t\tconst typeSelection = new Range(position.lineNumber, 1, position.lineNumber, 1);\n\t\t\t\tcommands[i] = new ReplaceCommandThatPreservesSelection(typeSelection, text, selection, true);\n\t\t\t} else {\n\t\t\t\tconst shouldOvertypeOnPaste = config.overtypeOnPaste && config.inputMode === 'overtype';\n\t\t\t\tconst ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommand : ReplaceCommand;\n\t\t\t\tcommands[i] = new ChosenReplaceCommand(selection, text);\n\t\t\t}\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.Other, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: true\n\t\t});\n\t}\n}\n\nexport class CompositionOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number) {\n\t\tconst commands = selections.map(selection => this._compositionType(model, selection, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta));\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, EditOperationType.TypingOther),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n\n\tprivate static _compositionType(model: ITextModel, selection: Selection, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number): ICommand | null {\n\t\tif (!selection.isEmpty()) {\n\t\t\t// looks like https://github.com/microsoft/vscode/issues/2773\n\t\t\t// where a cursor operation occurred before a canceled composition\n\t\t\t// => ignore composition\n\t\t\treturn null;\n\t\t}\n\t\tconst pos = selection.getPosition();\n\t\tconst startColumn = Math.max(1, pos.column - replacePrevCharCnt);\n\t\tconst endColumn = Math.min(model.getLineMaxColumn(pos.lineNumber), pos.column + replaceNextCharCnt);\n\t\tconst range = new Range(pos.lineNumber, startColumn, pos.lineNumber, endColumn);\n\t\treturn new ReplaceCommandWithOffsetCursorState(range, text, 0, positionDelta);\n\t}\n}\n\nexport class TypeWithoutInterceptorsOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], str: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tcommands[i] = new ReplaceCommand(selections[i], str);\n\t\t}\n\t\tconst opType = getTypingOperation(str, prevEditOperationType);\n\t\treturn new EditOperationResult(opType, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, opType),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class TabOperation {\n\n\tpublic static getCommands(config: CursorConfiguration, model: ITextModel, selections: Selection[]) {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tif (selection.isEmpty()) {\n\t\t\t\tconst lineText = model.getLineContent(selection.startLineNumber);\n\t\t\t\tif (/^\\s*$/.test(lineText) && model.tokenization.isCheapToTokenize(selection.startLineNumber)) {\n\t\t\t\t\tlet goodIndent = this._goodIndentForLine(config, model, selection.startLineNumber);\n\t\t\t\t\tgoodIndent = goodIndent || '\\t';\n\t\t\t\t\tconst possibleTypeText = config.normalizeIndentation(goodIndent);\n\t\t\t\t\tif (!lineText.startsWith(possibleTypeText)) {\n\t\t\t\t\t\tcommands[i] = new ReplaceCommand(new Range(selection.startLineNumber, 1, selection.startLineNumber, lineText.length + 1), possibleTypeText, true);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcommands[i] = this._replaceJumpToNextIndent(config, model, selection, true);\n\t\t\t} else {\n\t\t\t\tif (selection.startLineNumber === selection.endLineNumber) {\n\t\t\t\t\tconst lineMaxColumn = model.getLineMaxColumn(selection.startLineNumber);\n\t\t\t\t\tif (selection.startColumn !== 1 || selection.endColumn !== lineMaxColumn) {\n\t\t\t\t\t\t// This is a single line selection that is not the entire line\n\t\t\t\t\t\tcommands[i] = this._replaceJumpToNextIndent(config, model, selection, false);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcommands[i] = new ShiftCommand(selection, {\n\t\t\t\t\tisUnshift: false,\n\t\t\t\t\ttabSize: config.tabSize,\n\t\t\t\t\tindentSize: config.indentSize,\n\t\t\t\t\tinsertSpaces: config.insertSpaces,\n\t\t\t\t\tuseTabStops: config.useTabStops,\n\t\t\t\t\tautoIndent: config.autoIndent\n\t\t\t\t}, config.languageConfigurationService);\n\t\t\t}\n\t\t}\n\t\treturn commands;\n\t}\n\n\tprivate static _goodIndentForLine(config: CursorConfiguration, model: ITextModel, lineNumber: number): string | null {\n\t\tlet action: IndentAction | EnterAction | null = null;\n\t\tlet indentation: string = '';\n\t\tconst expectedIndentAction = getInheritIndentForLine(config.autoIndent, model, lineNumber, false, config.languageConfigurationService);\n\t\tif (expectedIndentAction) {\n\t\t\taction = expectedIndentAction.action;\n\t\t\tindentation = expectedIndentAction.indentation;\n\t\t} else if (lineNumber > 1) {\n\t\t\tlet lastLineNumber: number;\n\t\t\tfor (lastLineNumber = lineNumber - 1; lastLineNumber >= 1; lastLineNumber--) {\n\t\t\t\tconst lineText = model.getLineContent(lastLineNumber);\n\t\t\t\tconst nonWhitespaceIdx = strings.lastNonWhitespaceIndex(lineText);\n\t\t\t\tif (nonWhitespaceIdx >= 0) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (lastLineNumber < 1) {\n\t\t\t\t// No previous line with content found\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst maxColumn = model.getLineMaxColumn(lastLineNumber);\n\t\t\tconst expectedEnterAction = getEnterAction(config.autoIndent, model, new Range(lastLineNumber, maxColumn, lastLineNumber, maxColumn), config.languageConfigurationService);\n\t\t\tif (expectedEnterAction) {\n\t\t\t\tindentation = expectedEnterAction.indentation + expectedEnterAction.appendText;\n\t\t\t}\n\t\t}\n\t\tif (action) {\n\t\t\tif (action === IndentAction.Indent) {\n\t\t\t\tindentation = shiftIndent(config, indentation);\n\t\t\t}\n\t\t\tif (action === IndentAction.Outdent) {\n\t\t\t\tindentation = unshiftIndent(config, indentation);\n\t\t\t}\n\t\t\tindentation = config.normalizeIndentation(indentation);\n\t\t}\n\t\tif (!indentation) {\n\t\t\treturn null;\n\t\t}\n\t\treturn indentation;\n\t}\n\n\tprivate static _replaceJumpToNextIndent(config: CursorConfiguration, model: ICursorSimpleModel, selection: Selection, insertsAutoWhitespace: boolean): ReplaceCommand {\n\t\tlet typeText = '';\n\t\tconst position = selection.getStartPosition();\n\t\tif (config.insertSpaces) {\n\t\t\tconst visibleColumnFromColumn = config.visibleColumnFromColumn(model, position);\n\t\t\tconst indentSize = config.indentSize;\n\t\t\tconst spacesCnt = indentSize - (visibleColumnFromColumn % indentSize);\n\t\t\tfor (let i = 0; i < spacesCnt; i++) {\n\t\t\t\ttypeText += ' ';\n\t\t\t}\n\t\t} else {\n\t\t\ttypeText = '\\t';\n\t\t}\n\t\treturn new ReplaceCommand(selection, typeText, insertsAutoWhitespace);\n\t}\n}\n\nexport class BaseTypeWithAutoClosingCommand extends ReplaceCommandWithOffsetCursorState {\n\n\tprivate readonly _openCharacter: string;\n\tprivate readonly _closeCharacter: string;\n\tpublic closeCharacterRange: Range | null;\n\tpublic enclosingRange: Range | null;\n\n\tconstructor(selection: Selection, text: string, lineNumberDeltaOffset: number, columnDeltaOffset: number, openCharacter: string, closeCharacter: string) {\n\t\tsuper(selection, text, lineNumberDeltaOffset, columnDeltaOffset);\n\t\tthis._openCharacter = openCharacter;\n\t\tthis._closeCharacter = closeCharacter;\n\t\tthis.closeCharacterRange = null;\n\t\tthis.enclosingRange = null;\n\t}\n\n\tprotected _computeCursorStateWithRange(model: ITextModel, range: Range, helper: ICursorStateComputerData): Selection {\n\t\tthis.closeCharacterRange = new Range(range.startLineNumber, range.endColumn - this._closeCharacter.length, range.endLineNumber, range.endColumn);\n\t\tthis.enclosingRange = new Range(range.startLineNumber, range.endColumn - this._openCharacter.length - this._closeCharacter.length, range.endLineNumber, range.endColumn);\n\t\treturn super.computeCursorState(model, helper);\n\t}\n}\n\nclass TypeWithAutoClosingCommand extends BaseTypeWithAutoClosingCommand {\n\n\tconstructor(selection: Selection, openCharacter: string, insertOpenCharacter: boolean, closeCharacter: string) {\n\t\tconst text = (insertOpenCharacter ? openCharacter : '') + closeCharacter;\n\t\tconst lineNumberDeltaOffset = 0;\n\t\tconst columnDeltaOffset = -closeCharacter.length;\n\t\tsuper(selection, text, lineNumberDeltaOffset, columnDeltaOffset, openCharacter, closeCharacter);\n\t}\n\n\tpublic override computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {\n\t\tconst inverseEditOperations = helper.getInverseEditOperations();\n\t\tconst range = inverseEditOperations[0].range;\n\t\treturn this._computeCursorStateWithRange(model, range, helper);\n\t}\n}\n\nclass TypeWithIndentationAndAutoClosingCommand extends BaseTypeWithAutoClosingCommand {\n\n\tprivate readonly _autoIndentationEdit: { range: Range; text: string };\n\tprivate readonly _autoClosingEdit: { range: Range; text: string };\n\n\tconstructor(autoIndentationEdit: { range: Range; text: string }, selection: Selection, openCharacter: string, closeCharacter: string) {\n\t\tconst text = openCharacter + closeCharacter;\n\t\tconst lineNumberDeltaOffset = 0;\n\t\tconst columnDeltaOffset = openCharacter.length;\n\t\tsuper(selection, text, lineNumberDeltaOffset, columnDeltaOffset, openCharacter, closeCharacter);\n\t\tthis._autoIndentationEdit = autoIndentationEdit;\n\t\tthis._autoClosingEdit = { range: selection, text };\n\t}\n\n\tpublic override getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {\n\t\tbuilder.addTrackedEditOperation(this._autoIndentationEdit.range, this._autoIndentationEdit.text);\n\t\tbuilder.addTrackedEditOperation(this._autoClosingEdit.range, this._autoClosingEdit.text);\n\t}\n\n\tpublic override computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {\n\t\tconst inverseEditOperations = helper.getInverseEditOperations();\n\t\tif (inverseEditOperations.length !== 2) {\n\t\t\tthrow new Error('There should be two inverse edit operations!');\n\t\t}\n\t\tconst range1 = inverseEditOperations[0].range;\n\t\tconst range2 = inverseEditOperations[1].range;\n\t\tconst range = range1.plusRange(range2);\n\t\treturn this._computeCursorStateWithRange(model, range, helper);\n\t}\n}\n\nfunction getTypingOperation(typedText: string, previousTypingOperation: EditOperationType): EditOperationType {\n\tif (typedText === ' ') {\n\t\treturn previousTypingOperation === EditOperationType.TypingFirstSpace\n\t\t\t|| previousTypingOperation === EditOperationType.TypingConsecutiveSpace\n\t\t\t? EditOperationType.TypingConsecutiveSpace\n\t\t\t: EditOperationType.TypingFirstSpace;\n\t}\n\n\treturn EditOperationType.TypingOther;\n}\n\nfunction shouldPushStackElementBetween(previousTypingOperation: EditOperationType, typingOperation: EditOperationType): boolean {\n\tif (isTypingOperation(previousTypingOperation) && !isTypingOperation(typingOperation)) {\n\t\t// Always set an undo stop before non-type operations\n\t\treturn true;\n\t}\n\tif (previousTypingOperation === EditOperationType.TypingFirstSpace) {\n\t\t// `abc |d`: No undo stop\n\t\t// `abc |d`: Undo stop\n\t\treturn false;\n\t}\n\t// Insert undo stop between different operation types\n\treturn normalizeOperationType(previousTypingOperation) !== normalizeOperationType(typingOperation);\n}\n\nfunction normalizeOperationType(type: EditOperationType): EditOperationType | 'space' {\n\treturn (type === EditOperationType.TypingConsecutiveSpace || type === EditOperationType.TypingFirstSpace)\n\t\t? 'space'\n\t\t: type;\n}\n\nfunction isTypingOperation(type: EditOperationType): boolean {\n\treturn type === EditOperationType.TypingOther\n\t\t|| type === EditOperationType.TypingFirstSpace\n\t\t|| type === EditOperationType.TypingConsecutiveSpace;\n}\n\nfunction isAutoClosingOvertype(config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): boolean {\n\tif (config.autoClosingOvertype === 'never') {\n\t\treturn false;\n\t}\n\tif (!config.autoClosingPairs.autoClosingPairsCloseSingleChar.has(ch)) {\n\t\treturn false;\n\t}\n\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\tconst selection = selections[i];\n\t\tif (!selection.isEmpty()) {\n\t\t\treturn false;\n\t\t}\n\t\tconst position = selection.getPosition();\n\t\tconst lineText = model.getLineContent(position.lineNumber);\n\t\tconst afterCharacter = lineText.charAt(position.column - 1);\n\t\tif (afterCharacter !== ch) {\n\t\t\treturn false;\n\t\t}\n\t\t// Do not over-type quotes after a backslash\n\t\tconst chIsQuote = isQuote(ch);\n\t\tconst beforeCharacter = position.column > 2 ? lineText.charCodeAt(position.column - 2) : CharCode.Null;\n\t\tif (beforeCharacter === CharCode.Backslash && chIsQuote) {\n\t\t\treturn false;\n\t\t}\n\t\t// Must over-type a closing character typed by the editor\n\t\tif (config.autoClosingOvertype === 'auto') {\n\t\t\tlet found = false;\n\t\t\tfor (let j = 0, lenJ = autoClosedCharacters.length; j < lenJ; j++) {\n\t\t\t\tconst autoClosedCharacter = autoClosedCharacters[j];\n\t\t\t\tif (position.lineNumber === autoClosedCharacter.startLineNumber && position.column === autoClosedCharacter.startColumn) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction typeCommand(range: Range, text: string, keepPosition: boolean): ICommand {\n\tif (keepPosition) {\n\t\treturn new ReplaceCommandWithoutChangingPosition(range, text, true);\n\t} else {\n\t\treturn new ReplaceCommand(range, text, true);\n\t}\n}\n\nexport function shiftIndent(config: CursorConfiguration, indentation: string, count?: number): string {\n\tcount = count || 1;\n\treturn ShiftCommand.shiftIndent(indentation, indentation.length + count, config.tabSize, config.indentSize, config.insertSpaces);\n}\n\nexport function unshiftIndent(config: CursorConfiguration, indentation: string, count?: number): string {\n\tcount = count || 1;\n\treturn ShiftCommand.unshiftIndent(indentation, indentation.length + count, config.tabSize, config.indentSize, config.insertSpaces);\n}\n\nexport function shouldSurroundChar(config: CursorConfiguration, ch: string): boolean {\n\tif (isQuote(ch)) {\n\t\treturn (config.autoSurround === 'quotes' || config.autoSurround === 'languageDefined');\n\t} else {\n\t\t// Character is a bracket\n\t\treturn (config.autoSurround === 'brackets' || config.autoSurround === 'languageDefined');\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { CharCode } from '../../../base/common/charCode.js';\nimport { onUnexpectedError } from '../../../base/common/errors.js';\nimport * as strings from '../../../base/common/strings.js';\nimport { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, ReplaceOvertypeCommandOnCompositionEnd } from '../commands/replaceCommand.js';\nimport { ShiftCommand } from '../commands/shiftCommand.js';\nimport { SurroundSelectionCommand } from '../commands/surroundSelectionCommand.js';\nimport { CursorConfiguration, EditOperationResult, EditOperationType, ICursorSimpleModel, isQuote } from '../cursorCommon.js';\nimport { WordCharacterClass, getMapForWordSeparators } from '../core/wordCharacterClassifier.js';\nimport { Range } from '../core/range.js';\nimport { Selection } from '../core/selection.js';\nimport { Position } from '../core/position.js';\nimport { ICommand, ICursorStateComputerData, IEditOperationBuilder } from '../editorCommon.js';\nimport { ITextModel } from '../model.js';\nimport { EnterAction, IndentAction, StandardAutoClosingPairConditional } from '../languages/languageConfiguration.js';\nimport { getIndentationAtPosition } from '../languages/languageConfigurationRegistry.js';\nimport { IElectricAction } from '../languages/supports/electricCharacter.js';\nimport { EditorAutoClosingStrategy, EditorAutoIndentStrategy } from '../config/editorOptions.js';\nimport { createScopedLineTokens } from '../languages/supports.js';\nimport { getIndentActionForType, getIndentForEnter, getInheritIndentForLine } from '../languages/autoIndent.js';\nimport { getEnterAction } from '../languages/enterAction.js';\nimport { CompositionOutcome } from './cursorTypeOperations.js';\n\nexport class AutoIndentOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition && this._isAutoIndentType(config, model, selections)) {\n\t\t\tconst indentationForSelections: { selection: Selection; indentation: string }[] = [];\n\t\t\tfor (const selection of selections) {\n\t\t\t\tconst indentation = this._findActualIndentationForSelection(config, model, selection, ch);\n\t\t\t\tif (indentation === null) {\n\t\t\t\t\t// Auto indentation failed\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tindentationForSelections.push({ selection, indentation });\n\t\t\t}\n\t\t\tconst autoClosingPairClose = AutoClosingOpenCharTypeOperation.getAutoClosingPairClose(config, model, selections, ch, false);\n\t\t\treturn this._getIndentationAndAutoClosingPairEdits(config, model, indentationForSelections, ch, autoClosingPairClose);\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _isAutoIndentType(config: CursorConfiguration, model: ITextModel, selections: Selection[]): boolean {\n\t\tif (config.autoIndent < EditorAutoIndentStrategy.Full) {\n\t\t\treturn false;\n\t\t}\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tif (!model.tokenization.isCheapToTokenize(selections[i].getEndPosition().lineNumber)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate static _findActualIndentationForSelection(config: CursorConfiguration, model: ITextModel, selection: Selection, ch: string): string | null {\n\t\tconst actualIndentation = getIndentActionForType(config, model, selection, ch, {\n\t\t\tshiftIndent: (indentation) => {\n\t\t\t\treturn shiftIndent(config, indentation);\n\t\t\t},\n\t\t\tunshiftIndent: (indentation) => {\n\t\t\t\treturn unshiftIndent(config, indentation);\n\t\t\t},\n\t\t}, config.languageConfigurationService);\n\n\t\tif (actualIndentation === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst currentIndentation = getIndentationAtPosition(model, selection.startLineNumber, selection.startColumn);\n\t\tif (actualIndentation === config.normalizeIndentation(currentIndentation)) {\n\t\t\treturn null;\n\t\t}\n\t\treturn actualIndentation;\n\t}\n\n\tprivate static _getIndentationAndAutoClosingPairEdits(config: CursorConfiguration, model: ITextModel, indentationForSelections: { selection: Selection; indentation: string }[], ch: string, autoClosingPairClose: string | null): EditOperationResult {\n\t\tconst commands: ICommand[] = indentationForSelections.map(({ selection, indentation }) => {\n\t\t\tif (autoClosingPairClose !== null) {\n\t\t\t\t// Apply both auto closing pair edits and auto indentation edits\n\t\t\t\tconst indentationEdit = this._getEditFromIndentationAndSelection(config, model, indentation, selection, ch, false);\n\t\t\t\treturn new TypeWithIndentationAndAutoClosingCommand(indentationEdit, selection, ch, autoClosingPairClose);\n\t\t\t} else {\n\t\t\t\t// Apply only auto indentation edits\n\t\t\t\tconst indentationEdit = this._getEditFromIndentationAndSelection(config, model, indentation, selection, ch, true);\n\t\t\t\treturn typeCommand(indentationEdit.range, indentationEdit.text, false);\n\t\t\t}\n\t\t});\n\t\tconst editOptions = { shouldPushStackElementBefore: true, shouldPushStackElementAfter: false };\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, editOptions);\n\t}\n\n\tprivate static _getEditFromIndentationAndSelection(config: CursorConfiguration, model: ITextModel, indentation: string, selection: Selection, ch: string, includeChInEdit: boolean = true): { range: Range; text: string } {\n\t\tconst startLineNumber = selection.startLineNumber;\n\t\tconst firstNonWhitespaceColumn = model.getLineFirstNonWhitespaceColumn(startLineNumber);\n\t\tlet text: string = config.normalizeIndentation(indentation);\n\t\tif (firstNonWhitespaceColumn !== 0) {\n\t\t\tconst startLine = model.getLineContent(startLineNumber);\n\t\t\ttext += startLine.substring(firstNonWhitespaceColumn - 1, selection.startColumn - 1);\n\t\t}\n\t\ttext += includeChInEdit ? ch : '';\n\t\tconst range = new Range(startLineNumber, 1, selection.endLineNumber, selection.endColumn);\n\t\treturn { range, text };\n\t}\n}\n\nexport class AutoClosingOvertypeOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult | undefined {\n\t\tif (isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) {\n\t\t\treturn this._runAutoClosingOvertype(prevEditOperationType, selections, ch);\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _runAutoClosingOvertype(prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tconst position = selection.getPosition();\n\t\t\tconst typeSelection = new Range(position.lineNumber, position.column, position.lineNumber, position.column + 1);\n\t\t\tcommands[i] = new ReplaceCommand(typeSelection, ch);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, EditOperationType.TypingOther),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class AutoClosingOvertypeWithInterceptorsOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult | undefined {\n\t\tif (isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) {\n\t\t\t// Unfortunately, the close character is at this point \"doubled\", so we need to delete it...\n\t\t\tconst commands = selections.map(s => new ReplaceCommand(new Range(s.positionLineNumber, s.positionColumn, s.positionLineNumber, s.positionColumn + 1), '', false));\n\t\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\t\tshouldPushStackElementBefore: true,\n\t\t\t\tshouldPushStackElementAfter: false\n\t\t\t});\n\t\t}\n\t\treturn;\n\t}\n}\n\nexport class AutoClosingOpenCharTypeOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, chIsAlreadyTyped: boolean, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition) {\n\t\t\tconst autoClosingPairClose = this.getAutoClosingPairClose(config, model, selections, ch, chIsAlreadyTyped);\n\t\t\tif (autoClosingPairClose !== null) {\n\t\t\t\treturn this._runAutoClosingOpenCharType(selections, ch, chIsAlreadyTyped, autoClosingPairClose);\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _runAutoClosingOpenCharType(selections: Selection[], ch: string, chIsAlreadyTyped: boolean, autoClosingPairClose: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tcommands[i] = new TypeWithAutoClosingCommand(selection, ch, !chIsAlreadyTyped, autoClosingPairClose);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n\n\tpublic static getAutoClosingPairClose(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, chIsAlreadyTyped: boolean): string | null {\n\t\tfor (const selection of selections) {\n\t\t\tif (!selection.isEmpty()) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\t// This method is called both when typing (regularly) and when composition ends\n\t\t// This means that we need to work with a text buffer where sometimes `ch` is not\n\t\t// there (it is being typed right now) or with a text buffer where `ch` has already been typed\n\t\t//\n\t\t// In order to avoid adding checks for `chIsAlreadyTyped` in all places, we will work\n\t\t// with two conceptual positions, the position before `ch` and the position after `ch`\n\t\t//\n\t\tconst positions: { lineNumber: number; beforeColumn: number; afterColumn: number }[] = selections.map((s) => {\n\t\t\tconst position = s.getPosition();\n\t\t\tif (chIsAlreadyTyped) {\n\t\t\t\treturn { lineNumber: position.lineNumber, beforeColumn: position.column - ch.length, afterColumn: position.column };\n\t\t\t} else {\n\t\t\t\treturn { lineNumber: position.lineNumber, beforeColumn: position.column, afterColumn: position.column };\n\t\t\t}\n\t\t});\n\t\t// Find the longest auto-closing open pair in case of multiple ending in `ch`\n\t\t// e.g. when having [f\",\"] and [\",\"], it picks [f\",\"] if the character before is f\n\t\tconst pair = this._findAutoClosingPairOpen(config, model, positions.map(p => new Position(p.lineNumber, p.beforeColumn)), ch);\n\t\tif (!pair) {\n\t\t\treturn null;\n\t\t}\n\t\tlet autoCloseConfig: EditorAutoClosingStrategy;\n\t\tlet shouldAutoCloseBefore: (ch: string) => boolean;\n\n\t\tconst chIsQuote = isQuote(ch);\n\t\tif (chIsQuote) {\n\t\t\tautoCloseConfig = config.autoClosingQuotes;\n\t\t\tshouldAutoCloseBefore = config.shouldAutoCloseBefore.quote;\n\t\t} else {\n\t\t\tconst pairIsForComments = config.blockCommentStartToken ? pair.open.includes(config.blockCommentStartToken) : false;\n\t\t\tif (pairIsForComments) {\n\t\t\t\tautoCloseConfig = config.autoClosingComments;\n\t\t\t\tshouldAutoCloseBefore = config.shouldAutoCloseBefore.comment;\n\t\t\t} else {\n\t\t\t\tautoCloseConfig = config.autoClosingBrackets;\n\t\t\t\tshouldAutoCloseBefore = config.shouldAutoCloseBefore.bracket;\n\t\t\t}\n\t\t}\n\t\tif (autoCloseConfig === 'never') {\n\t\t\treturn null;\n\t\t}\n\t\t// Sometimes, it is possible to have two auto-closing pairs that have a containment relationship\n\t\t// e.g. when having [(,)] and [(*,*)]\n\t\t// - when typing (, the resulting state is (|)\n\t\t// - when typing *, the desired resulting state is (*|*), not (*|*))\n\t\tconst containedPair = this._findContainedAutoClosingPair(config, pair);\n\t\tconst containedPairClose = containedPair ? containedPair.close : '';\n\t\tlet isContainedPairPresent = true;\n\n\t\tfor (const position of positions) {\n\t\t\tconst { lineNumber, beforeColumn, afterColumn } = position;\n\t\t\tconst lineText = model.getLineContent(lineNumber);\n\t\t\tconst lineBefore = lineText.substring(0, beforeColumn - 1);\n\t\t\tconst lineAfter = lineText.substring(afterColumn - 1);\n\n\t\t\tif (!lineAfter.startsWith(containedPairClose)) {\n\t\t\t\tisContainedPairPresent = false;\n\t\t\t}\n\t\t\t// Only consider auto closing the pair if an allowed character follows or if another autoclosed pair closing brace follows\n\t\t\tif (lineAfter.length > 0) {\n\t\t\t\tconst characterAfter = lineAfter.charAt(0);\n\t\t\t\tconst isBeforeCloseBrace = this._isBeforeClosingBrace(config, lineAfter);\n\t\t\t\tif (!isBeforeCloseBrace && !shouldAutoCloseBefore(characterAfter)) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Do not auto-close ' or \" after a word character\n\t\t\tif (pair.open.length === 1 && (ch === '\\'' || ch === '\"') && autoCloseConfig !== 'always') {\n\t\t\t\tconst wordSeparators = getMapForWordSeparators(config.wordSeparators, []);\n\t\t\t\tif (lineBefore.length > 0) {\n\t\t\t\t\tconst characterBefore = lineBefore.charCodeAt(lineBefore.length - 1);\n\t\t\t\t\tif (wordSeparators.get(characterBefore) === WordCharacterClass.Regular) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!model.tokenization.isCheapToTokenize(lineNumber)) {\n\t\t\t\t// Do not force tokenization\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tmodel.tokenization.forceTokenization(lineNumber);\n\t\t\tconst lineTokens = model.tokenization.getLineTokens(lineNumber);\n\t\t\tconst scopedLineTokens = createScopedLineTokens(lineTokens, beforeColumn - 1);\n\t\t\tif (!pair.shouldAutoClose(scopedLineTokens, beforeColumn - scopedLineTokens.firstCharOffset)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\t// Typing for example a quote could either start a new string, in which case auto-closing is desirable\n\t\t\t// or it could end a previously started string, in which case auto-closing is not desirable\n\t\t\t//\n\t\t\t// In certain cases, it is really not possible to look at the previous token to determine\n\t\t\t// what would happen. That's why we do something really unusual, we pretend to type a different\n\t\t\t// character and ask the tokenizer what the outcome of doing that is: after typing a neutral\n\t\t\t// character, are we in a string (i.e. the quote would most likely end a string) or not?\n\t\t\t//\n\t\t\tconst neutralCharacter = pair.findNeutralCharacter();\n\t\t\tif (neutralCharacter) {\n\t\t\t\tconst tokenType = model.tokenization.getTokenTypeIfInsertingCharacter(lineNumber, beforeColumn, neutralCharacter);\n\t\t\t\tif (!pair.isOK(tokenType)) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (isContainedPairPresent) {\n\t\t\treturn pair.close.substring(0, pair.close.length - containedPairClose.length);\n\t\t} else {\n\t\t\treturn pair.close;\n\t\t}\n\t}\n\n\t/**\n\t * Find another auto-closing pair that is contained by the one passed in.\n\t *\n\t * e.g. when having [(,)] and [(*,*)] as auto-closing pairs\n\t * this method will find [(,)] as a containment pair for [(*,*)]\n\t */\n\tprivate static _findContainedAutoClosingPair(config: CursorConfiguration, pair: StandardAutoClosingPairConditional): StandardAutoClosingPairConditional | null {\n\t\tif (pair.open.length <= 1) {\n\t\t\treturn null;\n\t\t}\n\t\tconst lastChar = pair.close.charAt(pair.close.length - 1);\n\t\t// get candidates with the same last character as close\n\t\tconst candidates = config.autoClosingPairs.autoClosingPairsCloseByEnd.get(lastChar) || [];\n\t\tlet result: StandardAutoClosingPairConditional | null = null;\n\t\tfor (const candidate of candidates) {\n\t\t\tif (candidate.open !== pair.open && pair.open.includes(candidate.open) && pair.close.endsWith(candidate.close)) {\n\t\t\t\tif (!result || candidate.open.length > result.open.length) {\n\t\t\t\t\tresult = candidate;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Determine if typing `ch` at all `positions` in the `model` results in an\n\t * auto closing open sequence being typed.\n\t *\n\t * Auto closing open sequences can consist of multiple characters, which\n\t * can lead to ambiguities. In such a case, the longest auto-closing open\n\t * sequence is returned.\n\t */\n\tprivate static _findAutoClosingPairOpen(config: CursorConfiguration, model: ITextModel, positions: Position[], ch: string): StandardAutoClosingPairConditional | null {\n\t\tconst candidates = config.autoClosingPairs.autoClosingPairsOpenByEnd.get(ch);\n\t\tif (!candidates) {\n\t\t\treturn null;\n\t\t}\n\t\t// Determine which auto-closing pair it is\n\t\tlet result: StandardAutoClosingPairConditional | null = null;\n\t\tfor (const candidate of candidates) {\n\t\t\tif (result === null || candidate.open.length > result.open.length) {\n\t\t\t\tlet candidateIsMatch = true;\n\t\t\t\tfor (const position of positions) {\n\t\t\t\t\tconst relevantText = model.getValueInRange(new Range(position.lineNumber, position.column - candidate.open.length + 1, position.lineNumber, position.column));\n\t\t\t\t\tif (relevantText + ch !== candidate.open) {\n\t\t\t\t\t\tcandidateIsMatch = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (candidateIsMatch) {\n\t\t\t\t\tresult = candidate;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate static _isBeforeClosingBrace(config: CursorConfiguration, lineAfter: string) {\n\t\t// If the start of lineAfter can be interpretted as both a starting or ending brace, default to returning false\n\t\tconst nextChar = lineAfter.charAt(0);\n\t\tconst potentialStartingBraces = config.autoClosingPairs.autoClosingPairsOpenByStart.get(nextChar) || [];\n\t\tconst potentialClosingBraces = config.autoClosingPairs.autoClosingPairsCloseByStart.get(nextChar) || [];\n\n\t\tconst isBeforeStartingBrace = potentialStartingBraces.some(x => lineAfter.startsWith(x.open));\n\t\tconst isBeforeClosingBrace = potentialClosingBraces.some(x => lineAfter.startsWith(x.close));\n\n\t\treturn !isBeforeStartingBrace && isBeforeClosingBrace;\n\t}\n}\n\nexport class CompositionEndOvertypeOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, compositions: CompositionOutcome[]): EditOperationResult | null {\n\t\tconst isOvertypeMode = config.inputMode === 'overtype';\n\t\tif (!isOvertypeMode) {\n\t\t\treturn null;\n\t\t}\n\t\tconst commands = compositions.map(composition => new ReplaceOvertypeCommandOnCompositionEnd(composition.insertedTextRange));\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class SurroundSelectionOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition && this._isSurroundSelectionType(config, model, selections, ch)) {\n\t\t\treturn this._runSurroundSelectionType(config, selections, ch);\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _runSurroundSelectionType(config: CursorConfiguration, selections: Selection[], ch: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tconst closeCharacter = config.surroundingPairs[ch];\n\t\t\tcommands[i] = new SurroundSelectionCommand(selection, ch, closeCharacter);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.Other, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: true\n\t\t});\n\t}\n\n\tprivate static _isSurroundSelectionType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean {\n\t\tif (!shouldSurroundChar(config, ch) || !config.surroundingPairs.hasOwnProperty(ch)) {\n\t\t\treturn false;\n\t\t}\n\t\tconst isTypingAQuoteCharacter = isQuote(ch);\n\t\tfor (const selection of selections) {\n\t\t\tif (selection.isEmpty()) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tlet selectionContainsOnlyWhitespace = true;\n\t\t\tfor (let lineNumber = selection.startLineNumber; lineNumber <= selection.endLineNumber; lineNumber++) {\n\t\t\t\tconst lineText = model.getLineContent(lineNumber);\n\t\t\t\tconst startIndex = (lineNumber === selection.startLineNumber ? selection.startColumn - 1 : 0);\n\t\t\t\tconst endIndex = (lineNumber === selection.endLineNumber ? selection.endColumn - 1 : lineText.length);\n\t\t\t\tconst selectedText = lineText.substring(startIndex, endIndex);\n\t\t\t\tif (/[^ \\t]/.test(selectedText)) {\n\t\t\t\t\t// this selected text contains something other than whitespace\n\t\t\t\t\tselectionContainsOnlyWhitespace = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (selectionContainsOnlyWhitespace) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (isTypingAQuoteCharacter && selection.startLineNumber === selection.endLineNumber && selection.startColumn + 1 === selection.endColumn) {\n\t\t\t\tconst selectionText = model.getValueInRange(selection);\n\t\t\t\tif (isQuote(selectionText)) {\n\t\t\t\t\t// Typing a quote character on top of another quote character\n\t\t\t\t\t// => disable surround selection type\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}\n\nexport class InterceptorElectricCharOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\t// Electric characters make sense only when dealing with a single cursor,\n\t\t// as multiple cursors typing brackets for example would interfer with bracket matching\n\t\tif (!isDoingComposition && this._isTypeInterceptorElectricChar(config, model, selections)) {\n\t\t\tconst r = this._typeInterceptorElectricChar(prevEditOperationType, config, model, selections[0], ch);\n\t\t\tif (r) {\n\t\t\t\treturn r;\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _isTypeInterceptorElectricChar(config: CursorConfiguration, model: ITextModel, selections: Selection[]) {\n\t\tif (selections.length === 1 && model.tokenization.isCheapToTokenize(selections[0].getEndPosition().lineNumber)) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate static _typeInterceptorElectricChar(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selection: Selection, ch: string): EditOperationResult | null {\n\t\tif (!config.electricChars.hasOwnProperty(ch) || !selection.isEmpty()) {\n\t\t\treturn null;\n\t\t}\n\t\tconst position = selection.getPosition();\n\t\tmodel.tokenization.forceTokenization(position.lineNumber);\n\t\tconst lineTokens = model.tokenization.getLineTokens(position.lineNumber);\n\t\tlet electricAction: IElectricAction | null;\n\t\ttry {\n\t\t\telectricAction = config.onElectricCharacter(ch, lineTokens, position.column);\n\t\t} catch (e) {\n\t\t\tonUnexpectedError(e);\n\t\t\treturn null;\n\t\t}\n\t\tif (!electricAction) {\n\t\t\treturn null;\n\t\t}\n\t\tif (electricAction.matchOpenBracket) {\n\t\t\tconst endColumn = (lineTokens.getLineContent() + ch).lastIndexOf(electricAction.matchOpenBracket) + 1;\n\t\t\tconst match = model.bracketPairs.findMatchingBracketUp(electricAction.matchOpenBracket, {\n\t\t\t\tlineNumber: position.lineNumber,\n\t\t\t\tcolumn: endColumn\n\t\t\t}, 500 /* give at most 500ms to compute */);\n\t\t\tif (match) {\n\t\t\t\tif (match.startLineNumber === position.lineNumber) {\n\t\t\t\t\t// matched something on the same line => no change in indentation\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst matchLine = model.getLineContent(match.startLineNumber);\n\t\t\t\tconst matchLineIndentation = strings.getLeadingWhitespace(matchLine);\n\t\t\t\tconst newIndentation = config.normalizeIndentation(matchLineIndentation);\n\t\t\t\tconst lineText = model.getLineContent(position.lineNumber);\n\t\t\t\tconst lineFirstNonBlankColumn = model.getLineFirstNonWhitespaceColumn(position.lineNumber) || position.column;\n\t\t\t\tconst prefix = lineText.substring(lineFirstNonBlankColumn - 1, position.column - 1);\n\t\t\t\tconst typeText = newIndentation + prefix + ch;\n\t\t\t\tconst typeSelection = new Range(position.lineNumber, 1, position.lineNumber, position.column);\n\t\t\t\tconst command = new ReplaceCommand(typeSelection, typeText);\n\t\t\t\treturn new EditOperationResult(getTypingOperation(typeText, prevEditOperationType), [command], {\n\t\t\t\t\tshouldPushStackElementBefore: false,\n\t\t\t\t\tshouldPushStackElementAfter: true\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n}\n\nexport class SimpleCharacterTypeOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, prevEditOperationType: EditOperationType, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult {\n\t\t// A simple character type\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst ChosenReplaceCommand = config.inputMode === 'overtype' && !isDoingComposition ? ReplaceOvertypeCommand : ReplaceCommand;\n\t\t\tcommands[i] = new ChosenReplaceCommand(selections[i], ch);\n\t\t}\n\n\t\tconst opType = getTypingOperation(ch, prevEditOperationType);\n\t\treturn new EditOperationResult(opType, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, opType),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class EnterOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined {\n\t\tif (!isDoingComposition && ch === '\\n') {\n\t\t\tconst commands: ICommand[] = [];\n\t\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\t\tcommands[i] = this._enter(config, model, false, selections[i]);\n\t\t\t}\n\t\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\t\tshouldPushStackElementBefore: true,\n\t\t\t\tshouldPushStackElementAfter: false,\n\t\t\t});\n\t\t}\n\t\treturn;\n\t}\n\n\tprivate static _enter(config: CursorConfiguration, model: ITextModel, keepPosition: boolean, range: Range): ICommand {\n\t\tif (config.autoIndent === EditorAutoIndentStrategy.None) {\n\t\t\treturn typeCommand(range, '\\n', keepPosition);\n\t\t}\n\t\tif (!model.tokenization.isCheapToTokenize(range.getStartPosition().lineNumber) || config.autoIndent === EditorAutoIndentStrategy.Keep) {\n\t\t\tconst lineText = model.getLineContent(range.startLineNumber);\n\t\t\tconst indentation = strings.getLeadingWhitespace(lineText).substring(0, range.startColumn - 1);\n\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(indentation), keepPosition);\n\t\t}\n\t\tconst r = getEnterAction(config.autoIndent, model, range, config.languageConfigurationService);\n\t\tif (r) {\n\t\t\tif (r.indentAction === IndentAction.None) {\n\t\t\t\t// Nothing special\n\t\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(r.indentation + r.appendText), keepPosition);\n\n\t\t\t} else if (r.indentAction === IndentAction.Indent) {\n\t\t\t\t// Indent once\n\t\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(r.indentation + r.appendText), keepPosition);\n\n\t\t\t} else if (r.indentAction === IndentAction.IndentOutdent) {\n\t\t\t\t// Ultra special\n\t\t\t\tconst normalIndent = config.normalizeIndentation(r.indentation);\n\t\t\t\tconst increasedIndent = config.normalizeIndentation(r.indentation + r.appendText);\n\t\t\t\tconst typeText = '\\n' + increasedIndent + '\\n' + normalIndent;\n\t\t\t\tif (keepPosition) {\n\t\t\t\t\treturn new ReplaceCommandWithoutChangingPosition(range, typeText, true);\n\t\t\t\t} else {\n\t\t\t\t\treturn new ReplaceCommandWithOffsetCursorState(range, typeText, -1, increasedIndent.length - normalIndent.length, true);\n\t\t\t\t}\n\t\t\t} else if (r.indentAction === IndentAction.Outdent) {\n\t\t\t\tconst actualIndentation = unshiftIndent(config, r.indentation);\n\t\t\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(actualIndentation + r.appendText), keepPosition);\n\t\t\t}\n\t\t}\n\n\t\tconst lineText = model.getLineContent(range.startLineNumber);\n\t\tconst indentation = strings.getLeadingWhitespace(lineText).substring(0, range.startColumn - 1);\n\n\t\tif (config.autoIndent >= EditorAutoIndentStrategy.Full) {\n\t\t\tconst ir = getIndentForEnter(config.autoIndent, model, range, {\n\t\t\t\tunshiftIndent: (indent) => {\n\t\t\t\t\treturn unshiftIndent(config, indent);\n\t\t\t\t},\n\t\t\t\tshiftIndent: (indent) => {\n\t\t\t\t\treturn shiftIndent(config, indent);\n\t\t\t\t},\n\t\t\t\tnormalizeIndentation: (indent) => {\n\t\t\t\t\treturn config.normalizeIndentation(indent);\n\t\t\t\t}\n\t\t\t}, config.languageConfigurationService);\n\n\t\t\tif (ir) {\n\t\t\t\tlet oldEndViewColumn = config.visibleColumnFromColumn(model, range.getEndPosition());\n\t\t\t\tconst oldEndColumn = range.endColumn;\n\t\t\t\tconst newLineContent = model.getLineContent(range.endLineNumber);\n\t\t\t\tconst firstNonWhitespace = strings.firstNonWhitespaceIndex(newLineContent);\n\t\t\t\tif (firstNonWhitespace >= 0) {\n\t\t\t\t\trange = range.setEndPosition(range.endLineNumber, Math.max(range.endColumn, firstNonWhitespace + 1));\n\t\t\t\t} else {\n\t\t\t\t\trange = range.setEndPosition(range.endLineNumber, model.getLineMaxColumn(range.endLineNumber));\n\t\t\t\t}\n\t\t\t\tif (keepPosition) {\n\t\t\t\t\treturn new ReplaceCommandWithoutChangingPosition(range, '\\n' + config.normalizeIndentation(ir.afterEnter), true);\n\t\t\t\t} else {\n\t\t\t\t\tlet offset = 0;\n\t\t\t\t\tif (oldEndColumn <= firstNonWhitespace + 1) {\n\t\t\t\t\t\tif (!config.insertSpaces) {\n\t\t\t\t\t\t\toldEndViewColumn = Math.ceil(oldEndViewColumn / config.indentSize);\n\t\t\t\t\t\t}\n\t\t\t\t\t\toffset = Math.min(oldEndViewColumn + 1 - config.normalizeIndentation(ir.afterEnter).length - 1, 0);\n\t\t\t\t\t}\n\t\t\t\t\treturn new ReplaceCommandWithOffsetCursorState(range, '\\n' + config.normalizeIndentation(ir.afterEnter), 0, offset, true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn typeCommand(range, '\\n' + config.normalizeIndentation(indentation), keepPosition);\n\t}\n\n\n\tpublic static lineInsertBefore(config: CursorConfiguration, model: ITextModel | null, selections: Selection[] | null): ICommand[] {\n\t\tif (model === null || selections === null) {\n\t\t\treturn [];\n\t\t}\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tlet lineNumber = selections[i].positionLineNumber;\n\t\t\tif (lineNumber === 1) {\n\t\t\t\tcommands[i] = new ReplaceCommandWithoutChangingPosition(new Range(1, 1, 1, 1), '\\n');\n\t\t\t} else {\n\t\t\t\tlineNumber--;\n\t\t\t\tconst column = model.getLineMaxColumn(lineNumber);\n\n\t\t\t\tcommands[i] = this._enter(config, model, false, new Range(lineNumber, column, lineNumber, column));\n\t\t\t}\n\t\t}\n\t\treturn commands;\n\t}\n\n\tpublic static lineInsertAfter(config: CursorConfiguration, model: ITextModel | null, selections: Selection[] | null): ICommand[] {\n\t\tif (model === null || selections === null) {\n\t\t\treturn [];\n\t\t}\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst lineNumber = selections[i].positionLineNumber;\n\t\t\tconst column = model.getLineMaxColumn(lineNumber);\n\t\t\tcommands[i] = this._enter(config, model, false, new Range(lineNumber, column, lineNumber, column));\n\t\t}\n\t\treturn commands;\n\t}\n\n\tpublic static lineBreakInsert(config: CursorConfiguration, model: ITextModel, selections: Selection[]): ICommand[] {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tcommands[i] = this._enter(config, model, true, selections[i]);\n\t\t}\n\t\treturn commands;\n\t}\n}\n\nexport class PasteOperation {\n\n\tpublic static getEdits(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]) {\n\t\tconst distributedPaste = this._distributePasteToCursors(config, selections, text, pasteOnNewLine, multicursorText);\n\t\tif (distributedPaste) {\n\t\t\tselections = selections.sort(Range.compareRangesUsingStarts);\n\t\t\treturn this._distributedPaste(config, model, selections, distributedPaste);\n\t\t} else {\n\t\t\treturn this._simplePaste(config, model, selections, text, pasteOnNewLine);\n\t\t}\n\t}\n\n\tprivate static _distributePasteToCursors(config: CursorConfiguration, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]): string[] | null {\n\t\tif (selections.length === 1) {\n\t\t\treturn null;\n\t\t}\n\t\tif (multicursorText && multicursorText.length === selections.length) {\n\t\t\treturn multicursorText;\n\t\t}\n\t\tif (pasteOnNewLine) {\n\t\t\treturn null;\n\t\t}\n\t\tif (config.multiCursorPaste === 'spread') {\n\t\t\t// Try to spread the pasted text in case the line count matches the cursor count\n\t\t\t// Remove trailing \\n if present\n\t\t\tif (text.charCodeAt(text.length - 1) === CharCode.LineFeed) {\n\t\t\t\ttext = text.substring(0, text.length - 1);\n\t\t\t}\n\t\t\t// Remove trailing \\r if present\n\t\t\tif (text.charCodeAt(text.length - 1) === CharCode.CarriageReturn) {\n\t\t\t\ttext = text.substring(0, text.length - 1);\n\t\t\t}\n\t\t\tconst lines = strings.splitLines(text);\n\t\t\tif (lines.length === selections.length) {\n\t\t\t\treturn lines;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate static _distributedPaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string[]): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst shouldOvertypeOnPaste = config.overtypeOnPaste && config.inputMode === 'overtype';\n\t\t\tconst ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommand : ReplaceCommand;\n\t\t\tcommands[i] = new ChosenReplaceCommand(selections[i], text[i]);\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.Other, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: true\n\t\t});\n\t}\n\n\tprivate static _simplePaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tconst position = selection.getPosition();\n\t\t\tif (pasteOnNewLine && !selection.isEmpty()) {\n\t\t\t\tpasteOnNewLine = false;\n\t\t\t}\n\t\t\tif (pasteOnNewLine && text.indexOf('\\n') !== text.length - 1) {\n\t\t\t\tpasteOnNewLine = false;\n\t\t\t}\n\t\t\tif (pasteOnNewLine) {\n\t\t\t\t// Paste entire line at the beginning of line\n\t\t\t\tconst typeSelection = new Range(position.lineNumber, 1, position.lineNumber, 1);\n\t\t\t\tcommands[i] = new ReplaceCommandThatPreservesSelection(typeSelection, text, selection, true);\n\t\t\t} else {\n\t\t\t\tconst shouldOvertypeOnPaste = config.overtypeOnPaste && config.inputMode === 'overtype';\n\t\t\t\tconst ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommand : ReplaceCommand;\n\t\t\t\tcommands[i] = new ChosenReplaceCommand(selection, text);\n\t\t\t}\n\t\t}\n\t\treturn new EditOperationResult(EditOperationType.Other, commands, {\n\t\t\tshouldPushStackElementBefore: true,\n\t\t\tshouldPushStackElementAfter: true\n\t\t});\n\t}\n}\n\nexport class CompositionOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number) {\n\t\tconst commands = selections.map(selection => this._compositionType(model, selection, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta));\n\t\treturn new EditOperationResult(EditOperationType.TypingOther, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, EditOperationType.TypingOther),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n\n\tprivate static _compositionType(model: ITextModel, selection: Selection, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number): ICommand | null {\n\t\tif (!selection.isEmpty()) {\n\t\t\t// looks like https://github.com/microsoft/vscode/issues/2773\n\t\t\t// where a cursor operation occurred before a canceled composition\n\t\t\t// => ignore composition\n\t\t\treturn null;\n\t\t}\n\t\tconst pos = selection.getPosition();\n\t\tconst startColumn = Math.max(1, pos.column - replacePrevCharCnt);\n\t\tconst endColumn = Math.min(model.getLineMaxColumn(pos.lineNumber), pos.column + replaceNextCharCnt);\n\t\tconst range = new Range(pos.lineNumber, startColumn, pos.lineNumber, endColumn);\n\t\treturn new ReplaceCommandWithOffsetCursorState(range, text, 0, positionDelta);\n\t}\n}\n\nexport class TypeWithoutInterceptorsOperation {\n\n\tpublic static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], str: string): EditOperationResult {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tcommands[i] = new ReplaceCommand(selections[i], str);\n\t\t}\n\t\tconst opType = getTypingOperation(str, prevEditOperationType);\n\t\treturn new EditOperationResult(opType, commands, {\n\t\t\tshouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, opType),\n\t\t\tshouldPushStackElementAfter: false\n\t\t});\n\t}\n}\n\nexport class TabOperation {\n\n\tpublic static getCommands(config: CursorConfiguration, model: ITextModel, selections: Selection[]) {\n\t\tconst commands: ICommand[] = [];\n\t\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\t\tconst selection = selections[i];\n\t\t\tif (selection.isEmpty()) {\n\t\t\t\tconst lineText = model.getLineContent(selection.startLineNumber);\n\t\t\t\tif (/^\\s*$/.test(lineText) && model.tokenization.isCheapToTokenize(selection.startLineNumber)) {\n\t\t\t\t\tlet goodIndent = this._goodIndentForLine(config, model, selection.startLineNumber);\n\t\t\t\t\tgoodIndent = goodIndent || '\\t';\n\t\t\t\t\tconst possibleTypeText = config.normalizeIndentation(goodIndent);\n\t\t\t\t\tif (!lineText.startsWith(possibleTypeText)) {\n\t\t\t\t\t\tcommands[i] = new ReplaceCommand(new Range(selection.startLineNumber, 1, selection.startLineNumber, lineText.length + 1), possibleTypeText, true);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcommands[i] = this._replaceJumpToNextIndent(config, model, selection, true);\n\t\t\t} else {\n\t\t\t\tif (selection.startLineNumber === selection.endLineNumber) {\n\t\t\t\t\tconst lineMaxColumn = model.getLineMaxColumn(selection.startLineNumber);\n\t\t\t\t\tif (selection.startColumn !== 1 || selection.endColumn !== lineMaxColumn) {\n\t\t\t\t\t\t// This is a single line selection that is not the entire line\n\t\t\t\t\t\tcommands[i] = this._replaceJumpToNextIndent(config, model, selection, false);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcommands[i] = new ShiftCommand(selection, {\n\t\t\t\t\tisUnshift: false,\n\t\t\t\t\ttabSize: config.tabSize,\n\t\t\t\t\tindentSize: config.indentSize,\n\t\t\t\t\tinsertSpaces: config.insertSpaces,\n\t\t\t\t\tuseTabStops: config.useTabStops,\n\t\t\t\t\tautoIndent: config.autoIndent\n\t\t\t\t}, config.languageConfigurationService);\n\t\t\t}\n\t\t}\n\t\treturn commands;\n\t}\n\n\tprivate static _goodIndentForLine(config: CursorConfiguration, model: ITextModel, lineNumber: number): string | null {\n\t\tlet action: IndentAction | EnterAction | null = null;\n\t\tlet indentation: string = '';\n\t\tconst expectedIndentAction = getInheritIndentForLine(config.autoIndent, model, lineNumber, false, config.languageConfigurationService);\n\t\tif (expectedIndentAction) {\n\t\t\taction = expectedIndentAction.action;\n\t\t\tindentation = expectedIndentAction.indentation;\n\t\t} else if (lineNumber > 1) {\n\t\t\tlet lastLineNumber: number;\n\t\t\tfor (lastLineNumber = lineNumber - 1; lastLineNumber >= 1; lastLineNumber--) {\n\t\t\t\tconst lineText = model.getLineContent(lastLineNumber);\n\t\t\t\tconst nonWhitespaceIdx = strings.lastNonWhitespaceIndex(lineText);\n\t\t\t\tif (nonWhitespaceIdx >= 0) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (lastLineNumber < 1) {\n\t\t\t\t// No previous line with content found\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst maxColumn = model.getLineMaxColumn(lastLineNumber);\n\t\t\tconst expectedEnterAction = getEnterAction(config.autoIndent, model, new Range(lastLineNumber, maxColumn, lastLineNumber, maxColumn), config.languageConfigurationService);\n\t\t\tif (expectedEnterAction) {\n\t\t\t\tindentation = expectedEnterAction.indentation + expectedEnterAction.appendText;\n\t\t\t}\n\t\t}\n\t\tif (action) {\n\t\t\tif (action === IndentAction.Indent) {\n\t\t\t\tindentation = shiftIndent(config, indentation);\n\t\t\t}\n\t\t\tif (action === IndentAction.Outdent) {\n\t\t\t\tindentation = unshiftIndent(config, indentation);\n\t\t\t}\n\t\t\tindentation = config.normalizeIndentation(indentation);\n\t\t}\n\t\tif (!indentation) {\n\t\t\treturn null;\n\t\t}\n\t\treturn indentation;\n\t}\n\n\tprivate static _replaceJumpToNextIndent(config: CursorConfiguration, model: ICursorSimpleModel, selection: Selection, insertsAutoWhitespace: boolean): ReplaceCommand {\n\t\tlet typeText = '';\n\t\tconst position = selection.getStartPosition();\n\t\tif (config.insertSpaces) {\n\t\t\tconst visibleColumnFromColumn = config.visibleColumnFromColumn(model, position);\n\t\t\tconst indentSize = config.indentSize;\n\t\t\tconst spacesCnt = indentSize - (visibleColumnFromColumn % indentSize);\n\t\t\tfor (let i = 0; i < spacesCnt; i++) {\n\t\t\t\ttypeText += ' ';\n\t\t\t}\n\t\t} else {\n\t\t\ttypeText = '\\t';\n\t\t}\n\t\treturn new ReplaceCommand(selection, typeText, insertsAutoWhitespace);\n\t}\n}\n\nexport class BaseTypeWithAutoClosingCommand extends ReplaceCommandWithOffsetCursorState {\n\n\tprivate readonly _openCharacter: string;\n\tprivate readonly _closeCharacter: string;\n\tpublic closeCharacterRange: Range | null;\n\tpublic enclosingRange: Range | null;\n\n\tconstructor(selection: Selection, text: string, lineNumberDeltaOffset: number, columnDeltaOffset: number, openCharacter: string, closeCharacter: string) {\n\t\tsuper(selection, text, lineNumberDeltaOffset, columnDeltaOffset);\n\t\tthis._openCharacter = openCharacter;\n\t\tthis._closeCharacter = closeCharacter;\n\t\tthis.closeCharacterRange = null;\n\t\tthis.enclosingRange = null;\n\t}\n\n\tprotected _computeCursorStateWithRange(model: ITextModel, range: Range, helper: ICursorStateComputerData): Selection {\n\t\tthis.closeCharacterRange = new Range(range.startLineNumber, range.endColumn - this._closeCharacter.length, range.endLineNumber, range.endColumn);\n\t\tthis.enclosingRange = new Range(range.startLineNumber, range.endColumn - this._openCharacter.length - this._closeCharacter.length, range.endLineNumber, range.endColumn);\n\t\treturn super.computeCursorState(model, helper);\n\t}\n}\n\nclass TypeWithAutoClosingCommand extends BaseTypeWithAutoClosingCommand {\n\n\tconstructor(selection: Selection, openCharacter: string, insertOpenCharacter: boolean, closeCharacter: string) {\n\t\tconst text = (insertOpenCharacter ? openCharacter : '') + closeCharacter;\n\t\tconst lineNumberDeltaOffset = 0;\n\t\tconst columnDeltaOffset = -closeCharacter.length;\n\t\tsuper(selection, text, lineNumberDeltaOffset, columnDeltaOffset, openCharacter, closeCharacter);\n\t}\n\n\tpublic override computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {\n\t\tconst inverseEditOperations = helper.getInverseEditOperations();\n\t\tconst range = inverseEditOperations[0].range;\n\t\treturn this._computeCursorStateWithRange(model, range, helper);\n\t}\n}\n\nclass TypeWithIndentationAndAutoClosingCommand extends BaseTypeWithAutoClosingCommand {\n\n\tprivate readonly _autoIndentationEdit: { range: Range; text: string };\n\tprivate readonly _autoClosingEdit: { range: Range; text: string };\n\n\tconstructor(autoIndentationEdit: { range: Range; text: string }, selection: Selection, openCharacter: string, closeCharacter: string) {\n\t\tconst text = openCharacter + closeCharacter;\n\t\tconst lineNumberDeltaOffset = 0;\n\t\tconst columnDeltaOffset = openCharacter.length;\n\t\tsuper(selection, text, lineNumberDeltaOffset, columnDeltaOffset, openCharacter, closeCharacter);\n\t\tthis._autoIndentationEdit = autoIndentationEdit;\n\t\tthis._autoClosingEdit = { range: selection, text };\n\t}\n\n\tpublic override getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {\n\t\tbuilder.addTrackedEditOperation(this._autoIndentationEdit.range, this._autoIndentationEdit.text);\n\t\tbuilder.addTrackedEditOperation(this._autoClosingEdit.range, this._autoClosingEdit.text);\n\t}\n\n\tpublic override computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {\n\t\tconst inverseEditOperations = helper.getInverseEditOperations();\n\t\tif (inverseEditOperations.length !== 2) {\n\t\t\tthrow new Error('There should be two inverse edit operations!');\n\t\t}\n\t\tconst range1 = inverseEditOperations[0].range;\n\t\tconst range2 = inverseEditOperations[1].range;\n\t\tconst range = range1.plusRange(range2);\n\t\treturn this._computeCursorStateWithRange(model, range, helper);\n\t}\n}\n\nfunction getTypingOperation(typedText: string, previousTypingOperation: EditOperationType): EditOperationType {\n\tif (typedText === ' ') {\n\t\treturn previousTypingOperation === EditOperationType.TypingFirstSpace\n\t\t\t|| previousTypingOperation === EditOperationType.TypingConsecutiveSpace\n\t\t\t? EditOperationType.TypingConsecutiveSpace\n\t\t\t: EditOperationType.TypingFirstSpace;\n\t}\n\n\treturn EditOperationType.TypingOther;\n}\n\nfunction shouldPushStackElementBetween(previousTypingOperation: EditOperationType, typingOperation: EditOperationType): boolean {\n\tif (isTypingOperation(previousTypingOperation) && !isTypingOperation(typingOperation)) {\n\t\t// Always set an undo stop before non-type operations\n\t\treturn true;\n\t}\n\tif (previousTypingOperation === EditOperationType.TypingFirstSpace) {\n\t\t// `abc |d`: No undo stop\n\t\t// `abc |d`: Undo stop\n\t\treturn false;\n\t}\n\t// Insert undo stop between different operation types\n\treturn normalizeOperationType(previousTypingOperation) !== normalizeOperationType(typingOperation);\n}\n\nfunction normalizeOperationType(type: EditOperationType): EditOperationType | 'space' {\n\treturn (type === EditOperationType.TypingConsecutiveSpace || type === EditOperationType.TypingFirstSpace)\n\t\t? 'space'\n\t\t: type;\n}\n\nfunction isTypingOperation(type: EditOperationType): boolean {\n\treturn type === EditOperationType.TypingOther\n\t\t|| type === EditOperationType.TypingFirstSpace\n\t\t|| type === EditOperationType.TypingConsecutiveSpace;\n}\n\nfunction isAutoClosingOvertype(config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): boolean {\n\tif (config.autoClosingOvertype === 'never') {\n\t\treturn false;\n\t}\n\tif (!config.autoClosingPairs.autoClosingPairsCloseSingleChar.has(ch)) {\n\t\treturn false;\n\t}\n\tfor (let i = 0, len = selections.length; i < len; i++) {\n\t\tconst selection = selections[i];\n\t\tif (!selection.isEmpty()) {\n\t\t\treturn false;\n\t\t}\n\t\tconst position = selection.getPosition();\n\t\tconst lineText = model.getLineContent(position.lineNumber);\n\t\tconst afterCharacter = lineText.charAt(position.column - 1);\n\t\tif (afterCharacter !== ch) {\n\t\t\treturn false;\n\t\t}\n\t\t// Do not over-type quotes after a backslash\n\t\tconst chIsQuote = isQuote(ch);\n\t\tconst beforeCharacter = position.column > 2 ? lineText.charCodeAt(position.column - 2) : CharCode.Null;\n\t\tif (beforeCharacter === CharCode.Backslash && chIsQuote) {\n\t\t\treturn false;\n\t\t}\n\t\t// Must over-type a closing character typed by the editor\n\t\tif (config.autoClosingOvertype === 'auto') {\n\t\t\tlet found = false;\n\t\t\tfor (let j = 0, lenJ = autoClosedCharacters.length; j < lenJ; j++) {\n\t\t\t\tconst autoClosedCharacter = autoClosedCharacters[j];\n\t\t\t\tif (position.lineNumber === autoClosedCharacter.startLineNumber && position.column === autoClosedCharacter.startColumn) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction typeCommand(range: Range, text: string, keepPosition: boolean): ICommand {\n\tif (keepPosition) {\n\t\treturn new ReplaceCommandWithoutChangingPosition(range, text, true);\n\t} else {\n\t\treturn new ReplaceCommand(range, text, true);\n\t}\n}\n\nexport function shiftIndent(config: CursorConfiguration, indentation: string, count?: number): string {\n\tcount = count || 1;\n\treturn ShiftCommand.shiftIndent(indentation, indentation.length + count, config.tabSize, config.indentSize, config.insertSpaces);\n}\n\nexport function unshiftIndent(config: CursorConfiguration, indentation: string, count?: number): string {\n\tcount = count || 1;\n\treturn ShiftCommand.unshiftIndent(indentation, indentation.length + count, config.tabSize, config.indentSize, config.insertSpaces);\n}\n\nexport function shouldSurroundChar(config: CursorConfiguration, ch: string): boolean {\n\tif (isQuote(ch)) {\n\t\treturn (config.autoSurround === 'quotes' || config.autoSurround === 'languageDefined');\n\t} else {\n\t\t// Character is a bracket\n\t\treturn (config.autoSurround === 'brackets' || config.autoSurround === 'languageDefined');\n\t}\n}\n"]}