mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-11 18:48:33 -05:00
Merge from vscode c58aaab8a1cc22a7139b761166a0d4f37d41e998 (#7880)
* Merge from vscode c58aaab8a1cc22a7139b761166a0d4f37d41e998 * fix pipelines * fix strict-null-checks * add missing files
This commit is contained in:
@@ -726,6 +726,11 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
return this._buffer.getValueLengthInRange(this.validateRange(rawRange), eol);
|
||||
}
|
||||
|
||||
public getCharacterCountInRange(rawRange: IRange, eol: model.EndOfLinePreference = model.EndOfLinePreference.TextDefined): number {
|
||||
this._assertNotDisposed();
|
||||
return this._buffer.getCharacterCountInRange(this.validateRange(rawRange), eol);
|
||||
}
|
||||
|
||||
public getLineCount(): number {
|
||||
this._assertNotDisposed();
|
||||
return this._buffer.getLineCount();
|
||||
@@ -1910,7 +1915,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 +1924,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 +1940,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 +1957,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 +2008,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 (bracket.isOpen(hitText)) {
|
||||
count++;
|
||||
} else if (bracket.isClose(hitText)) {
|
||||
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);
|
||||
const searchInToken = (lineTokens.getLanguageId(tokenIndex) === languageId && !ignoreBracketsInToken(lineTokens.getStandardTokenType(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) {
|
||||
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 +2091,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 (bracket.isOpen(hitText)) {
|
||||
count++;
|
||||
} else if (bracket.isClose(hitText)) {
|
||||
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);
|
||||
const searchInToken = (lineTokens.getLanguageId(tokenIndex) === languageId && !ignoreBracketsInToken(lineTokens.getStandardTokenType(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) {
|
||||
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 +2179,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;
|
||||
}
|
||||
|
||||
for (; tokenIndex >= 0; tokenIndex--) {
|
||||
searchStartOffset = position.column - 1;
|
||||
searchEndOffset = position.column - 1;
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
let prevSearchInToken = true;
|
||||
for (; tokenIndex >= 0; tokenIndex--) {
|
||||
const tokenLanguageId = lineTokens.getLanguageId(tokenIndex);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 +2247,187 @@ 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;
|
||||
}
|
||||
|
||||
for (; tokenIndex < tokenCount; tokenIndex++) {
|
||||
searchEndOffset = position.column - 1;
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
let prevSearchInToken = true;
|
||||
for (; tokenIndex < tokenCount; tokenIndex++) {
|
||||
const tokenLanguageId = lineTokens.getLanguageId(tokenIndex);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public findEnclosingBrackets(_position: IPosition): [Range, Range] | null {
|
||||
const position = this.validatePosition(_position);
|
||||
const lineCount = this.getLineCount();
|
||||
|
||||
let counts: number[] = [];
|
||||
const resetCounts = (modeBrackets: RichEditBrackets | null) => {
|
||||
counts = [];
|
||||
for (let i = 0, len = modeBrackets ? modeBrackets.brackets.length : 0; i < len; i++) {
|
||||
counts[i] = 0;
|
||||
}
|
||||
};
|
||||
const searchInRange = (modeBrackets: RichEditBrackets, lineNumber: number, lineText: string, searchStartOffset: number, searchEndOffset: number): [Range, Range] | null => {
|
||||
while (true) {
|
||||
const r = BracketsUtils.findNextBracketInRange(modeBrackets.forwardRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
|
||||
if (!r) {
|
||||
break;
|
||||
}
|
||||
|
||||
const hitText = lineText.substring(r.startColumn - 1, r.endColumn - 1).toLowerCase();
|
||||
const bracket = modeBrackets.textIsBracket[hitText];
|
||||
if (bracket) {
|
||||
if (bracket.isOpen(hitText)) {
|
||||
counts[bracket.index]++;
|
||||
} else if (bracket.isClose(hitText)) {
|
||||
counts[bracket.index]--;
|
||||
}
|
||||
|
||||
if (counts[bracket.index] === -1) {
|
||||
return this._matchFoundBracket(r, bracket, false);
|
||||
}
|
||||
}
|
||||
|
||||
searchStartOffset = r.endColumn - 1;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
let languageId: LanguageId = -1;
|
||||
let modeBrackets: RichEditBrackets | null = null;
|
||||
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);
|
||||
resetCounts(modeBrackets);
|
||||
}
|
||||
}
|
||||
|
||||
let prevSearchInToken = true;
|
||||
for (; tokenIndex < tokenCount; tokenIndex++) {
|
||||
const tokenLanguageId = lineTokens.getLanguageId(tokenIndex);
|
||||
|
||||
if (languageId !== tokenLanguageId) {
|
||||
// language id change!
|
||||
if (modeBrackets && prevSearchInToken && searchStartOffset !== searchEndOffset) {
|
||||
const r = searchInRange(modeBrackets, lineNumber, lineText, searchStartOffset, searchEndOffset);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
prevSearchInToken = false;
|
||||
}
|
||||
languageId = tokenLanguageId;
|
||||
modeBrackets = LanguageConfigurationRegistry.getBracketsSupport(languageId);
|
||||
resetCounts(modeBrackets);
|
||||
}
|
||||
|
||||
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 = searchInRange(modeBrackets, lineNumber, lineText, searchStartOffset, searchEndOffset);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prevSearchInToken = searchInToken;
|
||||
}
|
||||
|
||||
if (modeBrackets && prevSearchInToken && searchStartOffset !== searchEndOffset) {
|
||||
const r = searchInRange(modeBrackets, lineNumber, lineText, searchStartOffset, searchEndOffset);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user