@@ -2,6 +2,7 @@ import vscode from "vscode";
2
2
class EditDecorationManager {
3
3
private _lastEditor : vscode . TextEditor | undefined ;
4
4
private decorationType : vscode . TextEditorDecorationType ;
5
+ private activeRangesMap : Map < string , vscode . Range > = new Map ( ) ; // Store unique active ranges
5
6
6
7
constructor ( context : vscode . ExtensionContext ) {
7
8
this . decorationType = vscode . window . createTextEditorDecorationType ( {
@@ -23,18 +24,55 @@ class EditDecorationManager {
23
24
) ;
24
25
}
25
26
26
- setDecoration ( editor : vscode . TextEditor , range : vscode . Range ) {
27
- if ( this . _lastEditor ) {
28
- this . _lastEditor . setDecorations ( this . decorationType , [ ] ) ;
27
+ // Converts each range to a unique string for storing in the map
28
+ private rangeToString ( range : vscode . Range ) : string {
29
+ return `(${ range . start . line } ,${ range . start . character } )-(${ range . end . line } ,${ range . end . character } )` ;
30
+ }
31
+
32
+ // Checks if two ranges are adjacent or overlapping
33
+ private rangesCoincide ( range1 : vscode . Range , range2 : vscode . Range ) : boolean {
34
+ return range1 . start . isEqual ( range2 . start )
35
+ || range1 . end . isEqual ( range2 . start )
36
+ || range2 . end . isEqual ( range1 . start )
37
+ || ! ! range1 . intersection ( range2 ) ;
38
+ }
39
+
40
+ // Merges new range with existing ranges in the map
41
+ private mergeNewRange ( newRange : vscode . Range ) : void {
42
+ let mergedRange = newRange ;
43
+ const rangesToPrune : string [ ] = [ ] ;
44
+
45
+ for ( const [ key , existingRange ] of this . activeRangesMap . entries ( ) ) {
46
+ if ( ! this . rangesCoincide ( mergedRange , existingRange ) ) continue ;
47
+ mergedRange = mergedRange . union ( existingRange ) ;
48
+ rangesToPrune . push ( key ) ;
49
+ }
50
+
51
+ for ( const key of rangesToPrune ) this . activeRangesMap . delete ( key ) ;
52
+ this . activeRangesMap . set ( this . rangeToString ( mergedRange ) , mergedRange ) ;
53
+ }
54
+
55
+ // Adds a new decoration to the editor and merges it with existing ranges
56
+ addDecorations ( editor : vscode . TextEditor , ranges : vscode . Range [ ] ) : void {
57
+ if ( this . _lastEditor ?. document !== editor . document ) {
58
+ this . clear ( ) ; // Clear previous decorations if editor has changed
29
59
}
30
- editor . setDecorations ( this . decorationType , [ range ] ) ;
31
60
this . _lastEditor = editor ;
61
+
62
+ for ( const range of ranges ) this . mergeNewRange ( range ) ;
63
+
64
+ const activeRanges = Array . from ( this . activeRangesMap . values ( ) ) ;
65
+ if ( activeRanges . length === 0 ) return ; // No ranges to highlight
66
+
67
+ // Update active ranges and apply decorations
68
+ editor . setDecorations ( this . decorationType , activeRanges ) ;
32
69
this . updateInEditMode ( true ) ;
33
70
}
34
71
35
72
clear ( ) {
36
73
if ( this . _lastEditor ) {
37
74
this . _lastEditor . setDecorations ( this . decorationType , [ ] ) ;
75
+ this . activeRangesMap . clear ( ) ;
38
76
this . _lastEditor = undefined ;
39
77
this . updateInEditMode ( false ) ;
40
78
}
0 commit comments