@@ -22,6 +22,7 @@ import { getWordAtText } from 'vs/editor/common/model/wordHelper';
2222import { TokenizationResult2 } from 'vs/editor/common/core/token' ;
2323import { ITextSource , IRawTextSource } from 'vs/editor/common/model/textSource' ;
2424import * as textModelEvents from 'vs/editor/common/model/textModelEvents' ;
25+ import { IndentRange , computeRanges } from 'vs/editor/common/model/indentRanges' ;
2526
2627class ModelTokensChangedEventBuilder {
2728
@@ -69,6 +70,8 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
6970 private _invalidLineStartIndex : number ;
7071 private _lastState : IState ;
7172
73+ private _indentRanges : IndentRange [ ] ;
74+
7275 private _revalidateTokensTimeout : number ;
7376
7477 constructor ( rawTextSource : IRawTextSource , creationOptions : editorCommon . ITextModelCreationOptions , languageIdentifier : LanguageIdentifier ) {
@@ -96,6 +99,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
9699 this . _revalidateTokensTimeout = - 1 ;
97100
98101 this . _resetTokenizationState ( ) ;
102+ this . _resetIndentRanges ( ) ;
99103 }
100104
101105 public dispose ( ) : void {
@@ -114,6 +118,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
114118 super . _resetValue ( newValue ) ;
115119 // Cancel tokenization, clear all tokens and begin tokenizing
116120 this . _resetTokenizationState ( ) ;
121+ this . _resetIndentRanges ( ) ;
117122 }
118123
119124 protected _resetTokenizationState ( ) : void {
@@ -225,6 +230,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
225230
226231 // Cancel tokenization, clear all tokens and begin tokenizing
227232 this . _resetTokenizationState ( ) ;
233+ this . _resetIndentRanges ( ) ;
228234
229235 this . emitModelTokensChangedEvent ( {
230236 ranges : [ {
@@ -814,4 +820,63 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
814820 isOpen : modeBrackets . textIsOpenBracket [ text ]
815821 } ;
816822 }
823+
824+ protected _resetIndentRanges ( ) : void {
825+ this . _indentRanges = null ;
826+ }
827+
828+ private _getIndentRanges ( ) : IndentRange [ ] {
829+ if ( ! this . _indentRanges ) {
830+ this . _indentRanges = computeRanges ( this ) ;
831+ }
832+ return this . _indentRanges ;
833+ }
834+
835+ public getIndentRanges ( ) : IndentRange [ ] {
836+ this . _assertNotDisposed ( ) ;
837+ let indentRanges = this . _getIndentRanges ( ) ;
838+ return IndentRange . deepCloneArr ( indentRanges ) ;
839+ }
840+
841+ public getLineIndentGuide ( lineNumber : number ) : number {
842+ this . _assertNotDisposed ( ) ;
843+ if ( lineNumber < 1 || lineNumber > this . getLineCount ( ) ) {
844+ throw new Error ( 'Illegal value ' + lineNumber + ' for `lineNumber`' ) ;
845+ }
846+
847+ let indentRanges = this . _getIndentRanges ( ) ;
848+
849+ for ( let i = indentRanges . length - 1 ; i >= 0 ; i -- ) {
850+ let rng = indentRanges [ i ] ;
851+
852+ if ( rng . startLineNumber === lineNumber ) {
853+ return this . _toValidLineIndentGuide ( lineNumber , Math . ceil ( rng . indent / this . _options . tabSize ) ) ;
854+ }
855+ if ( rng . startLineNumber < lineNumber && lineNumber <= rng . endLineNumber ) {
856+ return this . _toValidLineIndentGuide ( lineNumber , 1 + Math . floor ( rng . indent / this . _options . tabSize ) ) ;
857+ }
858+ if ( rng . endLineNumber + 1 === lineNumber ) {
859+ let bestIndent = rng . indent ;
860+ while ( i > 0 ) {
861+ i -- ;
862+ rng = indentRanges [ i ] ;
863+ if ( rng . endLineNumber + 1 === lineNumber ) {
864+ bestIndent = rng . indent ;
865+ }
866+ }
867+ return this . _toValidLineIndentGuide ( lineNumber , Math . ceil ( bestIndent / this . _options . tabSize ) ) ;
868+ }
869+ }
870+
871+ return 0 ;
872+ }
873+
874+ private _toValidLineIndentGuide ( lineNumber : number , indentGuide : number ) : number {
875+ let lineIndentLevel = this . _lines [ lineNumber - 1 ] . getIndentLevel ( ) ;
876+ if ( lineIndentLevel === - 1 ) {
877+ return indentGuide ;
878+ }
879+ let maxIndentGuide = Math . ceil ( lineIndentLevel / this . _options . tabSize ) ;
880+ return Math . min ( maxIndentGuide , indentGuide ) ;
881+ }
817882}
0 commit comments