diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index ea1aa360a41..c150910415f 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -69,9 +69,7 @@ export interface ICommandHandler { declare module monaco.languages { #includeAll(vs/editor/browser/standalone/standaloneLanguages;modes.=>;editorCommon.=>editor.;IMarkerData=>editor.IMarkerData): -#include(vs/editor/common/modes/languageConfigurationRegistry): CommentRule, LanguageConfiguration -#include(vs/editor/common/modes/supports/onEnter): IndentationRule, OnEnterRule -#include(vs/editor/common/modes/supports/electricCharacter): IBracketElectricCharacterContribution, IDocComment +#includeAll(vs/editor/common/modes/languageConfiguration): #includeAll(vs/editor/common/modes;editorCommon.IRange=>IRange;editorCommon.IPosition=>IPosition;editorCommon.=>editor.;IToken2=>IToken;ILineTokens2=>ILineTokens;IState2=>IState): #include(vs/editor/common/services/modeService): ILanguageExtensionPoint #includeAll(vs/editor/common/modes/monarch/monarchTypes): diff --git a/src/vs/editor/browser/standalone/standaloneLanguages.ts b/src/vs/editor/browser/standalone/standaloneLanguages.ts index f7e14e0d68c..688d49ba25c 100644 --- a/src/vs/editor/browser/standalone/standaloneLanguages.ts +++ b/src/vs/editor/browser/standalone/standaloneLanguages.ts @@ -13,7 +13,7 @@ import { IMonarchLanguage } from 'vs/editor/common/modes/monarch/monarchTypes'; import { ILanguageExtensionPoint } from 'vs/editor/common/services/modeService'; import { StaticServices } from 'vs/editor/browser/standalone/standaloneServices'; import * as modes from 'vs/editor/common/modes'; -import { LanguageConfiguration } from 'vs/editor/common/modes/languageConfigurationRegistry'; +import { LanguageConfiguration, IndentAction } from 'vs/editor/common/modes/languageConfiguration'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; @@ -512,6 +512,6 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages { DocumentHighlightKind: modes.DocumentHighlightKind, CompletionItemKind: CompletionItemKind, SymbolKind: modes.SymbolKind, - IndentAction: modes.IndentAction + IndentAction: IndentAction }; } diff --git a/src/vs/editor/common/controller/cursorCollection.ts b/src/vs/editor/common/controller/cursorCollection.ts index 6b4b417e33b..a1345899f9d 100644 --- a/src/vs/editor/common/controller/cursorCollection.ts +++ b/src/vs/editor/common/controller/cursorCollection.ts @@ -8,7 +8,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { IModeConfiguration, IOneCursorState, IViewModelHelper, OneCursor } from 'vs/editor/common/controller/oneCursor'; import { Selection } from 'vs/editor/common/core/selection'; import { IConfiguration, IModel, ISelection } from 'vs/editor/common/editorCommon'; -import { IAutoClosingPair } from 'vs/editor/common/modes'; +import { IAutoClosingPair } from 'vs/editor/common/modes/languageConfiguration'; import { Position } from 'vs/editor/common/core/position'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; diff --git a/src/vs/editor/common/controller/oneCursor.ts b/src/vs/editor/common/controller/oneCursor.ts index 6a0a505dec4..2645cacb168 100644 --- a/src/vs/editor/common/controller/oneCursor.ts +++ b/src/vs/editor/common/controller/oneCursor.ts @@ -14,10 +14,11 @@ import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { Selection, SelectionDirection } from 'vs/editor/common/core/selection'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import { IElectricAction, IndentAction } from 'vs/editor/common/modes'; +import { IndentAction } from 'vs/editor/common/modes/languageConfiguration'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { CharCode } from 'vs/base/common/charCode'; import { CharacterClassifier } from 'vs/editor/common/core/characterClassifier'; +import { IElectricAction } from 'vs/editor/common/modes/supports/electricCharacter'; export interface IPostOperationRunnable { (ctx: IOneCursorOperationContext): void; diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index 6836e388096..dc7b78d9301 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -1848,17 +1848,6 @@ export interface IReadOnlyModel extends ITextModel { getWordUntilPosition(position: IPosition): IWordAtPosition; } -/** - * @internal - */ -export interface IRichEditBracket { - modeId: string; - open: string; - close: string; - forwardRegex: RegExp; - reversedRegex: RegExp; -} - /** * @internal */ diff --git a/src/vs/editor/common/model/textModelWithTokens.ts b/src/vs/editor/common/model/textModelWithTokens.ts index fba744b06e5..d02ce1631f7 100644 --- a/src/vs/editor/common/model/textModelWithTokens.ts +++ b/src/vs/editor/common/model/textModelWithTokens.ts @@ -13,10 +13,10 @@ import { Range } from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { TextModel } from 'vs/editor/common/model/textModel'; import { TokenIterator } from 'vs/editor/common/model/tokenIterator'; -import { ITokenizationSupport, ILineTokens, IMode, IState, TokenizationRegistry, IRichEditBrackets } from 'vs/editor/common/modes'; +import { ITokenizationSupport, ILineTokens, IMode, IState, TokenizationRegistry } from 'vs/editor/common/modes'; import { NULL_MODE_ID, nullTokenize } from 'vs/editor/common/modes/nullMode'; import { ignoreBracketsInToken } from 'vs/editor/common/modes/supports'; -import { BracketsUtils } from 'vs/editor/common/modes/supports/richEditBrackets'; +import { BracketsUtils, RichEditBrackets, IRichEditBracket } from 'vs/editor/common/modes/supports/richEditBrackets'; import { ModeTransition } from 'vs/editor/common/core/modeTransition'; import { TokensInflatorMap } from 'vs/editor/common/model/tokensBinaryEncoding'; import { Position } from 'vs/editor/common/core/position'; @@ -623,7 +623,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke return null; } - private _matchFoundBracket(foundBracket: Range, data: editorCommon.IRichEditBracket, isOpen: boolean): [Range, Range] { + private _matchFoundBracket(foundBracket: Range, data: IRichEditBracket, isOpen: boolean): [Range, Range] { if (isOpen) { let matched = this._findMatchingBracketDown(data, foundBracket.getEndPosition()); if (matched) { @@ -639,7 +639,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke return null; } - private _findMatchingBracketUp(bracket: editorCommon.IRichEditBracket, position: Position): Range { + private _findMatchingBracketUp(bracket: IRichEditBracket, position: Position): Range { // console.log('_findMatchingBracketUp: ', 'bracket: ', JSON.stringify(bracket), 'startPosition: ', String(position)); const modeId = bracket.modeId; @@ -698,7 +698,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke return null; } - private _findMatchingBracketDown(bracket: editorCommon.IRichEditBracket, position: Position): Range { + private _findMatchingBracketDown(bracket: IRichEditBracket, position: Position): Range { // console.log('_findMatchingBracketDown: ', 'bracket: ', JSON.stringify(bracket), 'startPosition: ', String(position)); const modeId = bracket.modeId; @@ -760,7 +760,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke const position = this.validatePosition(_position); let modeId: string = null; - let modeBrackets: IRichEditBrackets; + let modeBrackets: RichEditBrackets; for (let lineNumber = position.lineNumber; lineNumber >= 1; lineNumber--) { const lineTokens = this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap); const lineText = this._lines[lineNumber - 1].text; @@ -803,7 +803,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke const position = this.validatePosition(_position); let modeId: string = null; - let modeBrackets: IRichEditBrackets; + let modeBrackets: RichEditBrackets; for (let lineNumber = position.lineNumber, lineCount = this.getLineCount(); lineNumber <= lineCount; lineNumber++) { const lineTokens = this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap); const lineText = this._lines[lineNumber - 1].text; @@ -842,7 +842,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke return null; } - private _toFoundBracket(modeBrackets: IRichEditBrackets, r: Range): editorCommon.IFoundBracket { + private _toFoundBracket(modeBrackets: RichEditBrackets, r: Range): editorCommon.IFoundBracket { if (!r) { return null; } diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index ad2d0566605..13e4a00d227 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -661,104 +661,6 @@ export interface CodeLensProvider { resolveCodeLens?(model: editorCommon.IReadOnlyModel, codeLens: ICodeLensSymbol, token: CancellationToken): ICodeLensSymbol | Thenable; } -/** - * A tuple of two characters, like a pair of - * opening and closing brackets. - */ -export type CharacterPair = [string, string]; - -export interface IAutoClosingPairConditional extends IAutoClosingPair { - notIn?: string[]; - -} - -/** - * Interface used to support electric characters - * @internal - */ -export interface IElectricAction { - // Only one of the following properties should be defined: - - // The line will be indented at the same level of the line - // which contains the matching given bracket type. - matchOpenBracket?: string; - - // The text will be appended after the electric character. - appendText?: string; - - // The number of characters to advance the cursor, useful with appendText - advanceCount?: number; -} - -/** - * Describes what to do with the indentation when pressing Enter. - */ -export enum IndentAction { - /** - * Insert new line and copy the previous line's indentation. - */ - None = 0, - /** - * Insert new line and indent once (relative to the previous line's indentation). - */ - Indent = 1, - /** - * Insert two new lines: - * - the first one indented which will hold the cursor - * - the second one at the same indentation level - */ - IndentOutdent = 2, - /** - * Insert new line and outdent once (relative to the previous line's indentation). - */ - Outdent = 3 -} - -/** - * Describes what to do when pressing Enter. - */ -export interface EnterAction { - /** - * Describe what to do with the indentation. - */ - indentAction: IndentAction; - /** - * Describes text to be appended after the new line and after the indentation. - */ - appendText?: string; - /** - * Describes the number of characters to remove from the new line's indentation. - */ - removeText?: number; -} - -/** - * Interface used to support insertion of mode specific comments. - * @internal - */ -export interface ICommentsConfiguration { - lineCommentToken?: string; - blockCommentStartToken?: string; - blockCommentEndToken?: string; -} - -export interface IAutoClosingPair { - open: string; - close: string; -} - -/** - * @internal - */ -export interface IRichEditBrackets { - maxBracketLength: number; - forwardRegex: RegExp; - reversedRegex: RegExp; - brackets: editorCommon.IRichEditBracket[]; - textIsBracket: { [text: string]: editorCommon.IRichEditBracket; }; - textIsOpenBracket: { [text: string]: boolean; }; -} - // --- feature registries ------ /** diff --git a/src/vs/editor/common/modes/languageConfiguration.ts b/src/vs/editor/common/modes/languageConfiguration.ts new file mode 100644 index 00000000000..3591973bb53 --- /dev/null +++ b/src/vs/editor/common/modes/languageConfiguration.ts @@ -0,0 +1,183 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +/** + * Describes how comments for a language work. + */ +export interface CommentRule { + /** + * The line comment token, like `// this is a comment` + */ + lineComment?: string; + /** + * The block comment character pair, like `/* block comment */` + */ + blockComment?: CharacterPair; +} + +/** + * The language configuration interface defines the contract between extensions and + * various editor features, like automatic bracket insertion, automatic indentation etc. + */ +export interface LanguageConfiguration { + /** + * The language's comment settings. + */ + comments?: CommentRule; + /** + * The language's brackets. + * This configuration implicitly affects pressing Enter around these brackets. + */ + brackets?: CharacterPair[]; + /** + * The language's word definition. + * If the language supports Unicode identifiers (e.g. JavaScript), it is preferable + * to provide a word definition that uses exclusion of known separators. + * e.g.: A regex that matches anything except known separators (and dot is allowed to occur in a floating point number): + * /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g + */ + wordPattern?: RegExp; + /** + * The language's indentation settings. + */ + indentationRules?: IndentationRule; + /** + * The language's rules to be evaluated when pressing Enter. + */ + onEnterRules?: OnEnterRule[]; + /** + * The language's auto closing pairs. The 'close' character is automatically inserted with the + * 'open' character is typed. If not set, the configured brackets will be used. + */ + autoClosingPairs?: IAutoClosingPairConditional[]; + /** + * The language's surrounding pairs. When the 'open' character is typed on a selection, the + * selected string is surrounded by the open and close characters. If not set, the autoclosing pairs + * settings will be used. + */ + surroundingPairs?: IAutoClosingPair[]; + /** + * **Deprecated** Do not use. + * + * @deprecated Will be replaced by a better API soon. + */ + __electricCharacterSupport?: IBracketElectricCharacterContribution; +} + +/** + * Describes indentation rules for a language. + */ +export interface IndentationRule { + /** + * If a line matches this pattern, then all the lines after it should be unindendented once (until another rule matches). + */ + decreaseIndentPattern: RegExp; + /** + * If a line matches this pattern, then all the lines after it should be indented once (until another rule matches). + */ + increaseIndentPattern: RegExp; + /** + * If a line matches this pattern, then **only the next line** after it should be indented once. + */ + indentNextLinePattern?: RegExp; + /** + * If a line matches this pattern, then its indentation should not be changed and it should not be evaluated against the other rules. + */ + unIndentedLinePattern?: RegExp; +} + +/** + * Describes a rule to be evaluated when pressing Enter. + */ +export interface OnEnterRule { + /** + * This rule will only execute if the text before the cursor matches this regular expression. + */ + beforeText: RegExp; + /** + * This rule will only execute if the text after the cursor matches this regular expression. + */ + afterText?: RegExp; + /** + * The action to execute. + */ + action: EnterAction; +} + +export interface IBracketElectricCharacterContribution { + docComment?: IDocComment; +} + +/** + * Definition of documentation comments (e.g. Javadoc/JSdoc) + */ +export interface IDocComment { + /** + * The string that starts a doc comment (e.g. '/**') + */ + open: string; + /** + * The string that appears on the last line and closes the doc comment (e.g. ' * /'). + */ + close: string; +} + +/** + * A tuple of two characters, like a pair of + * opening and closing brackets. + */ +export type CharacterPair = [string, string]; + +export interface IAutoClosingPair { + open: string; + close: string; +} + +export interface IAutoClosingPairConditional extends IAutoClosingPair { + notIn?: string[]; +} + +/** + * Describes what to do with the indentation when pressing Enter. + */ +export enum IndentAction { + /** + * Insert new line and copy the previous line's indentation. + */ + None = 0, + /** + * Insert new line and indent once (relative to the previous line's indentation). + */ + Indent = 1, + /** + * Insert two new lines: + * - the first one indented which will hold the cursor + * - the second one at the same indentation level + */ + IndentOutdent = 2, + /** + * Insert new line and outdent once (relative to the previous line's indentation). + */ + Outdent = 3 +} + +/** + * Describes what to do when pressing Enter. + */ +export interface EnterAction { + /** + * Describe what to do with the indentation. + */ + indentAction: IndentAction; + /** + * Describes text to be appended after the new line and after the indentation. + */ + appendText?: string; + /** + * Describes the number of characters to remove from the new line's indentation. + */ + removeText?: number; +} diff --git a/src/vs/editor/common/modes/languageConfigurationRegistry.ts b/src/vs/editor/common/modes/languageConfigurationRegistry.ts index 3b7579515f9..df4b4308067 100644 --- a/src/vs/editor/common/modes/languageConfigurationRegistry.ts +++ b/src/vs/editor/common/modes/languageConfigurationRegistry.ts @@ -4,14 +4,9 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { - ICommentsConfiguration, IRichEditBrackets, IAutoClosingPair, - IAutoClosingPairConditional, CharacterPair, - EnterAction, IndentAction, IElectricAction -} from 'vs/editor/common/modes'; import { CharacterPairSupport } from 'vs/editor/common/modes/supports/characterPair'; -import { BracketElectricCharacterSupport, IBracketElectricCharacterContribution } from 'vs/editor/common/modes/supports/electricCharacter'; -import { IndentationRule, OnEnterRule, IOnEnterSupportOptions, OnEnterSupport } from 'vs/editor/common/modes/supports/onEnter'; +import { BracketElectricCharacterSupport, IElectricAction } from 'vs/editor/common/modes/supports/electricCharacter'; +import { IOnEnterSupportOptions, OnEnterSupport } from 'vs/editor/common/modes/supports/onEnter'; import { RichEditBrackets } from 'vs/editor/common/modes/supports/richEditBrackets'; import Event, { Emitter } from 'vs/base/common/event'; import { ITokenizedModel } from 'vs/editor/common/editorCommon'; @@ -21,68 +16,15 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { DEFAULT_WORD_REGEXP, ensureValidWordDefinition } from 'vs/editor/common/model/wordHelper'; import { createScopedLineTokens } from 'vs/editor/common/modes/supports'; import { LineTokens } from 'vs/editor/common/core/lineTokens'; +import { IndentAction, EnterAction, IAutoClosingPair, IAutoClosingPairConditional, LanguageConfiguration } from 'vs/editor/common/modes/languageConfiguration'; /** - * Describes how comments for a language work. + * Interface used to support insertion of mode specific comments. */ -export interface CommentRule { - /** - * The line comment token, like `// this is a comment` - */ - lineComment?: string; - /** - * The block comment character pair, like `/* block comment */` - */ - blockComment?: CharacterPair; -} - -/** - * The language configuration interface defines the contract between extensions and - * various editor features, like automatic bracket insertion, automatic indentation etc. - */ -export interface LanguageConfiguration { - /** - * The language's comment settings. - */ - comments?: CommentRule; - /** - * The language's brackets. - * This configuration implicitly affects pressing Enter around these brackets. - */ - brackets?: CharacterPair[]; - /** - * The language's word definition. - * If the language supports Unicode identifiers (e.g. JavaScript), it is preferable - * to provide a word definition that uses exclusion of known separators. - * e.g.: A regex that matches anything except known separators (and dot is allowed to occur in a floating point number): - * /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g - */ - wordPattern?: RegExp; - /** - * The language's indentation settings. - */ - indentationRules?: IndentationRule; - /** - * The language's rules to be evaluated when pressing Enter. - */ - onEnterRules?: OnEnterRule[]; - /** - * The language's auto closing pairs. The 'close' character is automatically inserted with the - * 'open' character is typed. If not set, the configured brackets will be used. - */ - autoClosingPairs?: IAutoClosingPairConditional[]; - /** - * The language's surrounding pairs. When the 'open' character is typed on a selection, the - * selected string is surrounded by the open and close characters. If not set, the autoclosing pairs - * settings will be used. - */ - surroundingPairs?: IAutoClosingPair[]; - /** - * **Deprecated** Do not use. - * - * @deprecated Will be replaced by a better API soon. - */ - __electricCharacterSupport?: IBracketElectricCharacterContribution; +export interface ICommentsConfiguration { + lineCommentToken?: string; + blockCommentStartToken?: string; + blockCommentEndToken?: string; } export class RichEditSupport { @@ -94,7 +36,7 @@ export class RichEditSupport { public characterPair: CharacterPairSupport; public wordDefinition: RegExp; public onEnter: OnEnterSupport; - public brackets: IRichEditBrackets; + public brackets: RichEditBrackets; constructor(modeId: string, previous: RichEditSupport, rawConf: LanguageConfiguration) { @@ -365,7 +307,7 @@ export class LanguageConfigurationRegistryImpl { // end onEnter - public getBracketsSupport(modeId: string): IRichEditBrackets { + public getBracketsSupport(modeId: string): RichEditBrackets { let value = this._getRichEditSupport(modeId); if (!value) { return null; diff --git a/src/vs/editor/common/modes/supports/characterPair.ts b/src/vs/editor/common/modes/supports/characterPair.ts index 52297b95157..1e1a209d1f1 100644 --- a/src/vs/editor/common/modes/supports/characterPair.ts +++ b/src/vs/editor/common/modes/supports/characterPair.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { IAutoClosingPair, IAutoClosingPairConditional, CharacterPair } from 'vs/editor/common/modes'; import { ScopedLineTokens } from 'vs/editor/common/modes/supports'; +import { CharacterPair, IAutoClosingPair, IAutoClosingPairConditional } from 'vs/editor/common/modes/languageConfiguration'; export class CharacterPairSupport { diff --git a/src/vs/editor/common/modes/supports/electricCharacter.ts b/src/vs/editor/common/modes/supports/electricCharacter.ts index 7521e0adb5b..40bed01b584 100644 --- a/src/vs/editor/common/modes/supports/electricCharacter.ts +++ b/src/vs/editor/common/modes/supports/electricCharacter.ts @@ -5,34 +5,35 @@ 'use strict'; import * as strings from 'vs/base/common/strings'; -import * as modes from 'vs/editor/common/modes'; import { ScopedLineTokens, ignoreBracketsInToken } from 'vs/editor/common/modes/supports'; import { BracketsUtils } from 'vs/editor/common/modes/supports/richEditBrackets'; +import { RichEditBrackets } from 'vs/editor/common/modes/supports/richEditBrackets'; +import { IAutoClosingPairConditional, IBracketElectricCharacterContribution } from 'vs/editor/common/modes/languageConfiguration'; /** - * Definition of documentation comments (e.g. Javadoc/JSdoc) + * Interface used to support electric characters + * @internal */ -export interface IDocComment { - /** - * The string that starts a doc comment (e.g. '/**') - */ - open: string; - /** - * The string that appears on the last line and closes the doc comment (e.g. ' * /'). - */ - close: string; -} +export interface IElectricAction { + // Only one of the following properties should be defined: -export interface IBracketElectricCharacterContribution { - docComment?: IDocComment; + // The line will be indented at the same level of the line + // which contains the matching given bracket type. + matchOpenBracket?: string; + + // The text will be appended after the electric character. + appendText?: string; + + // The number of characters to advance the cursor, useful with appendText + advanceCount?: number; } export class BracketElectricCharacterSupport { - private readonly _richEditBrackets: modes.IRichEditBrackets; - private readonly _complexAutoClosePairs: modes.IAutoClosingPairConditional[]; + private readonly _richEditBrackets: RichEditBrackets; + private readonly _complexAutoClosePairs: IAutoClosingPairConditional[]; - constructor(richEditBrackets: modes.IRichEditBrackets, autoClosePairs: modes.IAutoClosingPairConditional[], contribution: IBracketElectricCharacterContribution) { + constructor(richEditBrackets: RichEditBrackets, autoClosePairs: IAutoClosingPairConditional[], contribution: IBracketElectricCharacterContribution) { contribution = contribution || {}; this._richEditBrackets = richEditBrackets; this._complexAutoClosePairs = autoClosePairs.filter(pair => pair.open.length > 1 && !!pair.close); @@ -66,7 +67,7 @@ export class BracketElectricCharacterSupport { return result; } - public onElectricCharacter(context: ScopedLineTokens, offset: number): modes.IElectricAction { + public onElectricCharacter(context: ScopedLineTokens, offset: number): IElectricAction { if (context.getTokenCount() === 0) { return null; } @@ -85,7 +86,7 @@ export class BracketElectricCharacterSupport { return true; } - private _onElectricAutoIndent(context: ScopedLineTokens, offset: number): modes.IElectricAction { + private _onElectricAutoIndent(context: ScopedLineTokens, offset: number): IElectricAction { if (!this._richEditBrackets || this._richEditBrackets.brackets.length === 0) { return null; @@ -121,7 +122,7 @@ export class BracketElectricCharacterSupport { return null; } - private _onElectricAutoClose(context: ScopedLineTokens, offset: number): modes.IElectricAction { + private _onElectricAutoClose(context: ScopedLineTokens, offset: number): IElectricAction { if (!this._complexAutoClosePairs.length) { return null; diff --git a/src/vs/editor/common/modes/supports/onEnter.ts b/src/vs/editor/common/modes/supports/onEnter.ts index 602c84b3b7e..2cd37261c60 100644 --- a/src/vs/editor/common/modes/supports/onEnter.ts +++ b/src/vs/editor/common/modes/supports/onEnter.ts @@ -6,47 +6,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import * as strings from 'vs/base/common/strings'; -import { EnterAction, IndentAction, CharacterPair } from 'vs/editor/common/modes'; - -/** - * Describes indentation rules for a language. - */ -export interface IndentationRule { - /** - * If a line matches this pattern, then all the lines after it should be unindendented once (until another rule matches). - */ - decreaseIndentPattern: RegExp; - /** - * If a line matches this pattern, then all the lines after it should be indented once (until another rule matches). - */ - increaseIndentPattern: RegExp; - /** - * If a line matches this pattern, then **only the next line** after it should be indented once. - */ - indentNextLinePattern?: RegExp; - /** - * If a line matches this pattern, then its indentation should not be changed and it should not be evaluated against the other rules. - */ - unIndentedLinePattern?: RegExp; -} - -/** - * Describes a rule to be evaluated when pressing Enter. - */ -export interface OnEnterRule { - /** - * This rule will only execute if the text before the cursor matches this regular expression. - */ - beforeText: RegExp; - /** - * This rule will only execute if the text after the cursor matches this regular expression. - */ - afterText?: RegExp; - /** - * The action to execute. - */ - action: EnterAction; -} +import { CharacterPair, IndentationRule, IndentAction, EnterAction, OnEnterRule } from 'vs/editor/common/modes/languageConfiguration'; export interface IOnEnterSupportOptions { brackets?: CharacterPair[]; diff --git a/src/vs/editor/common/modes/supports/richEditBrackets.ts b/src/vs/editor/common/modes/supports/richEditBrackets.ts index 13d5efcd312..9ecc298b566 100644 --- a/src/vs/editor/common/modes/supports/richEditBrackets.ts +++ b/src/vs/editor/common/modes/supports/richEditBrackets.ts @@ -6,22 +6,30 @@ import * as strings from 'vs/base/common/strings'; import { Range } from 'vs/editor/common/core/range'; -import { IRichEditBracket } from 'vs/editor/common/editorCommon'; -import { IRichEditBrackets, CharacterPair } from 'vs/editor/common/modes'; +import { CharacterPair } from 'vs/editor/common/modes/languageConfiguration'; interface ISimpleInternalBracket { open: string; close: string; } -export class RichEditBrackets implements IRichEditBrackets { +export interface IRichEditBracket { + readonly modeId: string; + readonly open: string; + readonly close: string; + readonly forwardRegex: RegExp; + readonly reversedRegex: RegExp; +} - public brackets: IRichEditBracket[]; - public forwardRegex: RegExp; - public reversedRegex: RegExp; - public maxBracketLength: number; - public textIsBracket: { [text: string]: IRichEditBracket; }; - public textIsOpenBracket: { [text: string]: boolean; }; +export class RichEditBrackets { + _richEditBracketsBrand: void; + + public readonly brackets: IRichEditBracket[]; + public readonly forwardRegex: RegExp; + public readonly reversedRegex: RegExp; + public readonly maxBracketLength: number; + public readonly textIsBracket: { [text: string]: IRichEditBracket; }; + public readonly textIsOpenBracket: { [text: string]: boolean; }; constructor(modeId: string, brackets: CharacterPair[]) { this.brackets = brackets.map((b) => { @@ -38,15 +46,17 @@ export class RichEditBrackets implements IRichEditBrackets { this.textIsBracket = {}; this.textIsOpenBracket = {}; - this.maxBracketLength = 0; + + let maxBracketLength = 0; this.brackets.forEach((b) => { this.textIsBracket[b.open.toLowerCase()] = b; this.textIsBracket[b.close.toLowerCase()] = b; this.textIsOpenBracket[b.open.toLowerCase()] = true; this.textIsOpenBracket[b.close.toLowerCase()] = false; - this.maxBracketLength = Math.max(this.maxBracketLength, b.open.length); - this.maxBracketLength = Math.max(this.maxBracketLength, b.close.length); + maxBracketLength = Math.max(maxBracketLength, b.open.length); + maxBracketLength = Math.max(maxBracketLength, b.close.length); }); + this.maxBracketLength = maxBracketLength; } } diff --git a/src/vs/editor/contrib/comment/common/blockCommentCommand.ts b/src/vs/editor/contrib/comment/common/blockCommentCommand.ts index 044a379ab2f..b21f9c3fa67 100644 --- a/src/vs/editor/contrib/comment/common/blockCommentCommand.ts +++ b/src/vs/editor/contrib/comment/common/blockCommentCommand.ts @@ -9,8 +9,7 @@ import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import { ICommentsConfiguration } from 'vs/editor/common/modes'; -import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; +import { ICommentsConfiguration, LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; export class BlockCommentCommand implements editorCommon.ICommand { diff --git a/src/vs/editor/contrib/comment/common/lineCommentCommand.ts b/src/vs/editor/contrib/comment/common/lineCommentCommand.ts index 4778eed2dab..7b0853ab141 100644 --- a/src/vs/editor/contrib/comment/common/lineCommentCommand.ts +++ b/src/vs/editor/contrib/comment/common/lineCommentCommand.ts @@ -10,9 +10,8 @@ import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import { ICommentsConfiguration } from 'vs/editor/common/modes'; import { BlockCommentCommand } from './blockCommentCommand'; -import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; +import { ICommentsConfiguration, LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { CharCode } from 'vs/base/common/charCode'; export interface IInsertionPoint { diff --git a/src/vs/editor/contrib/smartSelect/common/tokenTree.ts b/src/vs/editor/contrib/smartSelect/common/tokenTree.ts index 6a19a70b5e0..4577b526551 100644 --- a/src/vs/editor/contrib/smartSelect/common/tokenTree.ts +++ b/src/vs/editor/contrib/smartSelect/common/tokenTree.ts @@ -8,9 +8,8 @@ import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { IModel, IPosition } from 'vs/editor/common/editorCommon'; import { LineToken } from 'vs/editor/common/core/lineTokens'; -import { IRichEditBrackets } from 'vs/editor/common/modes'; import { ignoreBracketsInToken } from 'vs/editor/common/modes/supports'; -import { BracketsUtils } from 'vs/editor/common/modes/supports/richEditBrackets'; +import { BracketsUtils, RichEditBrackets } from 'vs/editor/common/modes/supports/richEditBrackets'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; export const enum TokenTreeBracket { @@ -189,7 +188,7 @@ class TokenScanner { private _rawTokenScanner: ModelRawTokenScanner; private _nextBuff: Token[]; - private _cachedModeBrackets: IRichEditBrackets; + private _cachedModeBrackets: RichEditBrackets; private _cachedModeId: string; constructor(model: IModel) { diff --git a/src/vs/editor/contrib/smartSelect/test/common/tokenSelectionSupport.test.ts b/src/vs/editor/contrib/smartSelect/test/common/tokenSelectionSupport.test.ts index 49cd28be2eb..ad8a30c2766 100644 --- a/src/vs/editor/contrib/smartSelect/test/common/tokenSelectionSupport.test.ts +++ b/src/vs/editor/contrib/smartSelect/test/common/tokenSelectionSupport.test.ts @@ -7,7 +7,8 @@ import * as assert from 'assert'; import URI from 'vs/base/common/uri'; import { Range } from 'vs/editor/common/core/range'; -import { IMode, IndentAction } from 'vs/editor/common/modes'; +import { IMode } from 'vs/editor/common/modes'; +import { IndentAction } from 'vs/editor/common/modes/languageConfiguration'; import { TokenSelectionSupport } from 'vs/editor/contrib/smartSelect/common/tokenSelectionSupport'; import { MockTokenizingMode } from 'vs/editor/test/common/mocks/mockMode'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; diff --git a/src/vs/editor/node/languageConfiguration.ts b/src/vs/editor/node/languageConfigurationExtensionPoint.ts similarity index 95% rename from src/vs/editor/node/languageConfiguration.ts rename to src/vs/editor/node/languageConfigurationExtensionPoint.ts index 02e20dc20da..61f8f204da1 100644 --- a/src/vs/editor/node/languageConfiguration.ts +++ b/src/vs/editor/node/languageConfigurationExtensionPoint.ts @@ -7,24 +7,16 @@ import * as nls from 'vs/nls'; import { parse } from 'vs/base/common/json'; import { readFile } from 'vs/base/node/pfs'; -import { LanguageConfiguration } from 'vs/editor/common/modes/languageConfigurationRegistry'; +import { CharacterPair, LanguageConfiguration, IAutoClosingPair, IAutoClosingPairConditional, CommentRule } from 'vs/editor/common/modes/languageConfiguration'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { IAutoClosingPair, IAutoClosingPairConditional } from 'vs/editor/common/modes'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { Extensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { Registry } from 'vs/platform/platform'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { MainProcessTextMateSyntax } from 'vs/editor/node/textMate/TMSyntax'; -type CharacterPair = [string, string]; - -interface ICommentRule { - lineComment?: string; - blockComment?: CharacterPair; -} - interface ILanguageConfiguration { - comments?: ICommentRule; + comments?: CommentRule; brackets?: CharacterPair[]; autoClosingPairs?: (CharacterPair | IAutoClosingPairConditional)[]; surroundingPairs?: (CharacterPair | IAutoClosingPair)[]; diff --git a/src/vs/editor/test/common/commands/shiftCommand.test.ts b/src/vs/editor/test/common/commands/shiftCommand.test.ts index a2a744a099a..a85e9a05742 100644 --- a/src/vs/editor/test/common/commands/shiftCommand.test.ts +++ b/src/vs/editor/test/common/commands/shiftCommand.test.ts @@ -8,7 +8,7 @@ import * as assert from 'assert'; import { ShiftCommand } from 'vs/editor/common/commands/shiftCommand'; import { Selection } from 'vs/editor/common/core/selection'; import { IIdentifiedSingleEditOperation } from 'vs/editor/common/editorCommon'; -import { IndentAction } from 'vs/editor/common/modes'; +import { IndentAction } from 'vs/editor/common/modes/languageConfiguration'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { createSingleEditOp, getEditOperation, testCommand } from 'vs/editor/test/common/commands/commandTestUtils'; import { withEditorModel } from 'vs/editor/test/common/editorTestUtils'; diff --git a/src/vs/editor/test/common/controller/cursor.test.ts b/src/vs/editor/test/common/controller/cursor.test.ts index 6ff2f451a4c..67b78a3f9ab 100644 --- a/src/vs/editor/test/common/controller/cursor.test.ts +++ b/src/vs/editor/test/common/controller/cursor.test.ts @@ -17,7 +17,7 @@ import { ICursorPositionChangedEvent, ICursorSelectionChangedEvent } from 'vs/editor/common/editorCommon'; import { Model } from 'vs/editor/common/model/model'; -import { IndentAction } from 'vs/editor/common/modes'; +import { IndentAction } from 'vs/editor/common/modes/languageConfiguration'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { MockConfiguration } from 'vs/editor/test/common/mocks/mockConfiguration'; import { MockMode } from 'vs/editor/test/common/mocks/mockMode'; diff --git a/src/vs/editor/test/common/model/textModelWithTokens.test.ts b/src/vs/editor/test/common/model/textModelWithTokens.test.ts index b07c86f1b3e..8e94e5e4c1f 100644 --- a/src/vs/editor/test/common/model/textModelWithTokens.test.ts +++ b/src/vs/editor/test/common/model/textModelWithTokens.test.ts @@ -7,7 +7,8 @@ import * as assert from 'assert'; import { Model } from 'vs/editor/common/model/model'; import { ViewLineToken } from 'vs/editor/common/core/viewLineToken'; -import { TokenizationRegistry, CharacterPair } from 'vs/editor/common/modes'; +import { TokenizationRegistry } from 'vs/editor/common/modes'; +import { CharacterPair } from 'vs/editor/common/modes/languageConfiguration'; import { MockMode } from 'vs/editor/test/common/mocks/mockMode'; import { Token } from 'vs/editor/common/core/token'; import { Range } from 'vs/editor/common/core/range'; diff --git a/src/vs/editor/test/common/modes/supports/onEnter.test.ts b/src/vs/editor/test/common/modes/supports/onEnter.test.ts index 185ba1d7093..075f4cfb14d 100644 --- a/src/vs/editor/test/common/modes/supports/onEnter.test.ts +++ b/src/vs/editor/test/common/modes/supports/onEnter.test.ts @@ -5,7 +5,7 @@ 'use strict'; import * as assert from 'assert'; -import { IndentAction, CharacterPair } from 'vs/editor/common/modes'; +import { CharacterPair, IndentAction } from 'vs/editor/common/modes/languageConfiguration'; import { OnEnterSupport } from 'vs/editor/common/modes/supports/onEnter'; suite('OnEnter', () => { diff --git a/src/vs/editor/test/common/testModes.ts b/src/vs/editor/test/common/testModes.ts index 4e3c144111e..eeda213c85e 100644 --- a/src/vs/editor/test/common/testModes.ts +++ b/src/vs/editor/test/common/testModes.ts @@ -4,7 +4,8 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { LanguageConfigurationRegistry, CommentRule } from 'vs/editor/common/modes/languageConfigurationRegistry'; +import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; +import { CommentRule } from 'vs/editor/common/modes/languageConfiguration'; import { MockMode } from 'vs/editor/test/common/mocks/mockMode'; export class CommentMode extends MockMode { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 87c608a1944..ea0f731b4c2 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -4067,7 +4067,6 @@ declare module monaco.languages { */ resolveCompletionItem?(item: CompletionItem, token: CancellationToken): CompletionItem | Thenable; } - /** * Describes how comments for a language work. */ @@ -4189,6 +4188,63 @@ declare module monaco.languages { close: string; } + /** + * A tuple of two characters, like a pair of + * opening and closing brackets. + */ + export type CharacterPair = [string, string]; + + export interface IAutoClosingPair { + open: string; + close: string; + } + + export interface IAutoClosingPairConditional extends IAutoClosingPair { + notIn?: string[]; + } + + /** + * Describes what to do with the indentation when pressing Enter. + */ + export enum IndentAction { + /** + * Insert new line and copy the previous line's indentation. + */ + None = 0, + /** + * Insert new line and indent once (relative to the previous line's indentation). + */ + Indent = 1, + /** + * Insert two new lines: + * - the first one indented which will hold the cursor + * - the second one at the same indentation level + */ + IndentOutdent = 2, + /** + * Insert new line and outdent once (relative to the previous line's indentation). + */ + Outdent = 3, + } + + /** + * Describes what to do when pressing Enter. + */ + export interface EnterAction { + /** + * Describe what to do with the indentation. + */ + indentAction: IndentAction; + /** + * Describes text to be appended after the new line and after the indentation. + */ + appendText?: string; + /** + * Describes the number of characters to remove from the new line's indentation. + */ + removeText?: number; + } + /** * A mode. Will soon be obsolete. */ @@ -4623,63 +4679,6 @@ declare module monaco.languages { resolveCodeLens?(model: editor.IReadOnlyModel, codeLens: ICodeLensSymbol, token: CancellationToken): ICodeLensSymbol | Thenable; } - /** - * A tuple of two characters, like a pair of - * opening and closing brackets. - */ - export type CharacterPair = [string, string]; - - export interface IAutoClosingPairConditional extends IAutoClosingPair { - notIn?: string[]; - } - - /** - * Describes what to do with the indentation when pressing Enter. - */ - export enum IndentAction { - /** - * Insert new line and copy the previous line's indentation. - */ - None = 0, - /** - * Insert new line and indent once (relative to the previous line's indentation). - */ - Indent = 1, - /** - * Insert two new lines: - * - the first one indented which will hold the cursor - * - the second one at the same indentation level - */ - IndentOutdent = 2, - /** - * Insert new line and outdent once (relative to the previous line's indentation). - */ - Outdent = 3, - } - - /** - * Describes what to do when pressing Enter. - */ - export interface EnterAction { - /** - * Describe what to do with the indentation. - */ - indentAction: IndentAction; - /** - * Describes text to be appended after the new line and after the indentation. - */ - appendText?: string; - /** - * Describes the number of characters to remove from the new line's indentation. - */ - removeText?: number; - } - - export interface IAutoClosingPair { - open: string; - close: string; - } - export interface ILanguageExtensionPoint { id: string; extensions?: string[]; diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 0ade921823e..f7b8eea2f56 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -30,7 +30,6 @@ import { ExtHostLanguages } from 'vs/workbench/api/node/extHostLanguages'; import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures'; import { ExtHostApiCommands } from 'vs/workbench/api/node/extHostApiCommands'; import * as extHostTypes from 'vs/workbench/api/node/extHostTypes'; -import Modes = require('vs/editor/common/modes'); import URI from 'vs/base/common/uri'; import Severity from 'vs/base/common/severity'; import EditorCommon = require('vs/editor/common/editorCommon'); @@ -44,6 +43,7 @@ import * as paths from 'vs/base/common/paths'; import { realpathSync } from 'fs'; import { ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry'; import { MainContext, ExtHostContext, InstanceCollection, IInitConfiguration } from './extHost.protocol'; +import * as languageConfiguration from 'vs/editor/common/modes/languageConfiguration'; export interface IExtensionApiFactory { @@ -385,7 +385,7 @@ export function createApiFactory(initDataConfiguration: IInitConfiguration, init DocumentLink: extHostTypes.DocumentLink, ViewColumn: extHostTypes.ViewColumn, StatusBarAlignment: extHostTypes.StatusBarAlignment, - IndentAction: Modes.IndentAction, + IndentAction: languageConfiguration.IndentAction, OverviewRulerLane: EditorCommon.OverviewRulerLane, TextEditorRevealType: extHostTypes.TextEditorRevealType, EndOfLine: extHostTypes.EndOfLine, diff --git a/src/vs/workbench/api/node/extHost.contribution.ts b/src/vs/workbench/api/node/extHost.contribution.ts index 084e049ff3d..809d2240679 100644 --- a/src/vs/workbench/api/node/extHost.contribution.ts +++ b/src/vs/workbench/api/node/extHost.contribution.ts @@ -37,7 +37,7 @@ import { MainThreadFileSystemEventService } from './mainThreadFileSystemEventSer import { MainProcessTextMateSyntax } from 'vs/editor/node/textMate/TMSyntax'; import { MainProcessTextMateSnippet } from 'vs/editor/node/textMate/TMSnippets'; import { JSONValidationExtensionPoint } from 'vs/platform/jsonschemas/common/jsonValidationExtensionPoint'; -import { LanguageConfigurationFileHandler } from 'vs/editor/node/languageConfiguration'; +import { LanguageConfigurationFileHandler } from 'vs/editor/node/languageConfigurationExtensionPoint'; import { SaveParticipant } from './mainThreadSaveParticipant'; // --- registers itself as service diff --git a/src/vs/workbench/api/node/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/node/mainThreadLanguageFeatures.ts index 31b8e5fc3cd..275a9350c95 100644 --- a/src/vs/workbench/api/node/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/node/mainThreadLanguageFeatures.ts @@ -16,7 +16,8 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Position as EditorPosition } from 'vs/editor/common/core/position'; import { Range as EditorRange } from 'vs/editor/common/core/range'; import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape } from './extHost.protocol'; -import { LanguageConfigurationRegistry, LanguageConfiguration } from 'vs/editor/common/modes/languageConfigurationRegistry'; +import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; +import { LanguageConfiguration } from 'vs/editor/common/modes/languageConfiguration'; import { IHeapService } from './mainThreadHeapService'; export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape {