提交 ebc30748 编写于 作者: M Martin Aeschlimann

Emulate LanguageConfiguration.__electricCharacterSupport.docComment with autoClosingPairs

上级 24b9f788
......@@ -206,18 +206,17 @@ class LanguageProvider {
}
],
__electricCharacterSupport: {
docComment: { scope: 'comment.documentation', open: '/**', lineStart: ' * ', close: ' */' }
},
__characterPairSupport: {
autoClosingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"', notIn: ['string'] },
{ open: '\'', close: '\'', notIn: ['string', 'comment'] },
{ open: '`', close: '`', notIn: ['string', 'comment'] }
{ open: '`', close: '`', notIn: ['string', 'comment'] },
{ open: '/**', close: ' */', notIn: ['string'] }
]
}
});
......
......@@ -879,6 +879,7 @@ export type CharacterPair = [string, string];
export interface IAutoClosingPairConditional extends IAutoClosingPair {
notIn?: string[];
}
/**
......
......@@ -111,10 +111,7 @@ export class RichEditSupport {
this._handleComments(modeId, this._conf);
this.characterPair = new CharacterPairSupport(LanguageConfigurationRegistry, modeId, this._conf);
if (this._conf.__electricCharacterSupport || this._conf.brackets) {
this.electricCharacter = new BracketElectricCharacterSupport(LanguageConfigurationRegistry, modeId, this.brackets, this._conf.__electricCharacterSupport);
}
this.electricCharacter = new BracketElectricCharacterSupport(LanguageConfigurationRegistry, modeId, this.brackets, this.characterPair.getAutoClosingPairs(), this._conf.__electricCharacterSupport);
this.wordDefinition = this._conf.wordPattern || DEFAULT_WORD_REGEXP;
}
......
......@@ -32,11 +32,11 @@ export class BracketElectricCharacterSupport implements modes.IRichEditElectricC
private contribution: IBracketElectricCharacterContribution;
private brackets: Brackets;
constructor(registry:LanguageConfigurationRegistryImpl, modeId: string, brackets: modes.IRichEditBrackets, contribution: IBracketElectricCharacterContribution) {
constructor(registry:LanguageConfigurationRegistryImpl, modeId: string, brackets: modes.IRichEditBrackets, autoClosePairs: modes.IAutoClosingPairConditional[], contribution: IBracketElectricCharacterContribution) {
this._registry = registry;
this._modeId = modeId;
this.contribution = contribution || {};
this.brackets = new Brackets(modeId, brackets, this.contribution.docComment);
this.brackets = new Brackets(modeId, brackets, autoClosePairs, contribution.docComment);
}
public getElectricCharacters(): string[]{
......@@ -66,12 +66,16 @@ export class Brackets {
private _modeId: string;
private _richEditBrackets: modes.IRichEditBrackets;
private _docComment: IDocComment;
private _complexAutoClosePairs: modes.IAutoClosingPairConditional[];
constructor(modeId: string, richEditBrackets: modes.IRichEditBrackets, docComment: IDocComment = null) {
constructor(modeId: string, richEditBrackets: modes.IRichEditBrackets, autoClosePairs: modes.IAutoClosingPairConditional[], docComment?: IDocComment) {
this._modeId = modeId;
this._richEditBrackets = richEditBrackets;
this._docComment = docComment ? docComment : null;
this._complexAutoClosePairs = autoClosePairs.filter(pair => pair.open.length > 1 && !!pair.close);
if (docComment) {
// IDocComment is legacy, only partially supported
this._complexAutoClosePairs.push({ open:docComment.open, close: docComment.close });
}
}
public getElectricCharacters():string[] {
......@@ -85,9 +89,9 @@ export class Brackets {
}
}
// Doc comments
if (this._docComment){
result.push(this._docComment.open.charAt(this._docComment.open.length - 1));
// auto close
for (let pair of this._complexAutoClosePairs) {
result.push(pair.open.charAt(pair.open.length - 1));
}
// Filter duplicate entries
......@@ -103,8 +107,8 @@ export class Brackets {
return null;
}
return (this._onElectricCharacterDocComment(context, offset) ||
this._onElectricCharacterStandardBrackets(context, offset));
return (this._onElectricAutoClose(context, offset) ||
this._onElectricAutoIndent(context, offset));
}
private containsTokenTypes(fullTokenSpec: string, tokensToLookFor: string): boolean {
......@@ -117,7 +121,7 @@ export class Brackets {
return true;
}
private _onElectricCharacterStandardBrackets(context: modes.ILineContext, offset: number): modes.IElectricAction {
private _onElectricAutoIndent(context: modes.ILineContext, offset: number): modes.IElectricAction {
if (!this._richEditBrackets || this._richEditBrackets.brackets.length === 0) {
return null;
......@@ -151,35 +155,44 @@ export class Brackets {
return null;
}
private _onElectricCharacterDocComment(context: modes.ILineContext, offset: number): modes.IElectricAction {
// We only auto-close, so do nothing if there is no closing part.
if (!this._docComment || !this._docComment.close) {
private _onElectricAutoClose(context: modes.ILineContext, offset: number): modes.IElectricAction {
if (!this._complexAutoClosePairs.length) {
return null;
}
var line = context.getLineContent();
var char: string = line[offset];
// See if the right electric character was pressed
if (char !== this._docComment.open.charAt(this._docComment.open.length - 1)) {
return null;
}
for (let i = 0; i < this._complexAutoClosePairs.length; i++) {
let pair = this._complexAutoClosePairs[i];
// If this line already contains the closing tag, do nothing.
if (line.indexOf(this._docComment.close, offset) >= 0) {
return null;
}
// See if the right electric character was pressed
if (char !== pair.open.charAt(pair.open.length - 1)) {
continue;
}
// If we're not in a documentation comment, do nothing.
var lastTokenIndex = context.findIndexOfOffset(offset);
if (! this.containsTokenTypes(context.getTokenType(lastTokenIndex), this._docComment.scope)) {
return null;
}
// If this line already contains the closing tag, do nothing.
if (line.indexOf(pair.close, offset) >= 0) {
continue;
}
if (line.substring(context.getTokenStartIndex(lastTokenIndex), offset+1/* include electric char*/) !== this._docComment.open) {
return null;
// check if the full open bracket matches
let lastTokenIndex = context.findIndexOfOffset(offset);
if (line.substring(context.getTokenStartIndex(lastTokenIndex), offset+1/* include electric char*/) !== pair.open) {
continue;
}
// If we're in a scope listen in 'notIn', do nothing
if (pair.notIn) {
let tokenType = context.getTokenType(lastTokenIndex);
if (pair.notIn.some(scope => this.containsTokenTypes(tokenType, scope))) {
continue;
}
}
return { appendText: pair.close};
}
return { appendText: this._docComment.close};
}
}
......@@ -10,8 +10,7 @@ import {createLineContextFromTokenText} from 'vs/editor/test/common/modesTestUti
suite('Editor Modes - Auto Indentation', () => {
test('Doc comments', () => {
var brackets = new Brackets('test', null,
{ scope: 'doc', open: '/**', lineStart: ' * ', close: ' */' });
var brackets = new Brackets('test', null, [{ open: '/**', close: ' */' }]);
assert.equal(brackets.onElectricCharacter(createLineContextFromTokenText([
{ text: '/**', type: 'doc' },
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册