monaco-editor-core
Version:
A browser based code editor
137 lines (136 loc) • 5.3 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/**
* Describes what to do with the indentation when pressing Enter.
*/
export var IndentAction;
(function (IndentAction) {
/**
* Insert new line and copy the previous line's indentation.
*/
IndentAction[IndentAction["None"] = 0] = "None";
/**
* Insert new line and indent once (relative to the previous line's indentation).
*/
IndentAction[IndentAction["Indent"] = 1] = "Indent";
/**
* Insert two new lines:
* - the first one indented which will hold the cursor
* - the second one at the same indentation level
*/
IndentAction[IndentAction["IndentOutdent"] = 2] = "IndentOutdent";
/**
* Insert new line and outdent once (relative to the previous line's indentation).
*/
IndentAction[IndentAction["Outdent"] = 3] = "Outdent";
})(IndentAction || (IndentAction = {}));
/**
* @internal
*/
export class StandardAutoClosingPairConditional {
constructor(source) {
this._neutralCharacter = null;
this._neutralCharacterSearched = false;
this.open = source.open;
this.close = source.close;
// initially allowed in all tokens
this._inString = true;
this._inComment = true;
this._inRegEx = true;
if (Array.isArray(source.notIn)) {
for (let i = 0, len = source.notIn.length; i < len; i++) {
const notIn = source.notIn[i];
switch (notIn) {
case 'string':
this._inString = false;
break;
case 'comment':
this._inComment = false;
break;
case 'regex':
this._inRegEx = false;
break;
}
}
}
}
isOK(standardToken) {
switch (standardToken) {
case 0 /* StandardTokenType.Other */:
return true;
case 1 /* StandardTokenType.Comment */:
return this._inComment;
case 2 /* StandardTokenType.String */:
return this._inString;
case 3 /* StandardTokenType.RegEx */:
return this._inRegEx;
}
}
shouldAutoClose(context, column) {
// Always complete on empty line
if (context.getTokenCount() === 0) {
return true;
}
const tokenIndex = context.findTokenIndexAtOffset(column - 2);
const standardTokenType = context.getStandardTokenType(tokenIndex);
return this.isOK(standardTokenType);
}
_findNeutralCharacterInRange(fromCharCode, toCharCode) {
for (let charCode = fromCharCode; charCode <= toCharCode; charCode++) {
const character = String.fromCharCode(charCode);
if (!this.open.includes(character) && !this.close.includes(character)) {
return character;
}
}
return null;
}
/**
* Find a character in the range [0-9a-zA-Z] that does not appear in the open or close
*/
findNeutralCharacter() {
if (!this._neutralCharacterSearched) {
this._neutralCharacterSearched = true;
if (!this._neutralCharacter) {
this._neutralCharacter = this._findNeutralCharacterInRange(48 /* CharCode.Digit0 */, 57 /* CharCode.Digit9 */);
}
if (!this._neutralCharacter) {
this._neutralCharacter = this._findNeutralCharacterInRange(97 /* CharCode.a */, 122 /* CharCode.z */);
}
if (!this._neutralCharacter) {
this._neutralCharacter = this._findNeutralCharacterInRange(65 /* CharCode.A */, 90 /* CharCode.Z */);
}
}
return this._neutralCharacter;
}
}
/**
* @internal
*/
export class AutoClosingPairs {
constructor(autoClosingPairs) {
this.autoClosingPairsOpenByStart = new Map();
this.autoClosingPairsOpenByEnd = new Map();
this.autoClosingPairsCloseByStart = new Map();
this.autoClosingPairsCloseByEnd = new Map();
this.autoClosingPairsCloseSingleChar = new Map();
for (const pair of autoClosingPairs) {
appendEntry(this.autoClosingPairsOpenByStart, pair.open.charAt(0), pair);
appendEntry(this.autoClosingPairsOpenByEnd, pair.open.charAt(pair.open.length - 1), pair);
appendEntry(this.autoClosingPairsCloseByStart, pair.close.charAt(0), pair);
appendEntry(this.autoClosingPairsCloseByEnd, pair.close.charAt(pair.close.length - 1), pair);
if (pair.close.length === 1 && pair.open.length === 1) {
appendEntry(this.autoClosingPairsCloseSingleChar, pair.close, pair);
}
}
}
}
function appendEntry(target, key, value) {
if (target.has(key)) {
target.get(key).push(value);
}
else {
target.set(key, [value]);
}
}