1
- import type * as CSS from 'vscode-css-languageservice'
1
+ import * as CSS from 'vscode-css-languageservice'
2
2
import type { TextDocument } from 'vscode-languageserver-textdocument'
3
3
import {
4
- type Color ,
5
4
type LanguageServicePlugin ,
6
- TextEdit ,
7
5
type VirtualCode ,
8
6
} from '@volar/language-service'
9
7
import { type Provide , create as baseCreate } from 'volar-service-css'
@@ -13,13 +11,23 @@ import { MpxVirtualCode } from '@mpxjs/language-core'
13
11
function parseStylusColors ( document : TextDocument ) : CSS . ColorInformation [ ] {
14
12
const colors : CSS . ColorInformation [ ] = [ ]
15
13
const text = document . getText ( )
16
-
17
- const regex = / # ( [ 0 - 9 a - f A - F ] { 3 } | [ 0 - 9 a - f A - F ] { 6 } ) \b / g
14
+ const regex = / (?: ^ | [ \s : , ( ] ) # ( [ 0 - 9 a - f A - F ] { 3 } | [ 0 - 9 a - f A - F ] { 6 } ) (? ! [ \w - ] ) / g
18
15
let match : RegExpExecArray | null
16
+
19
17
while ( ( match = regex . exec ( text ) ) ) {
20
- const start = document . positionAt ( match . index )
21
- const end = document . positionAt ( match . index + match [ 0 ] . length )
22
18
const hex = match [ 1 ]
19
+
20
+ // 精确 range:找到 #hex 的起始位置
21
+ const colorStartIndex = match . index + match [ 0 ] . lastIndexOf ( hex )
22
+ const start = document . positionAt ( colorStartIndex - 1 ) // 包含 #
23
+ const end = document . positionAt ( colorStartIndex - 1 + hex . length + 1 )
24
+
25
+ // 获取当前行,排除 ID 选择器
26
+ const lineStart = text . lastIndexOf ( '\n' , match . index ) + 1
27
+ const line = text . slice ( lineStart , text . indexOf ( '\n' , match . index ) )
28
+ if ( / ^ \s * # \w / . test ( line ) ) continue
29
+
30
+ // 转换颜色
23
31
let r = 0 ,
24
32
g = 0 ,
25
33
b = 0
@@ -32,13 +40,11 @@ function parseStylusColors(document: TextDocument): CSS.ColorInformation[] {
32
40
g = parseInt ( hex . slice ( 2 , 4 ) , 16 )
33
41
b = parseInt ( hex . slice ( 4 , 6 ) , 16 )
34
42
}
35
- const color : Color = {
36
- red : r / 255 ,
37
- green : g / 255 ,
38
- blue : b / 255 ,
39
- alpha : 1 ,
40
- }
41
- colors . push ( { range : { start, end } , color } )
43
+
44
+ colors . push ( {
45
+ range : { start, end } ,
46
+ color : { red : r / 255 , green : g / 255 , blue : b / 255 , alpha : 1 } ,
47
+ } )
42
48
}
43
49
44
50
return colors
@@ -53,10 +59,9 @@ function parseStylusColorPresentation(
53
59
const g = Math . round ( color . green * 255 )
54
60
const b = Math . round ( color . blue * 255 )
55
61
const hex = `#${ r . toString ( 16 ) . padStart ( 2 , '0' ) } ${ g . toString ( 16 ) . padStart ( 2 , '0' ) } ${ b . toString ( 16 ) . padStart ( 2 , '0' ) } `
56
-
57
62
colors . push ( {
58
63
label : hex ,
59
- textEdit : TextEdit . replace ( range , hex ) ,
64
+ textEdit : CSS . TextEdit . replace ( range , hex ) ,
60
65
} )
61
66
return colors
62
67
}
0 commit comments