@@ -45,10 +45,10 @@ interface EndOffsetToken {
45
45
interface EndOffsetAndScopes {
46
46
endOffset : number ;
47
47
scopes : string [ ] ;
48
- bracket ?: boolean ;
48
+ bracket ?: number [ ] ;
49
49
}
50
50
51
- const BRACKETS = / [ \{ \} \[ \] \< \> \( \) ] / ;
51
+ const BRACKETS = / [ \{ \} \[ \] \< \> \( \) ] / g ;
52
52
53
53
export class TreeSitterTokenizationFeature extends Disposable implements ITreeSitterTokenizationFeature {
54
54
public _serviceBrand : undefined ;
@@ -558,56 +558,76 @@ export class TreeSitterTokenizationSupport extends Disposable implements ITreeSi
558
558
continue ;
559
559
}
560
560
561
- const hasBracket = ( ) => {
562
- return ! ! capture . text ?. match ( BRACKETS ) && capture . name . includes ( 'punctuation' ) ;
561
+ const brackets = ( ) : number [ ] | undefined => {
562
+ return ( capture . name . includes ( 'punctuation' ) && capture . text ) ? Array . from ( capture . text . matchAll ( BRACKETS ) ) . map ( match => startOffset + match . index ) : undefined ;
563
563
} ;
564
564
565
- const addCurrentTokenToArray = ( ) => {
566
- endOffsetsAndScopes [ tokenIndex ] = { endOffset : endOffset , scopes : [ capture . name ] , bracket : hasBracket ( ) } ;
565
+ const addCurrentTokenToArray = ( position ?: number ) => {
566
+ if ( position !== undefined ) {
567
+ let oldBracket = endOffsetsAndScopes [ position ] . bracket ;
568
+ // Check that the previous token ends at the same point that the current token starts
569
+ const prevEndOffset = position > 0 ? endOffsetsAndScopes [ position - 1 ] . endOffset : 0 ;
570
+ if ( prevEndOffset !== startOffset ) {
571
+ let preInsertBracket : number [ ] | undefined = undefined ;
572
+ if ( oldBracket && oldBracket . length > 0 ) {
573
+ preInsertBracket = [ ] ;
574
+ const postInsertBracket : number [ ] = [ ] ;
575
+ for ( let i = 0 ; i < oldBracket . length ; i ++ ) {
576
+ const bracket = oldBracket [ i ] ;
577
+ if ( bracket < startOffset ) {
578
+ preInsertBracket . push ( bracket ) ;
579
+ } else if ( bracket > endOffset ) {
580
+ postInsertBracket . push ( bracket ) ;
581
+ }
582
+ }
583
+ if ( preInsertBracket . length === 0 ) {
584
+ preInsertBracket = undefined ;
585
+ }
586
+ if ( postInsertBracket . length === 0 ) {
587
+ oldBracket = undefined ;
588
+ } else {
589
+ oldBracket = postInsertBracket ;
590
+ }
591
+ }
592
+ // We need to add some of the position token to cover the space
593
+ endOffsetsAndScopes . splice ( position , 0 , { endOffset : startOffset , scopes : [ ...endOffsetsAndScopes [ position ] . scopes ] , bracket : preInsertBracket } ) ;
594
+ position ++ ;
595
+ increaseSizeOfTokensByOneToken ( ) ;
596
+ tokenIndex ++ ;
597
+ }
598
+
599
+ endOffsetsAndScopes . splice ( position , 0 , { endOffset : endOffset , scopes : [ capture . name ] , bracket : brackets ( ) } ) ;
600
+ endOffsetsAndScopes [ tokenIndex ] . bracket = oldBracket ;
601
+ } else {
602
+ endOffsetsAndScopes [ tokenIndex ] = { endOffset : endOffset , scopes : [ capture . name ] , bracket : brackets ( ) } ;
603
+ }
567
604
tokenIndex ++ ;
568
605
} ;
569
606
570
607
if ( previousEndOffset >= endOffset ) {
571
608
// walk back through the tokens until we find the one that contains the current token
572
609
let withinTokenIndex = tokenIndex - 1 ;
573
- let originalPreviousTokenEndOffset ;
610
+ let previousTokenEndOffset = endOffsetsAndScopes [ withinTokenIndex ] . endOffset ;
574
611
575
- let previousTokenStartOffset ;
576
- let previousPreviousTokenEndOffset ;
612
+ let previousTokenStartOffset = ( ( withinTokenIndex >= 2 ) ? endOffsetsAndScopes [ withinTokenIndex - 1 ] . endOffset : 0 ) ;
577
613
do {
578
- originalPreviousTokenEndOffset = endOffsetsAndScopes [ withinTokenIndex ] . endOffset ;
579
- previousTokenStartOffset = ( ( withinTokenIndex >= 2 ) ? endOffsetsAndScopes [ withinTokenIndex - 1 ] . endOffset : 0 ) ;
580
- previousPreviousTokenEndOffset = ( withinTokenIndex >= 2 ) ? endOffsetsAndScopes [ withinTokenIndex - 1 ] . endOffset : 0 ;
581
614
582
615
// Check that the current token doesn't just replace the last token
583
- if ( ( previousTokenStartOffset + currentTokenLength ) === originalPreviousTokenEndOffset ) {
616
+ if ( ( previousTokenStartOffset + currentTokenLength ) === previousTokenEndOffset ) {
584
617
if ( previousTokenStartOffset === startOffset ) {
585
618
// Current token and previous token span the exact same characters, replace the last scope
586
619
endOffsetsAndScopes [ withinTokenIndex ] . scopes [ endOffsetsAndScopes [ withinTokenIndex ] . scopes . length - 1 ] = capture . name ;
620
+ endOffsetsAndScopes [ withinTokenIndex ] . bracket = brackets ( ) ;
587
621
}
588
- } else if ( previousPreviousTokenEndOffset <= startOffset ) {
589
- let originalPreviousTokenScopes ;
622
+ } else if ( previousTokenStartOffset <= startOffset ) {
590
623
// The current token is within the previous token. Adjust the end of the previous token
591
- if ( previousPreviousTokenEndOffset !== startOffset ) {
592
- endOffsetsAndScopes [ withinTokenIndex ] = { endOffset : startOffset , scopes : endOffsetsAndScopes [ withinTokenIndex ] . scopes , bracket : hasBracket ( ) } ;
593
- addCurrentTokenToArray ( ) ;
594
- originalPreviousTokenScopes = [ ...endOffsetsAndScopes [ withinTokenIndex ] . scopes ] ;
595
- } else {
596
- originalPreviousTokenScopes = [ ...endOffsetsAndScopes [ withinTokenIndex ] . scopes ] ;
597
- endOffsetsAndScopes [ withinTokenIndex ] = { endOffset : endOffset , scopes : [ capture . name ] , bracket : hasBracket ( ) } ;
598
- }
599
-
600
- // Add the rest of the previous token after the current token
601
- if ( originalPreviousTokenEndOffset !== endOffset ) {
602
- increaseSizeOfTokensByOneToken ( ) ;
603
- endOffsetsAndScopes [ tokenIndex ] = { endOffset : originalPreviousTokenEndOffset , scopes : originalPreviousTokenScopes , bracket : endOffsetsAndScopes [ withinTokenIndex ] . bracket } ;
604
- tokenIndex ++ ;
605
- } else {
606
- endOffsetsAndScopes [ withinTokenIndex ] . scopes . unshift ( ...originalPreviousTokenScopes ) ;
607
- }
624
+ addCurrentTokenToArray ( withinTokenIndex ) ;
625
+ break ;
608
626
}
609
627
withinTokenIndex -- ;
610
- } while ( previousTokenStartOffset > startOffset ) ;
628
+ previousTokenStartOffset = ( ( withinTokenIndex >= 2 ) ? endOffsetsAndScopes [ withinTokenIndex - 1 ] . endOffset : 0 ) ;
629
+ previousTokenEndOffset = endOffsetsAndScopes [ withinTokenIndex ] . endOffset ;
630
+ } while ( previousTokenEndOffset > startOffset ) ;
611
631
} else {
612
632
// Just add the token to the array
613
633
addCurrentTokenToArray ( ) ;
@@ -640,10 +660,10 @@ export class TreeSitterTokenizationSupport extends Disposable implements ITreeSi
640
660
if ( ! emptyTokens ) {
641
661
return undefined ;
642
662
}
643
- const endOffsetsAndScopes : { endOffset : number ; scopes : string [ ] ; metadata ?: number ; bracket ?: boolean } [ ] = emptyTokens . endOffsets ;
663
+ const endOffsetsAndScopes : { endOffset : number ; scopes : string [ ] ; metadata ?: number ; bracket ?: number [ ] } [ ] = emptyTokens . endOffsets ;
644
664
for ( let i = 0 ; i < endOffsetsAndScopes . length ; i ++ ) {
645
665
const token = endOffsetsAndScopes [ i ] ;
646
- token . metadata = findMetadata ( this . _colorThemeData , token . scopes , encodedLanguageId , ! ! token . bracket ) ;
666
+ token . metadata = findMetadata ( this . _colorThemeData , token . scopes , encodedLanguageId , ! ! token . bracket && ( token . bracket . length > 0 ) ) ;
647
667
}
648
668
649
669
const metadataTime = stopwatch . elapsed ( ) ;
0 commit comments