@@ -17,6 +17,16 @@ export const enum RenderWhitespace {
1717 All = 3
1818}
1919
20+ export const enum LinePartMetadata {
21+ IS_WHITESPACE = 1 ,
22+ PSEUDO_BEFORE = 2 ,
23+ PSEUDO_AFTER = 4 ,
24+
25+ IS_WHITESPACE_MASK = 0b001 ,
26+ PSEUDO_BEFORE_MASK = 0b010 ,
27+ PSEUDO_AFTER_MASK = 0b100 ,
28+ }
29+
2030class LinePart {
2131 _linePartBrand : void ;
2232
@@ -25,10 +35,16 @@ class LinePart {
2535 */
2636 public readonly endIndex : number ;
2737 public readonly type : string ;
38+ public readonly metadata : number ;
2839
29- constructor ( endIndex : number , type : string ) {
40+ constructor ( endIndex : number , type : string , metadata : number ) {
3041 this . endIndex = endIndex ;
3142 this . type = type ;
43+ this . metadata = metadata ;
44+ }
45+
46+ public isWhitespace ( ) : boolean {
47+ return ( this . metadata & LinePartMetadata . IS_WHITESPACE_MASK ? true : false ) ;
3248 }
3349}
3450
@@ -470,7 +486,7 @@ function transformAndRemoveOverflowing(tokens: IViewLineTokens, fauxIndentLength
470486
471487 // The faux indent part of the line should have no token type
472488 if ( fauxIndentLength > 0 ) {
473- result [ resultLen ++ ] = new LinePart ( fauxIndentLength , '' ) ;
489+ result [ resultLen ++ ] = new LinePart ( fauxIndentLength , '' , 0 ) ;
474490 }
475491
476492 for ( let tokenIndex = 0 , tokensLen = tokens . getCount ( ) ; tokenIndex < tokensLen ; tokenIndex ++ ) {
@@ -481,10 +497,10 @@ function transformAndRemoveOverflowing(tokens: IViewLineTokens, fauxIndentLength
481497 }
482498 const type = tokens . getClassName ( tokenIndex ) ;
483499 if ( endIndex >= len ) {
484- result [ resultLen ++ ] = new LinePart ( len , type ) ;
500+ result [ resultLen ++ ] = new LinePart ( len , type , 0 ) ;
485501 break ;
486502 }
487- result [ resultLen ++ ] = new LinePart ( endIndex , type ) ;
503+ result [ resultLen ++ ] = new LinePart ( endIndex , type , 0 ) ;
488504 }
489505
490506 return result ;
@@ -513,6 +529,7 @@ function splitLargeTokens(lineContent: string, tokens: LinePart[], onlyAtSpaces:
513529 const tokenEndIndex = token . endIndex ;
514530 if ( lastTokenEndIndex + Constants . LongToken < tokenEndIndex ) {
515531 const tokenType = token . type ;
532+ const tokenMetadata = token . metadata ;
516533
517534 let lastSpaceOffset = - 1 ;
518535 let currTokenStart = lastTokenEndIndex ;
@@ -522,13 +539,13 @@ function splitLargeTokens(lineContent: string, tokens: LinePart[], onlyAtSpaces:
522539 }
523540 if ( lastSpaceOffset !== - 1 && j - currTokenStart >= Constants . LongToken ) {
524541 // Split at `lastSpaceOffset` + 1
525- result [ resultLen ++ ] = new LinePart ( lastSpaceOffset + 1 , tokenType ) ;
542+ result [ resultLen ++ ] = new LinePart ( lastSpaceOffset + 1 , tokenType , tokenMetadata ) ;
526543 currTokenStart = lastSpaceOffset + 1 ;
527544 lastSpaceOffset = - 1 ;
528545 }
529546 }
530547 if ( currTokenStart !== tokenEndIndex ) {
531- result [ resultLen ++ ] = new LinePart ( tokenEndIndex , tokenType ) ;
548+ result [ resultLen ++ ] = new LinePart ( tokenEndIndex , tokenType , tokenMetadata ) ;
532549 }
533550 } else {
534551 result [ resultLen ++ ] = token ;
@@ -544,12 +561,13 @@ function splitLargeTokens(lineContent: string, tokens: LinePart[], onlyAtSpaces:
544561 let diff = ( tokenEndIndex - lastTokenEndIndex ) ;
545562 if ( diff > Constants . LongToken ) {
546563 const tokenType = token . type ;
564+ const tokenMetadata = token . metadata ;
547565 const piecesCount = Math . ceil ( diff / Constants . LongToken ) ;
548566 for ( let j = 1 ; j < piecesCount ; j ++ ) {
549567 let pieceEndIndex = lastTokenEndIndex + ( j * Constants . LongToken ) ;
550- result [ resultLen ++ ] = new LinePart ( pieceEndIndex , tokenType ) ;
568+ result [ resultLen ++ ] = new LinePart ( pieceEndIndex , tokenType , tokenMetadata ) ;
551569 }
552- result [ resultLen ++ ] = new LinePart ( tokenEndIndex , tokenType ) ;
570+ result [ resultLen ++ ] = new LinePart ( tokenEndIndex , tokenType , tokenMetadata ) ;
553571 } else {
554572 result [ resultLen ++ ] = token ;
555573 }
@@ -640,17 +658,17 @@ function _applyRenderWhitespace(input: RenderLineInput, lineContent: string, len
640658 if ( generateLinePartForEachWhitespace ) {
641659 const lastEndIndex = ( resultLen > 0 ? result [ resultLen - 1 ] . endIndex : fauxIndentLength ) ;
642660 for ( let i = lastEndIndex + 1 ; i <= charIndex ; i ++ ) {
643- result [ resultLen ++ ] = new LinePart ( i , 'mtkw' ) ;
661+ result [ resultLen ++ ] = new LinePart ( i , 'mtkw' , LinePartMetadata . IS_WHITESPACE ) ;
644662 }
645663 } else {
646- result [ resultLen ++ ] = new LinePart ( charIndex , 'mtkw' ) ;
664+ result [ resultLen ++ ] = new LinePart ( charIndex , 'mtkw' , LinePartMetadata . IS_WHITESPACE ) ;
647665 }
648666 tmpIndent = tmpIndent % tabSize ;
649667 }
650668 } else {
651669 // was in regular token
652670 if ( charIndex === tokenEndIndex || ( isInWhitespace && charIndex > fauxIndentLength ) ) {
653- result [ resultLen ++ ] = new LinePart ( charIndex , tokenType ) ;
671+ result [ resultLen ++ ] = new LinePart ( charIndex , tokenType , 0 ) ;
654672 tmpIndent = tmpIndent % tabSize ;
655673 }
656674 }
@@ -693,13 +711,13 @@ function _applyRenderWhitespace(input: RenderLineInput, lineContent: string, len
693711 if ( generateLinePartForEachWhitespace ) {
694712 const lastEndIndex = ( resultLen > 0 ? result [ resultLen - 1 ] . endIndex : fauxIndentLength ) ;
695713 for ( let i = lastEndIndex + 1 ; i <= len ; i ++ ) {
696- result [ resultLen ++ ] = new LinePart ( i , 'mtkw' ) ;
714+ result [ resultLen ++ ] = new LinePart ( i , 'mtkw' , LinePartMetadata . IS_WHITESPACE ) ;
697715 }
698716 } else {
699- result [ resultLen ++ ] = new LinePart ( len , 'mtkw' ) ;
717+ result [ resultLen ++ ] = new LinePart ( len , 'mtkw' , LinePartMetadata . IS_WHITESPACE ) ;
700718 }
701719 } else {
702- result [ resultLen ++ ] = new LinePart ( len , tokenType ) ;
720+ result [ resultLen ++ ] = new LinePart ( len , tokenType , 0 ) ;
703721 }
704722
705723 return result ;
@@ -720,42 +738,45 @@ function _applyInlineDecorations(lineContent: string, len: number, tokens: LineP
720738 const token = tokens [ tokenIndex ] ;
721739 const tokenEndIndex = token . endIndex ;
722740 const tokenType = token . type ;
741+ const tokenMetadata = token . metadata ;
723742
724743 while ( lineDecorationIndex < lineDecorationsLen && lineDecorations [ lineDecorationIndex ] . startOffset < tokenEndIndex ) {
725744 const lineDecoration = lineDecorations [ lineDecorationIndex ] ;
726745
727746 if ( lineDecoration . startOffset > lastResultEndIndex ) {
728747 lastResultEndIndex = lineDecoration . startOffset ;
729- result [ resultLen ++ ] = new LinePart ( lastResultEndIndex , tokenType ) ;
748+ result [ resultLen ++ ] = new LinePart ( lastResultEndIndex , tokenType , tokenMetadata ) ;
730749 }
731750
732751 if ( lineDecoration . endOffset + 1 <= tokenEndIndex ) {
733752 // This line decoration ends before this token ends
734753 lastResultEndIndex = lineDecoration . endOffset + 1 ;
735- result [ resultLen ++ ] = new LinePart ( lastResultEndIndex , tokenType + ' ' + lineDecoration . className ) ;
754+ result [ resultLen ++ ] = new LinePart ( lastResultEndIndex , tokenType + ' ' + lineDecoration . className , tokenMetadata | lineDecoration . metadata ) ;
736755 lineDecorationIndex ++ ;
737756 } else {
738757 // This line decoration continues on to the next token
739758 lastResultEndIndex = tokenEndIndex ;
740- result [ resultLen ++ ] = new LinePart ( lastResultEndIndex , tokenType + ' ' + lineDecoration . className ) ;
759+ result [ resultLen ++ ] = new LinePart ( lastResultEndIndex , tokenType + ' ' + lineDecoration . className , tokenMetadata | lineDecoration . metadata ) ;
741760 break ;
742761 }
743762 }
744763
745764 if ( tokenEndIndex > lastResultEndIndex ) {
746765 lastResultEndIndex = tokenEndIndex ;
747- result [ resultLen ++ ] = new LinePart ( lastResultEndIndex , tokenType ) ;
766+ result [ resultLen ++ ] = new LinePart ( lastResultEndIndex , tokenType , tokenMetadata ) ;
748767 }
749768 }
750769
751770 const lastTokenEndIndex = tokens [ tokens . length - 1 ] . endIndex ;
752771 if ( lineDecorationIndex < lineDecorationsLen && lineDecorations [ lineDecorationIndex ] . startOffset === lastTokenEndIndex ) {
753772 let classNames : string [ ] = [ ] ;
773+ let metadata = 0 ;
754774 while ( lineDecorationIndex < lineDecorationsLen && lineDecorations [ lineDecorationIndex ] . startOffset === lastTokenEndIndex ) {
755775 classNames . push ( lineDecorations [ lineDecorationIndex ] . className ) ;
776+ metadata |= lineDecorations [ lineDecorationIndex ] . metadata ;
756777 lineDecorationIndex ++ ;
757778 }
758- result [ resultLen ++ ] = new LinePart ( lastResultEndIndex , classNames . join ( ' ' ) ) ;
779+ result [ resultLen ++ ] = new LinePart ( lastResultEndIndex , classNames . join ( ' ' ) , metadata ) ;
759780 }
760781
761782 return result ;
@@ -799,7 +820,7 @@ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): Render
799820 const part = parts [ partIndex ] ;
800821 const partEndIndex = part . endIndex ;
801822 const partType = part . type ;
802- const partRendersWhitespace = ( renderWhitespace !== RenderWhitespace . None && ( partType . indexOf ( 'mtkw' ) >= 0 ) ) ;
823+ const partRendersWhitespace = ( renderWhitespace !== RenderWhitespace . None && part . isWhitespace ( ) ) ;
803824 const partRendersWhitespaceWithWidth = partRendersWhitespace && ! fontIsMonospace && ( partType === 'mtkw' /*only whitespace*/ || ! containsForeignElements ) ;
804825 charOffsetInPart = 0 ;
805826
0 commit comments