-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathfind-colors.ts
115 lines (105 loc) · 2.94 KB
/
find-colors.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { getNodeAtOffset } from "@somesass/vscode-css-languageservice";
import ColorDotJS from "colorjs.io";
import { LanguageFeature } from "../language-feature";
import {
Color,
ColorInformation,
ColorPresentation,
NodeType,
Range,
TextDocument,
Variable,
} from "../language-services-types";
export class FindColors extends LanguageFeature {
async findColors(document: TextDocument): Promise<ColorInformation[]> {
const config = this.languageConfiguration(document);
const variables: Variable[] = [];
const stylesheet = this.ls.parseStylesheet(document);
stylesheet.accept((node) => {
if (node.type !== NodeType.VariableName) {
return true;
}
const parent = node.getParent();
if (
parent &&
parent.type !== NodeType.VariableDeclaration &&
parent.type !== NodeType.FunctionParameter
) {
variables.push(node as Variable);
}
return true;
});
if (variables.length > this.configuration.editor.colorDecoratorsLimit) {
// skip color decorators for large documents, it freezes up other features
return [];
}
const result: (ColorInformation | null)[] = await Promise.all(
variables.map(async (variable) => {
const value = await this.findValue(
document,
document.positionAt(variable.offset),
);
if (value) {
try {
const color = ColorDotJS.parse(value);
const srgba = ColorDotJS.to(color, "srgb");
const colorInformation: ColorInformation = {
color: {
alpha: srgba.alpha || 1,
red: srgba.coords[0],
green: srgba.coords[1],
blue: srgba.coords[2],
},
range: {
start: document.positionAt(variable.offset),
end: document.positionAt(
variable.offset + (variable as Variable).getName().length,
),
},
};
return colorInformation;
} catch {
// do nothing
}
}
return null;
}),
);
if (config.colors.includeFromCurrentDocument) {
const upstream = this.getUpstreamLanguageServer(
document,
).findDocumentColors(document, stylesheet);
result.push(...upstream);
}
return result.filter((c) => c !== null);
}
getColorPresentations(
document: TextDocument,
color: Color,
range: Range,
): ColorPresentation[] {
const stylesheet = this.ls.parseStylesheet(document);
const node = getNodeAtOffset(stylesheet, document.offsetAt(range.start));
// Only suggest alternate presentations for the declaration
// so we don't suggest replacing ex. color: $variable; with color: #ffffff;
if (node && node.type === NodeType.VariableName) {
const parent = node.getParent();
if (parent && parent.type === NodeType.VariableDeclaration) {
return this.getUpstreamLanguageServer(document).getColorPresentations(
document,
stylesheet,
color,
range,
);
} else {
return [];
}
}
return this.getUpstreamLanguageServer(document).getColorPresentations(
document,
stylesheet,
color,
range,
);
}
}