diff --git a/src/vs/editor/common/model/textModelWithTokens.ts b/src/vs/editor/common/model/textModelWithTokens.ts index e1874c101790cca9f9494775f95539e081e9f030..4076b029ca0ed62d41b134c85eb64525b1623ddd 100644 --- a/src/vs/editor/common/model/textModelWithTokens.ts +++ b/src/vs/editor/common/model/textModelWithTokens.ts @@ -861,39 +861,57 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke throw new Error('Illegal value ' + lineNumber + ' for `lineNumber`'); } - let indentRanges = this._getIndentRanges(); - - for (let i = indentRanges.length - 1; i >= 0; i--) { - let startLineNumber = indentRanges.getStartLineNumber(i); - if (startLineNumber === lineNumber) { - return this._toValidLineIndentGuide(lineNumber, Math.ceil(indentRanges.getIndent(i) / this._options.tabSize)); - } - let endLineNumber = indentRanges.getEndLineNumber(i); - if (startLineNumber < lineNumber && lineNumber <= endLineNumber) { - return this._toValidLineIndentGuide(lineNumber, 1 + Math.floor(indentRanges.getIndent(i) / this._options.tabSize)); + const currentIndent = this._lines[lineNumber - 1].getIndentLevel(); + if (currentIndent >= 0) { + // This line has content (besides whitespace) + // Use the line's indent + return Math.ceil(currentIndent / this._options.tabSize); + } + + let belowIndent = -1; + for (let lineIndex = lineNumber, lineCount = this.getLineCount(); lineIndex < lineCount; lineIndex++) { + let indent = this._lines[lineIndex].getIndentLevel(); + if (indent >= 0) { + belowIndent = indent; + break; } - if (endLineNumber + 1 === lineNumber) { - let bestIndent = indentRanges.getIndent(i); - while (i > 0) { - i--; - endLineNumber = indentRanges.getEndLineNumber(i); - if (endLineNumber + 1 === lineNumber) { - bestIndent = indentRanges.getIndent(i); - } - } - return this._toValidLineIndentGuide(lineNumber, Math.ceil(bestIndent / this._options.tabSize)); + + } + + let aboveIndent = -1; + for (let lineIndex = lineNumber - 2; lineIndex >= 0; lineIndex--) { + let indent = this._lines[lineIndex].getIndentLevel(); + if (indent >= 0) { + aboveIndent = indent; + break; } } - return 0; - } + if (aboveIndent === -1 || belowIndent === -1) { + // At the top or bottom of the file + return 0; + } + + if (aboveIndent < belowIndent) { + // we are inside the region above + return (1 + Math.floor(aboveIndent / this._options.tabSize)); + } + + if (aboveIndent === belowIndent) { + // we are in between two regions + return Math.ceil(belowIndent / this._options.tabSize); + } - private _toValidLineIndentGuide(lineNumber: number, indentGuide: number): number { - let lineIndentLevel = this._lines[lineNumber - 1].getIndentLevel(); - if (lineIndentLevel === -1) { - return indentGuide; + let foldingRules = LanguageConfigurationRegistry.getFoldingRules(this._languageIdentifier.id); + let offSide = foldingRules && foldingRules.offSide; + if (offSide) { + // same level as region below + return Math.ceil(belowIndent / this._options.tabSize); + } else { + // we are inside the region that ends below + return (1 + Math.floor(belowIndent / this._options.tabSize)); } - let maxIndentGuide = Math.ceil(lineIndentLevel / this._options.tabSize); - return Math.min(maxIndentGuide, indentGuide); } + + } diff --git a/src/vs/editor/test/common/model/textModelWithTokens.test.ts b/src/vs/editor/test/common/model/textModelWithTokens.test.ts index 24c66e08947e08c4ae3009ebed97378dd900dae6..60ce51f23907fc1fe97ff7ece40fd71d5ea52750 100644 --- a/src/vs/editor/test/common/model/textModelWithTokens.test.ts +++ b/src/vs/editor/test/common/model/textModelWithTokens.test.ts @@ -408,8 +408,8 @@ suite('TextModel.getLineIndentGuide', () => { test('getLineIndentGuide decreasing indent', () => { assertIndentGuides([ - [0, ' A'], - [0, ' A'], + [1, ' A'], + [1, ' A'], [0, 'A'], ]); }); @@ -450,7 +450,7 @@ suite('TextModel.getLineIndentGuide', () => { [1, ''], [1, ' void foo() {'], [1, ' '], - [1, ' return 1;'], + [2, ' return 1;'], [1, ' }'], [1, ' '], [0, '}'],