1
1
import * as vscode from "vscode" ;
2
2
import { genMarkdownString , getColorTokenValue } from "./utils" ;
3
3
4
- interface DecorationItem {
4
+ interface LineDecorationItem {
5
5
line : number ;
6
6
disposable : vscode . TextEditorDecorationType ;
7
7
}
@@ -12,18 +12,15 @@ export default function setupChangeEvent(
12
12
) {
13
13
let timeout : NodeJS . Timer | undefined = undefined ;
14
14
let activeEditor = vscode . window . activeTextEditor ;
15
- const fullTokenKeys = Object . keys ( fullToken ) ;
16
- const fileDecorationMap = new Map < string , DecorationItem [ ] > ( ) ;
17
- const openedFileNameSet = new Set < string > ( ) ;
18
- let lineCount = 0 ;
15
+ const fileDecorationMap = new Map <
16
+ string ,
17
+ Map < number , vscode . TextEditorDecorationType [ ] >
18
+ > ( ) ;
19
+ let fileLineCount = 0 ;
19
20
20
21
if ( activeEditor ) {
21
- lineCount = activeEditor . document . lineCount ;
22
- const isOpened = checkOpenedFile ( activeEditor . document . fileName ) ;
23
-
24
- if ( ! isOpened ) {
25
- triggerUpdateDecorations ( ) ;
26
- }
22
+ fileLineCount = activeEditor . document . lineCount ;
23
+ triggerUpdateDecorations ( ) ;
27
24
}
28
25
29
26
vscode . workspace . onDidChangeTextDocument (
@@ -33,7 +30,7 @@ export default function setupChangeEvent(
33
30
}
34
31
35
32
const startLine = event . contentChanges [ 0 ] . range . start . line ;
36
- let endLine = event . contentChanges [ 0 ] . range . end . line ;
33
+ const endLine = event . contentChanges [ 0 ] . range . end . line ;
37
34
38
35
if ( activeEditor && event . document === activeEditor . document ) {
39
36
/**
@@ -43,7 +40,7 @@ export default function setupChangeEvent(
43
40
const throttle =
44
41
event . reason !== undefined
45
42
? false
46
- : event . document . lineCount - lineCount >= 0 ;
43
+ : event . document . lineCount - fileLineCount >= 0 ;
47
44
triggerUpdateDecorations ( throttle , true , startLine , endLine ) ;
48
45
}
49
46
} ,
@@ -53,14 +50,18 @@ export default function setupChangeEvent(
53
50
54
51
vscode . window . onDidChangeActiveTextEditor (
55
52
( editor ) => {
53
+ console . log ( "Active Editor!" , editor ?. document . fileName ) ;
56
54
activeEditor = editor ;
57
55
if ( editor ) {
58
- lineCount = editor . document . lineCount ;
59
- const isOpened = checkOpenedFile ( editor . document . fileName ) ;
56
+ const fileName = editor . document . fileName ;
57
+ fileLineCount = editor . document . lineCount ;
60
58
61
- if ( ! isOpened ) {
62
- triggerUpdateDecorations ( ) ;
59
+ if ( fileDecorationMap . has ( fileName ) ) {
60
+ clearDecoration ( fileName ) ;
61
+ fileDecorationMap . set ( fileName , new Map ( ) ) ;
63
62
}
63
+
64
+ triggerUpdateDecorations ( ) ;
64
65
}
65
66
} ,
66
67
null ,
@@ -79,132 +80,137 @@ export default function setupChangeEvent(
79
80
}
80
81
if ( throttle ) {
81
82
timeout = setTimeout ( ( ) => {
82
- updateDecorations ( isEdit , startLine , endLine ) ;
83
+ updateDecorations ( startLine , endLine ) ;
83
84
} , 500 ) ;
84
85
} else {
85
- updateDecorations ( isEdit , startLine , endLine ) ;
86
+ updateDecorations ( startLine , endLine ) ;
86
87
}
87
88
}
88
89
89
- function updateDecorations (
90
- isEdit : boolean ,
91
- startLine ?: number ,
92
- endLine ?: number
93
- ) {
90
+ function updateDecorations ( startLine ?: number , endLine ?: number ) {
94
91
if ( activeEditor ) {
95
- console . log ( "!!!!!!update!!!!" , startLine , endLine ) ;
96
- const text = activeEditor . document . getText ( ) ;
97
- const fileName = activeEditor . document . fileName ;
98
-
99
- if ( ! fileDecorationMap . has ( fileName ) ) {
100
- fileDecorationMap . set ( fileName , [ ] ) ;
101
- }
92
+ if ( startLine && endLine ) {
93
+ console . log ( "editing" , startLine , endLine ) ;
94
+ const currentLineCount = activeEditor . document . lineCount ;
95
+ const diffLine = currentLineCount - fileLineCount ;
96
+ const fileName = activeEditor . document . fileName ;
97
+ console . log ( "diffLine" , diffLine ) ;
98
+
99
+ if ( diffLine < 0 ) {
100
+ const lines = getLines ( startLine , endLine ) ;
101
+ return clearDecoration ( fileName , lines ) ;
102
+ }
102
103
103
- const currentFileDecorations = fileDecorationMap . get ( fileName ) || [ ] ;
104
- const currentLineCount = activeEditor . document . lineCount ;
105
- const diffLine = currentLineCount - lineCount ;
106
- console . log ( "diffLine" , diffLine ) ;
107
- lineCount = currentLineCount ;
108
-
109
- /**
110
- * Dispose the line decoration between start and end
111
- */
112
- if (
113
- startLine &&
114
- endLine &&
115
- currentFileDecorations . length &&
116
- diffLine <= 0
117
- ) {
118
- for ( let i = startLine ; i <= endLine ; i ++ ) {
119
- for ( let j = 0 ; j < currentFileDecorations . length ; j ++ ) {
120
- if ( currentFileDecorations [ j ] . line === i ) {
121
- currentFileDecorations [ j ] . disposable . dispose ( ) ;
122
- console . log ( "dispose" , i ) ;
123
- currentFileDecorations . splice ( j -- , 1 ) ;
124
- }
125
- }
104
+ if ( diffLine === 0 ) {
105
+ clearDecoration ( fileName , [ startLine ] ) ;
126
106
}
127
107
}
128
108
129
- // if (diffLine > 0) {
130
- // return;
131
- // }
109
+ setupDecoration ( startLine , endLine ) ;
110
+ }
111
+ }
132
112
133
- fullTokenKeys . forEach ( ( key : string ) => {
134
- if ( ! activeEditor ) {
135
- return ;
136
- }
113
+ function setupDecoration ( startLine ?: number , endLine ?: number ) {
114
+ console . log ( "!!!!!!updating!!!!!" , startLine , endLine ) ;
115
+ const fileName = activeEditor ! . document . fileName ;
116
+ const text = activeEditor ! . document . getText ( ) ;
117
+ const fullTokenKeys = Object . keys ( fullToken ) ;
118
+ const lineDecorationMap = new Map <
119
+ number ,
120
+ vscode . TextEditorDecorationType [ ]
121
+ > ( ) ;
122
+
123
+ if ( ! fileDecorationMap . has ( fileName ) ) {
124
+ fileDecorationMap . set ( fileName , new Map ( ) ) ;
125
+ }
137
126
138
- const regEx = new RegExp ( `\\b(${ key } )\\b(?!-)` , "g" ) ;
139
-
140
- let match ;
141
- while ( ( match = regEx . exec ( text ) ) ) {
142
- const valueDecorations : vscode . DecorationOptions [ ] = [ ] ;
143
- let decorationType : vscode . TextEditorDecorationType ;
144
-
145
- /**
146
- * TIPS:
147
- * Actually, they are always at the same line.
148
- */
149
- const startPos = activeEditor . document . positionAt ( match . index ) ;
150
- const endPos = activeEditor . document . positionAt (
151
- match . index + match [ 0 ] . length
152
- ) ;
153
- const currentLine = startPos . line ;
154
-
155
- if (
156
- ! isEdit ||
157
- // diffLine > 0 ||
158
- ( startLine &&
159
- endLine &&
160
- currentLine >= startLine &&
161
- currentLine <= endLine )
162
- ) {
163
- const value = String ( fullToken [ key ] ) ;
164
- const colorSpan = genMarkdownString ( value ) ;
165
- const markDownString = new vscode . MarkdownString (
166
- `<h3>antd design token: ${ match [ 0 ] } </h3>${ colorSpan } <code>${ value } </code><br></br>`
167
- ) ;
168
- markDownString . supportHtml = true ;
169
- markDownString . isTrusted = true ;
170
-
171
- const decoration = {
172
- range : new vscode . Range ( startPos , endPos ) ,
173
- hoverMessage : markDownString ,
174
- } ;
175
-
176
- const colorValue = getColorTokenValue ( fullToken [ key ] ) ;
177
- valueDecorations . push ( decoration ) ;
178
-
179
- decorationType = vscode . window . createTextEditorDecorationType ( {
180
- after : {
181
- contentText : colorValue ? `**` : `(${ String ( fullToken [ key ] ) } )` ,
182
- backgroundColor : colorValue || "" ,
183
- margin : "0 0 0 4px;" ,
184
- color : colorValue || "#1890ff" ,
185
- fontWeight : "bolder" ,
186
- } ,
187
- } ) ;
188
-
189
- currentFileDecorations . push ( {
190
- line : currentLine ,
191
- disposable : decorationType ,
192
- } ) ;
193
- console . log ( "setDecorations" , currentLine ) ;
194
- activeEditor . setDecorations ( decorationType , valueDecorations ) ;
195
- }
196
- }
197
- } ) ;
198
- fileDecorationMap . set ( fileName , currentFileDecorations ) ;
127
+ fullTokenKeys . forEach ( ( key : string ) => {
128
+ const regEx = new RegExp ( `\\b(${ key } )\\b(?!-)` , "g" ) ;
129
+ let match ;
130
+
131
+ while ( ( match = regEx . exec ( text ) ) ) {
132
+ const valueDecorations : vscode . DecorationOptions [ ] = [ ] ;
133
+ let decorationType : vscode . TextEditorDecorationType ;
134
+
135
+ /**
136
+ * TIPS:
137
+ * Actually, they are always at the same line.
138
+ */
139
+ const startPos = activeEditor ! . document . positionAt ( match . index ) ;
140
+ const endPos = activeEditor ! . document . positionAt (
141
+ match . index + match [ 0 ] . length
142
+ ) ;
143
+ const currentLine = startPos . line ;
144
+ const value = String ( fullToken [ key ] ) ;
145
+ const colorSpan = genMarkdownString ( value ) ;
146
+ const markDownString = new vscode . MarkdownString (
147
+ `<h3>antd design token: ${ match [ 0 ] } </h3>${ colorSpan } <code>${ value } </code><br></br>`
148
+ ) ;
149
+ markDownString . supportHtml = true ;
150
+ markDownString . isTrusted = true ;
151
+
152
+ const decoration = {
153
+ range : new vscode . Range ( startPos , endPos ) ,
154
+ hoverMessage : markDownString ,
155
+ } ;
156
+
157
+ const colorValue = getColorTokenValue ( fullToken [ key ] ) ;
158
+ valueDecorations . push ( decoration ) ;
159
+
160
+ decorationType = vscode . window . createTextEditorDecorationType ( {
161
+ after : {
162
+ contentText : colorValue ? `**` : `${ String ( fullToken [ key ] ) } ` ,
163
+ backgroundColor : colorValue || "" ,
164
+ margin : "0 0 0 5px;" ,
165
+ color : colorValue || "#b37feb" ,
166
+ fontWeight : "bolder" ,
167
+ } ,
168
+ } ) ;
169
+
170
+ const lineValue = lineDecorationMap . get ( currentLine ) ;
171
+ lineDecorationMap . set (
172
+ currentLine ,
173
+ lineValue ? lineValue . concat ( [ decorationType ] ) : [ decorationType ]
174
+ ) ;
175
+ console . log ( "setDecorations" , currentLine ) ;
176
+ activeEditor ! . setDecorations ( decorationType , valueDecorations ) ;
177
+ }
178
+ } ) ;
179
+
180
+ fileDecorationMap . set ( fileName , lineDecorationMap ) ;
181
+ console . log ( fileDecorationMap ) ;
182
+ }
183
+
184
+ function clearDecoration ( fileName : string , lines ?: number [ ] ) {
185
+ const lineDecorationMap = fileDecorationMap . get ( fileName ) ;
186
+ if ( lineDecorationMap ) {
187
+ if ( lines ) {
188
+ lines . forEach ( ( line ) => {
189
+ console . log ( "dispose line" , line ) ;
190
+ lineDecorationMap . get ( line ) ?. forEach ( dispose ) ;
191
+ } ) ;
192
+ } else {
193
+ lineDecorationMap . forEach ( ( value ) => {
194
+ value . forEach ( dispose ) ;
195
+ } ) ;
196
+ }
199
197
}
200
198
}
201
199
202
- function checkOpenedFile ( fileName : string ) : boolean {
203
- if ( openedFileNameSet . has ( fileName ) ) {
204
- return true ;
205
- } else {
206
- openedFileNameSet . add ( fileName ) ;
207
- return false ;
200
+ function dispose ( disposable : vscode . TextEditorDecorationType ) {
201
+ disposable . dispose ( ) ;
202
+ }
203
+
204
+ function getLines ( start : number , end : number ) : number [ ] {
205
+ const result : number [ ] = [ ] ;
206
+
207
+ if ( start > end ) {
208
+ return [ ] ;
209
+ }
210
+
211
+ for ( let i = start ; i <= end ; i ++ ) {
212
+ result . push ( i ) ;
208
213
}
214
+ return result ;
209
215
}
210
216
}
0 commit comments