提交 3ad82b90 编写于 作者: A Alex Dima

Simplify bracket matching code

上级 9e45371e
...@@ -42,12 +42,34 @@ export class LineToken { ...@@ -42,12 +42,34 @@ export class LineToken {
if (this._modeIndex === 0) { if (this._modeIndex === 0) {
return new LineToken(this._source, this._tokenIndex - 1, this._modeIndex); return new LineToken(this._source, this._tokenIndex - 1, this._modeIndex);
} }
let modeTransition = this._source.modeTransitions[this._modeIndex]; const modeTransitions = this._source.modeTransitions;
if (this.startOffset === modeTransition.startIndex) { const currentModeTransition = modeTransitions[this._modeIndex];
const prevStartOffset = this._source.getTokenStartOffset(this._tokenIndex - 1);
if (prevStartOffset < currentModeTransition.startIndex) {
// Going to previous mode transition
return new LineToken(this._source, this._tokenIndex - 1, this._modeIndex - 1); return new LineToken(this._source, this._tokenIndex - 1, this._modeIndex - 1);
} }
return new LineToken(this._source, this._tokenIndex - 1, this._modeIndex); return new LineToken(this._source, this._tokenIndex - 1, this._modeIndex);
} }
public next(): LineToken {
if (!this.hasNext) {
return null;
}
const modeTransitions = this._source.modeTransitions;
if (this._modeIndex === modeTransitions.length - 1) {
return new LineToken(this._source, this._tokenIndex + 1, this._modeIndex);
}
const nextModeTransition = modeTransitions[this._modeIndex + 1];
const nextStartOffset = this._source.getTokenStartOffset(this._tokenIndex + 1);
if (nextStartOffset >= nextModeTransition.startIndex) {
// Going to next mode transition
return new LineToken(this._source, this._tokenIndex + 1, this._modeIndex + 1);
}
return new LineToken(this._source, this._tokenIndex + 1, this._modeIndex);
}
} }
export class LineTokens { export class LineTokens {
...@@ -112,11 +134,15 @@ export class LineTokens { ...@@ -112,11 +134,15 @@ export class LineTokens {
public findTokenAtOffset(offset:number): LineToken { public findTokenAtOffset(offset:number): LineToken {
let tokenIndex = this.findTokenIndexAtOffset(offset); let tokenIndex = this.findTokenIndexAtOffset(offset);
let modeIndex = ModeTransition.findIndexInSegmentsArray(this.modeTransitions, offset); let modeIndex = ModeTransition.findIndexInSegmentsArray(this.modeTransitions, offset);
return new LineToken( return new LineToken(this, tokenIndex, modeIndex);
this, }
tokenIndex,
modeIndex public first(): LineToken {
); return new LineToken(this, 0, 0);
}
public last(): LineToken {
return new LineToken(this, this._tokens.length - 1, this.modeTransitions.length - 1);
} }
public inflate(): ViewLineToken[] { public inflate(): ViewLineToken[] {
......
...@@ -24,7 +24,7 @@ import {TokensInflatorMap} from 'vs/editor/common/model/tokensBinaryEncoding'; ...@@ -24,7 +24,7 @@ import {TokensInflatorMap} from 'vs/editor/common/model/tokensBinaryEncoding';
import {Position} from 'vs/editor/common/core/position'; import {Position} from 'vs/editor/common/core/position';
import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry'; import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {Token} from 'vs/editor/common/core/token'; import {Token} from 'vs/editor/common/core/token';
import {LineTokens} from 'vs/editor/common/core/lineTokens'; import {LineTokens, LineToken} from 'vs/editor/common/core/lineTokens';
class Mode implements IMode { class Mode implements IMode {
...@@ -610,43 +610,29 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke ...@@ -610,43 +610,29 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
private _findMatchingBracketUp(bracket:editorCommon.IRichEditBracket, position:Position): Range { private _findMatchingBracketUp(bracket:editorCommon.IRichEditBracket, position:Position): Range {
// console.log('_findMatchingBracketUp: ', 'bracket: ', JSON.stringify(bracket), 'startPosition: ', String(position)); // console.log('_findMatchingBracketUp: ', 'bracket: ', JSON.stringify(bracket), 'startPosition: ', String(position));
let modeId = bracket.modeId; const modeId = bracket.modeId;
let reversedBracketRegex = bracket.reversedRegex; const reversedBracketRegex = bracket.reversedRegex;
let count = -1; let count = -1;
for (let lineNumber = position.lineNumber; lineNumber >= 1; lineNumber--) { for (let lineNumber = position.lineNumber; lineNumber >= 1; lineNumber--) {
let lineTokens = this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap); const lineTokens = this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap);
let lineText = this._lines[lineNumber - 1].text; const lineText = this._lines[lineNumber - 1].text;
let modeTransitions = this._lines[lineNumber - 1].getModeTransitions(this.getModeId());
let currentModeIndex = modeTransitions.length - 1;
let currentModeStart = modeTransitions[currentModeIndex].startIndex;
let currentModeId = modeTransitions[currentModeIndex].modeId;
let tokensLength = lineTokens.getTokenCount() - 1; let currentToken: LineToken;
let currentTokenEndOffset = lineText.length; let searchStopOffset: number;
if (lineNumber === position.lineNumber) { if (lineNumber === position.lineNumber) {
tokensLength = lineTokens.findTokenIndexAtOffset(position.column - 1); currentToken = lineTokens.findTokenAtOffset(position.column - 1);
currentTokenEndOffset = position.column - 1; searchStopOffset = position.column - 1;
} else {
currentModeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, position.column - 1); currentToken = lineTokens.last();
currentModeStart = modeTransitions[currentModeIndex].startIndex; searchStopOffset = currentToken.endOffset;
currentModeId = modeTransitions[currentModeIndex].modeId;
} }
for (let tokenIndex = tokensLength; tokenIndex >= 0; tokenIndex--) { do {
let currentTokenType = lineTokens.getTokenType(tokenIndex); if (currentToken.modeId === modeId && !ignoreBracketsInToken(currentToken.type)) {
let currentTokenStartOffset = lineTokens.getTokenStartOffset(tokenIndex);
if (currentTokenStartOffset < currentModeStart) {
currentModeIndex--;
currentModeStart = modeTransitions[currentModeIndex].startIndex;
currentModeId = modeTransitions[currentModeIndex].modeId;
}
if (currentModeId === modeId && !ignoreBracketsInToken(currentTokenType)) {
while (true) { while (true) {
let r = BracketsUtils.findPrevBracketInToken(reversedBracketRegex, lineNumber, lineText, currentTokenStartOffset, currentTokenEndOffset); let r = BracketsUtils.findPrevBracketInToken(reversedBracketRegex, lineNumber, lineText, currentToken.startOffset, searchStopOffset);
if (!r) { if (!r) {
break; break;
} }
...@@ -664,12 +650,16 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke ...@@ -664,12 +650,16 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
return r; return r;
} }
currentTokenEndOffset = r.startColumn - 1; searchStopOffset = r.startColumn - 1;
} }
} }
currentTokenEndOffset = currentTokenStartOffset; currentToken = currentToken.prev();
} if (currentToken) {
searchStopOffset = currentToken.endOffset;
}
} while(currentToken);
} }
return null; return null;
...@@ -678,42 +668,28 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke ...@@ -678,42 +668,28 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
private _findMatchingBracketDown(bracket:editorCommon.IRichEditBracket, position:Position): Range { private _findMatchingBracketDown(bracket:editorCommon.IRichEditBracket, position:Position): Range {
// console.log('_findMatchingBracketDown: ', 'bracket: ', JSON.stringify(bracket), 'startPosition: ', String(position)); // console.log('_findMatchingBracketDown: ', 'bracket: ', JSON.stringify(bracket), 'startPosition: ', String(position));
let modeId = bracket.modeId; const modeId = bracket.modeId;
let bracketRegex = bracket.forwardRegex; const bracketRegex = bracket.forwardRegex;
let count = 1; let count = 1;
for (let lineNumber = position.lineNumber, lineCount = this.getLineCount(); lineNumber <= lineCount; lineNumber++) { for (let lineNumber = position.lineNumber, lineCount = this.getLineCount(); lineNumber <= lineCount; lineNumber++) {
let lineTokens = this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap); const lineTokens = this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap);
let lineText = this._lines[lineNumber - 1].text; const lineText = this._lines[lineNumber - 1].text;
let modeTransitions = this._lines[lineNumber - 1].getModeTransitions(this.getModeId());
let currentModeIndex = 0;
let nextModeStart = (currentModeIndex + 1 < modeTransitions.length ? modeTransitions[currentModeIndex + 1].startIndex : lineText.length + 1);
let currentModeId = modeTransitions[currentModeIndex].modeId;
let startTokenIndex = 0; let currentToken: LineToken;
let currentTokenStartOffset = lineTokens.getTokenStartOffset(startTokenIndex); let searchStartOffset: number;
if (lineNumber === position.lineNumber) { if (lineNumber === position.lineNumber) {
startTokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1); currentToken = lineTokens.findTokenAtOffset(position.column - 1);
currentTokenStartOffset = Math.max(currentTokenStartOffset, position.column - 1); searchStartOffset = position.column - 1;
} else {
currentModeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, position.column - 1); currentToken = lineTokens.first();
nextModeStart = (currentModeIndex + 1 < modeTransitions.length ? modeTransitions[currentModeIndex + 1].startIndex : lineText.length + 1); searchStartOffset = currentToken.startOffset;
currentModeId = modeTransitions[currentModeIndex].modeId;
} }
for (let tokenIndex = startTokenIndex, tokensLength = lineTokens.getTokenCount(); tokenIndex < tokensLength; tokenIndex++) { do {
let currentTokenType = lineTokens.getTokenType(tokenIndex); if (currentToken.modeId === modeId && !ignoreBracketsInToken(currentToken.type)) {
let currentTokenEndOffset = lineTokens.getTokenEndOffset(tokenIndex);
if (currentTokenStartOffset >= nextModeStart) {
currentModeIndex++;
nextModeStart = (currentModeIndex + 1 < modeTransitions.length ? modeTransitions[currentModeIndex + 1].startIndex : lineText.length + 1);
currentModeId = modeTransitions[currentModeIndex].modeId;
}
if (currentModeId === modeId && !ignoreBracketsInToken(currentTokenType)) {
while (true) { while (true) {
let r = BracketsUtils.findNextBracketInToken(bracketRegex, lineNumber, lineText, currentTokenStartOffset, currentTokenEndOffset); let r = BracketsUtils.findNextBracketInToken(bracketRegex, lineNumber, lineText, searchStartOffset, currentToken.endOffset);
if (!r) { if (!r) {
break; break;
} }
...@@ -731,12 +707,15 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke ...@@ -731,12 +707,15 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
return r; return r;
} }
currentTokenStartOffset = r.endColumn - 1; searchStartOffset = r.endColumn - 1;
} }
} }
currentTokenStartOffset = currentTokenEndOffset; currentToken = currentToken.next();
} if (currentToken) {
searchStartOffset = currentToken.startOffset;
}
} while (currentToken);
} }
return null; return null;
......
...@@ -104,13 +104,26 @@ function createOrRegex(pieces:string[]): RegExp { ...@@ -104,13 +104,26 @@ function createOrRegex(pieces:string[]): RegExp {
return strings.createRegExp(regexStr, true); return strings.createRegExp(regexStr, true);
} }
function toReversedString(str:string): string { let toReversedString = (function() {
let reversedStr = '';
for (let i = str.length - 1; i >= 0; i--) { function reverse(str:string): string {
reversedStr += str.charAt(i); let reversedStr = '';
for (let i = str.length - 1; i >= 0; i--) {
reversedStr += str.charAt(i);
}
return reversedStr;
} }
return reversedStr;
} let lastInput: string = null;
let lastOutput: string = null;
return function toReversedString(str:string): string {
if (lastInput !== str) {
lastInput = str;
lastOutput = reverse(lastInput);
}
return lastOutput;
};
})();
export class BracketsUtils { export class BracketsUtils {
...@@ -130,12 +143,10 @@ export class BracketsUtils { ...@@ -130,12 +143,10 @@ export class BracketsUtils {
public static findPrevBracketInToken(reversedBracketRegex:RegExp, lineNumber:number, lineText:string, currentTokenStart:number, currentTokenEnd:number): Range { public static findPrevBracketInToken(reversedBracketRegex:RegExp, lineNumber:number, lineText:string, currentTokenStart:number, currentTokenEnd:number): Range {
// Because JS does not support backwards regex search, we search forwards in a reversed string with a reversed regex ;) // Because JS does not support backwards regex search, we search forwards in a reversed string with a reversed regex ;)
let currentTokenReversedText = ''; let reversedLineText = toReversedString(lineText);
for (let index = currentTokenEnd - 1; index >= currentTokenStart; index--) { let reversedTokenText = reversedLineText.substring(lineText.length - currentTokenEnd, lineText.length - currentTokenStart);
currentTokenReversedText += lineText.charAt(index);
}
return this._findPrevBracketInText(reversedBracketRegex, lineNumber, currentTokenReversedText, currentTokenStart); return this._findPrevBracketInText(reversedBracketRegex, lineNumber, reversedTokenText, currentTokenStart);
} }
public static findNextBracketInText(bracketRegex:RegExp, lineNumber:number, text:string, offset:number): Range { public static findNextBracketInText(bracketRegex:RegExp, lineNumber:number, text:string, offset:number): Range {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册