css-variable-lsp 1.0.16 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +1 -1
  2. package/docs/SCSS_SASS_SUPPORT_RESEARCH.md +96 -0
  3. package/out/completionContext.js +244 -0
  4. package/out/completionContext.js.map +1 -0
  5. package/out/cssVariableManager.js +5 -5
  6. package/out/cssVariableManager.js.map +1 -1
  7. package/out/handlers/callHierarchy.js +128 -0
  8. package/out/handlers/callHierarchy.js.map +1 -0
  9. package/out/handlers/codeAction.js +142 -0
  10. package/out/handlers/codeAction.js.map +1 -0
  11. package/out/handlers/codeLens.js +41 -0
  12. package/out/handlers/codeLens.js.map +1 -0
  13. package/out/handlers/declaration.js +34 -0
  14. package/out/handlers/declaration.js.map +1 -0
  15. package/out/handlers/documentHighlight.js +45 -0
  16. package/out/handlers/documentHighlight.js.map +1 -0
  17. package/out/handlers/documentLink.js +61 -0
  18. package/out/handlers/documentLink.js.map +1 -0
  19. package/out/handlers/documentSync.js +15 -0
  20. package/out/handlers/documentSync.js.map +1 -0
  21. package/out/handlers/foldingRange.js +77 -0
  22. package/out/handlers/foldingRange.js.map +1 -0
  23. package/out/handlers/formatting.js +99 -0
  24. package/out/handlers/formatting.js.map +1 -0
  25. package/out/handlers/implementation.js +35 -0
  26. package/out/handlers/implementation.js.map +1 -0
  27. package/out/handlers/inlayHint.js +46 -0
  28. package/out/handlers/inlayHint.js.map +1 -0
  29. package/out/handlers/linkedEditingRange.js +45 -0
  30. package/out/handlers/linkedEditingRange.js.map +1 -0
  31. package/out/handlers/prepareRename.js +44 -0
  32. package/out/handlers/prepareRename.js.map +1 -0
  33. package/out/handlers/selectionRange.js +100 -0
  34. package/out/handlers/selectionRange.js.map +1 -0
  35. package/out/handlers/semanticTokens.js +57 -0
  36. package/out/handlers/semanticTokens.js.map +1 -0
  37. package/out/handlers/signatureHelp.js +54 -0
  38. package/out/handlers/signatureHelp.js.map +1 -0
  39. package/out/handlers/typeDefinition.js +35 -0
  40. package/out/handlers/typeDefinition.js.map +1 -0
  41. package/out/hierarchy/callHierarchy.js +119 -0
  42. package/out/hierarchy/callHierarchy.js.map +1 -0
  43. package/out/hierarchy/shared/hierarchyTypes.js +45 -0
  44. package/out/hierarchy/shared/hierarchyTypes.js.map +1 -0
  45. package/out/hierarchy/shared/variableAnalyzer.js +43 -0
  46. package/out/hierarchy/shared/variableAnalyzer.js.map +1 -0
  47. package/out/server.js +5 -130
  48. package/out/server.js.map +1 -1
  49. package/package.json +1 -1
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleCodeActions = handleCodeActions;
4
+ const node_1 = require("vscode-languageserver/node");
5
+ /**
6
+ * Handle code action requests for CSS documents.
7
+ * Provides quick fixes for undefined CSS variables.
8
+ */
9
+ function handleCodeActions(params, documents, cssVariableManager) {
10
+ const document = documents.get(params.textDocument.uri);
11
+ if (!document) {
12
+ return null;
13
+ }
14
+ const codeActions = [];
15
+ // Process diagnostics for undefined variables
16
+ for (const diagnostic of params.context.diagnostics) {
17
+ if (diagnostic.source !== "css-variable-lsp") {
18
+ continue;
19
+ }
20
+ // Extract variable name from the diagnostic message
21
+ const match = diagnostic.message.match(/CSS variable '(--[\w-]+)' is not defined/);
22
+ if (!match) {
23
+ continue;
24
+ }
25
+ const variableName = match[1];
26
+ // Code action: Create variable in :root
27
+ const createInRootAction = createVariableInRoot(document, variableName, diagnostic);
28
+ if (createInRootAction) {
29
+ codeActions.push(createInRootAction);
30
+ }
31
+ // Code action: Suggest similar existing variables
32
+ const suggestions = getSimilarVariables(variableName, cssVariableManager);
33
+ for (const suggestion of suggestions) {
34
+ codeActions.push(createReplacementAction(document, diagnostic, variableName, suggestion));
35
+ }
36
+ }
37
+ return codeActions;
38
+ }
39
+ /**
40
+ * Create a code action to define the variable in :root
41
+ */
42
+ function createVariableInRoot(document, variableName, diagnostic) {
43
+ const text = document.getText();
44
+ // Find :root selector
45
+ const rootMatch = text.match(/:root\s*\{/);
46
+ let edit;
47
+ if (rootMatch) {
48
+ // Add variable after :root {
49
+ const insertPosition = document.positionAt(rootMatch.index + rootMatch[0].length);
50
+ edit = {
51
+ changes: {
52
+ [document.uri]: [
53
+ {
54
+ range: { start: insertPosition, end: insertPosition },
55
+ newText: `\n ${variableName}: /* TODO: add value */;`,
56
+ },
57
+ ],
58
+ },
59
+ };
60
+ }
61
+ else {
62
+ // Add :root at the start of the file
63
+ const startPos = { line: 0, character: 0 };
64
+ edit = {
65
+ changes: {
66
+ [document.uri]: [
67
+ {
68
+ range: { start: startPos, end: startPos },
69
+ newText: `:root {\n ${variableName}: /* TODO: add value */;\n}\n\n`,
70
+ },
71
+ ],
72
+ },
73
+ };
74
+ }
75
+ return {
76
+ title: `Create '${variableName}' in :root`,
77
+ kind: node_1.CodeActionKind.QuickFix,
78
+ diagnostics: [diagnostic],
79
+ edit,
80
+ };
81
+ }
82
+ /**
83
+ * Find similar variable names that might be typos
84
+ */
85
+ function getSimilarVariables(variableName, cssVariableManager) {
86
+ const allVariables = cssVariableManager.getAllVariables();
87
+ const uniqueNames = new Set(allVariables.map((v) => v.name));
88
+ const similar = [];
89
+ const varNameLower = variableName.toLowerCase();
90
+ for (const name of uniqueNames) {
91
+ const nameLower = name.toLowerCase();
92
+ // Simple similarity check: same prefix or few character difference
93
+ if (nameLower.startsWith(varNameLower.slice(0, 5)) ||
94
+ varNameLower.startsWith(nameLower.slice(0, 5)) ||
95
+ levenshteinDistance(varNameLower, nameLower) <= 3) {
96
+ similar.push(name);
97
+ if (similar.length >= 3)
98
+ break; // Limit suggestions
99
+ }
100
+ }
101
+ return similar;
102
+ }
103
+ /**
104
+ * Create a code action to replace variable with a suggestion
105
+ */
106
+ function createReplacementAction(document, diagnostic, original, replacement) {
107
+ return {
108
+ title: `Replace with '${replacement}'`,
109
+ kind: node_1.CodeActionKind.QuickFix,
110
+ diagnostics: [diagnostic],
111
+ edit: {
112
+ changes: {
113
+ [document.uri]: [
114
+ {
115
+ range: diagnostic.range,
116
+ newText: `var(${replacement})`,
117
+ },
118
+ ],
119
+ },
120
+ },
121
+ };
122
+ }
123
+ /**
124
+ * Simple Levenshtein distance for typo detection
125
+ */
126
+ function levenshteinDistance(a, b) {
127
+ const matrix = [];
128
+ for (let i = 0; i <= a.length; i++) {
129
+ matrix[i] = [i];
130
+ }
131
+ for (let j = 0; j <= b.length; j++) {
132
+ matrix[0][j] = j;
133
+ }
134
+ for (let i = 1; i <= a.length; i++) {
135
+ for (let j = 1; j <= b.length; j++) {
136
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
137
+ matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + cost);
138
+ }
139
+ }
140
+ return matrix[a.length][b.length];
141
+ }
142
+ //# sourceMappingURL=codeAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeAction.js","sourceRoot":"","sources":["../../src/handlers/codeAction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleCodeLens = handleCodeLens;
4
+ /**
5
+ * Handle code lens requests for CSS documents.
6
+ * Shows usage counts above CSS variable definitions.
7
+ */
8
+ function handleCodeLens(params, documents, cssVariableManager) {
9
+ const document = documents.get(params.textDocument.uri);
10
+ if (!document) {
11
+ return null;
12
+ }
13
+ const codeLenses = [];
14
+ const allVariables = cssVariableManager.getAllVariables();
15
+ // Find variables defined in this document
16
+ const documentVariables = allVariables.filter((v) => v.uri === document.uri);
17
+ // Group by variable name to avoid duplicate lenses
18
+ const seen = new Set();
19
+ for (const variable of documentVariables) {
20
+ if (seen.has(variable.name))
21
+ continue;
22
+ seen.add(variable.name);
23
+ // Get usage count for this variable
24
+ const references = cssVariableManager.getReferences(variable.name);
25
+ // Filter to only usages (not definitions)
26
+ const usages = references.filter((ref) => !("selector" in ref));
27
+ const usageCount = usages.length;
28
+ // Use the nameRange if available, otherwise fall back to range
29
+ const range = variable.nameRange || variable.range;
30
+ const command = {
31
+ title: usageCount === 1 ? `${usageCount} usage` : `${usageCount} usages`,
32
+ command: "", // No command, just informational
33
+ };
34
+ codeLenses.push({
35
+ range,
36
+ command,
37
+ });
38
+ }
39
+ return codeLenses;
40
+ }
41
+ //# sourceMappingURL=codeLens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeLens.js","sourceRoot":"","sources":["../../src/handlers/codeLens.ts"],"names":[],"mappings":";;AAQA,wCA4CC;AAhDD;;;GAGG;AACH,SAAgB,cAAc,CAC5B,MAAsB,EACtB,SAAyD,EACzD,kBAAsC;IAEtC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAe,EAAE,CAAC;IAClC,MAAM,YAAY,GAAG,kBAAkB,CAAC,eAAe,EAAE,CAAC;IAE1D,0CAA0C;IAC1C,MAAM,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG,CAAC,CAAC;IAE7E,mDAAmD;IACnD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,QAAQ,IAAI,iBAAiB,EAAE,CAAC;QACzC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,SAAS;QACtC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAExB,oCAAoC;QACpC,MAAM,UAAU,GAAG,kBAAkB,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnE,0CAA0C;QAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC;QAChE,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;QAEjC,+DAA+D;QAC/D,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC;QAEnD,MAAM,OAAO,GAAY;YACvB,KAAK,EAAE,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,QAAQ,CAAC,CAAC,CAAC,GAAG,UAAU,SAAS;YACxE,OAAO,EAAE,EAAE,EAAE,iCAAiC;SAC/C,CAAC;QAEF,UAAU,CAAC,IAAI,CAAC;YACd,KAAK;YACL,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleDeclaration = handleDeclaration;
4
+ const node_1 = require("vscode-languageserver/node");
5
+ /**
6
+ * Handle declaration requests for CSS variables.
7
+ * For CSS variables, declaration and definition are the same.
8
+ */
9
+ function handleDeclaration(params, documents, cssVariableManager) {
10
+ const document = documents.get(params.textDocument.uri);
11
+ if (!document) {
12
+ return null;
13
+ }
14
+ const text = document.getText();
15
+ const offset = document.offsetAt(params.position);
16
+ // Find the word at the cursor position
17
+ const left = text.slice(0, offset).match(/[\w-]*$/);
18
+ const right = text.slice(offset).match(/^[\w-]*/);
19
+ if (!left || !right) {
20
+ return null;
21
+ }
22
+ const word = left[0] + right[0];
23
+ // Check if it's a CSS variable
24
+ if (word.startsWith("--")) {
25
+ const variables = cssVariableManager.getVariables(word);
26
+ if (variables.length > 0) {
27
+ // For CSS variables, return the first definition location
28
+ // This could be enhanced to handle multiple declarations
29
+ return node_1.Location.create(variables[0].uri, variables[0].range);
30
+ }
31
+ }
32
+ return null;
33
+ }
34
+ //# sourceMappingURL=declaration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declaration.js","sourceRoot":"","sources":["../../src/handlers/declaration.ts"],"names":[],"mappings":";;AAaA,8CAkCC;AAxCD,qDAAsD;AAEtD;;;GAGG;AACH,SAAgB,iBAAiB,CAC/B,MAAkC,EAClC,SAAyD,EACzD,kBAAsC;IAEtC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAElD,uCAAuC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAElD,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEhC,+BAA+B;IAC/B,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,kBAAkB,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,0DAA0D;YAC1D,yDAAyD;YACzD,OAAO,eAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleDocumentHighlight = handleDocumentHighlight;
4
+ const node_1 = require("vscode-languageserver/node");
5
+ /**
6
+ * Handle document highlight requests for CSS variables.
7
+ * Highlights all occurrences of the variable at the cursor position.
8
+ */
9
+ function handleDocumentHighlight(params, documents, cssVariableManager) {
10
+ const document = documents.get(params.textDocument.uri);
11
+ if (!document) {
12
+ return null;
13
+ }
14
+ const text = document.getText();
15
+ const offset = document.offsetAt(params.position);
16
+ // Find the word at the cursor position
17
+ const left = text.slice(0, offset).match(/[\w-]*$/);
18
+ const right = text.slice(offset).match(/^[\w-]*/);
19
+ if (!left || !right) {
20
+ return null;
21
+ }
22
+ const word = left[0] + right[0];
23
+ // Check if it's a CSS variable
24
+ if (word.startsWith("--")) {
25
+ const highlights = [];
26
+ // Get all references to this variable
27
+ const references = cssVariableManager.getReferences(word);
28
+ // Filter references to only those in the current document
29
+ const currentDocRefs = references.filter(ref => ref.uri === document.uri);
30
+ // Create highlights for each reference
31
+ for (const ref of currentDocRefs) {
32
+ // Check if it's a definition by checking if it has a selector property
33
+ const isDefinition = 'selector' in ref;
34
+ const highlight = {
35
+ range: ref.range,
36
+ // Use Write kind for definitions, Text kind for usages
37
+ kind: isDefinition ? node_1.DocumentHighlightKind.Write : node_1.DocumentHighlightKind.Text,
38
+ };
39
+ highlights.push(highlight);
40
+ }
41
+ return highlights;
42
+ }
43
+ return null;
44
+ }
45
+ //# sourceMappingURL=documentHighlight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentHighlight.js","sourceRoot":"","sources":["../../src/handlers/documentHighlight.ts"],"names":[],"mappings":";;AAaA,0DAiDC;AA9DD,qDAIoC;AAKpC;;;GAGG;AACH,SAAgB,uBAAuB,CACrC,MAA+B,EAC/B,SAAyD,EACzD,kBAAsC;IAEtC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAElD,uCAAuC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAElD,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEhC,+BAA+B;IAC/B,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAwB,EAAE,CAAC;QAE3C,sCAAsC;QACtC,MAAM,UAAU,GAAG,kBAAkB,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAE1D,0DAA0D;QAC1D,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG,CAAC,CAAC;QAE1E,uCAAuC;QACvC,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,uEAAuE;YACvE,MAAM,YAAY,GAAG,UAAU,IAAI,GAAG,CAAC;YACvC,MAAM,SAAS,GAAsB;gBACnC,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,uDAAuD;gBACvD,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,4BAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,4BAAqB,CAAC,IAAI;aAC9E,CAAC;YACF,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleDocumentLinks = handleDocumentLinks;
4
+ const vscode_uri_1 = require("vscode-uri");
5
+ const path = require("path");
6
+ /**
7
+ * Handle document link requests for CSS documents.
8
+ * Returns clickable links for @import and url() references.
9
+ */
10
+ function handleDocumentLinks(params, documents) {
11
+ const document = documents.get(params.textDocument.uri);
12
+ if (!document) {
13
+ return null;
14
+ }
15
+ const text = document.getText();
16
+ const documentUri = vscode_uri_1.URI.parse(document.uri);
17
+ const documentDir = path.dirname(documentUri.fsPath);
18
+ const links = [];
19
+ // Match @import statements
20
+ // @import "path"; @import url("path"); @import url(path);
21
+ const importRegex = /@import\s+(?:url\s*\(\s*)?["']?([^"';\)\s]+)["']?\s*\)?/g;
22
+ let match;
23
+ while ((match = importRegex.exec(text)) !== null) {
24
+ const importPath = match[1];
25
+ if (!importPath ||
26
+ importPath.startsWith("http") ||
27
+ importPath.startsWith("//")) {
28
+ continue; // Skip external URLs
29
+ }
30
+ const startPos = document.positionAt(match.index + match[0].indexOf(importPath));
31
+ const endPos = document.positionAt(match.index + match[0].indexOf(importPath) + importPath.length);
32
+ const resolvedPath = path.resolve(documentDir, importPath);
33
+ const targetUri = vscode_uri_1.URI.file(resolvedPath).toString();
34
+ links.push({
35
+ range: { start: startPos, end: endPos },
36
+ target: targetUri,
37
+ });
38
+ }
39
+ // Match url() references in CSS properties
40
+ // background: url("image.png"); src: url(font.woff);
41
+ const urlRegex = /url\s*\(\s*["']?([^"'\)\s]+)["']?\s*\)/g;
42
+ while ((match = urlRegex.exec(text)) !== null) {
43
+ const urlPath = match[1];
44
+ if (!urlPath ||
45
+ urlPath.startsWith("http") ||
46
+ urlPath.startsWith("//") ||
47
+ urlPath.startsWith("data:")) {
48
+ continue; // Skip external URLs and data URIs
49
+ }
50
+ const startPos = document.positionAt(match.index + match[0].indexOf(urlPath));
51
+ const endPos = document.positionAt(match.index + match[0].indexOf(urlPath) + urlPath.length);
52
+ const resolvedPath = path.resolve(documentDir, urlPath);
53
+ const targetUri = vscode_uri_1.URI.file(resolvedPath).toString();
54
+ links.push({
55
+ range: { start: startPos, end: endPos },
56
+ target: targetUri,
57
+ });
58
+ }
59
+ return links;
60
+ }
61
+ //# sourceMappingURL=documentLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentLink.js","sourceRoot":"","sources":["../../src/handlers/documentLink.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setupDocumentSync = setupDocumentSync;
4
+ /**
5
+ * Document sync setup for CSS LSP.
6
+ * Note: In the current version, document save events are handled
7
+ * through the existing file watching mechanism.
8
+ */
9
+ function setupDocumentSync(documents, cssVariableManager) {
10
+ // The TextDocuments manager already handles document changes
11
+ // Save events are handled through the existing file watching system
12
+ // in server.ts via connection.onDidChangeWatchedFiles
13
+ console.log("[css-lsp] Document sync setup complete");
14
+ }
15
+ //# sourceMappingURL=documentSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentSync.js","sourceRoot":"","sources":["../../src/handlers/documentSync.ts"],"names":[],"mappings":";;AASA,8CASC;AAdD;;;;GAIG;AACH,SAAgB,iBAAiB,CAC/B,SAAsC,EACtC,kBAAsC;IAEtC,6DAA6D;IAC7D,oEAAoE;IACpE,sDAAsD;IAEtD,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleFoldingRange = handleFoldingRange;
4
+ const node_1 = require("vscode-languageserver/node");
5
+ const csstree = require("css-tree");
6
+ /**
7
+ * Handle folding range requests for CSS documents.
8
+ * Provides folding for:
9
+ * - CSS rule blocks (selector { ... })
10
+ * - At-rules (@media, @keyframes, @supports, etc.)
11
+ * - Multi-line comments
12
+ */
13
+ function handleFoldingRange(params, documents) {
14
+ const document = documents.get(params.textDocument.uri);
15
+ if (!document) {
16
+ return null;
17
+ }
18
+ const text = document.getText();
19
+ const foldingRanges = [];
20
+ // Parse CSS and find foldable blocks
21
+ try {
22
+ const ast = csstree.parse(text, {
23
+ positions: true,
24
+ onParseError: () => {
25
+ // Ignore parse errors for folding
26
+ },
27
+ });
28
+ csstree.walk(ast, {
29
+ enter: (node) => {
30
+ // Fold CSS rules (selector { ... })
31
+ if (node.type === "Rule" && node.loc) {
32
+ const startLine = node.loc.start.line - 1; // LSP is 0-based
33
+ const endLine = node.loc.end.line - 1;
34
+ // Only fold if it spans multiple lines
35
+ if (endLine > startLine) {
36
+ foldingRanges.push({
37
+ startLine,
38
+ endLine,
39
+ kind: node_1.FoldingRangeKind.Region,
40
+ });
41
+ }
42
+ }
43
+ // Fold at-rules (@media, @keyframes, @supports, @font-face, etc.)
44
+ if (node.type === "Atrule" && node.loc && node.block) {
45
+ const startLine = node.loc.start.line - 1;
46
+ const endLine = node.loc.end.line - 1;
47
+ if (endLine > startLine) {
48
+ foldingRanges.push({
49
+ startLine,
50
+ endLine,
51
+ kind: node_1.FoldingRangeKind.Region,
52
+ });
53
+ }
54
+ }
55
+ },
56
+ });
57
+ }
58
+ catch {
59
+ // If CSS parsing fails, fall back to brace matching
60
+ }
61
+ // Find multi-line comments using regex
62
+ const commentRegex = /\/\*[\s\S]*?\*\//g;
63
+ let match;
64
+ while ((match = commentRegex.exec(text)) !== null) {
65
+ const startPos = document.positionAt(match.index);
66
+ const endPos = document.positionAt(match.index + match[0].length);
67
+ if (endPos.line > startPos.line) {
68
+ foldingRanges.push({
69
+ startLine: startPos.line,
70
+ endLine: endPos.line,
71
+ kind: node_1.FoldingRangeKind.Comment,
72
+ });
73
+ }
74
+ }
75
+ return foldingRanges;
76
+ }
77
+ //# sourceMappingURL=foldingRange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foldingRange.js","sourceRoot":"","sources":["../../src/handlers/foldingRange.ts"],"names":[],"mappings":";;AAeA,gDA0EC;AAzFD,qDAIoC;AAEpC,oCAAoC;AAEpC;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAChC,MAA0B,EAC1B,SAAyD;IAEzD,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;IAChC,MAAM,aAAa,GAAmB,EAAE,CAAC;IAEzC,qCAAqC;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE;YAC9B,SAAS,EAAE,IAAI;YACf,YAAY,EAAE,GAAG,EAAE;gBACjB,kCAAkC;YACpC,CAAC;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;YAChB,KAAK,EAAE,CAAC,IAAqB,EAAE,EAAE;gBAC/B,oCAAoC;gBACpC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;oBACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,iBAAiB;oBAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;oBAEtC,uCAAuC;oBACvC,IAAI,OAAO,GAAG,SAAS,EAAE,CAAC;wBACxB,aAAa,CAAC,IAAI,CAAC;4BACjB,SAAS;4BACT,OAAO;4BACP,IAAI,EAAE,uBAAgB,CAAC,MAAM;yBAC9B,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAED,kEAAkE;gBAClE,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBACrD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;oBAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;oBAEtC,IAAI,OAAO,GAAG,SAAS,EAAE,CAAC;wBACxB,aAAa,CAAC,IAAI,CAAC;4BACjB,SAAS;4BACT,OAAO;4BACP,IAAI,EAAE,uBAAgB,CAAC,MAAM;yBAC9B,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,oDAAoD;IACtD,CAAC;IAED,uCAAuC;IACvC,MAAM,YAAY,GAAG,mBAAmB,CAAC;IACzC,IAAI,KAAK,CAAC;IACV,OAAO,CAAC,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAElE,IAAI,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;YAChC,aAAa,CAAC,IAAI,CAAC;gBACjB,SAAS,EAAE,QAAQ,CAAC,IAAI;gBACxB,OAAO,EAAE,MAAM,CAAC,IAAI;gBACpB,IAAI,EAAE,uBAAgB,CAAC,OAAO;aAC/B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleDocumentFormatting = handleDocumentFormatting;
4
+ exports.handleDocumentRangeFormatting = handleDocumentRangeFormatting;
5
+ const node_1 = require("vscode-languageserver/node");
6
+ /**
7
+ * Handle document formatting requests.
8
+ * Basic CSS formatting implementation.
9
+ */
10
+ function handleDocumentFormatting(params, documents) {
11
+ const document = documents.get(params.textDocument.uri);
12
+ if (!document) {
13
+ return null;
14
+ }
15
+ const text = document.getText();
16
+ const formatted = formatCss(text, params.options);
17
+ // Replace entire document
18
+ const fullRange = {
19
+ start: document.positionAt(0),
20
+ end: document.positionAt(text.length),
21
+ };
22
+ return [node_1.TextEdit.replace(fullRange, formatted)];
23
+ }
24
+ /**
25
+ * Handle document range formatting requests.
26
+ */
27
+ function handleDocumentRangeFormatting(params, documents) {
28
+ const document = documents.get(params.textDocument.uri);
29
+ if (!document) {
30
+ return null;
31
+ }
32
+ const startOffset = document.offsetAt(params.range.start);
33
+ const endOffset = document.offsetAt(params.range.end);
34
+ const text = document.getText();
35
+ // Format the selected text (basic implementation)
36
+ const selectedText = text.slice(startOffset, endOffset);
37
+ const formatted = formatCss(selectedText, params.options);
38
+ return [node_1.TextEdit.replace(params.range, formatted)];
39
+ }
40
+ /**
41
+ * Simple CSS formatter.
42
+ * TODO: Integrate a proper parser/formatter like prettier or css-tree's generator if needed.
43
+ * This is a basic rule-based formatter.
44
+ */
45
+ function formatCss(text, options) {
46
+ const indentChar = options.insertSpaces ? " ".repeat(options.tabSize) : "\t";
47
+ let depth = 0;
48
+ let output = "";
49
+ let insideString = null;
50
+ // Normalize newlines
51
+ const lines = text
52
+ .split(/\r?\n/)
53
+ .map((l) => l.trim())
54
+ .filter((l) => l.length > 0);
55
+ const joined = lines.join(" ");
56
+ // Simple tokenizing
57
+ let i = 0;
58
+ while (i < joined.length) {
59
+ const char = joined[i];
60
+ if (insideString) {
61
+ output += char;
62
+ if (char === insideString && joined[i - 1] !== "\\") {
63
+ insideString = null;
64
+ }
65
+ i++;
66
+ continue;
67
+ }
68
+ if (char === '"' || char === "'") {
69
+ insideString = char;
70
+ output += char;
71
+ i++;
72
+ continue;
73
+ }
74
+ if (char === "{") {
75
+ depth++;
76
+ output += " {\n" + indentChar.repeat(depth);
77
+ i++;
78
+ }
79
+ else if (char === "}") {
80
+ depth = Math.max(0, depth - 1);
81
+ output = output.trimEnd() + "\n" + indentChar.repeat(depth) + "}";
82
+ // If next char is not a closing brace, add newline
83
+ if (i + 1 < joined.length && joined[i + 1] !== "}") {
84
+ output += "\n" + indentChar.repeat(depth);
85
+ }
86
+ i++;
87
+ }
88
+ else if (char === ";") {
89
+ output += ";\n" + indentChar.repeat(depth);
90
+ i++;
91
+ }
92
+ else {
93
+ output += char;
94
+ i++;
95
+ }
96
+ }
97
+ return output.trim() + "\n";
98
+ }
99
+ //# sourceMappingURL=formatting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatting.js","sourceRoot":"","sources":["../../src/handlers/formatting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleImplementation = handleImplementation;
4
+ const node_1 = require("vscode-languageserver/node");
5
+ /**
6
+ * Handle implementation requests for CSS variables.
7
+ * For CSS variables, implementation points to where the variable is actually
8
+ * used or defined (similar to definition for variables).
9
+ */
10
+ function handleImplementation(params, documents, cssVariableManager) {
11
+ const document = documents.get(params.textDocument.uri);
12
+ if (!document) {
13
+ return null;
14
+ }
15
+ const text = document.getText();
16
+ const offset = document.offsetAt(params.position);
17
+ // Find the word at the cursor position
18
+ const left = text.slice(0, offset).match(/[\w-]*$/);
19
+ const right = text.slice(offset).match(/^[\w-]*/);
20
+ if (!left || !right) {
21
+ return null;
22
+ }
23
+ const word = left[0] + right[0];
24
+ // Check if it's a CSS variable
25
+ if (word.startsWith("--")) {
26
+ const variables = cssVariableManager.getVariables(word);
27
+ if (variables.length > 0) {
28
+ // For CSS variables, implementation points to the definition
29
+ // This could be enhanced to point to actual usage/implementation sites
30
+ return node_1.Location.create(variables[0].uri, variables[0].range);
31
+ }
32
+ }
33
+ return null;
34
+ }
35
+ //# sourceMappingURL=implementation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"implementation.js","sourceRoot":"","sources":["../../src/handlers/implementation.ts"],"names":[],"mappings":";;AAcA,oDAkCC;AAzCD,qDAAsD;AAEtD;;;;GAIG;AACH,SAAgB,oBAAoB,CAClC,MAAkC,EAClC,SAAyD,EACzD,kBAAsC;IAEtC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAElD,uCAAuC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAElD,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEhC,+BAA+B;IAC/B,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,kBAAkB,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,6DAA6D;YAC7D,uEAAuE;YACvE,OAAO,eAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleInlayHints = handleInlayHints;
4
+ const node_1 = require("vscode-languageserver/node");
5
+ /**
6
+ * Handle inlay hint requests for CSS documents.
7
+ * Shows resolved variable values inline after var() usages.
8
+ */
9
+ function handleInlayHints(params, documents, cssVariableManager) {
10
+ const document = documents.get(params.textDocument.uri);
11
+ if (!document) {
12
+ return null;
13
+ }
14
+ const text = document.getText();
15
+ const hints = [];
16
+ // Find all var(--name) usages
17
+ const varRegex = /var\((--[\w-]+)(?:\s*,\s*[^)]+)?\)/g;
18
+ let match;
19
+ while ((match = varRegex.exec(text)) !== null) {
20
+ const variableName = match[1];
21
+ const matchEnd = match.index + match[0].length;
22
+ // Check if this match is within the requested range
23
+ const endPos = document.positionAt(matchEnd);
24
+ if (endPos.line < params.range.start.line ||
25
+ endPos.line > params.range.end.line) {
26
+ continue;
27
+ }
28
+ // Get the variable value
29
+ const variables = cssVariableManager.getVariables(variableName);
30
+ if (variables.length === 0) {
31
+ continue;
32
+ }
33
+ // Use the first (highest priority) definition
34
+ const value = variables[0].value;
35
+ // Truncate long values
36
+ const displayValue = value.length > 30 ? value.slice(0, 27) + "..." : value;
37
+ hints.push({
38
+ position: endPos,
39
+ label: ` → ${displayValue}`,
40
+ kind: node_1.InlayHintKind.Type,
41
+ paddingLeft: true,
42
+ });
43
+ }
44
+ return hints;
45
+ }
46
+ //# sourceMappingURL=inlayHint.js.map