未验证 提交 c6b09780 编写于 作者: A Alex Dima

Allow bracket matching to search across multiple tokens

上级 2205002a
......@@ -1910,7 +1910,7 @@ export class TextModel extends Disposable implements model.ITextModel {
const lineTokens = this._getLineTokens(lineNumber);
const lineText = this._buffer.getLineContent(lineNumber);
let tokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1);
const tokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1);
if (tokenIndex < 0) {
return null;
}
......@@ -1919,15 +1919,15 @@ export class TextModel extends Disposable implements model.ITextModel {
// check that the token is not to be ignored
if (currentModeBrackets && !ignoreBracketsInToken(lineTokens.getStandardTokenType(tokenIndex))) {
// limit search to not go before `maxBracketLength`
let searchStartOffset = Math.max(lineTokens.getStartOffset(tokenIndex), position.column - 1 - currentModeBrackets.maxBracketLength);
let searchStartOffset = Math.max(0, position.column - 1 - currentModeBrackets.maxBracketLength);
// limit search to not go after `maxBracketLength`
const searchEndOffset = Math.min(lineTokens.getEndOffset(tokenIndex), position.column - 1 + currentModeBrackets.maxBracketLength);
const searchEndOffset = Math.min(lineText.length, position.column - 1 + currentModeBrackets.maxBracketLength);
// it might be the case that [currentTokenStart -> currentTokenEnd] contains multiple brackets
// `bestResult` will contain the most right-side result
let bestResult: [Range, Range] | null = null;
while (true) {
let foundBracket = BracketsUtils.findNextBracketInToken(currentModeBrackets.forwardRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
const foundBracket = BracketsUtils.findNextBracketInRange(currentModeBrackets.forwardRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
if (!foundBracket) {
// there are no more brackets in this text
break;
......@@ -1935,12 +1935,8 @@ export class TextModel extends Disposable implements model.ITextModel {
// check that we didn't hit a bracket too far away from position
if (foundBracket.startColumn <= position.column && position.column <= foundBracket.endColumn) {
let foundBracketText = lineText.substring(foundBracket.startColumn - 1, foundBracket.endColumn - 1);
foundBracketText = foundBracketText.toLowerCase();
let r = this._matchFoundBracket(foundBracket, currentModeBrackets.textIsBracket[foundBracketText], currentModeBrackets.textIsOpenBracket[foundBracketText]);
// check that we can actually match this bracket
const foundBracketText = lineText.substring(foundBracket.startColumn - 1, foundBracket.endColumn - 1).toLowerCase();
const r = this._matchFoundBracket(foundBracket, currentModeBrackets.textIsBracket[foundBracketText], currentModeBrackets.textIsOpenBracket[foundBracketText]);
if (r) {
bestResult = r;
}
......@@ -1956,24 +1952,20 @@ export class TextModel extends Disposable implements model.ITextModel {
// If position is in between two tokens, try also looking in the previous token
if (tokenIndex > 0 && lineTokens.getStartOffset(tokenIndex) === position.column - 1) {
const searchEndOffset = lineTokens.getStartOffset(tokenIndex);
tokenIndex--;
const prevModeBrackets = LanguageConfigurationRegistry.getBracketsSupport(lineTokens.getLanguageId(tokenIndex));
const prevTokenIndex = tokenIndex - 1;
const prevModeBrackets = LanguageConfigurationRegistry.getBracketsSupport(lineTokens.getLanguageId(prevTokenIndex));
// check that previous token is not to be ignored
if (prevModeBrackets && !ignoreBracketsInToken(lineTokens.getStandardTokenType(tokenIndex))) {
if (prevModeBrackets && !ignoreBracketsInToken(lineTokens.getStandardTokenType(prevTokenIndex))) {
// limit search in case previous token is very large, there's no need to go beyond `maxBracketLength`
const searchStartOffset = Math.max(lineTokens.getStartOffset(tokenIndex), position.column - 1 - prevModeBrackets.maxBracketLength);
const foundBracket = BracketsUtils.findPrevBracketInToken(prevModeBrackets.reversedRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
const searchStartOffset = Math.max(0, position.column - 1 - prevModeBrackets.maxBracketLength);
const searchEndOffset = Math.min(lineText.length, position.column - 1 + prevModeBrackets.maxBracketLength);
const foundBracket = BracketsUtils.findPrevBracketInRange(prevModeBrackets.reversedRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
// check that we didn't hit a bracket too far away from position
if (foundBracket && foundBracket.startColumn <= position.column && position.column <= foundBracket.endColumn) {
let foundBracketText = lineText.substring(foundBracket.startColumn - 1, foundBracket.endColumn - 1);
foundBracketText = foundBracketText.toLowerCase();
let r = this._matchFoundBracket(foundBracket, prevModeBrackets.textIsBracket[foundBracketText], prevModeBrackets.textIsOpenBracket[foundBracketText]);
// check that we can actually match this bracket
const foundBracketText = lineText.substring(foundBracket.startColumn - 1, foundBracket.endColumn - 1).toLowerCase();
const r = this._matchFoundBracket(foundBracket, prevModeBrackets.textIsBracket[foundBracketText], prevModeBrackets.textIsOpenBracket[foundBracketText]);
if (r) {
return r;
}
......@@ -2011,54 +2003,76 @@ export class TextModel extends Disposable implements model.ITextModel {
const reversedBracketRegex = bracket.reversedRegex;
let count = -1;
const searchPrevMatchingBracketInRange = (lineNumber: number, lineText: string, searchStartOffset: number, searchEndOffset: number): Range | null => {
while (true) {
const r = BracketsUtils.findPrevBracketInRange(reversedBracketRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
if (!r) {
break;
}
const hitText = lineText.substring(r.startColumn - 1, r.endColumn - 1).toLowerCase();
if (hitText === bracket.open) {
count++;
} else if (hitText === bracket.close) {
count--;
}
if (count === 0) {
return r;
}
searchEndOffset = r.startColumn - 1;
}
return null;
};
for (let lineNumber = position.lineNumber; lineNumber >= 1; lineNumber--) {
const lineTokens = this._getLineTokens(lineNumber);
const tokenCount = lineTokens.getCount();
const lineText = this._buffer.getLineContent(lineNumber);
let tokenIndex = tokenCount - 1;
let searchStopOffset = -1;
let searchStartOffset = lineText.length;
let searchEndOffset = lineText.length;
if (lineNumber === position.lineNumber) {
tokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1);
searchStopOffset = position.column - 1;
searchStartOffset = position.column - 1;
searchEndOffset = position.column - 1;
}
let prevSearchInToken = true;
for (; tokenIndex >= 0; tokenIndex--) {
const tokenLanguageId = lineTokens.getLanguageId(tokenIndex);
const tokenType = lineTokens.getStandardTokenType(tokenIndex);
const tokenStartOffset = lineTokens.getStartOffset(tokenIndex);
const tokenEndOffset = lineTokens.getEndOffset(tokenIndex);
if (searchStopOffset === -1) {
searchStopOffset = tokenEndOffset;
}
if (tokenLanguageId === languageId && !ignoreBracketsInToken(tokenType)) {
while (true) {
let r = BracketsUtils.findPrevBracketInToken(reversedBracketRegex, lineNumber, lineText, tokenStartOffset, searchStopOffset);
if (!r) {
break;
}
let hitText = lineText.substring(r.startColumn - 1, r.endColumn - 1);
hitText = hitText.toLowerCase();
if (hitText === bracket.open) {
count++;
} else if (hitText === bracket.close) {
count--;
}
if (count === 0) {
const searchInToken = (lineTokens.getLanguageId(tokenIndex) === languageId && !ignoreBracketsInToken(lineTokens.getStandardTokenType(tokenIndex)));
if (searchInToken) {
// this token should be searched
if (prevSearchInToken) {
// the previous token should be searched, simply extend searchStartOffset
searchStartOffset = lineTokens.getStartOffset(tokenIndex);
} else {
// the previous token should not be searched
searchStartOffset = lineTokens.getStartOffset(tokenIndex);
searchEndOffset = lineTokens.getEndOffset(tokenIndex);
}
} else {
// this token should not be searched
if (prevSearchInToken && searchStartOffset !== searchEndOffset) {
const r = searchPrevMatchingBracketInRange(lineNumber, lineText, searchStartOffset, searchEndOffset);
if (r) {
return r;
}
searchStopOffset = r.startColumn - 1;
}
}
searchStopOffset = -1;
prevSearchInToken = searchInToken;
}
if (prevSearchInToken && searchStartOffset !== searchEndOffset) {
const r = searchPrevMatchingBracketInRange(lineNumber, lineText, searchStartOffset, searchEndOffset);
if (r) {
return r;
}
}
}
......@@ -2072,53 +2086,77 @@ export class TextModel extends Disposable implements model.ITextModel {
const bracketRegex = bracket.forwardRegex;
let count = 1;
for (let lineNumber = position.lineNumber, lineCount = this.getLineCount(); lineNumber <= lineCount; lineNumber++) {
const searchNextMatchingBracketInRange = (lineNumber: number, lineText: string, searchStartOffset: number, searchEndOffset: number): Range | null => {
while (true) {
const r = BracketsUtils.findNextBracketInRange(bracketRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
if (!r) {
break;
}
const hitText = lineText.substring(r.startColumn - 1, r.endColumn - 1).toLowerCase();
if (hitText === bracket.open) {
count++;
} else if (hitText === bracket.close) {
count--;
}
if (count === 0) {
return r;
}
searchStartOffset = r.endColumn - 1;
}
return null;
};
const lineCount = this.getLineCount();
for (let lineNumber = position.lineNumber; lineNumber <= lineCount; lineNumber++) {
const lineTokens = this._getLineTokens(lineNumber);
const tokenCount = lineTokens.getCount();
const lineText = this._buffer.getLineContent(lineNumber);
let tokenIndex = 0;
let searchStartOffset = 0;
let searchEndOffset = 0;
if (lineNumber === position.lineNumber) {
tokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1);
searchStartOffset = position.column - 1;
searchEndOffset = position.column - 1;
}
let prevSearchInToken = true;
for (; tokenIndex < tokenCount; tokenIndex++) {
const tokenLanguageId = lineTokens.getLanguageId(tokenIndex);
const tokenType = lineTokens.getStandardTokenType(tokenIndex);
const tokenStartOffset = lineTokens.getStartOffset(tokenIndex);
const tokenEndOffset = lineTokens.getEndOffset(tokenIndex);
if (searchStartOffset === 0) {
searchStartOffset = tokenStartOffset;
}
if (tokenLanguageId === languageId && !ignoreBracketsInToken(tokenType)) {
while (true) {
let r = BracketsUtils.findNextBracketInToken(bracketRegex, lineNumber, lineText, searchStartOffset, tokenEndOffset);
if (!r) {
break;
}
let hitText = lineText.substring(r.startColumn - 1, r.endColumn - 1);
hitText = hitText.toLowerCase();
if (hitText === bracket.open) {
count++;
} else if (hitText === bracket.close) {
count--;
}
if (count === 0) {
const searchInToken = (lineTokens.getLanguageId(tokenIndex) === languageId && !ignoreBracketsInToken(lineTokens.getStandardTokenType(tokenIndex)));
if (searchInToken) {
// this token should be searched
if (prevSearchInToken) {
// the previous token should be searched, simply extend searchEndOffset
searchEndOffset = lineTokens.getEndOffset(tokenIndex);
} else {
// the previous token should not be searched
searchStartOffset = lineTokens.getStartOffset(tokenIndex);
searchEndOffset = lineTokens.getEndOffset(tokenIndex);
}
} else {
// this token should not be searched
if (prevSearchInToken && searchStartOffset !== searchEndOffset) {
const r = searchNextMatchingBracketInRange(lineNumber, lineText, searchStartOffset, searchEndOffset);
if (r) {
return r;
}
searchStartOffset = r.endColumn - 1;
}
}
searchStartOffset = 0;
prevSearchInToken = searchInToken;
}
if (prevSearchInToken && searchStartOffset !== searchEndOffset) {
const r = searchNextMatchingBracketInRange(lineNumber, lineText, searchStartOffset, searchEndOffset);
if (r) {
return r;
}
}
}
......@@ -2136,33 +2174,66 @@ export class TextModel extends Disposable implements model.ITextModel {
const lineText = this._buffer.getLineContent(lineNumber);
let tokenIndex = tokenCount - 1;
let searchStopOffset = -1;
let searchStartOffset = lineText.length;
let searchEndOffset = lineText.length;
if (lineNumber === position.lineNumber) {
tokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1);
searchStopOffset = position.column - 1;
searchStartOffset = position.column - 1;
searchEndOffset = position.column - 1;
const tokenLanguageId = lineTokens.getLanguageId(tokenIndex);
if (languageId !== tokenLanguageId) {
languageId = tokenLanguageId;
modeBrackets = LanguageConfigurationRegistry.getBracketsSupport(languageId);
}
}
let prevSearchInToken = true;
for (; tokenIndex >= 0; tokenIndex--) {
const tokenLanguageId = lineTokens.getLanguageId(tokenIndex);
const tokenType = lineTokens.getStandardTokenType(tokenIndex);
const tokenStartOffset = lineTokens.getStartOffset(tokenIndex);
const tokenEndOffset = lineTokens.getEndOffset(tokenIndex);
if (searchStopOffset === -1) {
searchStopOffset = tokenEndOffset;
}
if (languageId !== tokenLanguageId) {
// language id change!
if (modeBrackets && prevSearchInToken && searchStartOffset !== searchEndOffset) {
const r = BracketsUtils.findPrevBracketInRange(modeBrackets.reversedRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
if (r) {
return this._toFoundBracket(modeBrackets, r);
}
prevSearchInToken = false;
}
languageId = tokenLanguageId;
modeBrackets = LanguageConfigurationRegistry.getBracketsSupport(languageId);
}
if (modeBrackets && !ignoreBracketsInToken(tokenType)) {
let r = BracketsUtils.findPrevBracketInToken(modeBrackets.reversedRegex, lineNumber, lineText, tokenStartOffset, searchStopOffset);
if (r) {
return this._toFoundBracket(modeBrackets, r);
const searchInToken = (!!modeBrackets && !ignoreBracketsInToken(lineTokens.getStandardTokenType(tokenIndex)));
if (searchInToken) {
// this token should be searched
if (prevSearchInToken) {
// the previous token should be searched, simply extend searchStartOffset
searchStartOffset = lineTokens.getStartOffset(tokenIndex);
} else {
// the previous token should not be searched
searchStartOffset = lineTokens.getStartOffset(tokenIndex);
searchEndOffset = lineTokens.getEndOffset(tokenIndex);
}
} else {
// this token should not be searched
if (modeBrackets && prevSearchInToken && searchStartOffset !== searchEndOffset) {
const r = BracketsUtils.findPrevBracketInRange(modeBrackets.reversedRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
if (r) {
return this._toFoundBracket(modeBrackets, r);
}
}
}
searchStopOffset = -1;
prevSearchInToken = searchInToken;
}
if (modeBrackets && prevSearchInToken && searchStartOffset !== searchEndOffset) {
const r = BracketsUtils.findPrevBracketInRange(modeBrackets.reversedRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
if (r) {
return this._toFoundBracket(modeBrackets, r);
}
}
}
......@@ -2171,43 +2242,75 @@ export class TextModel extends Disposable implements model.ITextModel {
public findNextBracket(_position: IPosition): model.IFoundBracket | null {
const position = this.validatePosition(_position);
const lineCount = this.getLineCount();
let languageId: LanguageId = -1;
let modeBrackets: RichEditBrackets | null = null;
for (let lineNumber = position.lineNumber, lineCount = this.getLineCount(); lineNumber <= lineCount; lineNumber++) {
for (let lineNumber = position.lineNumber; lineNumber <= lineCount; lineNumber++) {
const lineTokens = this._getLineTokens(lineNumber);
const tokenCount = lineTokens.getCount();
const lineText = this._buffer.getLineContent(lineNumber);
let tokenIndex = 0;
let searchStartOffset = 0;
let searchEndOffset = 0;
if (lineNumber === position.lineNumber) {
tokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1);
searchStartOffset = position.column - 1;
searchEndOffset = position.column - 1;
const tokenLanguageId = lineTokens.getLanguageId(tokenIndex);
if (languageId !== tokenLanguageId) {
languageId = tokenLanguageId;
modeBrackets = LanguageConfigurationRegistry.getBracketsSupport(languageId);
}
}
let prevSearchInToken = true;
for (; tokenIndex < tokenCount; tokenIndex++) {
const tokenLanguageId = lineTokens.getLanguageId(tokenIndex);
const tokenType = lineTokens.getStandardTokenType(tokenIndex);
const tokenStartOffset = lineTokens.getStartOffset(tokenIndex);
const tokenEndOffset = lineTokens.getEndOffset(tokenIndex);
if (searchStartOffset === 0) {
searchStartOffset = tokenStartOffset;
}
if (languageId !== tokenLanguageId) {
// language id change!
if (modeBrackets && prevSearchInToken && searchStartOffset !== searchEndOffset) {
const r = BracketsUtils.findNextBracketInRange(modeBrackets.forwardRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
if (r) {
return this._toFoundBracket(modeBrackets, r);
}
prevSearchInToken = false;
}
languageId = tokenLanguageId;
modeBrackets = LanguageConfigurationRegistry.getBracketsSupport(languageId);
}
if (modeBrackets && !ignoreBracketsInToken(tokenType)) {
let r = BracketsUtils.findNextBracketInToken(modeBrackets.forwardRegex, lineNumber, lineText, searchStartOffset, tokenEndOffset);
if (r) {
return this._toFoundBracket(modeBrackets, r);
const searchInToken = (!!modeBrackets && !ignoreBracketsInToken(lineTokens.getStandardTokenType(tokenIndex)));
if (searchInToken) {
// this token should be searched
if (prevSearchInToken) {
// the previous token should be searched, simply extend searchEndOffset
searchEndOffset = lineTokens.getEndOffset(tokenIndex);
} else {
// the previous token should not be searched
searchStartOffset = lineTokens.getStartOffset(tokenIndex);
searchEndOffset = lineTokens.getEndOffset(tokenIndex);
}
} else {
// this token should not be searched
if (modeBrackets && prevSearchInToken && searchStartOffset !== searchEndOffset) {
const r = BracketsUtils.findNextBracketInRange(modeBrackets.forwardRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
if (r) {
return this._toFoundBracket(modeBrackets, r);
}
}
}
searchStartOffset = 0;
prevSearchInToken = searchInToken;
}
if (modeBrackets && prevSearchInToken && searchStartOffset !== searchEndOffset) {
const r = BracketsUtils.findNextBracketInRange(modeBrackets.forwardRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
if (r) {
return this._toFoundBracket(modeBrackets, r);
}
}
}
......
......@@ -56,7 +56,7 @@ export class BracketElectricCharacterSupport {
let reversedBracketRegex = this._richEditBrackets.reversedRegex;
let text = context.getLineContent().substring(0, column - 1) + character;
let r = BracketsUtils.findPrevBracketInToken(reversedBracketRegex, 1, text, 0, text.length);
let r = BracketsUtils.findPrevBracketInRange(reversedBracketRegex, 1, text, 0, text.length);
if (!r) {
return null;
}
......
......@@ -168,12 +168,11 @@ export class BracketsUtils {
return new Range(lineNumber, absoluteMatchOffset - matchLength + 1, lineNumber, absoluteMatchOffset + 1);
}
public static findPrevBracketInToken(reversedBracketRegex: RegExp, lineNumber: number, lineText: string, currentTokenStart: number, currentTokenEnd: number): Range | null {
public static findPrevBracketInRange(reversedBracketRegex: RegExp, lineNumber: number, lineText: string, startOffset: number, endOffset: number): Range | null {
// Because JS does not support backwards regex search, we search forwards in a reversed string with a reversed regex ;)
let reversedLineText = toReversedString(lineText);
let reversedTokenText = reversedLineText.substring(lineText.length - currentTokenEnd, lineText.length - currentTokenStart);
return this._findPrevBracketInText(reversedBracketRegex, lineNumber, reversedTokenText, currentTokenStart);
const reversedLineText = toReversedString(lineText);
const reversedSubstr = reversedLineText.substring(lineText.length - endOffset, lineText.length - startOffset);
return this._findPrevBracketInText(reversedBracketRegex, lineNumber, reversedSubstr, startOffset);
}
public static findNextBracketInText(bracketRegex: RegExp, lineNumber: number, text: string, offset: number): Range | null {
......@@ -193,10 +192,8 @@ export class BracketsUtils {
return new Range(lineNumber, absoluteMatchOffset + 1, lineNumber, absoluteMatchOffset + 1 + matchLength);
}
public static findNextBracketInToken(bracketRegex: RegExp, lineNumber: number, lineText: string, currentTokenStart: number, currentTokenEnd: number): Range | null {
let currentTokenText = lineText.substring(currentTokenStart, currentTokenEnd);
return this.findNextBracketInText(bracketRegex, lineNumber, currentTokenText, currentTokenStart);
public static findNextBracketInRange(bracketRegex: RegExp, lineNumber: number, lineText: string, startOffset: number, endOffset: number): Range | null {
const substr = lineText.substring(startOffset, endOffset);
return this.findNextBracketInText(bracketRegex, lineNumber, substr, startOffset);
}
}
......@@ -9,71 +9,71 @@ import { BracketsUtils } from 'vs/editor/common/modes/supports/richEditBrackets'
suite('richEditBrackets', () => {
function findPrevBracketInToken(reversedBracketRegex: RegExp, lineText: string, currentTokenStart: number, currentTokenEnd: number): Range | null {
return BracketsUtils.findPrevBracketInToken(reversedBracketRegex, 1, lineText, currentTokenStart, currentTokenEnd);
function findPrevBracketInRange(reversedBracketRegex: RegExp, lineText: string, currentTokenStart: number, currentTokenEnd: number): Range | null {
return BracketsUtils.findPrevBracketInRange(reversedBracketRegex, 1, lineText, currentTokenStart, currentTokenEnd);
}
function findNextBracketInToken(forwardBracketRegex: RegExp, lineText: string, currentTokenStart: number, currentTokenEnd: number): Range | null {
return BracketsUtils.findNextBracketInToken(forwardBracketRegex, 1, lineText, currentTokenStart, currentTokenEnd);
function findNextBracketInRange(forwardBracketRegex: RegExp, lineText: string, currentTokenStart: number, currentTokenEnd: number): Range | null {
return BracketsUtils.findNextBracketInRange(forwardBracketRegex, 1, lineText, currentTokenStart, currentTokenEnd);
}
test('findPrevBracketInToken one char 1', () => {
let result = findPrevBracketInToken(/(\{)|(\})/i, '{', 0, 1);
let result = findPrevBracketInRange(/(\{)|(\})/i, '{', 0, 1);
assert.equal(result!.startColumn, 1);
assert.equal(result!.endColumn, 2);
});
test('findPrevBracketInToken one char 2', () => {
let result = findPrevBracketInToken(/(\{)|(\})/i, '{{', 0, 1);
let result = findPrevBracketInRange(/(\{)|(\})/i, '{{', 0, 1);
assert.equal(result!.startColumn, 1);
assert.equal(result!.endColumn, 2);
});
test('findPrevBracketInToken one char 3', () => {
let result = findPrevBracketInToken(/(\{)|(\})/i, '{hello world!', 0, 13);
let result = findPrevBracketInRange(/(\{)|(\})/i, '{hello world!', 0, 13);
assert.equal(result!.startColumn, 1);
assert.equal(result!.endColumn, 2);
});
test('findPrevBracketInToken more chars 1', () => {
let result = findPrevBracketInToken(/(olleh)/i, 'hello world!', 0, 12);
let result = findPrevBracketInRange(/(olleh)/i, 'hello world!', 0, 12);
assert.equal(result!.startColumn, 1);
assert.equal(result!.endColumn, 6);
});
test('findPrevBracketInToken more chars 2', () => {
let result = findPrevBracketInToken(/(olleh)/i, 'hello world!', 0, 5);
let result = findPrevBracketInRange(/(olleh)/i, 'hello world!', 0, 5);
assert.equal(result!.startColumn, 1);
assert.equal(result!.endColumn, 6);
});
test('findPrevBracketInToken more chars 3', () => {
let result = findPrevBracketInToken(/(olleh)/i, ' hello world!', 0, 6);
let result = findPrevBracketInRange(/(olleh)/i, ' hello world!', 0, 6);
assert.equal(result!.startColumn, 2);
assert.equal(result!.endColumn, 7);
});
test('findNextBracketInToken one char', () => {
let result = findNextBracketInToken(/(\{)|(\})/i, '{', 0, 1);
let result = findNextBracketInRange(/(\{)|(\})/i, '{', 0, 1);
assert.equal(result!.startColumn, 1);
assert.equal(result!.endColumn, 2);
});
test('findNextBracketInToken more chars', () => {
let result = findNextBracketInToken(/(world)/i, 'hello world!', 0, 12);
let result = findNextBracketInRange(/(world)/i, 'hello world!', 0, 12);
assert.equal(result!.startColumn, 7);
assert.equal(result!.endColumn, 12);
});
test('findNextBracketInToken with emoty result', () => {
let result = findNextBracketInToken(/(\{)|(\})/i, '', 0, 0);
let result = findNextBracketInRange(/(\{)|(\})/i, '', 0, 0);
assert.equal(result, null);
});
test('issue #3894: [Handlebars] Curly braces edit issues', () => {
let result = findPrevBracketInToken(/(\-\-!<)|(>\-\-)|(\{\{)|(\}\})/i, '{{asd}}', 0, 2);
let result = findPrevBracketInRange(/(\-\-!<)|(>\-\-)|(\{\{)|(\}\})/i, '{{asd}}', 0, 2);
assert.equal(result!.startColumn, 1);
assert.equal(result!.endColumn, 3);
});
});
\ No newline at end of file
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册