提交 65463e2d 编写于 作者: A Alex Dima

Consolidate 5 descriptive mode supports into IRichEditSupport

上级 284014c8
......@@ -307,19 +307,21 @@ export class CursorCollection {
}
private getModeConfiguration(): IModeConfiguration {
var i: number;
let i: number;
var result: IModeConfiguration = {
let result: IModeConfiguration = {
electricChars: {},
autoClosingPairsOpen: {},
autoClosingPairsClose: {},
surroundingPairs: {}
};
var electricChars: string[];
if (this.model.getMode().electricCharacterSupport) {
let richEditSupport = this.model.getMode().richEditSupport;
let electricChars: string[];
if (richEditSupport && richEditSupport.electricCharacter) {
try {
electricChars = this.model.getMode().electricCharacterSupport.getElectricCharacters();
electricChars = richEditSupport.electricCharacter.getElectricCharacters();
} catch(e) {
Errors.onUnexpectedError(e);
electricChars = null;
......@@ -331,10 +333,10 @@ export class CursorCollection {
}
}
var autoClosingPairs: IAutoClosingPair[];
if (this.model.getMode().characterPairSupport) {
let autoClosingPairs: IAutoClosingPair[];
if (richEditSupport && richEditSupport.characterPair) {
try {
autoClosingPairs = this.model.getMode().characterPairSupport.getAutoClosingPairs();
autoClosingPairs = richEditSupport.characterPair.getAutoClosingPairs();
} catch(e) {
Errors.onUnexpectedError(e);
autoClosingPairs = null;
......@@ -347,10 +349,10 @@ export class CursorCollection {
}
}
var surroundingPairs: IAutoClosingPair[];
if (this.model.getMode().characterPairSupport) {
let surroundingPairs: IAutoClosingPair[];
if (richEditSupport && richEditSupport.characterPair) {
try {
surroundingPairs = this.model.getMode().characterPairSupport.getSurroundingPairs();
surroundingPairs = richEditSupport.characterPair.getSurroundingPairs();
} catch(e) {
Errors.onUnexpectedError(e);
surroundingPairs = null;
......
......@@ -1035,7 +1035,9 @@ export class OneCursorOp {
return false;
}
if(!cursor.model.getMode().characterPairSupport) {
let richEditSupport = cursor.model.getMode().richEditSupport;
if(!richEditSupport || !richEditSupport.characterPair) {
return false;
}
......@@ -1061,7 +1063,7 @@ export class OneCursorOp {
var shouldAutoClosePair = false;
try {
shouldAutoClosePair = cursor.model.getMode().characterPairSupport.shouldAutoClosePair(ch, lineContext, position.column - 1);
shouldAutoClosePair = richEditSupport.characterPair.shouldAutoClosePair(ch, lineContext, position.column - 1);
} catch(e) {
Errors.onUnexpectedError(e);
}
......@@ -1144,9 +1146,10 @@ export class OneCursorOp {
var lineContext = cursor.model.getLineContext(position.lineNumber);
var electricAction:IElectricAction;
if(cursor.model.getMode().electricCharacterSupport) {
let richEditSupport = cursor.model.getMode().richEditSupport;
if(richEditSupport && richEditSupport.electricCharacter) {
try {
electricAction = cursor.model.getMode().electricCharacterSupport.onElectricCharacter(lineContext, position.column - 2);
electricAction = richEditSupport.electricCharacter.onElectricCharacter(lineContext, position.column - 2);
} catch(e) {
Errors.onUnexpectedError(e);
}
......
......@@ -750,13 +750,9 @@ export interface IModeSupportChangedEvent {
emitOutputSupport:boolean;
linkSupport:boolean;
configSupport:boolean;
electricCharacterSupport:boolean;
commentsSupport:boolean;
characterPairSupport:boolean;
tokenTypeClassificationSupport:boolean;
quickFixSupport: boolean;
codeLensSupport: boolean;
onEnterSupport: boolean;
richEditSupport: boolean;
}
/**
......
......@@ -39,14 +39,19 @@ export interface INonWordTokenMap {
export class WordHelper {
private static _safeGetWordDefinition(mode:Modes.IMode): RegExp {
var result: RegExp = null;
let richEditSupport = mode.richEditSupport;
if (!richEditSupport) {
return null;
}
if (!richEditSupport.tokenTypeClassification) {
return null;
}
if (mode.tokenTypeClassificationSupport) {
try {
result = mode.tokenTypeClassificationSupport.getWordDefinition();
} catch(e) {
Errors.onUnexpectedError(e);
}
var result: RegExp = null;
try {
result = richEditSupport.tokenTypeClassification.getWordDefinition();
} catch(e) {
Errors.onUnexpectedError(e);
}
return result;
......
......@@ -282,26 +282,6 @@ export interface IMode {
*/
configSupport?:IConfigurationSupport;
/**
* Optional adapter to support electric characters.
*/
electricCharacterSupport?:IElectricCharacterSupport;
/**
* Optional adapter to support comment insertion.
*/
commentsSupport?:ICommentsSupport;
/**
* Optional adapter to support insertion of character pair.
*/
characterPairSupport?:ICharacterPairSupport;
/**
* Optional adapter to support classification of tokens.
*/
tokenTypeClassificationSupport?:ITokenTypeClassificationSupport;
/**
* Optional adapter to support quick fix of typing errors.
*/
......@@ -322,7 +302,10 @@ export interface IMode {
*/
taskSupport?: ITaskSupport;
onEnterSupport?: IOnEnterSupport;
/**
* Optional adapter to support rich editing.
*/
richEditSupport?: IRichEditSupport;
}
/**
......@@ -644,87 +627,6 @@ export interface IConfigurationSupport {
configure(options:any):TPromise<boolean>;
}
/**
* Interface used to support electric characters
*/
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.
matchBracketType?: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 enum IndentAction {
None,
Indent,
IndentOutdent,
Outdent
}
/**
* An action the editor executes when 'enter' is being pressed
*/
export interface IEnterAction {
indentAction:IndentAction;
appendText?:string;
removeText?:number;
}
export interface IElectricCharacterSupport {
getElectricCharacters():string[];
// Should return opening bracket type to match indentation with
onElectricCharacter(context:ILineContext, offset:number):IElectricAction;
onEnter(context:ILineContext, offset:number):IEnterAction;
}
export interface IOnEnterSupport {
onEnter(model:EditorCommon.ITokenizedModel, position: EditorCommon.IPosition): IEnterAction;
}
/**
* Interface used to support insertion of mode specific comments.
*/
export interface ICommentsConfiguration {
lineCommentTokens?:string[];
blockCommentStartToken?:string;
blockCommentEndToken?:string;
}
export interface ICommentsSupport {
getCommentsConfiguration():ICommentsConfiguration;
}
/**
* Interface used to support insertion of matching characters like brackets and qoutes.
*/
export interface IAutoClosingPair {
open:string;
close:string;
}
export interface ICharacterPairSupport {
getAutoClosingPairs():IAutoClosingPairConditional[];
shouldAutoClosePair(character:string, context:ILineContext, offset:number):boolean;
getSurroundingPairs():IAutoClosingPair[];
}
/**
* Interface used to support the classification of tokens.
*/
export interface ITokenTypeClassificationSupport {
getWordDefinition():RegExp;
}
export interface IResourceEdit {
resource: URI;
range?: EditorCommon.IRange;
......@@ -826,4 +728,107 @@ export interface IAutoClosingPairConditional extends IAutoClosingPair {
export interface ICharacterPairContribution {
autoClosingPairs: IAutoClosingPairConditional[];
surroundingPairs?: IAutoClosingPair[];
}
\ No newline at end of file
}
/**
* Interface used to support electric characters
*/
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.
matchBracketType?: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 enum IndentAction {
None,
Indent,
IndentOutdent,
Outdent
}
/**
* An action the editor executes when 'enter' is being pressed
*/
export interface IEnterAction {
indentAction:IndentAction;
appendText?:string;
removeText?:number;
}
export interface IRichEditElectricCharacter {
getElectricCharacters():string[];
// Should return opening bracket type to match indentation with
onElectricCharacter(context:ILineContext, offset:number):IElectricAction;
onEnter(context:ILineContext, offset:number):IEnterAction;
}
export interface IRichEditOnEnter {
onEnter(model:EditorCommon.ITokenizedModel, position: EditorCommon.IPosition): IEnterAction;
}
/**
* Interface used to support insertion of mode specific comments.
*/
export interface ICommentsConfiguration {
lineCommentTokens?:string[];
blockCommentStartToken?:string;
blockCommentEndToken?:string;
}
export interface IRichEditComments {
getCommentsConfiguration():ICommentsConfiguration;
}
/**
* Interface used to support insertion of matching characters like brackets and qoutes.
*/
export interface IAutoClosingPair {
open:string;
close:string;
}
export interface IRichEditCharacterPair {
getAutoClosingPairs():IAutoClosingPairConditional[];
shouldAutoClosePair(character:string, context:ILineContext, offset:number):boolean;
getSurroundingPairs():IAutoClosingPair[];
}
/**
* Interface used to support the classification of tokens.
*/
export interface IRichEditTokenTypeClassification {
getWordDefinition():RegExp;
}
export interface IRichEditSupport {
/**
* Optional adapter for electric characters.
*/
electricCharacter?:IRichEditElectricCharacter;
/**
* Optional adapter for comment insertion.
*/
comments?:IRichEditComments;
/**
* Optional adapter for insertion of character pair.
*/
characterPair?:IRichEditCharacterPair;
/**
* Optional adapter for classification of tokens.
*/
tokenTypeClassification?:IRichEditTokenTypeClassification;
/**
* Optional adapter for custom Enter handling.
*/
onEnter?: IRichEditOnEnter;
}
......@@ -41,8 +41,6 @@ export class AbstractMode<W extends AbstractModeWorker> implements Modes.IMode {
public dirtyDiffSupport:Modes.IDirtyDiffSupport;
public linkSupport:Modes.ILinkSupport;
public configSupport:Modes.IConfigurationSupport;
public commentsSupport:Modes.ICommentsSupport;
public tokenTypeClassificationSupport:Modes.ITokenTypeClassificationSupport;
public codeLensSupport:Modes.ICodeLensSupport;
// adapters end
......@@ -68,8 +66,6 @@ export class AbstractMode<W extends AbstractModeWorker> implements Modes.IMode {
this.dirtyDiffSupport = this;
this.linkSupport = this;
this.configSupport = this;
this.commentsSupport = this;
this.tokenTypeClassificationSupport = this;
this._workerPiecePromise = null;
this._simplifiedMode = null;
......@@ -228,24 +224,12 @@ export class AbstractMode<W extends AbstractModeWorker> implements Modes.IMode {
}
// END
public getWordDefinition():RegExp {
return NullMode.DEFAULT_WORD_REGEXP;
}
public getCommentsConfiguration():Modes.ICommentsConfiguration {
return null;
}
}
class SimplifiedMode implements Modes.IMode {
tokenizationSupport: Modes.ITokenizationSupport;
electricCharacterSupport: Modes.IElectricCharacterSupport;
commentsSupport: Modes.ICommentsSupport;
characterPairSupport: Modes.ICharacterPairSupport;
tokenTypeClassificationSupport: Modes.ITokenTypeClassificationSupport;
onEnterSupport: Modes.IOnEnterSupport;
richEditSupport: Modes.IRichEditSupport;
private _sourceMode: Modes.IMode;
private _eventEmitter: EventEmitter;
......@@ -259,7 +243,7 @@ class SimplifiedMode implements Modes.IMode {
if (this._sourceMode.addSupportChangedListener) {
this._sourceMode.addSupportChangedListener((e) => {
if (e.tokenizationSupport || e.electricCharacterSupport || e.commentsSupport || e.characterPairSupport || e.tokenTypeClassificationSupport || e.onEnterSupport) {
if (e.tokenizationSupport || e.richEditSupport) {
this._assignSupports();
let newEvent = SimplifiedMode._createModeSupportChangedEvent(e);
this._eventEmitter.emit('modeSupportChanged', newEvent);
......@@ -278,11 +262,7 @@ class SimplifiedMode implements Modes.IMode {
private _assignSupports(): void {
this.tokenizationSupport = this._sourceMode.tokenizationSupport;
this.electricCharacterSupport = this._sourceMode.electricCharacterSupport;
this.commentsSupport = this._sourceMode.commentsSupport;
this.characterPairSupport = this._sourceMode.characterPairSupport;
this.tokenTypeClassificationSupport = this._sourceMode.tokenTypeClassificationSupport;
this.onEnterSupport = this._sourceMode.onEnterSupport;
this.richEditSupport = this._sourceMode.richEditSupport;
}
private static _createModeSupportChangedEvent(originalModeEvent:EditorCommon.IModeSupportChangedEvent): EditorCommon.IModeSupportChangedEvent {
......@@ -306,12 +286,8 @@ class SimplifiedMode implements Modes.IMode {
emitOutputSupport:false,
linkSupport:false,
configSupport:false,
electricCharacterSupport: originalModeEvent.electricCharacterSupport,
commentsSupport: originalModeEvent.commentsSupport,
characterPairSupport: originalModeEvent.characterPairSupport,
tokenTypeClassificationSupport: originalModeEvent.tokenTypeClassificationSupport,
quickFixSupport:false,
onEnterSupport: originalModeEvent.onEnterSupport
richEditSupport: originalModeEvent.richEditSupport,
};
return event;
}
......@@ -392,7 +368,7 @@ export class FrankensteinMode extends AbstractMode<AbstractModeWorker> {
}
function _createModeSupportChangedEvent(...changedSupports: string[]): EditorCommon.IModeSupportChangedEvent {
var event = {
var event:EditorCommon.IModeSupportChangedEvent = {
codeLensSupport: false,
tokenizationSupport:false,
occurrencesSupport:false,
......@@ -412,12 +388,8 @@ function _createModeSupportChangedEvent(...changedSupports: string[]): EditorCom
emitOutputSupport:false,
linkSupport:false,
configSupport:false,
electricCharacterSupport:false,
commentsSupport:false,
characterPairSupport:false,
tokenTypeClassificationSupport:false,
quickFixSupport:false,
onEnterSupport: false
richEditSupport: false
};
changedSupports.forEach(support => event[support] = true);
return event;
......
......@@ -21,15 +21,15 @@ import {IInstantiationService} from 'vs/platform/instantiation/common/instantiat
import {IThreadService} from 'vs/platform/thread/common/thread';
import {IModeService} from 'vs/editor/common/services/modeService';
import {IModelService} from 'vs/editor/common/services/modelService';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
/**
* The MonarchMode creates a Monaco language mode given a certain language description
*/
export class MonarchMode<W extends AbstractModeWorker> extends AbstractMode<W> {
public tokenizationSupport: Modes.ITokenizationSupport;
public electricCharacterSupport: Modes.IElectricCharacterSupport;
public characterPairSupport: Modes.ICharacterPairSupport;
public onEnterSupport: Modes.IOnEnterSupport;
public richEditSupport: Modes.IRichEditSupport;
constructor(
descriptor:Modes.IModeDescriptor,
......@@ -42,11 +42,9 @@ export class MonarchMode<W extends AbstractModeWorker> extends AbstractMode<W> {
super(descriptor, instantiationService, threadService);
this.tokenizationSupport = createTokenizationSupport(modeService, this, lexer);
this.electricCharacterSupport = new Supports.BracketElectricCharacterSupport(this, MonarchDefinition.createBracketElectricCharacterContribution(lexer));
this.commentsSupport = new Supports.CommentsSupport(MonarchDefinition.createCommentsSupport(lexer));
this.tokenTypeClassificationSupport = new Supports.TokenTypeClassificationSupport(MonarchDefinition.createTokenTypeClassificationSupportContribution(lexer));
this.characterPairSupport = new Supports.CharacterPairSupport(this, MonarchDefinition.createCharacterPairContribution(lexer));
this.richEditSupport = new RichEditSupport(this.getId(), MonarchDefinition.createRichEditSupport(lexer));
this.suggestSupport = new Supports.ComposableSuggestSupport(this, MonarchDefinition.createSuggestSupport(modelService, this, lexer));
this.onEnterSupport = new OnEnterSupport(this.getId(), MonarchDefinition.createOnEnterSupportOptions(lexer));
}
}
......@@ -17,35 +17,39 @@ import EditorCommon = require('vs/editor/common/editorCommon');
import {IModelService} from 'vs/editor/common/services/modelService';
import Modes = require('vs/editor/common/modes');
import {IOnEnterSupportOptions} from 'vs/editor/common/modes/supports/onEnter';
import {CharacterPair, IRichEditConfiguration} from 'vs/editor/common/modes/supports/richEditSupport';
export function createCommentsSupport(lexer: MonarchCommonTypes.ILexer): Supports.ICommentsSupportContribution {
return {
commentsConfiguration: {
lineCommentTokens: [lexer.lineComment],
blockCommentStartToken: lexer.blockCommentStart,
blockCommentEndToken: lexer.blockCommentEnd
}
};
}
export function createRichEditSupport(lexer: MonarchCommonTypes.ILexer): IRichEditConfiguration {
export function createBracketElectricCharacterContribution(lexer: MonarchCommonTypes.ILexer): Supports.IBracketElectricCharacterContribution {
return {
brackets: lexer.standardBrackets,
regexBrackets: lexer.enhancedBrackets,
caseInsensitive: lexer.ignoreCase,
embeddedElectricCharacters: lexer.outdentTriggers.split('')
};
}
function toBracket(input:Modes.IBracketPair): CharacterPair {
return [input.open, input.close];
}
export function createTokenTypeClassificationSupportContribution(lexer: MonarchCommonTypes.ILexer): Supports.ITokenTypeClassificationSupportContribution {
return {
wordDefinition: lexer.wordDefinition
};
}
function toBrackets(input:Modes.IBracketPair[]): CharacterPair[] {
return input.map(toBracket);
}
export function createCharacterPairContribution(lexer: MonarchCommonTypes.ILexer): Modes.ICharacterPairContribution {
return {
autoClosingPairs: lexer.autoClosingPairs
wordPattern: lexer.wordDefinition,
comments: {
lineComment: lexer.lineComment,
blockComment: [lexer.blockCommentStart, lexer.blockCommentEnd]
},
brackets: toBrackets(lexer.standardBrackets),
__electricCharacterSupport: {
brackets: lexer.standardBrackets,
regexBrackets: lexer.enhancedBrackets,
caseInsensitive: lexer.ignoreCase,
embeddedElectricCharacters: lexer.outdentTriggers.split('')
},
__characterPairSupport: {
autoClosingPairs: lexer.autoClosingPairs
}
};
}
......@@ -67,12 +71,6 @@ function _addSuggestionsAtPosition(model: EditorCommon.IModel, position:EditorCo
return superSuggestions;
}
export function createOnEnterSupportOptions(lexer:MonarchCommonTypes.ILexer): IOnEnterSupportOptions {
return {
brackets: lexer.standardBrackets
};
}
export function createSuggestSupport(modelService: IModelService, mode:Modes.IMode, lexer:MonarchCommonTypes.ILexer): Supports.IComposableSuggestContribution {
if (lexer.suggestSupport.textualCompletions && mode instanceof AbstractMode) {
return {
......
......@@ -80,10 +80,14 @@ export class NullMode implements Modes.IMode {
public static ID = 'vs.editor.modes.nullMode';
public tokenTypeClassificationSupport: Modes.ITokenTypeClassificationSupport;
public richEditSupport: Modes.IRichEditSupport;
constructor() {
this.tokenTypeClassificationSupport = this;
this.richEditSupport = {
tokenTypeClassification: {
getWordDefinition: () => NullMode.DEFAULT_WORD_REGEXP
}
};
}
public getId():string {
......@@ -93,10 +97,6 @@ export class NullMode implements Modes.IMode {
public toSimplifiedMode(): Modes.IMode {
return this;
}
public getWordDefinition():RegExp {
return NullMode.DEFAULT_WORD_REGEXP;
}
}
export function nullTokenize(mode: Modes.IMode, buffer:string, state: Modes.IState, deltaOffset:number = 0, stopAtOffset?:number): Modes.ILineTokens {
......
......@@ -503,57 +503,6 @@ export class TokenizationSupport extends AbstractSupport implements Modes.IToken
}
}
export interface IBracketElectricCharacterContribution {
brackets: Modes.IBracketPair[];
regexBrackets?: Modes.IRegexBracketPair[];
docComment?: Modes.IDocComment;
caseInsensitive?: boolean;
embeddedElectricCharacters?: string[];
}
export class BracketElectricCharacterSupport extends AbstractSupport implements Modes.IElectricCharacterSupport {
private contribution: IBracketElectricCharacterContribution;
private brackets: Brackets;
constructor(mode:Modes.IMode, contribution: IBracketElectricCharacterContribution) {
super(mode);
this.contribution = contribution;
this.brackets = new Brackets(contribution.brackets, contribution.regexBrackets,
contribution.docComment, contribution.caseInsensitive);
}
public getElectricCharacters(): string[]{
if (Array.isArray(this.contribution.embeddedElectricCharacters)) {
return this.contribution.embeddedElectricCharacters.concat(this.brackets.getElectricCharacters());
}
return this.brackets.getElectricCharacters();
}
public onElectricCharacter(context:Modes.ILineContext, offset:number): Modes.IElectricAction {
return handleEvent(context, offset, (nestedMode:Modes.IMode, context:Modes.ILineContext, offset:number) => {
if (this.mode === nestedMode) {
return this.brackets.onElectricCharacter(context, offset);
} else if (nestedMode.electricCharacterSupport) {
return nestedMode.electricCharacterSupport.onElectricCharacter(context, offset);
} else {
return null;
}
});
}
public onEnter(context: Modes.ILineContext, offset: number): Modes.IEnterAction {
return handleEvent(context, offset, (nestedMode:Modes.IMode, context:Modes.ILineContext, offset:number) => {
if (this.mode === nestedMode) {
return this.brackets.onEnter(context, offset);
} else if (nestedMode.electricCharacterSupport) {
return nestedMode.electricCharacterSupport.onEnter(context, offset);
} else {
return null;
}
});
}
}
// TODO@Alex -> refactor to use `brackets` from language configuration
export function getBracketFor(tokenType:string, tokenText:string, mode:Modes.IMode): Modes.Bracket {
if (tokenText === '{' || tokenText === '(' || tokenText === '[') {
......@@ -786,61 +735,6 @@ export class ComposableSuggestSupport extends SuggestSupport {
}
export class CharacterPairSupport extends AbstractSupport implements Modes.ICharacterPairSupport {
private _autoClosingPairs: Modes.IAutoClosingPairConditional[];
private _surroundingPairs: Modes.IAutoClosingPair[];
constructor(mode: Modes.IMode, contribution: Modes.ICharacterPairContribution) {
super(mode);
this._autoClosingPairs = contribution.autoClosingPairs;
this._surroundingPairs = Array.isArray(contribution.surroundingPairs) ? contribution.surroundingPairs : contribution.autoClosingPairs;
}
public getAutoClosingPairs(): Modes.IAutoClosingPair[] {
return this._autoClosingPairs;
}
public shouldAutoClosePair(character:string, context:Modes.ILineContext, offset:number): boolean {
return handleEvent(context, offset, (nestedMode:Modes.IMode, context:Modes.ILineContext, offset:number) => {
if (this.mode === nestedMode) {
// Always complete on empty line
if (context.getTokenCount() === 0) {
return true;
}
var tokenIndex = context.findIndexOfOffset(offset - 1);
var tokenType = context.getTokenType(tokenIndex);
for (var i = 0; i < this._autoClosingPairs.length; ++i) {
if (this._autoClosingPairs[i].open === character) {
if (this._autoClosingPairs[i].notIn) {
for (var notInIndex = 0; notInIndex < this._autoClosingPairs[i].notIn.length; ++notInIndex) {
if (tokenType.indexOf(this._autoClosingPairs[i].notIn[notInIndex]) > -1) {
return false;
}
}
}
break;
}
}
return true;
} else if (nestedMode.characterPairSupport) {
return nestedMode.characterPairSupport.shouldAutoClosePair(character, context, offset);
} else {
return null;
}
});
}
public getSurroundingPairs(): Modes.IAutoClosingPair[]{
return this._surroundingPairs;
}
}
export interface IReplaceSupportHelper {
valueSetReplace(valueSet: string[], value: string, up: boolean): string;
valueSetsReplace(valueSets: string[][], value: string, up: boolean): string;
......@@ -1012,41 +906,3 @@ export class MainInplaceReplaceSupport extends AbstractInplaceReplaceSupport {
return this.modelService.getModel(resource);
}
}
export interface ICommentsSupportContribution {
commentsConfiguration: Modes.ICommentsConfiguration;
}
export class CommentsSupport implements Modes.ICommentsSupport {
private _contribution: ICommentsSupportContribution;
constructor(contribution:ICommentsSupportContribution) {
this._contribution = contribution;
}
public getCommentsConfiguration(): Modes.ICommentsConfiguration {
return this._contribution.commentsConfiguration;
}
}
export interface ITokenTypeClassificationSupportContribution {
wordDefinition?: RegExp;
}
export class TokenTypeClassificationSupport implements Modes.ITokenTypeClassificationSupport {
private _contribution: ITokenTypeClassificationSupportContribution;
constructor(contribution: ITokenTypeClassificationSupportContribution) {
this._contribution = contribution;
}
public getWordDefinition(): RegExp {
if (typeof this._contribution.wordDefinition === 'undefined') {
return NullMode.DEFAULT_WORD_REGEXP;
}
return this._contribution.wordDefinition;
}
}
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {handleEvent} from 'vs/editor/common/modes/supports';
import * as Modes from 'vs/editor/common/modes';
export class CharacterPairSupport implements Modes.IRichEditCharacterPair {
private _modeId: string;
private _autoClosingPairs: Modes.IAutoClosingPairConditional[];
private _surroundingPairs: Modes.IAutoClosingPair[];
constructor(modeId: string, contribution: Modes.ICharacterPairContribution) {
this._modeId = modeId;
this._autoClosingPairs = contribution.autoClosingPairs;
this._surroundingPairs = Array.isArray(contribution.surroundingPairs) ? contribution.surroundingPairs : contribution.autoClosingPairs;
}
public getAutoClosingPairs(): Modes.IAutoClosingPair[] {
return this._autoClosingPairs;
}
public shouldAutoClosePair(character:string, context:Modes.ILineContext, offset:number): boolean {
return handleEvent(context, offset, (nestedMode:Modes.IMode, context:Modes.ILineContext, offset:number) => {
if (this._modeId === nestedMode.getId()) {
// Always complete on empty line
if (context.getTokenCount() === 0) {
return true;
}
var tokenIndex = context.findIndexOfOffset(offset - 1);
var tokenType = context.getTokenType(tokenIndex);
for (var i = 0; i < this._autoClosingPairs.length; ++i) {
if (this._autoClosingPairs[i].open === character) {
if (this._autoClosingPairs[i].notIn) {
for (var notInIndex = 0; notInIndex < this._autoClosingPairs[i].notIn.length; ++notInIndex) {
if (tokenType.indexOf(this._autoClosingPairs[i].notIn[notInIndex]) > -1) {
return false;
}
}
}
break;
}
}
return true;
} else if (nestedMode.richEditSupport && nestedMode.richEditSupport.characterPair) {
return nestedMode.richEditSupport.characterPair.shouldAutoClosePair(character, context, offset);
} else {
return null;
}
});
}
public getSurroundingPairs(): Modes.IAutoClosingPair[]{
return this._surroundingPairs;
}
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as Modes from 'vs/editor/common/modes';
export interface ICommentsSupportContribution {
commentsConfiguration: Modes.ICommentsConfiguration;
}
export class CommentsSupport implements Modes.IRichEditComments {
private _contribution: ICommentsSupportContribution;
constructor(contribution:ICommentsSupportContribution) {
this._contribution = contribution;
}
public getCommentsConfiguration(): Modes.ICommentsConfiguration {
return this._contribution.commentsConfiguration;
}
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {Brackets} from 'vs/editor/common/modes/autoIndentation';
import * as Modes from 'vs/editor/common/modes';
import {handleEvent} from 'vs/editor/common/modes/supports';
export interface IBracketElectricCharacterContribution {
brackets: Modes.IBracketPair[];
regexBrackets?: Modes.IRegexBracketPair[];
docComment?: Modes.IDocComment;
caseInsensitive?: boolean;
embeddedElectricCharacters?: string[];
}
export class BracketElectricCharacterSupport implements Modes.IRichEditElectricCharacter {
private _modeId: string;
private contribution: IBracketElectricCharacterContribution;
private brackets: Brackets;
constructor(modeId: string, contribution: IBracketElectricCharacterContribution) {
this._modeId = modeId;
this.contribution = contribution;
this.brackets = new Brackets(contribution.brackets, contribution.regexBrackets,
contribution.docComment, contribution.caseInsensitive);
}
public getElectricCharacters(): string[]{
if (Array.isArray(this.contribution.embeddedElectricCharacters)) {
return this.contribution.embeddedElectricCharacters.concat(this.brackets.getElectricCharacters());
}
return this.brackets.getElectricCharacters();
}
public onElectricCharacter(context:Modes.ILineContext, offset:number): Modes.IElectricAction {
return handleEvent(context, offset, (nestedMode:Modes.IMode, context:Modes.ILineContext, offset:number) => {
if (this._modeId === nestedMode.getId()) {
return this.brackets.onElectricCharacter(context, offset);
} else if (nestedMode.richEditSupport && nestedMode.richEditSupport.electricCharacter) {
return nestedMode.richEditSupport.electricCharacter.onElectricCharacter(context, offset);
} else {
return null;
}
});
}
public onEnter(context: Modes.ILineContext, offset: number): Modes.IEnterAction {
return handleEvent(context, offset, (nestedMode:Modes.IMode, context:Modes.ILineContext, offset:number) => {
if (this._modeId === nestedMode.getId()) {
return this.brackets.onEnter(context, offset);
} else if (nestedMode.richEditSupport && nestedMode.richEditSupport.electricCharacter) {
return nestedMode.richEditSupport.electricCharacter.onEnter(context, offset);
} else {
return null;
}
});
}
}
......@@ -5,7 +5,7 @@
'use strict';
import {handleEvent} from 'vs/editor/common/modes/supports';
import {IEnterAction, IndentAction, IOnEnterSupport, ILineContext, IMode} from 'vs/editor/common/modes';
import {IEnterAction, IndentAction, IRichEditOnEnter, ILineContext, IMode} from 'vs/editor/common/modes';
import EditorCommon = require('vs/editor/common/editorCommon');
import Errors = require('vs/base/common/errors');
import Strings = require('vs/base/common/strings');
......@@ -40,7 +40,7 @@ interface IProcessedBracketPair extends IBracketPair {
closeRegExp: RegExp;
}
export class OnEnterSupport implements IOnEnterSupport {
export class OnEnterSupport implements IRichEditOnEnter {
private static _INDENT: IEnterAction = { indentAction: IndentAction.Indent };
private static _INDENT_OUTDENT: IEnterAction = { indentAction: IndentAction.IndentOutdent };
......@@ -78,8 +78,8 @@ export class OnEnterSupport implements IOnEnterSupport {
return handleEvent(context, position.column - 1, (nestedMode:IMode, context:ILineContext, offset:number) => {
if (this._modeId === nestedMode.getId()) {
return this._onEnter(model, position);
} else if (nestedMode.onEnterSupport) {
return nestedMode.onEnterSupport.onEnter(model, position);
} else if (nestedMode.richEditSupport && nestedMode.richEditSupport.onEnter) {
return nestedMode.richEditSupport.onEnter.onEnter(model, position);
} else {
return null;
}
......@@ -184,19 +184,21 @@ export class OnEnterSupport implements IOnEnterSupport {
export function getRawEnterActionAtPosition(model:EditorCommon.ITokenizedModel, lineNumber:number, column:number): IEnterAction {
let enterAction:IEnterAction;
if (model.getMode().onEnterSupport) {
let richEditSupport = model.getMode().richEditSupport;
if (richEditSupport && richEditSupport.onEnter) {
try {
enterAction = model.getMode().onEnterSupport.onEnter(model, new Position(lineNumber, column));
enterAction = richEditSupport.onEnter.onEnter(model, new Position(lineNumber, column));
} catch (e) {
Errors.onUnexpectedError(e);
}
}
if (!enterAction) {
if (model.getMode().electricCharacterSupport) {
if (richEditSupport && richEditSupport.electricCharacter) {
let lineContext = model.getLineContext(lineNumber);
try {
enterAction = model.getMode().electricCharacterSupport.onEnter(lineContext, column - 1);
enterAction = richEditSupport.electricCharacter.onEnter(lineContext, column - 1);
} catch(e) {
Errors.onUnexpectedError(e);
}
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as Modes from 'vs/editor/common/modes';
import {OnEnterSupport, IOnEnterSupportOptions, IIndentationRules, IOnEnterRegExpRules} from 'vs/editor/common/modes/supports/onEnter';
import {CharacterPairSupport} from 'vs/editor/common/modes/supports/characterPair';
import {BracketElectricCharacterSupport, IBracketElectricCharacterContribution} from 'vs/editor/common/modes/supports/electricCharacter';
import {TokenTypeClassificationSupport} from 'vs/editor/common/modes/supports/tokenTypeClassification';
import {CommentsSupport, ICommentsSupportContribution} from 'vs/editor/common/modes/supports/comments';
export type CharacterPair = [string, string];
export interface CommentRule {
lineComment?: string;
blockComment?: CharacterPair;
}
export interface IRichEditConfiguration {
comments?: CommentRule;
brackets?: CharacterPair[];
wordPattern?: RegExp;
indentationRules?: IIndentationRules;
onEnterRules?: IOnEnterRegExpRules[];
__electricCharacterSupport?: IBracketElectricCharacterContribution;
__characterPairSupport?: Modes.ICharacterPairContribution;
}
export class RichEditSupport implements Modes.IRichEditSupport {
public electricCharacter: Modes.IRichEditElectricCharacter;
public comments: Modes.IRichEditComments;
public characterPair: Modes.IRichEditCharacterPair;
public tokenTypeClassification: Modes.IRichEditTokenTypeClassification;
public onEnter: Modes.IRichEditOnEnter;
constructor(modeId:string, conf:IRichEditConfiguration) {
this._handleOnEnter(modeId, conf);
this._handleComments(modeId, conf);
if (conf.__characterPairSupport) {
this.characterPair = new CharacterPairSupport(modeId, conf.__characterPairSupport);
}
if (conf.__electricCharacterSupport) {
this.electricCharacter = new BracketElectricCharacterSupport(modeId, conf.__electricCharacterSupport);
}
this.tokenTypeClassification = new TokenTypeClassificationSupport({
wordDefinition: conf.wordPattern
});
}
private _handleOnEnter(modeId:string, conf:IRichEditConfiguration): void {
// on enter
let onEnter: IOnEnterSupportOptions = {};
let empty = true;
let {brackets, indentationRules, onEnterRules} = conf;
if (brackets) {
empty = false;
onEnter.brackets = brackets.map(pair => {
let [open, close] = pair;
return { open, close };
});
}
if (indentationRules) {
empty = false;
onEnter.indentationRules = indentationRules;
}
if (onEnterRules) {
empty = false;
onEnter.regExpRules = <any>onEnterRules;
}
if (!empty) {
this.onEnter = new OnEnterSupport(modeId, onEnter);
}
}
private _handleComments(modeId:string, conf:IRichEditConfiguration): void {
let {comments} = conf;
// comment configuration
if (comments) {
let contrib: ICommentsSupportContribution = { commentsConfiguration: {} };
if (comments.lineComment) {
contrib.commentsConfiguration.lineCommentTokens = [comments.lineComment];
}
if (comments.blockComment) {
let [blockStart, blockEnd] = comments.blockComment;
contrib.commentsConfiguration.blockCommentStartToken = blockStart;
contrib.commentsConfiguration.blockCommentEndToken = blockEnd;
}
this.comments = new CommentsSupport(contrib);
}
}
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as Modes from 'vs/editor/common/modes';
import {NullMode} from 'vs/editor/common/modes/nullMode';
export interface ITokenTypeClassificationSupportContribution {
wordDefinition?: RegExp;
}
export class TokenTypeClassificationSupport implements Modes.IRichEditTokenTypeClassification {
private _contribution: ITokenTypeClassificationSupportContribution;
constructor(contribution: ITokenTypeClassificationSupportContribution) {
this._contribution = contribution;
}
public getWordDefinition(): RegExp {
if (typeof this._contribution.wordDefinition === 'undefined') {
return NullMode.DEFAULT_WORD_REGEXP;
}
return this._contribution.wordDefinition;
}
}
......@@ -11,6 +11,7 @@ import Supports = require ('vs/editor/common/modes/supports');
import MonarchTypes = require('vs/editor/common/modes/monarch/monarchTypes');
import {IOnEnterSupportOptions} from 'vs/editor/common/modes/supports/onEnter';
import {IDisposable} from 'vs/base/common/lifecycle';
import {IRichEditConfiguration} from 'vs/editor/common/modes/supports/richEditSupport';
export var IModeService = createDecorator<IModeService>('modeService');
......@@ -34,11 +35,8 @@ export interface IModeService {
getOrCreateModeByLanguageName(languageName: string): TPromise<Modes.IMode>;
getOrCreateModeByFilenameOrFirstLine(filename: string, firstLine?:string): TPromise<Modes.IMode>;
registerDeclarativeCharacterPairSupport(modeId: string, support: Modes.ICharacterPairContribution): IDisposable;
registerCodeLensSupport(modeId: string, support: Modes.ICodeLensSupport): IDisposable;
registerDeclarativeCommentsSupport(modeId: string, support: Supports.ICommentsSupportContribution): IDisposable;
registerDeclarativeDeclarationSupport(modeId: string, contribution: Supports.IDeclarationContribution): IDisposable;
registerDeclarativeElectricCharacterSupport(modeId: string, support: Supports.IBracketElectricCharacterContribution): IDisposable;
registerExtraInfoSupport(modeId: string, support: Modes.IExtraInfoSupport): IDisposable;
registerFormattingSupport(modeId: string, support: Modes.IFormattingSupport): IDisposable;
registerInplaceReplaceSupport(modeId: string, support: Modes.IInplaceReplaceSupport): IDisposable;
......@@ -50,8 +48,7 @@ export interface IModeService {
registerRenameSupport(modeId: string, support: Modes.IRenameSupport): IDisposable;
registerDeclarativeSuggestSupport(modeId: string, declaration: Supports.ISuggestContribution): IDisposable;
registerTokenizationSupport(modeId: string, callback: (mode: Modes.IMode) => Modes.ITokenizationSupport): IDisposable;
registerDeclarativeTokenTypeClassificationSupport(modeId: string, support: Supports.ITokenTypeClassificationSupportContribution): IDisposable;
registerDeclarativeOnEnterSupport(modeId: string, support: IOnEnterSupportOptions): IDisposable;
registerRichEditSupport(modeId: string, support: IRichEditConfiguration): IDisposable;
registerMonarchDefinition(modeId:string, language:MonarchTypes.ILanguage): IDisposable;
}
......@@ -25,6 +25,7 @@ import MonarchCommonTypes = require('vs/editor/common/modes/monarch/monarchCommo
import {OnEnterSupport, IOnEnterSupportOptions} from 'vs/editor/common/modes/supports/onEnter';
import {IDisposable, combinedDispose, empty as EmptyDisposable} from 'vs/base/common/lifecycle';
import {createAsyncDescriptor0, createAsyncDescriptor1} from 'vs/platform/instantiation/common/descriptors';
import {RichEditSupport, IRichEditConfiguration} from 'vs/editor/common/modes/supports/richEditSupport';
interface IModeConfigurationMap { [modeId: string]: any; }
......@@ -263,15 +264,7 @@ export class ModeServiceImpl implements IModeService {
return createTokenizationSupport(this, mode, lexer);
}),
this.registerDeclarativeCommentsSupport(modeId, MonarchDefinition.createCommentsSupport(lexer)),
this.registerDeclarativeElectricCharacterSupport(modeId, MonarchDefinition.createBracketElectricCharacterContribution(lexer)),
this.registerDeclarativeTokenTypeClassificationSupport(modeId, MonarchDefinition.createTokenTypeClassificationSupportContribution(lexer)),
this.registerDeclarativeCharacterPairSupport(modeId, MonarchDefinition.createCharacterPairContribution(lexer)),
this.registerDeclarativeOnEnterSupport(modeId, MonarchDefinition.createOnEnterSupportOptions(lexer))
this.registerRichEditSupport(modeId, MonarchDefinition.createRichEditSupport(lexer))
);
}
......@@ -280,26 +273,18 @@ export class ModeServiceImpl implements IModeService {
return this.doRegisterMonarchDefinition(modeId, lexer);
}
public registerDeclarativeCharacterPairSupport(modeId: string, support: Modes.ICharacterPairContribution): IDisposable {
return this.registerModeSupport(modeId, 'characterPairSupport', (mode) => new Supports.CharacterPairSupport(mode, support));
}
public registerCodeLensSupport(modeId: string, support: Modes.ICodeLensSupport): IDisposable {
return this.registerModeSupport(modeId, 'codeLensSupport', (mode) => support);
}
public registerDeclarativeCommentsSupport(modeId: string, support: Supports.ICommentsSupportContribution): IDisposable {
return this.registerModeSupport(modeId, 'commentsSupport', (mode) => new Supports.CommentsSupport(support));
public registerRichEditSupport(modeId: string, support: IRichEditConfiguration): IDisposable {
return this.registerModeSupport(modeId, 'richEditSupport', (mode) => new RichEditSupport(modeId, support));
}
public registerDeclarativeDeclarationSupport(modeId: string, contribution: Supports.IDeclarationContribution): IDisposable {
return this.registerModeSupport(modeId, 'declarationSupport', (mode) => new Supports.DeclarationSupport(mode, contribution));
}
public registerDeclarativeElectricCharacterSupport(modeId: string, support: Supports.IBracketElectricCharacterContribution): IDisposable {
return this.registerModeSupport(modeId, 'electricCharacterSupport', (mode) => new Supports.BracketElectricCharacterSupport(mode, support));
}
public registerExtraInfoSupport(modeId: string, support: Modes.IExtraInfoSupport): IDisposable {
return this.registerModeSupport(modeId, 'extraInfoSupport', (mode) => support);
}
......@@ -343,14 +328,6 @@ export class ModeServiceImpl implements IModeService {
public registerTokenizationSupport(modeId: string, callback: (mode: Modes.IMode) => Modes.ITokenizationSupport): IDisposable {
return this.registerModeSupport(modeId, 'tokenizationSupport', callback);
}
public registerDeclarativeTokenTypeClassificationSupport(modeId: string, support: Supports.ITokenTypeClassificationSupportContribution): IDisposable {
return this.registerModeSupport(modeId, 'tokenTypeClassificationSupport', (mode) => new Supports.TokenTypeClassificationSupport(support));
}
public registerDeclarativeOnEnterSupport(modeId: string, opts: IOnEnterSupportOptions): IDisposable {
return this.registerModeSupport(modeId, 'onEnterSupport', (mode) => new OnEnterSupport(modeId, opts));
}
}
export class MainThreadModeServiceImpl extends ModeServiceImpl {
......
......@@ -121,7 +121,8 @@ export class BlockCommentCommand implements EditorCommon.ICommand {
var endLineNumber = this._selection.endLineNumber;
var endColumn = this._selection.endColumn;
var commentsSupport = model.getModeAtPosition(startLineNumber, startColumn).commentsSupport;
let richEditSupport = model.getModeAtPosition(startLineNumber, startColumn).richEditSupport;
var commentsSupport = richEditSupport? richEditSupport.comments : null;
if (!commentsSupport) {
// Mode does not support comments
return;
......
......@@ -81,7 +81,7 @@ export class LineCommentCommand implements EditorCommon.ICommand {
if (seenModes[modeId]) {
commentStr = seenModes[modeId];
} else {
config = (mode.commentsSupport ? mode.commentsSupport.getCommentsConfiguration() : null);
config = (mode.richEditSupport && mode.richEditSupport.comments ? mode.richEditSupport.comments.getCommentsConfiguration() : null);
commentStr = (config && config.lineCommentTokens && config.lineCommentTokens.length > 0 ? config.lineCommentTokens[0] : null);
if (commentStr === null || commentStr.length === 0) {
// Mode does not support line comments
......@@ -273,7 +273,8 @@ export class LineCommentCommand implements EditorCommon.ICommand {
* Given an unsuccessful analysis, delegate to the block comment command
*/
private _executeBlockComment(model:EditorCommon.ITokenizedModel, builder:EditorCommon.IEditOperationBuilder, s:EditorCommon.IEditorSelection): void {
var commentsSupport = model.getModeAtPosition(s.startLineNumber, s.startColumn).commentsSupport;
let richEditSupport = model.getModeAtPosition(s.startLineNumber, s.startColumn).richEditSupport;
var commentsSupport = richEditSupport ? richEditSupport.comments : null;
if (!commentsSupport) {
// Mode does not support comments
return;
......
......@@ -12,6 +12,7 @@ import Supports = require ('vs/editor/common/modes/supports');
import {IOnEnterSupportOptions} from 'vs/editor/common/modes/supports/onEnter';
import json = require('vs/base/common/json');
import {ICharacterPairContribution} from 'vs/editor/common/modes';
import {IRichEditConfiguration} from 'vs/editor/common/modes/supports/richEditSupport';
type CharacterPair = [string, string];
......@@ -62,47 +63,33 @@ export class LanguageConfigurationFileHandler {
}
private _handleConfig(modeId:string, configuration:ILanguageConfiguration): void {
if (configuration.comments) {
let comments = configuration.comments;
let contrib: Supports.ICommentsSupportContribution = { commentsConfiguration: {} };
if (comments.lineComment) {
contrib.commentsConfiguration.lineCommentTokens = [comments.lineComment];
}
if (comments.blockComment) {
contrib.commentsConfiguration.blockCommentStartToken = comments.blockComment[0];
contrib.commentsConfiguration.blockCommentEndToken = comments.blockComment[1];
}
let richEditConfig:IRichEditConfiguration = {};
this._modeService.registerDeclarativeCommentsSupport(modeId, contrib);
if (configuration.comments) {
richEditConfig.comments = configuration.comments;
}
if (configuration.brackets) {
let brackets = configuration.brackets;
richEditConfig.brackets = configuration.brackets;
let onEnterContrib: IOnEnterSupportOptions = {};
onEnterContrib.brackets = brackets.map(pair => {
let [open, close] = pair;
return { open: open, close: close };
});
this._modeService.registerDeclarativeOnEnterSupport(modeId, onEnterContrib);
let characterPairContrib: ICharacterPairContribution = {
autoClosingPairs: brackets.map(pair => {
richEditConfig.__characterPairSupport = {
autoClosingPairs: configuration.brackets.map(pair => {
let [open, close] = pair;
return { open: open, close: close };
})
};
this._modeService.registerDeclarativeCharacterPairSupport(modeId, characterPairContrib);
}
}
// TMSyntax hard-codes these and tokenizes them as brackets
this._modeService.registerDeclarativeElectricCharacterSupport(modeId, {
richEditConfig.__electricCharacterSupport = {
brackets: [
{ tokenType:'delimiter.curly.' + modeId, open: '{', close: '}', isElectric: true },
{ tokenType:'delimiter.square.' + modeId, open: '[', close: ']', isElectric: true },
{ tokenType:'delimiter.paren.' + modeId, open: '(', close: ')', isElectric: true }
]
});
};
this._modeService.registerRichEditSupport(modeId, richEditConfig);
}
}
......@@ -11,6 +11,7 @@ import modesUtil = require('vs/editor/test/common/modesUtil');
import monarchCompile = require('vs/editor/common/modes/monarch/monarchCompile');
import MonarchDefinition = require('vs/editor/common/modes/monarch/monarchDefinition');
import {OnEnterSupport} from 'vs/editor/common/modes/supports/onEnter';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
export enum Bracket {
None = 0,
......@@ -47,8 +48,8 @@ export function testOnEnter(name:string, language: types.ILanguage, callback:(as
suite(language.displayName || name, () => {
test('onEnter', () => {
var lexer = monarchCompile.compile(language);
var onEnterSupport = new OnEnterSupport('test', MonarchDefinition.createOnEnterSupportOptions(lexer));
callback(modesUtil.createOnEnterAsserter('test', onEnterSupport));
var richEditSupport = new RichEditSupport('test', MonarchDefinition.createRichEditSupport(lexer));
callback(modesUtil.createOnEnterAsserter('test', richEditSupport));
});
});
}
\ No newline at end of file
}
......@@ -13,6 +13,7 @@ import {Selection} from 'vs/editor/common/core/selection';
import {Cursor} from 'vs/editor/common/controller/cursor';
import * as Modes from 'vs/editor/common/modes';
import {OnEnterSupport} from 'vs/editor/common/modes/supports/onEnter';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
function testShiftCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
TU.testCommand(lines, null, selection, (sel) => new ShiftCommand(sel, {
......@@ -32,16 +33,17 @@ function testUnshiftCommand(lines: string[], selection: Selection, expectedLines
class DocBlockCommentMode implements Modes.IMode {
public onEnterSupport: Modes.IOnEnterSupport;
public richEditSupport: Modes.IRichEditSupport;
constructor() {
this.onEnterSupport = new OnEnterSupport(this.getId(), {
this.richEditSupport = new RichEditSupport(this.getId(), {
brackets: [
{ open: '(', close: ')' },
{ open: '{', close: '}' },
{ open: '[', close: ']' }
['(', ')'],
['{', '}'],
['[', ']']
],
regExpRules: [
onEnterRules: [
{
// e.g. /** | */
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
......
......@@ -15,7 +15,7 @@ import {Handler, EventType, IPosition, ISelection, EndOfLinePreference} from 'vs
import {MockConfiguration} from 'vs/editor/test/common/mocks/mockConfiguration';
import {EditOperation} from 'vs/editor/common/core/editOperation';
import {AbstractState} from 'vs/editor/common/modes/abstractState';
import {CharacterPairSupport} from 'vs/editor/common/modes/supports';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
let H = Handler;
......@@ -768,28 +768,32 @@ class TestMode {
}
class SurroundingMode extends TestMode {
public characterPairSupport: Modes.ICharacterPairSupport;
public richEditSupport: Modes.IRichEditSupport;
constructor() {
super();
this.characterPairSupport = new CharacterPairSupport(this, {
autoClosingPairs: [{ open: '(', close: ')' }]
this.richEditSupport = new RichEditSupport(this.getId(), {
__characterPairSupport: {
autoClosingPairs: [{ open: '(', close: ')' }]
}
});
}
}
class OnEnterMode extends TestMode {
public electricCharacterSupport: Modes.IElectricCharacterSupport;
public richEditSupport: Modes.IRichEditSupport;
constructor(indentAction: Modes.IndentAction) {
super();
this.electricCharacterSupport = {
getElectricCharacters: ():string[] => null,
onElectricCharacter: (context:Modes.ILineContext, offset:number): Modes.IElectricAction => null,
onEnter: (context:Modes.ILineContext, offset:number): Modes.IEnterAction => {
return {
indentAction: indentAction
};
this.richEditSupport = {
electricCharacter: {
getElectricCharacters: ():string[] => null,
onElectricCharacter: (context:Modes.ILineContext, offset:number): Modes.IElectricAction => null,
onEnter: (context:Modes.ILineContext, offset:number): Modes.IEnterAction => {
return {
indentAction: indentAction
};
}
}
};
}
......
......@@ -4,47 +4,45 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import modes = require('vs/editor/common/modes');
import Modes = require('vs/editor/common/modes');
import {Arrays} from 'vs/editor/common/core/arrays';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
class SimpleTokenTypeClassificationMode implements modes.IMode {
class SimpleTokenTypeClassificationMode implements Modes.IMode {
private _id:string;
public tokenTypeClassificationSupport: modes.ITokenTypeClassificationSupport;
constructor(id:string, tokenTypeClassificationSupport: modes.ITokenTypeClassificationSupport) {
public richEditSupport: Modes.IRichEditSupport;
constructor(id:string, wordRegExp:RegExp) {
this._id = id;
this.tokenTypeClassificationSupport = tokenTypeClassificationSupport;
this.richEditSupport = new RichEditSupport(this._id, {
wordPattern: wordRegExp
});
}
public getId(): string {
return this._id;
}
public toSimplifiedMode(): modes.IMode {
public toSimplifiedMode(): Modes.IMode {
return this;
}
}
export function createMockMode(id:string, wordRegExp:RegExp = null):modes.IMode {
var tokenTypeClassificationSupport: modes.ITokenTypeClassificationSupport;
if (wordRegExp) {
tokenTypeClassificationSupport = {
getWordDefinition: () => wordRegExp
};
}
return new SimpleTokenTypeClassificationMode(id, tokenTypeClassificationSupport);
export function createMockMode(id:string, wordRegExp:RegExp = null):Modes.IMode {
return new SimpleTokenTypeClassificationMode(id, wordRegExp);
}
export interface TokenText {
text: string;
type: string;
bracket?: modes.Bracket;
bracket?: Modes.Bracket;
}
export function createLineContextFromTokenText(tokens: TokenText[]): modes.ILineContext {
export function createLineContextFromTokenText(tokens: TokenText[]): Modes.ILineContext {
var line = '';
var processedTokens: modes.IToken[] = [];
var processedTokens: Modes.IToken[] = [];
var indexSoFar = 0;
for (var i = 0; i < tokens.length; ++i){
......@@ -56,17 +54,17 @@ export function createLineContextFromTokenText(tokens: TokenText[]): modes.ILine
return new TestLineContext(line, processedTokens, null);
}
export function createLineContext(line:string, tokens:modes.ILineTokens): modes.ILineContext {
export function createLineContext(line:string, tokens:Modes.ILineTokens): Modes.ILineContext {
return new TestLineContext(line, tokens.tokens, tokens.modeTransitions);
}
class TestLineContext implements modes.ILineContext {
class TestLineContext implements Modes.ILineContext {
public modeTransitions: modes.IModeTransition[];
public modeTransitions: Modes.IModeTransition[];
private _line:string;
private _tokens: modes.IToken[];
private _tokens: Modes.IToken[];
constructor(line:string, tokens: modes.IToken[], modeTransitions:modes.IModeTransition[]) {
constructor(line:string, tokens: Modes.IToken[], modeTransitions:Modes.IModeTransition[]) {
this.modeTransitions = modeTransitions;
this._line = line;
this._tokens = tokens;
......
......@@ -38,7 +38,7 @@ export function createOnElectricCharacter(mode:modes.IMode): IOnElectricCharacte
return function onElectricCharacter(line:string, offset:number, state?:modes.IState): modes.IElectricAction {
state = state || mode.tokenizationSupport.getInitialState();
var lineTokens = mode.tokenizationSupport.tokenize(line, state);
return mode.electricCharacterSupport.onElectricCharacter(createLineContext(line, lineTokens), offset);
return mode.richEditSupport.electricCharacter.onElectricCharacter(createLineContext(line, lineTokens), offset);
};
}
......@@ -50,7 +50,7 @@ export function createOnEnter(mode:modes.IMode): IOnEnterFunc {
return function onEnter(line:string, offset:number, state?:modes.IState): modes.IEnterAction {
state = state || mode.tokenizationSupport.getInitialState();
var lineTokens = mode.tokenizationSupport.tokenize(line, state);
return mode.electricCharacterSupport.onEnter(createLineContext(line, lineTokens), offset);
return mode.richEditSupport.electricCharacter.onEnter(createLineContext(line, lineTokens), offset);
};
}
......@@ -103,13 +103,13 @@ class SimpleMode implements modes.IMode {
}
}
export function createOnEnterAsserter(modeId:string, onEnterSupport: modes.IOnEnterSupport): IOnEnterAsserter {
export function createOnEnterAsserter(modeId:string, richEditSupport: modes.IRichEditSupport): IOnEnterAsserter {
var assertOne = (oneLineAboveText:string, beforeText:string, afterText:string, expected: modes.IndentAction) => {
var model = new Model(
[ oneLineAboveText, beforeText + afterText ].join('\n'),
new SimpleMode(modeId)
);
var actual = onEnterSupport.onEnter(model, { lineNumber: 2, column: beforeText.length + 1 });
var actual = richEditSupport.onEnter.onEnter(model, { lineNumber: 2, column: beforeText.length + 1 });
if (expected === modes.IndentAction.None) {
assert.equal(actual, null, oneLineAboveText + '\\n' + beforeText + '|' + afterText);
} else {
......
......@@ -9,6 +9,7 @@ import supports = require('vs/editor/common/modes/supports');
import {AbstractMode} from 'vs/editor/common/modes/abstractMode';
import {AbstractState} from 'vs/editor/common/modes/abstractState';
import {AbstractModeWorker} from 'vs/editor/common/modes/abstractModeWorker';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
export class CommentState extends AbstractState {
......@@ -32,21 +33,21 @@ export class CommentState extends AbstractState {
export class CommentMode extends AbstractMode<AbstractModeWorker> {
private commentsConfig:modes.ICommentsConfiguration;
public tokenizationSupport: modes.ITokenizationSupport;
public richEditSupport: modes.IRichEditSupport;
constructor(commentsConfig:modes.ICommentsConfiguration) {
super({ id: 'tests.commentMode', workerParticipants: [] }, null, null);
this.commentsConfig = commentsConfig;
this.tokenizationSupport = new supports.TokenizationSupport(this, {
getInitialState: () => new CommentState(this, 0)
}, false, false);
}
public getCommentsConfiguration():modes.ICommentsConfiguration {
return this.commentsConfig;
this.richEditSupport = {
comments: {
getCommentsConfiguration: () => commentsConfig
}
};
}
}
......
......@@ -20,6 +20,7 @@ import {IMarker} from 'vs/platform/markers/common/markers';
import {OnEnterSupport} from 'vs/editor/common/modes/supports/onEnter';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IThreadService} from 'vs/platform/thread/common/thread';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
export enum States {
Selector,
......@@ -279,8 +280,7 @@ export class State extends AbstractState {
export class CSSMode extends AbstractMode<cssWorker.CSSWorker> {
public tokenizationSupport: Modes.ITokenizationSupport;
public electricCharacterSupport: Modes.IElectricCharacterSupport;
public characterPairSupport: Modes.ICharacterPairSupport;
public richEditSupport: Modes.IRichEditSupport;
public referenceSupport: Modes.IReferenceSupport;
public logicalSelectionSupport: Modes.ILogicalSelectionSupport;
......@@ -290,7 +290,6 @@ export class CSSMode extends AbstractMode<cssWorker.CSSWorker> {
public declarationSupport: Modes.IDeclarationSupport;
public suggestSupport: Modes.ISuggestSupport;
public quickFixSupport: Modes.IQuickFixSupport;
public onEnterSupport: Modes.IOnEnterSupport;
constructor(
descriptor:Modes.IModeDescriptor,
......@@ -302,9 +301,37 @@ export class CSSMode extends AbstractMode<cssWorker.CSSWorker> {
this.tokenizationSupport = new supports.TokenizationSupport(this, {
getInitialState: () => new State(this, States.Selector, false, null, false, 0)
}, false, false);
this.electricCharacterSupport = new supports.BracketElectricCharacterSupport(this, { brackets: [
{ tokenType: 'punctuation.bracket.css', open: '{', close: '}', isElectric: true }
] });
this.richEditSupport = new RichEditSupport(this.getId(), {
// TODO@Martin: This definition does not work with umlauts for example
wordPattern: /(#?-?\d*\.\d\w*%?)|((::|[@#.!:])?[\w-?]+%?)|::|[@#.!:]/g,
comments: {
blockComment: ['/*', '*/']
},
brackets: [
['{', '}'],
['[', ']'],
['(', ')']
],
__electricCharacterSupport: {
brackets: [
{ tokenType: 'punctuation.bracket.css', open: '{', close: '}', isElectric: true }
]
},
__characterPairSupport: {
autoClosingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"', notIn: ['string'] },
{ open: '\'', close: '\'', notIn: ['string'] }
]
}
});
this.occurrencesSupport = this;
this.extraInfoSupport = this;
......@@ -317,27 +344,11 @@ export class CSSMode extends AbstractMode<cssWorker.CSSWorker> {
tokens: [cssTokenTypes.TOKEN_VALUE + '.css'],
findDeclaration: (resource, position) => this.findDeclaration(resource, position)});
this.characterPairSupport = new supports.CharacterPairSupport(this, {
autoClosingPairs:
[ { open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"', notIn: ['string'] },
{ open: '\'', close: '\'', notIn: ['string'] }
]});
this.suggestSupport = new supports.SuggestSupport(this, {
triggerCharacters: [' ', ':'],
excludeTokens: ['comment.css', 'string.css'],
suggest: (resource, position) => this.suggest(resource, position)});
this.onEnterSupport = new OnEnterSupport(this.getId(), {
brackets: [
{ open: '(', close: ')' },
{ open: '{', close: '}' },
{ open: '[', close: ']' }
]
});
this.quickFixSupport = this;
}
......@@ -376,15 +387,6 @@ export class CSSMode extends AbstractMode<cssWorker.CSSWorker> {
return this._worker((w) => w.getOutline(resource));
}
public getCommentsConfiguration():Modes.ICommentsConfiguration {
return { blockCommentStartToken: '/*', blockCommentEndToken: '*/' };
}
// TODO@Martin: This definition does not work with umlauts for example
public getWordDefinition():RegExp {
return /(#?-?\d*\.\d\w*%?)|((::|[@#.!:])?[\w-?]+%?)|::|[@#.!:]/g;
}
static $findColorDeclarations = OneWorkerAttr(CSSMode, CSSMode.prototype.findColorDeclarations);
public findColorDeclarations(resource:URI):WinJS.TPromise<{range:EditorCommon.IRange; value:string; }[]> {
return this._worker((w) => w.findColorDeclarations(resource));
......
......@@ -21,8 +21,8 @@ suite('CSS Colorizing', () => {
suiteSetup((done) => {
modesUtil.load('css').then(mode => {
tokenizationSupport = mode.tokenizationSupport;
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.onEnterSupport);
wordDefinition = mode.tokenTypeClassificationSupport.getWordDefinition();
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.richEditSupport);
wordDefinition = mode.richEditSupport.tokenTypeClassification.getWordDefinition();
done();
});
});
......
......@@ -14,6 +14,8 @@ import htmlWorker = require('vs/languages/html/common/htmlWorker');
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IThreadService} from 'vs/platform/thread/common/thread';
import {IModeService} from 'vs/editor/common/services/modeService';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
import {createWordRegExp} from 'vs/editor/common/modes/abstractMode';
export enum States {
HTML,
......@@ -115,29 +117,44 @@ export class HandlebarsMode extends htmlMode.HTMLMode<htmlWorker.HTMLWorker> {
super(descriptor, instantiationService, threadService, modeService);
this.formattingSupport = null;
this.onEnterSupport = new OnEnterSupport(this.getId(), {
brackets: [
{ open: '<!--', close: '-->' },
{ open: '{{', close: '}}' },
]
});
}
public asyncCtor(): winjs.Promise {
return super.asyncCtor().then(() => {
var pairs = this.characterPairSupport.getAutoClosingPairs().slice(0).concat([
{ open: '{', close: '}'}
]);
protected _createRichEditSupport(embeddedAutoClosingPairs: Modes.IAutoClosingPair[]): Modes.IRichEditSupport {
return new RichEditSupport(this.getId(), {
this.characterPairSupport = new supports.CharacterPairSupport(this, {
autoClosingPairs: pairs.slice(0),
wordPattern: createWordRegExp('#-?%'),
comments: {
blockComment: ['<!--', '-->']
},
brackets: [
['<!--', '-->'],
['{{', '}}']
],
__electricCharacterSupport: {
brackets: [],
regexBrackets: [{
tokenType: htmlMode.htmlTokenTypes.getTag('$1'),
open: new RegExp(`<(?!(?:${htmlMode.EMPTY_ELEMENTS.join("|")}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
closeComplete: '</$1>',
close: /<\/(\w[\w\d]*)\s*>$/i
}],
caseInsensitive: true,
embeddedElectricCharacters: ['*', '}', ']', ')']
},
__characterPairSupport: {
autoClosingPairs: embeddedAutoClosingPairs.slice(0).concat([
{ open: '{', close: '}'}
]),
surroundingPairs: [
{ open: '<', close: '>' },
{ open: '"', close: '"' },
{ open: '\'', close: '\'' }
]
});
}
});
}
......
......@@ -25,8 +25,10 @@ import {IInstantiationService} from 'vs/platform/instantiation/common/instantiat
import {IThreadService } from 'vs/platform/thread/common/thread';
import * as htmlTokenTypes from 'vs/languages/html/common/htmlTokenTypes';
import {EMPTY_ELEMENTS} from 'vs/languages/html/common/htmlEmptyTagsShared';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
export { htmlTokenTypes }; // export to be used by Razor. We are the main module, so Razor should get ot from use.
export { EMPTY_ELEMENTS }; // export to be used by Razor. We are the main module, so Razor should get ot from use.
export enum States {
Content,
......@@ -273,8 +275,7 @@ export class State extends AbstractState {
export class HTMLMode<W extends htmlWorker.HTMLWorker> extends AbstractMode<W> implements supports.ITokenizationCustomization {
public tokenizationSupport: Modes.ITokenizationSupport;
public electricCharacterSupport: Modes.IElectricCharacterSupport;
public characterPairSupport: Modes.ICharacterPairSupport;
public richEditSupport: Modes.IRichEditSupport;
public extraInfoSupport:Modes.IExtraInfoSupport;
public occurrencesSupport:Modes.IOccurrencesSupport;
......@@ -283,7 +284,6 @@ export class HTMLMode<W extends htmlWorker.HTMLWorker> extends AbstractMode<W> i
public formattingSupport: Modes.IFormattingSupport;
public parameterHintsSupport: Modes.IParameterHintsSupport;
public suggestSupport: Modes.ISuggestSupport;
public onEnterSupport: Modes.IOnEnterSupport;
private modeService:IModeService;
......@@ -298,17 +298,6 @@ export class HTMLMode<W extends htmlWorker.HTMLWorker> extends AbstractMode<W> i
this.modeService = modeService;
this.tokenizationSupport = new supports.TokenizationSupport(this, this, true, true);
this.electricCharacterSupport = new supports.BracketElectricCharacterSupport(this,
{
brackets: [],
regexBrackets:[
{ tokenType: htmlTokenTypes.getTag('$1'),
open: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join("|")}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
closeComplete: '</$1>',
close: /<\/(\w[\w\d]*)\s*>$/i }],
caseInsensitive:true,
embeddedElectricCharacters: ['*', '}', ']', ')']
});
this.formattingSupport = this;
this.extraInfoSupport = this;
......@@ -331,12 +320,6 @@ export class HTMLMode<W extends htmlWorker.HTMLWorker> extends AbstractMode<W> i
triggerCharacters: ['.', ':', '<', '"', '=', '/'],
excludeTokens: ['comment'],
suggest: (resource, position) => this.suggest(resource, position)});
this.onEnterSupport = new OnEnterSupport(this.getId(), {
brackets: [
{ open: '<!--', close: '-->' }
]
});
}
public asyncCtor(): winjs.Promise {
......@@ -345,13 +328,42 @@ export class HTMLMode<W extends htmlWorker.HTMLWorker> extends AbstractMode<W> i
this.modeService.getOrCreateMode('text/css')
]).then((embeddableModes) => {
var autoClosingPairs = this._getAutoClosingPairs(embeddableModes);
this.richEditSupport = this._createRichEditSupport(autoClosingPairs);
});
}
protected _createRichEditSupport(embeddedAutoClosingPairs: Modes.IAutoClosingPair[]): Modes.IRichEditSupport {
return new RichEditSupport(this.getId(), {
this.characterPairSupport = new supports.CharacterPairSupport(this, {
autoClosingPairs: autoClosingPairs.slice(0),
wordPattern: createWordRegExp('#-?%'),
comments: {
blockComment: ['<!--', '-->']
},
brackets: [
['<!--', '-->']
],
__electricCharacterSupport: {
brackets: [],
regexBrackets: [{
tokenType: htmlTokenTypes.getTag('$1'),
open: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join("|")}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
closeComplete: '</$1>',
close: /<\/(\w[\w\d]*)\s*>$/i
}],
caseInsensitive: true,
embeddedElectricCharacters: ['*', '}', ']', ')']
},
__characterPairSupport: {
autoClosingPairs: embeddedAutoClosingPairs.slice(0),
surroundingPairs: [
{ open: '"', close: '"' },
{ open: '\'', close: '\'' }
]});
{ open: '"', close: '"' },
{ open: '\'', close: '\'' }
]
}
});
}
......@@ -377,12 +389,13 @@ export class HTMLMode<W extends htmlWorker.HTMLWorker> extends AbstractMode<W> i
}
private _collectAutoClosingPairs(result:{[key:string]:string;}, mode:Modes.IMode): void {
if (mode && mode.characterPairSupport) {
var acp = mode.characterPairSupport.getAutoClosingPairs();
if (acp !== null) {
for(var i = 0; i < acp.length; i++) {
result[acp[i].open] = acp[i].close;
}
if (!mode || !mode.richEditSupport || !mode.richEditSupport.characterPair) {
return;
}
var acp = mode.richEditSupport.characterPair.getAutoClosingPairs();
if (acp !== null) {
for(var i = 0; i < acp.length; i++) {
result[acp[i].open] = acp[i].close;
}
}
}
......@@ -443,15 +456,6 @@ export class HTMLMode<W extends htmlWorker.HTMLWorker> extends AbstractMode<W> i
return null;
}
public static WORD_DEFINITION = createWordRegExp('#-?%');
public getWordDefinition():RegExp {
return HTMLMode.WORD_DEFINITION;
}
public getCommentsConfiguration():Modes.ICommentsConfiguration {
return { blockCommentStartToken: '<!--', blockCommentEndToken: '-->' };
}
protected _getWorkerDescriptor(): AsyncDescriptor2<Modes.IMode, Modes.IWorkerParticipant[], htmlWorker.HTMLWorker> {
return createAsyncDescriptor2('vs/languages/html/common/htmlWorker', 'HTMLWorker');
}
......
......@@ -609,7 +609,7 @@ suite('Colorizing - HTML', () => {
test('onEnter', function() {
var model = new Model('<script type=\"text/javascript\">function f() { foo(); }', _mode);
var actual = _mode.onEnterSupport.onEnter(model, {
var actual = _mode.richEditSupport.onEnter.onEnter(model, {
lineNumber: 1,
column: 46
});
......
......@@ -19,6 +19,7 @@ import {OnEnterSupport} from 'vs/editor/common/modes/supports/onEnter';
import {IThreadService} from 'vs/platform/thread/common/thread';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
export class JSMode extends typescriptMode.TypeScriptMode<javascriptWorker.JavaScriptWorker> {
......@@ -29,7 +30,6 @@ export class JSMode extends typescriptMode.TypeScriptMode<javascriptWorker.JavaS
public logicalSelectionSupport: Modes.ILogicalSelectionSupport;
public typeDeclarationSupport: Modes.ITypeDeclarationSupport;
public suggestSupport: Modes.ISuggestSupport;
public onEnterSupport: Modes.IOnEnterSupport;
constructor(
descriptor:Modes.IModeDescriptor,
......@@ -53,31 +53,21 @@ export class JSMode extends typescriptMode.TypeScriptMode<javascriptWorker.JavaS
excludeTokens: ['string.js', 'string.escape.js'],
getParameterHints: (resource, position) => this.getParameterHints(resource, position)});
this.electricCharacterSupport = new supports.BracketElectricCharacterSupport(this,
{
brackets: [
{ tokenType: 'delimiter.bracket.js', open: '{', close: '}', isElectric: true },
{ tokenType: 'delimiter.array.js', open: '[', close: ']', isElectric: true },
{ tokenType: 'delimiter.parenthesis.js', open: '(', close: ')', isElectric: true } ],
docComment: { scope: 'comment.doc', open: '/**', lineStart: ' * ', close: ' */' }
});
this.richEditSupport = new RichEditSupport(this.getId(), {
wordPattern: createWordRegExp('$'),
this.characterPairSupport = new supports.CharacterPairSupport(this, {
autoClosingPairs:
[ { open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"', notIn: ['string'] },
{ open: '\'', close: '\'', notIn: ['string', 'comment'] }
]});
comments: {
lineComment: '//',
blockComment: ['/*', '*/']
},
this.onEnterSupport = new OnEnterSupport(this.getId(), {
brackets: [
{ open: '(', close: ')' },
{ open: '{', close: '}' },
{ open: '[', close: ']' }
['{', '}'],
['[', ']'],
['(', ')']
],
regExpRules: [
onEnterRules: [
{
// e.g. /** | */
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
......@@ -99,7 +89,26 @@ export class JSMode extends typescriptMode.TypeScriptMode<javascriptWorker.JavaS
beforeText: /^(\t|(\ \ ))*\ \*\/\s*$/,
action: { indentAction: Modes.IndentAction.None, removeText: 1 }
}
]
],
__electricCharacterSupport: {
brackets: [
{ tokenType: 'delimiter.bracket.js', open: '{', close: '}', isElectric: true },
{ tokenType: 'delimiter.array.js', open: '[', close: ']', isElectric: true },
{ tokenType: 'delimiter.parenthesis.js', open: '(', close: ')', isElectric: true }
],
docComment: { scope: 'comment.doc', open: '/**', lineStart: ' * ', close: ' */' }
},
__characterPairSupport: {
autoClosingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"', notIn: ['string'] },
{ open: '\'', close: '\'', notIn: ['string', 'comment'] }
]
}
});
this.suggestSupport = new supports.SuggestSupport(this, {
......@@ -136,15 +145,6 @@ export class JSMode extends typescriptMode.TypeScriptMode<javascriptWorker.JavaS
return createAsyncDescriptor2('vs/languages/javascript/common/javascriptWorker', 'JavaScriptWorker');
}
public getCommentsConfiguration(): Modes.ICommentsConfiguration {
return { lineCommentTokens: ['//'], blockCommentStartToken: '/*', blockCommentEndToken: '*/' };
}
private static JS_WORD_DEFINITION = createWordRegExp('$');
public getWordDefinition(): RegExp {
return JSMode.JS_WORD_DEFINITION;
}
public get filter() {
return void 0;
}
......
......@@ -13,17 +13,15 @@ import modesUtil = require('vs/editor/test/common/modesUtil');
suite('JS - Auto Indent', () => {
var wordDefinition:RegExp;
var onEnter: modesUtil.IOnEnterFunc;
var assertOnEnter: modesUtil.IOnEnterAsserter;
var onElectricCharacter: modesUtil.IOnElectricCharacterFunc;
var assertWords = modesUtil.assertWords;
suiteSetup((done) => {
modesUtil.load('javascript').then(mode => {
onEnter = modesUtil.createOnEnter(mode);
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.onEnterSupport);
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.richEditSupport);
onElectricCharacter = modesUtil.createOnElectricCharacter(mode);
wordDefinition = mode.tokenTypeClassificationSupport.getWordDefinition();
wordDefinition = mode.richEditSupport.tokenTypeClassification.getWordDefinition();
done();
});
});
......
......@@ -22,12 +22,12 @@ import {AsyncDescriptor2, createAsyncDescriptor2} from 'vs/platform/instantiatio
import {OnEnterSupport} from 'vs/editor/common/modes/supports/onEnter';
import {IJSONContributionRegistry, Extensions, ISchemaContributions} from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
export class JSONMode extends AbstractMode<jsonWorker.JSONWorker> implements Modes.IExtraInfoSupport, Modes.IOutlineSupport, IThreadSynchronizableObject<ISchemaContributions> {
public tokenizationSupport: Modes.ITokenizationSupport;
public electricCharacterSupport: Modes.IElectricCharacterSupport;
public characterPairSupport: Modes.ICharacterPairSupport;
public richEditSupport: Modes.IRichEditSupport;
public extraInfoSupport: Modes.IExtraInfoSupport;
public outlineSupport: Modes.IOutlineSupport;
......@@ -37,8 +37,6 @@ export class JSONMode extends AbstractMode<jsonWorker.JSONWorker> implements Mod
public outlineGroupLabel : { [name: string]: string; };
public onEnterSupport: Modes.IOnEnterSupport;
constructor(
descriptor:Modes.IModeDescriptor,
@IInstantiationService instantiationService: IInstantiationService,
......@@ -47,10 +45,36 @@ export class JSONMode extends AbstractMode<jsonWorker.JSONWorker> implements Mod
super(descriptor, instantiationService, threadService);
this.tokenizationSupport = tokenization.createTokenizationSupport(this, true);
this.electricCharacterSupport = new supports.BracketElectricCharacterSupport(this, { brackets: [
{ tokenType:'delimiter.bracket.json', open: '{', close: '}', isElectric: true },
{ tokenType:'delimiter.array.json', open: '[', close: ']', isElectric: true }
] });
this.richEditSupport = new RichEditSupport(this.getId(), {
wordPattern: createWordRegExp('.-'),
comments: {
lineComment: '//',
blockComment: ['/*', '*/']
},
brackets: [
['{', '}'],
['[', ']']
],
__electricCharacterSupport: {
brackets: [
{ tokenType:'delimiter.bracket.json', open: '{', close: '}', isElectric: true },
{ tokenType:'delimiter.array.json', open: '[', close: ']', isElectric: true }
]
},
__characterPairSupport: {
autoClosingPairs: [
{ open: '{', close: '}', notIn: ['string'] },
{ open: '[', close: ']', notIn: ['string'] },
{ open: '"', close: '"', notIn: ['string'] }
]
}
});
this.extraInfoSupport = this;
......@@ -66,24 +90,10 @@ export class JSONMode extends AbstractMode<jsonWorker.JSONWorker> implements Mod
this.formattingSupport = this;
this.characterPairSupport = new supports.CharacterPairSupport(this, {
autoClosingPairs:
[ { open: '{', close: '}', notIn: ['string'] },
{ open: '[', close: ']', notIn: ['string'] },
{ open: '"', close: '"', notIn: ['string'] }
]});
this.suggestSupport = new supports.SuggestSupport(this, {
triggerCharacters: [],
excludeTokens: ['comment.line.json', 'comment.block.json'],
suggest: (resource, position) => this.suggest(resource, position)});
this.onEnterSupport = new OnEnterSupport(this.getId(), {
brackets: [
{ open: '{', close: '}' },
{ open: '[', close: ']' }
]
});
}
public creationDone(): void {
......@@ -142,17 +152,4 @@ export class JSONMode extends AbstractMode<jsonWorker.JSONWorker> implements Mod
public formatRange(resource:URI, range:EditorCommon.IRange, options:Modes.IFormattingOptions):WinJS.TPromise<EditorCommon.ISingleEditOperation[]> {
return this._worker((w) => w.format(resource, range, options));
}
public getCommentsConfiguration():Modes.ICommentsConfiguration {
return {
lineCommentTokens: ['//'],
blockCommentStartToken: '/*',
blockCommentEndToken: '*/'
};
}
private static WORD_DEFINITION = createWordRegExp('.-');
public getWordDefinition():RegExp {
return JSONMode.WORD_DEFINITION;
}
}
\ No newline at end of file
......@@ -20,7 +20,7 @@ suite('JSON - tokenization', () => {
setup((done) => {
modesUtil.load('json').then(mode => {
tokenizationSupport = mode.tokenizationSupport;
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.onEnterSupport);
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.richEditSupport);
done();
});
});
......
......@@ -21,7 +21,7 @@ suite('LESS-tokenization', () => {
setup((done) => {
modesUtil.load('less', ['javascript']).then(mode => {
tokenizationSupport = mode.tokenizationSupport;
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.onEnterSupport);
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.richEditSupport);
done();
});
});
......
......@@ -35,6 +35,9 @@ export const language =
autoClosingPairs: [],
blockCommentStart: '<!--',
blockCommentEnd: '-->',
// escape codes
control: /[\\`*_\[\]{}()#+\-\.!]/,
noncontrol: /[^\\`*_\[\]{}()#+\-\.!]/,
......@@ -221,10 +224,6 @@ export class MarkdownMode extends Monarch.MonarchMode<MarkdownWorker.MarkdownWor
this.emitOutputSupport = this;
}
public getCommentsConfiguration(): Modes.ICommentsConfiguration {
return { blockCommentStartToken: '<!--', blockCommentEndToken: '-->' };
}
static $getEmitOutput = OneWorkerAttr(MarkdownMode, MarkdownMode.prototype.getEmitOutput);
public getEmitOutput(resource: URI, absoluteWorkerResourcesPath?: string): WinJS.TPromise<Modes.IEmitOutput> { // TODO@Ben technical debt: worker cannot resolve paths absolute
return this._worker((w) => w.getEmitOutput(resource, absoluteWorkerResourcesPath));
......@@ -233,4 +232,4 @@ export class MarkdownMode extends Monarch.MonarchMode<MarkdownWorker.MarkdownWor
protected _getWorkerDescriptor(): AsyncDescriptor2<Modes.IMode, Modes.IWorkerParticipant[], MarkdownWorker.MarkdownWorker> {
return createAsyncDescriptor2('vs/languages/markdown/common/markdownWorker', 'MarkdownWorker');
}
}
\ No newline at end of file
}
......@@ -15,6 +15,7 @@ import {OnEnterSupport} from 'vs/editor/common/modes/supports/onEnter';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IThreadService} from 'vs/platform/thread/common/thread';
import {AbstractModeWorker} from 'vs/editor/common/modes/abstractModeWorker';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
var bracketsSource : Modes.IBracketPair[]= [
{ tokenType:'delimiter.bracket.php', open: '{', close: '}', isElectric: true },
......@@ -460,10 +461,7 @@ export class PHPEnterHTMLState extends PHPState {
export class PHPMode extends AbstractMode<AbstractModeWorker> implements supports.ITokenizationCustomization {
public tokenizationSupport: Modes.ITokenizationSupport;
public electricCharacterSupport: Modes.IElectricCharacterSupport;
public characterPairSupport: Modes.ICharacterPairSupport;
public onEnterSupport: Modes.IOnEnterSupport;
public richEditSupport: Modes.IRichEditSupport;
private modeService:IModeService;
......@@ -476,30 +474,41 @@ export class PHPMode extends AbstractMode<AbstractModeWorker> implements support
super(descriptor, instantiationService, threadService);
this.modeService = modeService;
this.electricCharacterSupport = new supports.BracketElectricCharacterSupport(this, { brackets: bracketsSource });
this.tokenizationSupport = new supports.TokenizationSupport(this, this, true, false);
this.characterPairSupport = new supports.CharacterPairSupport(this, {
autoClosingPairs:
[ { open: '{', close: '}', notIn: ['string.php'] },
this.richEditSupport = new RichEditSupport(this.getId(), {
wordPattern: createWordRegExp('$_'),
comments: {
lineComment: '//',
blockComment: ['/*', '*/']
},
brackets: [
['{', '}'],
['[', ']'],
['(', ')']
],
__electricCharacterSupport: {
brackets: bracketsSource
},
__characterPairSupport: {
autoClosingPairs: [
{ open: '{', close: '}', notIn: ['string.php'] },
{ open: '[', close: ']', notIn: ['string.php'] },
{ open: '(', close: ')', notIn: ['string.php'] },
{ open: '"', close: '"', notIn: ['string.php'] },
{ open: '\'', close: '\'', notIn: ['string.php'] }
]});
]
}
});
this.suggestSupport = new supports.SuggestSupport(this, {
triggerCharacters: ['.', ':', '$'],
excludeTokens: ['comment'],
suggest: (resource, position) => this.suggest(resource, position)});
this.onEnterSupport = new OnEnterSupport(this.getId(), {
brackets: [
{ open: '(', close: ')' },
{ open: '{', close: '}' },
{ open: '[', close: ']' }
]
});
}
public asyncCtor(): WinJS.Promise {
......@@ -550,13 +559,4 @@ export class PHPMode extends AbstractMode<AbstractModeWorker> implements support
// such that when we enter HTML again, we can recover the HTML state from .parent
(<PHPPlain>myStateAfterNestedMode).parent = lastNestedModeState;
}
public getCommentsConfiguration():Modes.ICommentsConfiguration {
return { lineCommentTokens: ['//','#'], blockCommentStartToken: '/*', blockCommentEndToken: '*/' };
}
private static WORD_DEFINITION = createWordRegExp('$_');
public getWordDefinition():RegExp {
return PHPMode.WORD_DEFINITION;
}
}
......@@ -26,8 +26,8 @@ suite('Syntax Highlighting - PHP', () => {
setup((done) => {
modesUtil.load('php').then(mode => {
tokenizationSupport = mode.tokenizationSupport;
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.onEnterSupport);
wordDefinition = mode.tokenTypeClassificationSupport.getWordDefinition();
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.richEditSupport);
wordDefinition = mode.richEditSupport.tokenTypeClassification.getWordDefinition();
done();
});
});
......
......@@ -16,6 +16,7 @@ import {RAZORWorker} from 'vs/languages/razor/common/razorWorker';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IThreadService} from 'vs/platform/thread/common/thread';
import {IModeService} from 'vs/editor/common/services/modeService';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
// for a brief description of the razor syntax see http://www.mikesdotnetting.com/Article/153/Inline-Razor-Syntax-Overview
......@@ -65,13 +66,42 @@ export class RAZORMode extends htmlMode.HTMLMode<RAZORWorker> {
super(descriptor, instantiationService, threadService, modeService);
this.formattingSupport = null;
}
protected _createRichEditSupport(embeddedAutoClosingPairs: Modes.IAutoClosingPair[]): Modes.IRichEditSupport {
return new RichEditSupport(this.getId(), {
wordPattern: createWordRegExp('#?%'),
comments: {
blockComment: ['<!--', '-->']
},
this.onEnterSupport = new OnEnterSupport(this.getId(), {
brackets: [
{ open: '<!--', close: '-->' },
{ open: '{', close: '}' },
{ open: '(', close: ')' },
]
['<!--', '-->'],
['{', '}'],
['(', ')']
],
__electricCharacterSupport: {
brackets: [],
regexBrackets: [{
tokenType: htmlMode.htmlTokenTypes.getTag('$1'),
open: new RegExp(`<(?!(?:${htmlMode.EMPTY_ELEMENTS.join("|")}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
closeComplete: '</$1>',
close: /<\/(\w[\w\d]*)\s*>$/i
}],
caseInsensitive: true,
embeddedElectricCharacters: ['*', '}', ']', ')']
},
__characterPairSupport: {
autoClosingPairs: embeddedAutoClosingPairs.slice(0),
surroundingPairs: [
{ open: '"', close: '"' },
{ open: '\'', close: '\'' }
]
}
});
}
......@@ -83,11 +113,6 @@ export class RAZORMode extends htmlMode.HTMLMode<RAZORWorker> {
return new RAZORState(this, htmlMode.States.Content, '', '', '', '', '');
}
public static WORD_DEFINITION = createWordRegExp('#?%');
public getWordDefinition():RegExp {
return RAZORMode.WORD_DEFINITION;
}
public getLeavingNestedModeData(line:string, state:Modes.IState): supports.ILeavingNestedModeData {
var leavingNestedModeData = super.getLeavingNestedModeData(line, state);
if (leavingNestedModeData) {
......@@ -96,4 +121,3 @@ export class RAZORMode extends htmlMode.HTMLMode<RAZORWorker> {
return leavingNestedModeData;
}
}
......@@ -18,7 +18,7 @@ suite('Sass Colorizer', () => {
setup((done) => {
modesUtil.load('sass').then(mode => {
tokenizationSupport = mode.tokenizationSupport;
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.onEnterSupport);
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.richEditSupport);
done();
});
});
......
......@@ -26,6 +26,7 @@ import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IThreadService, ThreadAffinity} from 'vs/platform/thread/common/thread';
import {OnEnterSupport} from 'vs/editor/common/modes/supports/onEnter';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
class SemanticValidator {
......@@ -128,8 +129,7 @@ class SemanticValidator {
export class TypeScriptMode<W extends typescriptWorker.TypeScriptWorker2> extends AbstractMode<W> implements lifecycle.IDisposable {
public tokenizationSupport: Modes.ITokenizationSupport;
public electricCharacterSupport: Modes.IElectricCharacterSupport;
public characterPairSupport: Modes.ICharacterPairSupport;
public richEditSupport: Modes.IRichEditSupport;
public referenceSupport: Modes.IReferenceSupport;
public extraInfoSupport:Modes.IExtraInfoSupport;
public occurrencesSupport:Modes.IOccurrencesSupport;
......@@ -143,8 +143,6 @@ export class TypeScriptMode<W extends typescriptWorker.TypeScriptWorker2> extend
public renameSupport: Modes.IRenameSupport;
public suggestSupport: Modes.ISuggestSupport;
public onEnterSupport: Modes.IOnEnterSupport;
private _telemetryService: ITelemetryService;
private _disposables: lifecycle.IDisposable[] = [];
private _projectResolver: WinJS.TPromise<typescript.IProjectResolver2>;
......@@ -195,50 +193,21 @@ export class TypeScriptMode<W extends typescriptWorker.TypeScriptWorker2> extend
this.renameSupport = this;
this.tokenizationSupport = tokenization.createTokenizationSupport(this, tokenization.Language.TypeScript);
this.electricCharacterSupport = new supports.BracketElectricCharacterSupport(this, {
brackets: [
{ tokenType:'delimiter.bracket.ts', open: '{', close: '}', isElectric: true },
{ tokenType:'delimiter.array.ts', open: '[', close: ']', isElectric: true },
{ tokenType:'delimiter.parenthesis.ts', open: '(', close: ')', isElectric: true }
],
docComment: {scope:'comment.doc', open:'/**', lineStart:' * ', close:' */'} });
this.referenceSupport = new supports.ReferenceSupport(this, {
tokens: ['identifier.ts'],
findReferences: (resource, position, includeDeclaration) => this.findReferences(resource, position, includeDeclaration)});
this.declarationSupport = new supports.DeclarationSupport(this, {
tokens: ['identifier.ts', 'string.ts', 'attribute.value.vs'],
findDeclaration: (resource, position) => this.findDeclaration(resource, position)});
this.parameterHintsSupport = new supports.ParameterHintsSupport(this, {
triggerCharacters: ['(', ','],
excludeTokens: ['string.ts'],
getParameterHints: (resource, position) => this.getParameterHints(resource, position)});
this.characterPairSupport = new supports.CharacterPairSupport(this, {
autoClosingPairs:
[ { open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"', notIn: ['string'] },
{ open: '\'', close: '\'', notIn: ['string', 'comment'] },
{ open: '`', close: '`' }
]});
this.richEditSupport = new RichEditSupport(this.getId(), {
wordPattern: createWordRegExp('$'),
this.suggestSupport = new supports.SuggestSupport(this, {
triggerCharacters: ['.'],
excludeTokens: ['string', 'comment', 'number'],
suggest: (resource, position) => this.suggest(resource, position),
getSuggestionDetails: (resource, position, suggestion) => this.getSuggestionDetails(resource, position, suggestion)});
comments: {
lineComment: '//',
blockComment: ['/*', '*/']
},
this.onEnterSupport = new OnEnterSupport(this.getId(), {
brackets: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
['{', '}'],
['[', ']'],
['(', ')']
],
regExpRules: [
onEnterRules: [
{
// e.g. /** | */
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
......@@ -260,8 +229,47 @@ export class TypeScriptMode<W extends typescriptWorker.TypeScriptWorker2> extend
beforeText: /^(\t|(\ \ ))*\ \*\/\s*$/,
action: { indentAction: Modes.IndentAction.None, removeText: 1 }
}
]
],
__electricCharacterSupport: {
brackets: [
{ tokenType:'delimiter.bracket.ts', open: '{', close: '}', isElectric: true },
{ tokenType:'delimiter.array.ts', open: '[', close: ']', isElectric: true },
{ tokenType:'delimiter.parenthesis.ts', open: '(', close: ')', isElectric: true }
],
docComment: {scope:'comment.doc', open:'/**', lineStart:' * ', close:' */'}
},
__characterPairSupport: {
autoClosingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"', notIn: ['string'] },
{ open: '\'', close: '\'', notIn: ['string', 'comment'] },
{ open: '`', close: '`' }
]
}
});
this.referenceSupport = new supports.ReferenceSupport(this, {
tokens: ['identifier.ts'],
findReferences: (resource, position, includeDeclaration) => this.findReferences(resource, position, includeDeclaration)});
this.declarationSupport = new supports.DeclarationSupport(this, {
tokens: ['identifier.ts', 'string.ts', 'attribute.value.vs'],
findDeclaration: (resource, position) => this.findDeclaration(resource, position)});
this.parameterHintsSupport = new supports.ParameterHintsSupport(this, {
triggerCharacters: ['(', ','],
excludeTokens: ['string.ts'],
getParameterHints: (resource, position) => this.getParameterHints(resource, position)});
this.suggestSupport = new supports.SuggestSupport(this, {
triggerCharacters: ['.'],
excludeTokens: ['string', 'comment', 'number'],
suggest: (resource, position) => this.suggest(resource, position),
getSuggestionDetails: (resource, position, suggestion) => this.getSuggestionDetails(resource, position, suggestion)});
}
public dispose(): void {
......@@ -367,10 +375,6 @@ export class TypeScriptMode<W extends typescriptWorker.TypeScriptWorker2> extend
return createAsyncDescriptor2('vs/languages/typescript/common/typescriptWorker2', 'TypeScriptWorker2');
}
public getCommentsConfiguration():Modes.ICommentsConfiguration {
return { lineCommentTokens: ['//'], blockCommentStartToken: '/*', blockCommentEndToken: '*/' };
}
static $_pickAWorkerToValidate = OneWorkerAttr(TypeScriptMode, TypeScriptMode.prototype._pickAWorkerToValidate, TypeScriptMode.prototype._syncProjects, ThreadAffinity.Group3);
public _pickAWorkerToValidate(): WinJS.Promise {
return this._worker((w) => w.enableValidator());
......@@ -432,11 +436,6 @@ export class TypeScriptMode<W extends typescriptWorker.TypeScriptWorker2> extend
return this._worker((w) => w.getEmitOutput(resource, type));
}
private static WORD_DEFINITION = createWordRegExp('$');
public getWordDefinition():RegExp {
return TypeScriptMode.WORD_DEFINITION;
}
static $findReferences = OneWorkerAttr(TypeScriptMode, TypeScriptMode.prototype.findReferences, TypeScriptMode.prototype._syncProjects, ThreadAffinity.Group3);
public findReferences(resource:URI, position:EditorCommon.IPosition, includeDeclaration:boolean):WinJS.TPromise<Modes.IReference[]> {
return this._worker((w) => w.findReferences(resource, position, includeDeclaration));
......
......@@ -19,7 +19,7 @@ suite('TS/JS - syntax highlighting', () => {
setup((done) => {
modesUtil.load('javascript').then(mode => {
tokenizationSupport = mode.tokenizationSupport;
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.onEnterSupport);
assertOnEnter = modesUtil.createOnEnterAsserter(mode.getId(), mode.richEditSupport);
done();
});
});
......
......@@ -5,7 +5,6 @@
'use strict';
import {Emitter} from 'vs/base/common/event';
import {IBracketElectricCharacterContribution} from 'vs/editor/common/modes/supports';
import {score} from 'vs/editor/common/modes/languageSelector';
import {Remotable, IThreadService} from 'vs/platform/thread/common/thread';
import * as errors from 'vs/base/common/errors';
......@@ -26,8 +25,6 @@ import {registerApiCommands} from 'vs/workbench/api/node/extHostApiCommands';
import * as extHostTypes from 'vs/workbench/api/node/extHostTypes';
import Modes = require('vs/editor/common/modes');
import {IModeService} from 'vs/editor/common/services/modeService';
import {ICommentsSupportContribution, ITokenTypeClassificationSupportContribution} from 'vs/editor/common/modes/supports';
import {IOnEnterSupportOptions} from 'vs/editor/common/modes/supports/onEnter';
import URI from 'vs/base/common/uri';
import Severity from 'vs/base/common/severity';
import {IDisposable} from 'vs/base/common/lifecycle';
......@@ -395,104 +392,21 @@ export class ExtHostAPIImplementation {
private _setLanguageConfiguration(modeId: string, configuration: vscode.LanguageConfiguration): vscode.Disposable {
let disposables: IDisposable[] = [];
let {comments, wordPattern} = configuration;
// comment configuration
if (comments) {
let contrib: ICommentsSupportContribution = { commentsConfiguration: {} };
if (comments.lineComment) {
contrib.commentsConfiguration.lineCommentTokens = [comments.lineComment];
}
if (comments.blockComment) {
let [blockStart, blockEnd] = comments.blockComment;
contrib.commentsConfiguration.blockCommentStartToken = blockStart;
contrib.commentsConfiguration.blockCommentEndToken = blockEnd;
}
let d = this.Modes_CommentsSupport_register(modeId, contrib);
disposables.push(d);
}
let {wordPattern} = configuration;
// word definition
if (wordPattern) {
setWordDefinitionFor(modeId, wordPattern);
let d = this.Modes_TokenTypeClassificationSupport_register(modeId, {
wordDefinition: wordPattern
});
disposables.push(d);
} else {
setWordDefinitionFor(modeId, null);
}
// on enter
let onEnter: IOnEnterSupportOptions = {};
let empty = true;
let {brackets, indentationRules, onEnterRules} = configuration;
if (brackets) {
empty = false;
onEnter.brackets = brackets.map(pair => {
let [open, close] = pair;
return { open, close };
});
}
if (indentationRules) {
empty = false;
onEnter.indentationRules = indentationRules;
}
if (onEnterRules) {
empty = false;
onEnter.regExpRules = <any>onEnterRules;
}
if (!empty) {
let d = this.Modes_OnEnterSupport_register(modeId, onEnter);
disposables.push(d);
}
if (configuration.__electricCharacterSupport) {
disposables.push(
this.Modes_ElectricCharacterSupport_register(modeId, configuration.__electricCharacterSupport)
);
}
if (configuration.__characterPairSupport) {
disposables.push(
this.Modes_CharacterPairSupport_register(modeId, configuration.__characterPairSupport)
);
}
return extHostTypes.Disposable.from(...disposables);
return this.Modes_RichEditSupport_register(modeId, configuration);
}
private Modes_CommentsSupport_register(modeId: string, commentsSupport: ICommentsSupportContribution): IDisposable {
private Modes_RichEditSupport_register(modeId: string, configuration:vscode.LanguageConfiguration): IDisposable {
let disposeToken = ExtHostAPIImplementation.generateDisposeToken();
this._proxy.Modes_CommentsSupport_register(disposeToken, modeId, commentsSupport);
return this._disposableFromToken(disposeToken);
}
private Modes_TokenTypeClassificationSupport_register(modeId: string, tokenTypeClassificationSupport:ITokenTypeClassificationSupportContribution): IDisposable {
let disposeToken = ExtHostAPIImplementation.generateDisposeToken();
this._proxy.Modes_TokenTypeClassificationSupport_register(disposeToken, modeId, tokenTypeClassificationSupport);
return this._disposableFromToken(disposeToken);
}
private Modes_ElectricCharacterSupport_register(modeId: string, electricCharacterSupport:IBracketElectricCharacterContribution): IDisposable {
let disposeToken = ExtHostAPIImplementation.generateDisposeToken();
this._proxy.Modes_ElectricCharacterSupport_register(disposeToken, modeId, electricCharacterSupport);
return this._disposableFromToken(disposeToken);
}
private Modes_CharacterPairSupport_register(modeId: string, characterPairSupport:Modes.ICharacterPairContribution): IDisposable {
let disposeToken = ExtHostAPIImplementation.generateDisposeToken();
this._proxy.Modes_CharacterPairSupport_register(disposeToken, modeId, characterPairSupport);
return this._disposableFromToken(disposeToken);
}
private Modes_OnEnterSupport_register(modeId: string, opts: IOnEnterSupportOptions): IDisposable {
let disposeToken = ExtHostAPIImplementation.generateDisposeToken();
this._proxy.Modes_OnEnterSupport_register(disposeToken, modeId, opts);
this._proxy.Modes_RichEditSupport_register(disposeToken, modeId, configuration);
return this._disposableFromToken(disposeToken);
}
}
......@@ -562,23 +476,7 @@ export class MainProcessVSCodeAPIHelper {
}
}
public Modes_CommentsSupport_register(disposeToken:string, modeId: string, commentsSupport: ICommentsSupportContribution): void {
this._token2Dispose[disposeToken] = this._modeService.registerDeclarativeCommentsSupport(modeId, commentsSupport);
}
public Modes_TokenTypeClassificationSupport_register(disposeToken:string, modeId: string, tokenTypeClassificationSupport:ITokenTypeClassificationSupportContribution): void {
this._token2Dispose[disposeToken] = this._modeService.registerDeclarativeTokenTypeClassificationSupport(modeId, tokenTypeClassificationSupport);
}
public Modes_ElectricCharacterSupport_register(disposeToken:string, modeId: string, electricCharacterSupport:IBracketElectricCharacterContribution): void {
this._token2Dispose[disposeToken] = this._modeService.registerDeclarativeElectricCharacterSupport(modeId, electricCharacterSupport);
}
public Modes_CharacterPairSupport_register(disposeToken:string, modeId: string, characterPairSupport:Modes.ICharacterPairContribution): void {
this._token2Dispose[disposeToken] = this._modeService.registerDeclarativeCharacterPairSupport(modeId, characterPairSupport);
}
public Modes_OnEnterSupport_register(disposeToken:string, modeId: string, opts:IOnEnterSupportOptions): void {
this._token2Dispose[disposeToken] = this._modeService.registerDeclarativeOnEnterSupport(modeId, <any>opts);
public Modes_RichEditSupport_register(disposeToken:string, modeId: string, configuration:vscode.LanguageConfiguration): void {
this._token2Dispose[disposeToken] = this._modeService.registerRichEditSupport(modeId, <any>configuration);
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册