@master/css-language-service 2.0.0-rc.7 → 2.0.0-rc.70
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.
- package/README.md +114 -0
- package/dist/common.d.ts +1 -0
- package/dist/common.mjs +1 -0
- package/dist/core.d.ts +30 -0
- package/dist/core.mjs +114 -0
- package/dist/features/edit-syntax-colors.d.ts +4 -0
- package/dist/features/edit-syntax-colors.mjs +17 -0
- package/dist/features/inspect-syntax.d.ts +4 -0
- package/dist/features/inspect-syntax.mjs +54 -0
- package/dist/features/render-semantic-tokens.d.ts +5 -0
- package/dist/features/render-semantic-tokens.mjs +10 -0
- package/dist/features/render-syntax-colors.d.ts +4 -0
- package/dist/features/render-syntax-colors.mjs +102 -0
- package/dist/features/suggest-syntax.d.ts +5 -0
- package/dist/features/suggest-syntax.mjs +18 -0
- package/dist/index.d.ts +7 -5
- package/dist/index.mjs +7 -0
- package/dist/settings.d.ts +16 -9
- package/dist/settings.mjs +53 -0
- package/dist/utils/beautify-css.d.ts +1 -0
- package/dist/utils/beautify-css.mjs +11 -0
- package/dist/utils/completion-index.d.ts +38 -0
- package/dist/utils/completion-index.mjs +268 -0
- package/dist/utils/convert-color-token.d.ts +4 -0
- package/dist/utils/convert-color-token.mjs +55 -0
- package/dist/utils/create-css-markdown-documentation.d.ts +5 -0
- package/dist/utils/create-css-markdown-documentation.mjs +15 -0
- package/dist/utils/create-doc.d.ts +16 -0
- package/dist/utils/create-doc.mjs +21 -0
- package/dist/utils/get-class-completion-items.d.ts +4 -0
- package/dist/utils/get-class-completion-items.mjs +20 -0
- package/dist/utils/get-color-completion-items.d.ts +3 -0
- package/dist/utils/get-color-completion-items.mjs +24 -0
- package/dist/utils/get-position.d.ts +1 -0
- package/dist/utils/get-position.mjs +10 -0
- package/dist/utils/get-pseudo-class-completion-items.d.ts +4 -0
- package/dist/utils/get-pseudo-class-completion-items.mjs +68 -0
- package/dist/utils/get-pseudo-element-completion-items.d.ts +4 -0
- package/dist/utils/get-pseudo-element-completion-items.mjs +43 -0
- package/dist/utils/get-query-completion-items.d.ts +4 -0
- package/dist/utils/get-query-completion-items.mjs +77 -0
- package/dist/utils/get-range.d.ts +2 -0
- package/dist/utils/get-range.mjs +21 -0
- package/dist/utils/get-utility-info.d.ts +4 -0
- package/dist/utils/get-utility-info.mjs +19 -0
- package/dist/utils/get-value-completion-items.d.ts +4 -0
- package/dist/utils/get-value-completion-items.mjs +203 -0
- package/dist/utils/query-syntax-completions.d.ts +4 -0
- package/dist/utils/query-syntax-completions.mjs +94 -0
- package/dist/utils/regex.mjs +3 -0
- package/dist/utils/sort-completion-items.d.ts +2 -0
- package/dist/utils/sort-completion-items.mjs +11 -0
- package/package.json +1 -1
- package/dist/constant.d.ts +0 -33
- package/dist/index.bundle.js +0 -33
- package/dist/position-check.d.ts +0 -20
- package/dist/providers/color.d.ts +0 -5
- package/dist/providers/completion.d.ts +0 -14
- package/dist/providers/hover.d.ts +0 -2
- package/dist/settings.bundle.js +0 -1
- package/dist/utils/get-css-entry-markdown-description.d.ts +0 -1
- package/dist/utils/hex-to-rgb.d.ts +0 -2
- package/dist/utils/oklab-to-rgb.d.ts +0 -1
- package/dist/utils/oklch-to-oklab.d.ts +0 -1
- package/dist/utils/to-two-digit-hex.d.ts +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<br>
|
|
2
|
+
<div align="center">
|
|
3
|
+
|
|
4
|
+
<p align="center">
|
|
5
|
+
<a href="https://css.master.co">
|
|
6
|
+
<picture>
|
|
7
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/33840671/201701649-3bb7d698-abec-4d5f-ac30-ccc4d7bafcd4.svg">
|
|
8
|
+
<source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/33840671/201703010-77bf2373-9899-40cc-98f5-30cf9b546941.svg">
|
|
9
|
+
<img alt="Master CSS" src="https://user-images.githubusercontent.com/33840671/201703010-77bf2373-9899-40cc-98f5-30cf9b546941.svg" width="100%">
|
|
10
|
+
</picture>
|
|
11
|
+
</a>
|
|
12
|
+
</p>
|
|
13
|
+
<p align="center">Language Service for Master CSS</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a aria-label="GitHub release (latest by date including pre-releases)" href="https://github.com/master-co/css/releases">
|
|
17
|
+
<picture>
|
|
18
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=212022&label=&style=for-the-badge&logo=github&logoColor=fff">
|
|
19
|
+
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=f6f7f8&label=&style=for-the-badge&logo=github&logoColor=%23000">
|
|
20
|
+
<img alt="NPM Version" src="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=f6f7f8&label=&style=for-the-badge&logo=github">
|
|
21
|
+
</picture>
|
|
22
|
+
</a>
|
|
23
|
+
<a aria-label="NPM Package" href="https://www.npmjs.com/package/@master/css-language-service">
|
|
24
|
+
<picture>
|
|
25
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/npm/dm/@master/css-language-service?color=212022&label=%20&logo=npm&style=for-the-badge">
|
|
26
|
+
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/npm/dm/@master/css-language-service?color=f6f7f8&label=%20&logo=npm&style=for-the-badge">
|
|
27
|
+
<img alt="NPM package ( download / month )" src="https://img.shields.io/npm/dm/@master/css-language-service?color=f6f7f8&label=%20&logo=npm&style=for-the-badge">
|
|
28
|
+
</picture>
|
|
29
|
+
</a>
|
|
30
|
+
<a aria-label="JSDelivr" href="https://www.jsdelivr.com/package/npm/@master/css-language-service">
|
|
31
|
+
<picture>
|
|
32
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/jsdelivr/npm/hm/@master/css-language-service?color=212022&label=%20&logo=jsdelivr&style=for-the-badge">
|
|
33
|
+
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/jsdelivr/npm/hm/@master/css-language-service?color=f6f7f8&label=%20&logo=jsdelivr&style=for-the-badge">
|
|
34
|
+
<img alt="JSDelivr hits (npm scoped)" src="https://img.shields.io/jsdelivr/npm/hm/@master/css-language-service?color=f6f7f8&label=%20&logo=jsdelivr&style=for-the-badge">
|
|
35
|
+
</picture>
|
|
36
|
+
</a>
|
|
37
|
+
<a aria-label="Discord Community" href="https://discord.gg/sZNKpAAAw6">
|
|
38
|
+
<picture>
|
|
39
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/discord/917780624314613760?color=212022&label=%20&logo=discord&style=for-the-badge">
|
|
40
|
+
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/discord/917780624314613760?color=f6f7f8&label=%20&logo=discord&style=for-the-badge">
|
|
41
|
+
<img alt="Discord online" src="https://img.shields.io/discord/917780624314613760?color=f6f7f8&label=%20&logo=discord&style=for-the-badge">
|
|
42
|
+
</picture>
|
|
43
|
+
</a>
|
|
44
|
+
<a aria-label="Follow @mastercorg" href="https://twitter.com/mastercorg">
|
|
45
|
+
<picture>
|
|
46
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/static/v1?label=%20&message=twitter&color=212022&logo=twitter&style=for-the-badge">
|
|
47
|
+
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/static/v1?label=%20&message=twitter&color=f6f7f8&logo=twitter&style=for-the-badge">
|
|
48
|
+
<img alt="Follow @mastercorg" src="https://img.shields.io/static/v1?label=%20&message=twitter&color=f6f7f8&logo=twitter&style=for-the-badge">
|
|
49
|
+
</picture>
|
|
50
|
+
</a>
|
|
51
|
+
<a aria-label="Github Actions" href="https://github.com/master-co/css/actions/workflows/ci-release.yml">
|
|
52
|
+
<picture>
|
|
53
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/ci-release.yml?branch=rc&label=%20&message=twitter&color=212022&logo=githubactions&style=for-the-badge">
|
|
54
|
+
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/ci-release.yml?branch=rc&label=%20&message=twitter&color=f6f7f8&logo=githubactions&style=for-the-badge&logoColor=%23000">
|
|
55
|
+
<img alt="Github release actions" src="https://img.shields.io/github/actions/workflow/status/master-co/css/ci-release.yml?branch=rc&label=%20&message=twitter&color=f6f7f8&logo=githubactions&style=for-the-badge&logoColor=%23000">
|
|
56
|
+
</picture>
|
|
57
|
+
</a>
|
|
58
|
+
</p>
|
|
59
|
+
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
## Installation
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm install @master/css-language-service
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
import CSSLanguageService from '@master/css-language-service'
|
|
72
|
+
|
|
73
|
+
const languageService = new CSSLanguageService(customSettings)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`CSSLanguageService` provides stateful completion, hover, color, color presentation, and semantic token features around the editor-neutral primitives in `@master/css-language`.
|
|
77
|
+
|
|
78
|
+
### Semantic tokens
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
const semanticTokens = languageService.renderSemanticTokens(textDocument)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Semantic tokens are generated with the project manifest, so custom variables, components, utilities, modes, and other manifest-dependent tokens can be classified after the caller loads the manifest.
|
|
85
|
+
|
|
86
|
+
Use `renderSemanticTokensAtPosition()` when a client wants active-only highlighting for the embedded class context at the current editor position.
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
const semanticTokens = languageService.renderSemanticTokensAtPosition(textDocument, position)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
CSS directive syntax in CSS-family documents is highlighted by the shared TextMate grammar. Semantic tokens are only added for directive class-list spans such as bare `@compose` preludes and quoted `@safelist` strings.
|
|
93
|
+
|
|
94
|
+
## Settings
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
import { settings } from '@master/css-language-service'
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
| Setting | Type | Default | Description |
|
|
101
|
+
| --- | --- | --- | --- |
|
|
102
|
+
| `includedLanguages` | `string[]` | Common web and template languages | Language IDs that receive language-service features. |
|
|
103
|
+
| `exclude` | `string[]` | `["**/.git/**", "**/node_modules/**", "**/.hg/**"]` | Glob patterns excluded from all features. |
|
|
104
|
+
| `classAttributes` | `string[]` | `["class", "className"]` | Quoted markup attributes that contain Master CSS class strings. |
|
|
105
|
+
| `classAttributeBindings` | `Record<string, [string, string] \| false>` | Framework binding defaults | Bound attributes such as `:class`, `[ngClass]`, and `class:list`. |
|
|
106
|
+
| `classFunctions` | `string[]` | Common class helpers | Functions and methods whose string arguments contain classes, such as `clsx()` and `classList.add()`. |
|
|
107
|
+
| `classDeclarations` | `string[]` | `[]` | Variable declarations or object properties whose string values contain classes. |
|
|
108
|
+
| `suggestSyntax` | `boolean` | `true` | Enables syntax suggestions. |
|
|
109
|
+
| `inspectSyntax` | `boolean` | `true` | Enables hover inspection and generated CSS previews. |
|
|
110
|
+
| `renderSyntaxColors` | `boolean` | `true` | Enables color rendering. |
|
|
111
|
+
| `editSyntaxColors` | `boolean` | `true` | Enables color editing. |
|
|
112
|
+
| `embeddedSyntaxHighlighting` | `'active' \| 'always' \| 'off'` | `'active'` | Controls embedded semantic token highlighting. |
|
|
113
|
+
|
|
114
|
+
Use `@master/css-language` directly for browser helpers, Shiki integration, TextMate grammar assets, and raw class-position scanning.
|
package/dist/common.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AT_TRIGGER_CHARACTER, DECLARATION_SEPARATOR_TRIGGER_CHARACTER, GROUP_TRIGGER_CHARACTER, INVOKED_TRIGGER_CHARACTERS, QUERY_TRIGGER_CHARACTERS, SELECTOR_TRIGGER_CHARACTERS, VALUE_TRIGGER_CHARACTERS } from '@master/css-language';
|
package/dist/common.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AT_TRIGGER_CHARACTER, DECLARATION_SEPARATOR_TRIGGER_CHARACTER, GROUP_TRIGGER_CHARACTER, INVOKED_TRIGGER_CHARACTERS, QUERY_TRIGGER_CHARACTERS, SELECTOR_TRIGGER_CHARACTERS, VALUE_TRIGGER_CHARACTERS } from '@master/css-language';
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { MasterCSS, type ClassPosition } from '@master/css-language';
|
|
2
|
+
import EventEmitter from 'node:events';
|
|
3
|
+
import type { Position } from 'vscode-languageserver-protocol';
|
|
4
|
+
import { type Settings } from './settings';
|
|
5
|
+
import inspectSyntax from './features/inspect-syntax';
|
|
6
|
+
import renderSyntaxColors from './features/render-syntax-colors';
|
|
7
|
+
import editSyntaxColors from './features/edit-syntax-colors';
|
|
8
|
+
import renderSemanticTokens, { renderSemanticTokensAtPosition } from './features/render-semantic-tokens';
|
|
9
|
+
import suggestSyntax from './features/suggest-syntax';
|
|
10
|
+
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
11
|
+
export type { ClassPosition };
|
|
12
|
+
export default class CSSLanguageService extends EventEmitter {
|
|
13
|
+
customSettings?: Settings | undefined;
|
|
14
|
+
css: MasterCSS;
|
|
15
|
+
settings: Settings;
|
|
16
|
+
private completionIndex?;
|
|
17
|
+
private classPositionCache;
|
|
18
|
+
constructor(customSettings?: Settings | undefined);
|
|
19
|
+
private getCompletionIndex;
|
|
20
|
+
inspectSyntax(...params: Parameters<typeof inspectSyntax>): import("vscode-languageserver-protocol").Hover | undefined;
|
|
21
|
+
renderSyntaxColors(...params: Parameters<typeof renderSyntaxColors>): Promise<import("vscode-languageserver-protocol").ColorInformation[] | undefined> | undefined;
|
|
22
|
+
editSyntaxColors(...params: Parameters<typeof editSyntaxColors>): import("vscode-languageserver-protocol").ColorPresentation[] | undefined;
|
|
23
|
+
renderSemanticTokens(...params: Parameters<typeof renderSemanticTokens>): import("vscode-languageserver-protocol").SemanticTokens | undefined;
|
|
24
|
+
renderSemanticTokensAtPosition(...params: Parameters<typeof renderSemanticTokensAtPosition>): import("vscode-languageserver-protocol").SemanticTokens | undefined;
|
|
25
|
+
suggestSyntax(document: Parameters<typeof suggestSyntax>[0], position: Parameters<typeof suggestSyntax>[1], context: Parameters<typeof suggestSyntax>[2]): import("vscode-languageserver-protocol").CompletionItem[] | undefined;
|
|
26
|
+
getClassPositions(textDocument: TextDocument): ClassPosition[];
|
|
27
|
+
getClassPosition(textDocument: TextDocument, position: Position): ClassPosition | undefined;
|
|
28
|
+
getClassContextPositions(textDocument: TextDocument, position: Position): ClassPosition[];
|
|
29
|
+
isDocumentAccepted(doc: TextDocument): boolean;
|
|
30
|
+
}
|
package/dist/core.mjs
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { ClassPositionCache, MasterCSS, matchesLanguageServiceNativeDeclaration, defaultManifest, getClassPositions } from '@master/css-language';
|
|
2
|
+
import extend from '@techor/extend';
|
|
3
|
+
import EventEmitter from 'node:events';
|
|
4
|
+
import settings from './settings.mjs';
|
|
5
|
+
import { minimatch } from 'minimatch';
|
|
6
|
+
import inspectSyntax from './features/inspect-syntax.mjs';
|
|
7
|
+
import renderSyntaxColors from './features/render-syntax-colors.mjs';
|
|
8
|
+
import editSyntaxColors from './features/edit-syntax-colors.mjs';
|
|
9
|
+
import renderSemanticTokens, { renderSemanticTokensAtPosition } from './features/render-semantic-tokens.mjs';
|
|
10
|
+
import suggestSyntax from './features/suggest-syntax.mjs';
|
|
11
|
+
import { createCompletionIndex } from './utils/completion-index.mjs';
|
|
12
|
+
|
|
13
|
+
class CSSLanguageService extends EventEmitter {
|
|
14
|
+
customSettings;
|
|
15
|
+
css;
|
|
16
|
+
settings;
|
|
17
|
+
completionIndex;
|
|
18
|
+
classPositionCache = new ClassPositionCache();
|
|
19
|
+
constructor(customSettings){
|
|
20
|
+
super(), this.customSettings = customSettings;
|
|
21
|
+
this.settings = extend(settings, customSettings);
|
|
22
|
+
this.css = MasterCSS.create({
|
|
23
|
+
manifest: this.settings.manifest || defaultManifest,
|
|
24
|
+
nativeDeclarationMatcher: matchesLanguageServiceNativeDeclaration
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
getCompletionIndex() {
|
|
28
|
+
this.completionIndex ??= createCompletionIndex(this.css);
|
|
29
|
+
return this.completionIndex;
|
|
30
|
+
}
|
|
31
|
+
inspectSyntax(...params) {
|
|
32
|
+
if (this.settings.inspectSyntax && this.isDocumentAccepted(params[0])) return inspectSyntax?.call(this, ...params);
|
|
33
|
+
}
|
|
34
|
+
renderSyntaxColors(...params) {
|
|
35
|
+
if (this.settings.renderSyntaxColors && this.isDocumentAccepted(params[0])) return renderSyntaxColors?.call(this, ...params);
|
|
36
|
+
}
|
|
37
|
+
editSyntaxColors(...params) {
|
|
38
|
+
if (this.settings.editSyntaxColors && this.isDocumentAccepted(params[0])) return editSyntaxColors?.call(this, ...params);
|
|
39
|
+
}
|
|
40
|
+
renderSemanticTokens(...params) {
|
|
41
|
+
if (this.isDocumentAccepted(params[0])) return renderSemanticTokens?.call(this, ...params);
|
|
42
|
+
}
|
|
43
|
+
renderSemanticTokensAtPosition(...params) {
|
|
44
|
+
if (this.isDocumentAccepted(params[0])) return renderSemanticTokensAtPosition?.call(this, ...params);
|
|
45
|
+
}
|
|
46
|
+
suggestSyntax(document, position, context) {
|
|
47
|
+
if (this.settings.suggestSyntax && this.isDocumentAccepted(document)) return suggestSyntax?.call(this, document, position, context, this.getCompletionIndex());
|
|
48
|
+
}
|
|
49
|
+
getClassPositions(textDocument) {
|
|
50
|
+
return getClassPositions(textDocument, this.settings, {
|
|
51
|
+
cache: this.classPositionCache
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
getClassPosition(textDocument, position) {
|
|
55
|
+
const cachedOxcClassPosition = getClassPositions(textDocument, this.settings, {
|
|
56
|
+
position,
|
|
57
|
+
includeEmpty: true,
|
|
58
|
+
provider: 'oxc',
|
|
59
|
+
oxcMode: 'cache-only',
|
|
60
|
+
cache: this.classPositionCache
|
|
61
|
+
})[0];
|
|
62
|
+
if (cachedOxcClassPosition) return cachedOxcClassPosition;
|
|
63
|
+
const regexClassPosition = getClassPositions(textDocument, this.settings, {
|
|
64
|
+
position,
|
|
65
|
+
includeEmpty: true,
|
|
66
|
+
provider: 'regex'
|
|
67
|
+
})[0];
|
|
68
|
+
if (regexClassPosition && !regexClassPosition.raw.includes('${')) {
|
|
69
|
+
return regexClassPosition;
|
|
70
|
+
}
|
|
71
|
+
return getClassPositions(textDocument, this.settings, {
|
|
72
|
+
position,
|
|
73
|
+
includeEmpty: true,
|
|
74
|
+
provider: 'oxc',
|
|
75
|
+
cache: this.classPositionCache
|
|
76
|
+
})[0] ?? regexClassPosition;
|
|
77
|
+
}
|
|
78
|
+
getClassContextPositions(textDocument, position) {
|
|
79
|
+
const cachedOxcClassPositions = getClassPositions(textDocument, this.settings, {
|
|
80
|
+
position,
|
|
81
|
+
provider: 'oxc',
|
|
82
|
+
oxcMode: 'cache-only',
|
|
83
|
+
positionMatch: 'context',
|
|
84
|
+
cache: this.classPositionCache
|
|
85
|
+
});
|
|
86
|
+
if (cachedOxcClassPositions.length) return cachedOxcClassPositions;
|
|
87
|
+
const regexClassPositions = getClassPositions(textDocument, this.settings, {
|
|
88
|
+
position,
|
|
89
|
+
provider: 'regex',
|
|
90
|
+
positionMatch: 'context'
|
|
91
|
+
});
|
|
92
|
+
if (regexClassPositions.length && regexClassPositions.every(({ raw })=>!raw.includes('${'))) {
|
|
93
|
+
return regexClassPositions;
|
|
94
|
+
}
|
|
95
|
+
const oxcClassPositions = getClassPositions(textDocument, this.settings, {
|
|
96
|
+
position,
|
|
97
|
+
provider: 'oxc',
|
|
98
|
+
positionMatch: 'context',
|
|
99
|
+
cache: this.classPositionCache
|
|
100
|
+
});
|
|
101
|
+
return oxcClassPositions.length ? oxcClassPositions : regexClassPositions;
|
|
102
|
+
}
|
|
103
|
+
isDocumentAccepted(doc) {
|
|
104
|
+
if (!this.settings.exclude) return true;
|
|
105
|
+
for (const exclude of this.settings.exclude){
|
|
106
|
+
if (minimatch(doc.uri, exclude)) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export { CSSLanguageService as default };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
2
|
+
import CSSLanguageService from '../core';
|
|
3
|
+
import type { ColorPresentationParams, ColorPresentation } from 'vscode-languageserver-protocol';
|
|
4
|
+
export default function editSyntaxColors(this: CSSLanguageService, document: TextDocument, color: ColorPresentationParams['color'], range: ColorPresentationParams['range']): ColorPresentation[];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import convertColorByToken from '../utils/convert-color-token.mjs';
|
|
2
|
+
|
|
3
|
+
function editSyntaxColors(document, color, range) {
|
|
4
|
+
const colorPresentations = [];
|
|
5
|
+
const selectedColorToken = document.getText(range);
|
|
6
|
+
const targetColorToken = convertColorByToken(color, selectedColorToken, this.css);
|
|
7
|
+
if (targetColorToken) colorPresentations.push({
|
|
8
|
+
label: targetColorToken,
|
|
9
|
+
textEdit: {
|
|
10
|
+
range,
|
|
11
|
+
newText: targetColorToken
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
return colorPresentations;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { editSyntaxColors as default };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Hover, HoverParams } from 'vscode-languageserver-protocol';
|
|
2
|
+
import type CSSLanguageService from '../core';
|
|
3
|
+
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
4
|
+
export default function inspectSyntax(this: CSSLanguageService, document: TextDocument, position: HoverParams['position']): Hover | undefined;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import createCSSMarkdownDocumentation from '../utils/create-css-markdown-documentation.mjs';
|
|
2
|
+
import { UtilityType, generateCSS } from '@master/css-language';
|
|
3
|
+
|
|
4
|
+
function inspectSyntax(document, position) {
|
|
5
|
+
const classPosition = this.getClassPosition(document, position);
|
|
6
|
+
if (!classPosition) return;
|
|
7
|
+
const { token } = classPosition;
|
|
8
|
+
const range = {
|
|
9
|
+
start: document.positionAt(classPosition.range.start),
|
|
10
|
+
end: document.positionAt(classPosition.range.end)
|
|
11
|
+
};
|
|
12
|
+
const utilities = this.css.generate(token);
|
|
13
|
+
const component = utilities.find((utility)=>utility.type === UtilityType.Semantic && utility.layerName === 'components');
|
|
14
|
+
if (component) {
|
|
15
|
+
const documentation = createCSSMarkdownDocumentation(generateCSS([
|
|
16
|
+
token
|
|
17
|
+
], this.css));
|
|
18
|
+
if (documentation) {
|
|
19
|
+
return {
|
|
20
|
+
contents: {
|
|
21
|
+
kind: documentation.kind,
|
|
22
|
+
value: `(components) ` + documentation.value
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
const utility = utilities[0];
|
|
28
|
+
if (utility) {
|
|
29
|
+
if (utility.type === UtilityType.Semantic) {
|
|
30
|
+
const documentation = createCSSMarkdownDocumentation(generateCSS([
|
|
31
|
+
token
|
|
32
|
+
], this.css));
|
|
33
|
+
if (documentation) {
|
|
34
|
+
return {
|
|
35
|
+
contents: documentation,
|
|
36
|
+
range
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
const documentation = createCSSMarkdownDocumentation(generateCSS([
|
|
41
|
+
token
|
|
42
|
+
], this.css));
|
|
43
|
+
if (documentation) {
|
|
44
|
+
return {
|
|
45
|
+
contents: documentation,
|
|
46
|
+
range
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { inspectSyntax as default };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type CSSLanguageService from '../core';
|
|
2
|
+
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
3
|
+
import type { SemanticTokens } from 'vscode-languageserver-protocol';
|
|
4
|
+
export declare function renderSemanticTokensAtPosition(this: CSSLanguageService, document: TextDocument, position: Parameters<CSSLanguageService['getClassPosition']>[1]): SemanticTokens | undefined;
|
|
5
|
+
export default function renderSemanticTokens(this: CSSLanguageService, document: TextDocument): SemanticTokens | undefined;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { renderSemanticTokens as renderSemanticTokens$1, renderSemanticTokensAtPosition as renderSemanticTokensAtPosition$1 } from '@master/css-language';
|
|
2
|
+
|
|
3
|
+
function renderSemanticTokensAtPosition(document, position) {
|
|
4
|
+
return renderSemanticTokensAtPosition$1(this.css, document, this.getClassContextPositions(document, position), position, this.settings);
|
|
5
|
+
}
|
|
6
|
+
function renderSemanticTokens(document) {
|
|
7
|
+
return renderSemanticTokens$1(this.css, document, this.getClassPositions(document), this.settings);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { renderSemanticTokens as default, renderSemanticTokensAtPosition };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ColorInformation } from 'vscode-languageserver-protocol';
|
|
2
|
+
import CSSLanguageService from '../core';
|
|
3
|
+
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
4
|
+
export default function renderSyntaxColors(this: CSSLanguageService, document: TextDocument): Promise<ColorInformation[] | undefined>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { instancePattern } from '../utils/regex.mjs';
|
|
2
|
+
import Color from 'colorjs.io';
|
|
3
|
+
import { UtilityType } from '@master/css-language';
|
|
4
|
+
|
|
5
|
+
function resolveVariableColorValue(variable, variables) {
|
|
6
|
+
let current = variable;
|
|
7
|
+
for(let i = 0; i < 8; i++){
|
|
8
|
+
const value = current?.value;
|
|
9
|
+
if (value === undefined) return;
|
|
10
|
+
const text = String(value);
|
|
11
|
+
const alias = /^\$([a-zA-Z0-9-]+)(?: ?\/ ?.+?)?$|^var\(--([_a-zA-Z0-9-]+)\)$/.exec(text);
|
|
12
|
+
const aliasName = alias?.[1] ?? alias?.[2];
|
|
13
|
+
if (!aliasName) return text;
|
|
14
|
+
current = variables.get(aliasName);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async function renderSyntaxColors(document) {
|
|
18
|
+
const text = document.getText() ?? '';
|
|
19
|
+
const colorInformations = [];
|
|
20
|
+
try {
|
|
21
|
+
for (const instanceMatch of text.matchAll(instancePattern)){
|
|
22
|
+
if (instanceMatch.index === undefined) break;
|
|
23
|
+
const instanceStartIndex = instanceMatch.index;
|
|
24
|
+
const syntax = instanceMatch[0];
|
|
25
|
+
const rule = this.css.generate(syntax)[0];
|
|
26
|
+
if (rule && rule.type !== UtilityType.Semantic) {
|
|
27
|
+
const keyTokenLength = rule.keyToken?.length ?? 0;
|
|
28
|
+
let currentLength = 0;
|
|
29
|
+
const resolveValueComponent = (valueComponent)=>{
|
|
30
|
+
if (valueComponent.text === undefined) return; // text is always existing, just for type
|
|
31
|
+
const startOffset = instanceStartIndex + keyTokenLength + currentLength;
|
|
32
|
+
// TODO: check number mt:1.875rem
|
|
33
|
+
const valueComponentTokenLength = valueComponent.token.length;
|
|
34
|
+
let color;
|
|
35
|
+
switch(valueComponent.type){
|
|
36
|
+
case 'function':
|
|
37
|
+
if ([
|
|
38
|
+
'rgb',
|
|
39
|
+
'rgba',
|
|
40
|
+
'hsl',
|
|
41
|
+
'hsla',
|
|
42
|
+
'hwb',
|
|
43
|
+
'lab',
|
|
44
|
+
'lch',
|
|
45
|
+
'oklab',
|
|
46
|
+
'oklch',
|
|
47
|
+
'color'
|
|
48
|
+
].includes(valueComponent.name)) {
|
|
49
|
+
color = new Color(valueComponent.text);
|
|
50
|
+
} else if (valueComponent.children.length) {
|
|
51
|
+
currentLength += valueComponent.name.length + 1; // function name + '('
|
|
52
|
+
valueComponent.children.forEach(resolveValueComponent);
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
case 'variable':
|
|
56
|
+
if (valueComponent.variable?.namespace?.startsWith('color') && valueComponent.variable.value !== undefined) {
|
|
57
|
+
color = new Color(resolveVariableColorValue(valueComponent.variable, this.css.variables) || String(valueComponent.variable.value));
|
|
58
|
+
if (valueComponent.alpha !== undefined) {
|
|
59
|
+
color.alpha *= valueComponent.alpha;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
63
|
+
case 'string':
|
|
64
|
+
if (valueComponent.text !== '#' && valueComponent.text?.startsWith('#')) {
|
|
65
|
+
color = new Color(valueComponent.text);
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
// check if rgba is valid
|
|
70
|
+
if (color) {
|
|
71
|
+
const rgbaColor = color.to('srgb');
|
|
72
|
+
colorInformations.push({
|
|
73
|
+
range: {
|
|
74
|
+
start: document.positionAt(startOffset),
|
|
75
|
+
end: document.positionAt(startOffset + valueComponentTokenLength)
|
|
76
|
+
},
|
|
77
|
+
color: {
|
|
78
|
+
red: rgbaColor.r ?? 0,
|
|
79
|
+
green: rgbaColor.g ?? 0,
|
|
80
|
+
blue: rgbaColor.b ?? 0,
|
|
81
|
+
alpha: Number(rgbaColor.alpha)
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
currentLength += valueComponentTokenLength || 0;
|
|
86
|
+
};
|
|
87
|
+
rule.valueComponents.forEach(resolveValueComponent);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} catch (e) {}
|
|
91
|
+
const colorIndexSet = new Set();
|
|
92
|
+
return colorInformations.filter((item)=>{
|
|
93
|
+
if (colorIndexSet.has(item.range.start)) {
|
|
94
|
+
return false;
|
|
95
|
+
} else {
|
|
96
|
+
colorIndexSet.add(item.range.start);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { renderSyntaxColors as default };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CompletionItem, CompletionParams } from 'vscode-languageserver-protocol';
|
|
2
|
+
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
3
|
+
import CSSLanguageService from '../core';
|
|
4
|
+
import type { CompletionIndex } from '../utils/completion-index';
|
|
5
|
+
export default function suggestSyntax(this: CSSLanguageService, document: TextDocument, position: CompletionParams['position'], context: CompletionParams['context'], completionIndex?: CompletionIndex): CompletionItem[] | undefined;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import querySyntaxCompletions from '../utils/query-syntax-completions.mjs';
|
|
2
|
+
|
|
3
|
+
function suggestSyntax(document, position, context, completionIndex) {
|
|
4
|
+
const classPosition = this.getClassPosition(document, position);
|
|
5
|
+
if (classPosition !== undefined) {
|
|
6
|
+
const q = context?.triggerCharacter === ' ' ? '' : document.getText({
|
|
7
|
+
start: document.positionAt(classPosition.range.start),
|
|
8
|
+
end: position
|
|
9
|
+
});
|
|
10
|
+
return querySyntaxCompletions(q, this.css, completionIndex);
|
|
11
|
+
}
|
|
12
|
+
// todo
|
|
13
|
+
// else if (isInstance === true && checkConfigColorsBlock(document, position) === true) {
|
|
14
|
+
// return getColorCompletionItems(this.css)
|
|
15
|
+
// }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { suggestSyntax as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
1
|
+
export { default, default as CSSLanguageService } from './core';
|
|
2
|
+
export { default as settings, type Settings } from './settings';
|
|
3
|
+
export * from './common';
|
|
4
|
+
export { default as inspectSyntax } from './features/inspect-syntax';
|
|
5
|
+
export { default as renderSyntaxColors } from './features/render-syntax-colors';
|
|
6
|
+
export { default as editSyntaxColors } from './features/edit-syntax-colors';
|
|
7
|
+
export { default as suggestSyntax } from './features/suggest-syntax';
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as CSSLanguageService, default } from './core.mjs';
|
|
2
|
+
export { default as settings } from './settings.mjs';
|
|
3
|
+
export { default as inspectSyntax } from './features/inspect-syntax.mjs';
|
|
4
|
+
export { default as renderSyntaxColors } from './features/render-syntax-colors.mjs';
|
|
5
|
+
export { default as editSyntaxColors } from './features/edit-syntax-colors.mjs';
|
|
6
|
+
export { default as suggestSyntax } from './features/suggest-syntax.mjs';
|
|
7
|
+
export { AT_TRIGGER_CHARACTER, DECLARATION_SEPARATOR_TRIGGER_CHARACTER, GROUP_TRIGGER_CHARACTER, INVOKED_TRIGGER_CHARACTERS, QUERY_TRIGGER_CHARACTERS, SELECTOR_TRIGGER_CHARACTERS, VALUE_TRIGGER_CHARACTERS } from '@master/css-language';
|
package/dist/settings.d.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { type LanguageSettings } from '@master/css-language';
|
|
2
|
+
import type { MasterCSSManifest } from '@master/css';
|
|
3
|
+
/**
|
|
4
|
+
* @example styles https://regex101.com/r/HLPdsw/1
|
|
5
|
+
**/
|
|
6
|
+
declare const settings: Settings;
|
|
7
|
+
export default settings;
|
|
8
|
+
export declare interface Settings extends LanguageSettings {
|
|
9
|
+
includedLanguages?: string[];
|
|
10
|
+
exclude?: string[];
|
|
11
|
+
manifest?: MasterCSSManifest;
|
|
12
|
+
suggestSyntax?: boolean;
|
|
13
|
+
inspectSyntax?: boolean;
|
|
14
|
+
renderSyntaxColors?: boolean;
|
|
15
|
+
editSyntaxColors?: boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { languageSettings } from '@master/css-language';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @example styles https://regex101.com/r/HLPdsw/1
|
|
5
|
+
**/ const settings = {
|
|
6
|
+
includedLanguages: [
|
|
7
|
+
"html",
|
|
8
|
+
"php",
|
|
9
|
+
"javascript",
|
|
10
|
+
"typescript",
|
|
11
|
+
"javascriptreact",
|
|
12
|
+
"typescriptreact",
|
|
13
|
+
"css",
|
|
14
|
+
"scss",
|
|
15
|
+
"less",
|
|
16
|
+
"vue",
|
|
17
|
+
"svelte",
|
|
18
|
+
"rust",
|
|
19
|
+
"astro",
|
|
20
|
+
"markdown",
|
|
21
|
+
"mdx",
|
|
22
|
+
"astro"
|
|
23
|
+
],
|
|
24
|
+
/**
|
|
25
|
+
* @example <div class="a b">
|
|
26
|
+
* @example <div className="a b">
|
|
27
|
+
*/ classAttributes: languageSettings.classAttributes,
|
|
28
|
+
/**
|
|
29
|
+
* @example <div class={active ? 'a' : 'b'}>
|
|
30
|
+
* @example <div className={active ? 'a' : 'b'}>
|
|
31
|
+
*/ classAttributeBindings: languageSettings.classAttributeBindings,
|
|
32
|
+
/**
|
|
33
|
+
* @example const classes = 'a b'
|
|
34
|
+
* @example { classes: { btn: 'a b' } }
|
|
35
|
+
*/ classDeclarations: languageSettings.classDeclarations,
|
|
36
|
+
/**
|
|
37
|
+
* @example clsx('a b')
|
|
38
|
+
* @example styled`a b`
|
|
39
|
+
* @example .classList.add('a')
|
|
40
|
+
*/ classFunctions: languageSettings.classFunctions,
|
|
41
|
+
exclude: [
|
|
42
|
+
"**/.git/**",
|
|
43
|
+
"**/node_modules/**",
|
|
44
|
+
"**/.hg/**"
|
|
45
|
+
],
|
|
46
|
+
suggestSyntax: true,
|
|
47
|
+
inspectSyntax: true,
|
|
48
|
+
renderSyntaxColors: true,
|
|
49
|
+
editSyntaxColors: true,
|
|
50
|
+
embeddedSyntaxHighlighting: 'active'
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export { settings as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function beautifyCSS(text: string): any;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { css_beautify } from 'js-beautify/js/lib/beautify-css.js';
|
|
2
|
+
|
|
3
|
+
// @ts-expect-error
|
|
4
|
+
function beautifyCSS(text) {
|
|
5
|
+
return css_beautify(text.replace(/@(media|container|supports|layer)\(/g, '@$1 ('), {
|
|
6
|
+
newline_between_rules: false,
|
|
7
|
+
indent_size: 2
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { beautifyCSS as default };
|