@master/css-language-service 2.0.0-rc.69 → 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 +57 -6
- package/dist/common.d.ts +1 -9
- package/dist/common.mjs +1 -48
- package/dist/core.d.ts +11 -10
- package/dist/core.mjs +70 -200
- package/dist/features/inspect-syntax.mjs +18 -32
- 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.mjs +23 -8
- package/dist/features/suggest-syntax.d.ts +2 -1
- package/dist/features/suggest-syntax.mjs +2 -2
- package/dist/index.mjs +1 -1
- package/dist/settings.d.ts +4 -7
- package/dist/settings.mjs +12 -41
- package/dist/utils/beautify-css.mjs +1 -1
- 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 +1 -1
- package/dist/utils/convert-color-token.mjs +1 -1
- package/dist/utils/create-css-markdown-documentation.d.ts +5 -0
- package/dist/utils/create-css-markdown-documentation.mjs +15 -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 +1 -1
- package/dist/utils/get-color-completion-items.mjs +6 -9
- package/dist/utils/get-pseudo-class-completion-items.d.ts +3 -2
- package/dist/utils/get-pseudo-class-completion-items.mjs +45 -42
- package/dist/utils/get-pseudo-element-completion-items.d.ts +3 -2
- package/dist/utils/get-pseudo-element-completion-items.mjs +17 -28
- package/dist/utils/get-query-completion-items.d.ts +3 -2
- package/dist/utils/get-query-completion-items.mjs +19 -32
- package/dist/utils/get-utility-info.d.ts +2 -5
- package/dist/utils/get-utility-info.mjs +4 -16
- package/dist/utils/get-value-completion-items.d.ts +3 -2
- package/dist/utils/get-value-completion-items.mjs +145 -123
- package/dist/utils/query-syntax-completions.d.ts +3 -2
- package/dist/utils/query-syntax-completions.mjs +25 -44
- package/package.json +1 -1
- package/dist/common.cjs +0 -57
- package/dist/core.cjs +0 -246
- package/dist/features/edit-syntax-colors.cjs +0 -19
- package/dist/features/inspect-syntax.cjs +0 -70
- package/dist/features/render-syntax-colors.cjs +0 -89
- package/dist/features/suggest-syntax.cjs +0 -20
- package/dist/index.cjs +0 -29
- package/dist/settings.cjs +0 -84
- package/dist/utils/beautify-css.cjs +0 -13
- package/dist/utils/convert-color-token.cjs +0 -60
- package/dist/utils/create-doc.cjs +0 -26
- package/dist/utils/css-data-provider.cjs +0 -9
- package/dist/utils/css-data-provider.d.ts +0 -3
- package/dist/utils/css-data-provider.mjs +0 -7
- package/dist/utils/find-matching-brackets.cjs +0 -29
- package/dist/utils/find-matching-brackets.d.ts +0 -1
- package/dist/utils/find-matching-brackets.mjs +0 -27
- package/dist/utils/get-color-completion-items.cjs +0 -29
- package/dist/utils/get-css-data-documentation.cjs +0 -88
- package/dist/utils/get-css-data-documentation.d.ts +0 -5
- package/dist/utils/get-css-data-documentation.mjs +0 -86
- package/dist/utils/get-main-completion-items.cjs +0 -106
- package/dist/utils/get-main-completion-items.d.ts +0 -3
- package/dist/utils/get-main-completion-items.mjs +0 -104
- package/dist/utils/get-position.cjs +0 -12
- package/dist/utils/get-pseudo-class-completion-items.cjs +0 -67
- package/dist/utils/get-pseudo-element-completion-items.cjs +0 -56
- package/dist/utils/get-query-completion-items.cjs +0 -92
- package/dist/utils/get-range.cjs +0 -23
- package/dist/utils/get-utility-info.cjs +0 -33
- package/dist/utils/get-value-completion-items.cjs +0 -183
- package/dist/utils/query-syntax-completions.cjs +0 -115
- package/dist/utils/regex.cjs +0 -5
- package/dist/utils/sort-completion-items.cjs +0 -13
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import { MasterCSS } from '@master/css';
|
|
1
|
+
import { MasterCSS } from '@master/css-language';
|
|
2
2
|
import { type CompletionItem } from 'vscode-languageserver-protocol';
|
|
3
|
-
|
|
3
|
+
import { type CompletionIndex } from './completion-index';
|
|
4
|
+
export default function getPseudoElementCompletionItems(css: MasterCSS | undefined, syntax: string, completionIndex?: CompletionIndex): CompletionItem[];
|
|
@@ -1,50 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import cssDataProvider from './css-data-provider.mjs';
|
|
1
|
+
import { generateCSS, createDefaultCSS } from '@master/css-language';
|
|
3
2
|
import { CompletionItemKind } from 'vscode-languageserver-protocol';
|
|
4
3
|
import sortCompletionItems from './sort-completion-items.mjs';
|
|
5
|
-
import
|
|
4
|
+
import createCSSMarkdownDocumentation from './create-css-markdown-documentation.mjs';
|
|
5
|
+
import { createCompletionIndex } from './completion-index.mjs';
|
|
6
6
|
|
|
7
7
|
const kind = CompletionItemKind.Function;
|
|
8
|
-
function getPseudoElementCompletionItems(css =
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
// fix https://github.com/microsoft/vscode-custom-data/issues/78
|
|
12
|
-
const name = /::(?:part|slotted)/.test(data.name) ? data.name + '()' : data.name;
|
|
8
|
+
function getPseudoElementCompletionItems(css = createDefaultCSS(), syntax, completionIndex = createCompletionIndex(css)) {
|
|
9
|
+
const completionItems = completionIndex.pseudoElementNames.map((pseudoElementName)=>{
|
|
10
|
+
const name = /::(?:part|slotted)/.test(pseudoElementName) ? pseudoElementName + '()' : pseudoElementName;
|
|
13
11
|
let sortText = name.startsWith('::-') ? 'zzzz' + name.slice(3) : 'zz' + name.replace(/^::/, '');
|
|
14
12
|
if (sortText.endsWith('()')) sortText = 'z' + sortText;
|
|
15
13
|
return {
|
|
16
14
|
label: name,
|
|
17
15
|
sortText,
|
|
18
|
-
documentation:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
docs: '/guide/selectors'
|
|
23
|
-
}),
|
|
24
|
-
kind,
|
|
25
|
-
data
|
|
16
|
+
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
17
|
+
syntax + name.slice(2)
|
|
18
|
+
], css)),
|
|
19
|
+
kind
|
|
26
20
|
};
|
|
27
21
|
});
|
|
28
|
-
for(const
|
|
29
|
-
|
|
30
|
-
const selectorValue =
|
|
22
|
+
for (const variant of completionIndex.pseudoElementSelectors){
|
|
23
|
+
const selectorName = variant.token;
|
|
24
|
+
const selectorValue = variant.selector.replace(/&/g, '');
|
|
31
25
|
const name = selectorName.endsWith('(') ? selectorName + ')' : selectorName;
|
|
32
26
|
const value = typeof selectorValue === 'string' ? selectorValue.endsWith('(') ? selectorValue + ')' : selectorValue : selectorValue;
|
|
33
|
-
const data = pseudoElementDataList.find((data)=>typeof value === 'string' ? value.startsWith(data.name) : false);
|
|
34
27
|
let sortText = name.startsWith('::-') ? 'zzzz' + name.slice(3) : 'zz' + name.replace(/^::/, '');
|
|
35
28
|
if (sortText.endsWith('()')) sortText = 'z' + sortText;
|
|
36
29
|
const completionItem = {
|
|
37
30
|
label: name,
|
|
38
|
-
documentation:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
], css),
|
|
42
|
-
docs: '/guide/selectors'
|
|
43
|
-
}),
|
|
31
|
+
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
32
|
+
syntax + name.slice(2)
|
|
33
|
+
], css)),
|
|
44
34
|
sortText,
|
|
45
35
|
kind,
|
|
46
|
-
detail: String(value)
|
|
47
|
-
data
|
|
36
|
+
detail: String(value)
|
|
48
37
|
};
|
|
49
38
|
completionItems.push(completionItem);
|
|
50
39
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import { MasterCSS } from '@master/css';
|
|
1
|
+
import { MasterCSS } from '@master/css-language';
|
|
2
2
|
import { CompletionItem } from 'vscode-languageserver-protocol';
|
|
3
|
-
|
|
3
|
+
import { type CompletionIndex } from './completion-index';
|
|
4
|
+
export default function getQueryCompletionItems(css: MasterCSS | undefined, triggerCharacter: string | undefined, syntax: string, completionIndex?: CompletionIndex): CompletionItem[];
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AT_SIGN, QUERY_COMPARISON_OPERATORS, generateCSS, QUERY_LOGICAL_OPERATORS, generateAt, parseAt, createDefaultCSS, getSingleAtNumberRuleNode } from '@master/css-language';
|
|
2
2
|
import { CompletionItemKind } from 'vscode-languageserver-protocol';
|
|
3
3
|
import sortCompletionItems from './sort-completion-items.mjs';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import createCSSMarkdownDocumentation from './create-css-markdown-documentation.mjs';
|
|
5
|
+
import { createCompletionIndex } from './completion-index.mjs';
|
|
6
6
|
|
|
7
|
-
function getQueryCompletionItems(css =
|
|
8
|
-
const atDataList = cssDataProvider.provideAtDirectives();
|
|
7
|
+
function getQueryCompletionItems(css = createDefaultCSS(), triggerCharacter = AT_SIGN, syntax, completionIndex = createCompletionIndex(css)) {
|
|
9
8
|
const completionItems = [];
|
|
10
9
|
if (!QUERY_COMPARISON_OPERATORS.includes(triggerCharacter)) {
|
|
11
10
|
[
|
|
@@ -18,12 +17,9 @@ function getQueryCompletionItems(css = createCSS(), triggerCharacter = AT_SIGN,
|
|
|
18
17
|
filterText: name + '()',
|
|
19
18
|
insertText: name + '()',
|
|
20
19
|
sortText: name + '()',
|
|
21
|
-
documentation:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
], css),
|
|
25
|
-
docs: '/guide/at'
|
|
26
|
-
})
|
|
20
|
+
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
21
|
+
syntax + name + '()'
|
|
22
|
+
], css))
|
|
27
23
|
});
|
|
28
24
|
});
|
|
29
25
|
}
|
|
@@ -40,32 +36,26 @@ function getQueryCompletionItems(css = createCSS(), triggerCharacter = AT_SIGN,
|
|
|
40
36
|
insertText: token,
|
|
41
37
|
detail: text,
|
|
42
38
|
kind: CompletionItemKind.Keyword,
|
|
43
|
-
documentation:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
], css),
|
|
47
|
-
docs: '/guide/at'
|
|
48
|
-
})
|
|
39
|
+
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
40
|
+
syntax + token
|
|
41
|
+
], css))
|
|
49
42
|
});
|
|
50
43
|
return true;
|
|
51
44
|
}
|
|
52
45
|
};
|
|
53
|
-
|
|
46
|
+
for (const [token, atRule] of completionIndex.atRules){
|
|
54
47
|
const completionItem = {
|
|
55
48
|
filterText: token,
|
|
56
49
|
insertText: token,
|
|
57
|
-
documentation:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
], css),
|
|
61
|
-
docs: '/guide/at'
|
|
62
|
-
})
|
|
50
|
+
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
51
|
+
syntax + token
|
|
52
|
+
], css))
|
|
63
53
|
};
|
|
64
54
|
if ([
|
|
65
55
|
AT_SIGN,
|
|
66
56
|
...QUERY_LOGICAL_OPERATORS
|
|
67
57
|
].includes(triggerCharacter)) {
|
|
68
|
-
if (handleNumberNodes(atRule, token))
|
|
58
|
+
if (handleNumberNodes(atRule, token)) continue;
|
|
69
59
|
const text = generateAt(parseAt(triggerCharacter + token, css));
|
|
70
60
|
completionItems.push({
|
|
71
61
|
...completionItem,
|
|
@@ -73,17 +63,14 @@ function getQueryCompletionItems(css = createCSS(), triggerCharacter = AT_SIGN,
|
|
|
73
63
|
detail: text,
|
|
74
64
|
sortText: CompletionItemKind.Keyword + token,
|
|
75
65
|
kind: CompletionItemKind.Keyword,
|
|
76
|
-
documentation:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
], css),
|
|
80
|
-
docs: '/guide/at'
|
|
81
|
-
})
|
|
66
|
+
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
67
|
+
syntax + token
|
|
68
|
+
], css))
|
|
82
69
|
});
|
|
83
70
|
} else if (QUERY_COMPARISON_OPERATORS.includes(triggerCharacter)) {
|
|
84
71
|
handleNumberNodes(atRule, token);
|
|
85
72
|
}
|
|
86
|
-
}
|
|
73
|
+
}
|
|
87
74
|
return sortCompletionItems(completionItems);
|
|
88
75
|
}
|
|
89
76
|
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export default function getUtilityInfo(syntax: DefinedRule, css?: import("@master/css").MasterCSS): {
|
|
4
|
-
docs: string;
|
|
5
|
-
data: IPropertyData | undefined;
|
|
1
|
+
import { type CompiledUtility } from '@master/css-language';
|
|
2
|
+
export default function getUtilityInfo(utility: CompiledUtility): {
|
|
6
3
|
detail: string | undefined;
|
|
7
4
|
};
|
|
@@ -1,29 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import cssDataProvider from './css-data-provider.mjs';
|
|
1
|
+
import { getStaticUtilityDeclarations } from '@master/css-language';
|
|
3
2
|
|
|
4
|
-
function getUtilityInfo(
|
|
5
|
-
const
|
|
6
|
-
const declarations = syntax.definition.declarations;
|
|
3
|
+
function getUtilityInfo(utility) {
|
|
4
|
+
const declarations = getStaticUtilityDeclarations(utility);
|
|
7
5
|
const propsLength = Object.keys(declarations || {}).length;
|
|
8
6
|
const propName = Object.keys(declarations || {})[0];
|
|
9
7
|
const propValue = declarations?.[propName];
|
|
10
|
-
let data;
|
|
11
8
|
let detail;
|
|
12
9
|
/**
|
|
13
10
|
* Remaps to native CSS properties when only one property is declared
|
|
14
11
|
* */ if (propsLength === 1) {
|
|
15
|
-
|
|
16
|
-
data = nativeCSSPropertyData?.values?.find(({ name })=>name === propValue || name.replace(/^-(ms|moz)-/, '') === propValue);
|
|
17
|
-
if (data) {
|
|
18
|
-
detail = `${propName}: ${propValue}`;
|
|
19
|
-
} else {
|
|
20
|
-
data = nativeCSSPropertyData;
|
|
21
|
-
detail = nativeCSSPropertyData?.syntax;
|
|
22
|
-
}
|
|
12
|
+
detail = `${propName}: ${propValue}`;
|
|
23
13
|
}
|
|
24
14
|
return {
|
|
25
|
-
docs: '/reference/' + (data ? propName : 'utilities'),
|
|
26
|
-
data,
|
|
27
15
|
detail
|
|
28
16
|
};
|
|
29
17
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { type CompletionItem } from 'vscode-languageserver-protocol';
|
|
2
|
-
import { MasterCSS } from '@master/css';
|
|
3
|
-
|
|
2
|
+
import { MasterCSS } from '@master/css-language';
|
|
3
|
+
import { type CompletionIndex } from './completion-index';
|
|
4
|
+
export default function getValueCompletionItems(css: MasterCSS | undefined, ruleKey: string, valuePrefix?: string, completionIndex?: CompletionIndex): CompletionItem[];
|
|
@@ -1,58 +1,78 @@
|
|
|
1
1
|
import { CompletionItemKind } from 'vscode-languageserver-protocol';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
2
|
+
import { getMdnPropertySyntax, getMdnPropertyValueNames, generateCSS, createDefaultCSS } from '@master/css-language';
|
|
3
|
+
import { builtinKeyAliases } from '@master/css-engine';
|
|
4
|
+
import createCSSMarkdownDocumentation from './create-css-markdown-documentation.mjs';
|
|
5
5
|
import sortCompletionItems from './sort-completion-items.mjs';
|
|
6
|
+
import { createCompletionIndex } from './completion-index.mjs';
|
|
6
7
|
|
|
7
8
|
const SCOPED_VARIABLE_PRIORITY = 'aaaa';
|
|
8
|
-
const AMBIGUOUS_PRIORITY = 'bbbb';
|
|
9
9
|
const NATIVE_PRIORITY = 'ccccc';
|
|
10
10
|
const GLOBAL_VARIABLE_PRIORITY = 'zzzz';
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const ANIMATION_REFERENCE_PROPERTIES = new Set([
|
|
12
|
+
'animation',
|
|
13
|
+
'animation-name'
|
|
14
|
+
]);
|
|
15
|
+
function getNumericSortValue(variable, rootSize) {
|
|
16
|
+
if (variable.numeric) {
|
|
17
|
+
switch(variable.numeric.unit){
|
|
18
|
+
case 'rem':
|
|
19
|
+
return variable.numeric.value * rootSize;
|
|
20
|
+
case undefined:
|
|
21
|
+
case '':
|
|
22
|
+
case 'px':
|
|
23
|
+
return variable.numeric.value;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return typeof variable.value === 'number' ? variable.value : 0;
|
|
27
|
+
}
|
|
28
|
+
function getVariableKeyByNamespace(variableName, namespace) {
|
|
29
|
+
const negative = variableName.startsWith('-');
|
|
30
|
+
const positiveName = negative ? variableName.slice(1) : variableName;
|
|
31
|
+
if (positiveName !== namespace && !positiveName.startsWith(namespace + '-')) return;
|
|
32
|
+
const key = positiveName === namespace ? '' : positiveName.slice(namespace.length + 1);
|
|
33
|
+
return negative ? '-' + key : key;
|
|
34
|
+
}
|
|
35
|
+
function getValueCompletionItems(css = createDefaultCSS(), ruleKey, valuePrefix = '', completionIndex = createCompletionIndex(css)) {
|
|
13
36
|
const completionItems = [];
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
37
|
+
const addedLabels = new Set();
|
|
38
|
+
const canonicalRuleKey = builtinKeyAliases[ruleKey] || ruleKey;
|
|
39
|
+
const nativeUtilityKey = completionIndex.nativeUtilityKeys.get(canonicalRuleKey);
|
|
40
|
+
const nativeKey = nativeUtilityKey || (getMdnPropertySyntax(canonicalRuleKey) ? canonicalRuleKey : undefined);
|
|
41
|
+
const nativePropertyValues = getMdnPropertyValueNames(nativeKey);
|
|
42
|
+
const pushCompletionItem = (completionItem)=>{
|
|
43
|
+
completionItems.push(completionItem);
|
|
44
|
+
addedLabels.add(completionItem.label);
|
|
45
|
+
};
|
|
46
|
+
const generateVariableCompletionItem = (variable, { appliedValue, label, negative, scoped } = {})=>{
|
|
47
|
+
const nativePropertySyntax = getMdnPropertySyntax(variable.namespace) || getMdnPropertySyntax(nativeKey);
|
|
48
|
+
if (variable.type === 'number' && variable.name.startsWith('-') && nativePropertySyntax?.includes('absolute')) return;
|
|
49
|
+
const valueToken = appliedValue ?? (scoped ? variable.key : variable.name);
|
|
50
|
+
const documentation = createCSSMarkdownDocumentation(generateCSS([
|
|
51
|
+
ruleKey + ':' + valueToken
|
|
52
|
+
], css));
|
|
53
|
+
const completionItemLabel = label ?? variable.name;
|
|
54
|
+
const conflicted = addedLabels.has(completionItemLabel);
|
|
27
55
|
const completionItem = {
|
|
28
|
-
label:
|
|
56
|
+
label: conflicted ? 'var(--' + completionItemLabel + ')' : completionItemLabel,
|
|
29
57
|
kind: CompletionItemKind.Value
|
|
30
58
|
};
|
|
31
|
-
const conflicted = completionItems.find(({ label })=>label === variable.name);
|
|
32
59
|
if (conflicted) {
|
|
33
|
-
completionItem.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
ruleKey + ':' + completionItem.label
|
|
37
|
-
], css),
|
|
38
|
-
docs: '/reference/' + (eachNativePropertyData?.name || 'variables')
|
|
39
|
-
});
|
|
60
|
+
completionItem.documentation = createCSSMarkdownDocumentation(generateCSS([
|
|
61
|
+
ruleKey + ':' + completionItem.label
|
|
62
|
+
], css));
|
|
40
63
|
} else {
|
|
41
|
-
completionItem.documentation =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
], css),
|
|
45
|
-
docs: '/reference/' + (eachNativePropertyData?.name || 'variables')
|
|
46
|
-
});
|
|
64
|
+
completionItem.documentation = createCSSMarkdownDocumentation(generateCSS([
|
|
65
|
+
ruleKey + ':' + valueToken
|
|
66
|
+
], css));
|
|
47
67
|
}
|
|
48
|
-
if (variable.
|
|
68
|
+
if (variable.namespace?.startsWith('color')) {
|
|
49
69
|
if (Object.keys(variable.modes || {}).length) {
|
|
50
70
|
completionItem.kind = CompletionItemKind.Color;
|
|
51
71
|
completionItem.detail = variable.name;
|
|
52
72
|
} else {
|
|
53
73
|
// todo: packages/core should support getTextByVariable(variable)
|
|
54
|
-
const configKey = 'variables.' + (variable.
|
|
55
|
-
const valueToken = variable.
|
|
74
|
+
const configKey = 'variables.' + (variable.namespace ? variable.namespace + '.' + variable.key : variable.name);
|
|
75
|
+
const valueToken = variable.value ?? variable.name;
|
|
56
76
|
// detail is shown in the detail pane
|
|
57
77
|
// todo: variable.token should be recorded as original config variable
|
|
58
78
|
completionItem.detail = String(configKey);
|
|
@@ -64,115 +84,117 @@ function getValueCompletionItems(css = createCSS(), ruleKey) {
|
|
|
64
84
|
completionItem.sortText = 'color-' + variable.name.replace(/(.+?)-(\d+)/, (match, prefix, num)=>prefix + num.padStart(10, '0'));
|
|
65
85
|
}
|
|
66
86
|
} else if (variable.type === 'number') {
|
|
67
|
-
if (variable.name.startsWith('-') && eachNativePropertyData?.syntax?.includes('absolute')) return;
|
|
68
87
|
completionItem.detail = String(variable.name);
|
|
69
|
-
|
|
88
|
+
const value = getNumericSortValue(variable, css.settings.rootSize);
|
|
89
|
+
const sortValue = negative ? -Math.abs(value) : value;
|
|
90
|
+
completionItem.sortText = (variable.namespace || '') + (sortValue >= 0 ? String(sortValue).padStart(10, '0') : '-' + String(Math.abs(sortValue)).padStart(10, '0'));
|
|
70
91
|
} else {
|
|
71
92
|
completionItem.detail = String(variable.value || variable.name);
|
|
72
93
|
}
|
|
73
94
|
return completionItem;
|
|
74
95
|
};
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (completionItem) {
|
|
86
|
-
completionItem.label = variableName;
|
|
87
|
-
completionItem.sortText = SCOPED_VARIABLE_PRIORITY + variableName;
|
|
88
|
-
completionItem.detail = '(scope) ' + completionItem.detail;
|
|
89
|
-
completionItems.push(completionItem);
|
|
90
|
-
}
|
|
91
|
-
});
|
|
96
|
+
const addScopedVariableCompletionItem = (variable, variableName)=>{
|
|
97
|
+
if (addedLabels.has(variableName)) return;
|
|
98
|
+
const completionItem = generateVariableCompletionItem(variable, {
|
|
99
|
+
scoped: true
|
|
100
|
+
});
|
|
101
|
+
if (completionItem) {
|
|
102
|
+
completionItem.label = variableName;
|
|
103
|
+
completionItem.sortText = SCOPED_VARIABLE_PRIORITY + (completionItem.sortText || variableName);
|
|
104
|
+
completionItem.detail = '(scope) ' + completionItem.detail;
|
|
105
|
+
pushCompletionItem(completionItem);
|
|
92
106
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
].includes(eachDefinedRule.definition.type);
|
|
101
|
-
completionItems.push({
|
|
102
|
-
label: animationName,
|
|
103
|
-
kind: CompletionItemKind.Value,
|
|
104
|
-
documentation: getCSSDataDocumentation(undefined, {
|
|
105
|
-
generatedCSS: generateCSS([
|
|
106
|
-
ruleKey + ':' + animationName
|
|
107
|
-
], css),
|
|
108
|
-
docs: '/reference/' + isCoreRule(eachDefinedRule.id) && eachDefinedRule.id
|
|
109
|
-
}),
|
|
110
|
-
detail: isNative ? eachDefinedRule.id + ': ' + animationName : animationName
|
|
111
|
-
});
|
|
107
|
+
const negativeVariableName = '-' + variableName;
|
|
108
|
+
if (valuePrefix.startsWith('-') && variableName[0] !== '-' && variable.type === 'number' && !addedLabels.has(negativeVariableName)) {
|
|
109
|
+
const negativeCompletionItem = generateVariableCompletionItem(variable, {
|
|
110
|
+
appliedValue: negativeVariableName,
|
|
111
|
+
label: negativeVariableName,
|
|
112
|
+
negative: true,
|
|
113
|
+
scoped: true
|
|
112
114
|
});
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
* @example t: -> center, left, right, justify
|
|
118
|
-
*/ if (eachDefinedRule.definition.aliasGroups?.includes(ruleKey) && eachDefinedRule.definition.values?.length) {
|
|
119
|
-
const nativePropertyData = nativeProperties.find((x)=>x.name === eachDefinedRule.id);
|
|
120
|
-
for (const value of eachDefinedRule.definition.values){
|
|
121
|
-
if (typeof value !== 'string') continue;
|
|
122
|
-
const nativeValueData = nativePropertyData?.values?.find((x)=>x.name === value);
|
|
123
|
-
const isNative = eachDefinedRule.definition.type && [
|
|
124
|
-
SyntaxRuleType.Native,
|
|
125
|
-
SyntaxRuleType.NativeShorthand
|
|
126
|
-
].includes(eachDefinedRule.definition.type);
|
|
127
|
-
completionItems.push({
|
|
128
|
-
label: value,
|
|
129
|
-
kind: CompletionItemKind.Value,
|
|
130
|
-
sortText: AMBIGUOUS_PRIORITY + value,
|
|
131
|
-
documentation: getCSSDataDocumentation({
|
|
132
|
-
...nativeValueData || {},
|
|
133
|
-
// use nativePropertyData.reference because nativeValueData does not have references
|
|
134
|
-
references: nativePropertyData?.references
|
|
135
|
-
}, {
|
|
136
|
-
generatedCSS: generateCSS([
|
|
137
|
-
ruleKey + ':' + value
|
|
138
|
-
], css),
|
|
139
|
-
docs: '/reference/' + isCoreRule(eachDefinedRule.id) && eachDefinedRule.id
|
|
140
|
-
}),
|
|
141
|
-
detail: isNative ? eachDefinedRule.id + ': ' + value : value
|
|
142
|
-
});
|
|
115
|
+
if (negativeCompletionItem) {
|
|
116
|
+
negativeCompletionItem.sortText = SCOPED_VARIABLE_PRIORITY + (negativeCompletionItem.sortText || negativeVariableName);
|
|
117
|
+
negativeCompletionItem.detail = '(scope) ' + negativeCompletionItem.detail;
|
|
118
|
+
pushCompletionItem(negativeCompletionItem);
|
|
143
119
|
}
|
|
144
120
|
}
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Scoped variables
|
|
124
|
+
* @example box: + content -> box-sizing:content
|
|
125
|
+
*/ for (const { name, variable } of completionIndex.scopedVariablesByKey.get(canonicalRuleKey) || []){
|
|
126
|
+
addScopedVariableCompletionItem(variable, name);
|
|
127
|
+
}
|
|
128
|
+
for (const { value } of completionIndex.patternValuesByKey.get(canonicalRuleKey) || []){
|
|
129
|
+
if (addedLabels.has(value)) continue;
|
|
130
|
+
pushCompletionItem({
|
|
131
|
+
label: value,
|
|
132
|
+
kind: CompletionItemKind.Value,
|
|
133
|
+
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
134
|
+
ruleKey + ':' + value
|
|
135
|
+
], css)),
|
|
136
|
+
detail: canonicalRuleKey + ': ' + value
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* @example animation:fade|fast animate:fade animation-name:fade
|
|
141
|
+
*/ for (const animationUtility of completionIndex.animationUtilitiesByKey.get(canonicalRuleKey) || []){
|
|
142
|
+
css.animations.forEach((_, animationName)=>{
|
|
143
|
+
pushCompletionItem({
|
|
144
|
+
label: animationName,
|
|
145
|
+
kind: CompletionItemKind.Value,
|
|
146
|
+
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
147
|
+
ruleKey + ':' + animationName
|
|
148
|
+
], css)),
|
|
149
|
+
detail: animationUtility.detailPrefix ? animationUtility.detailPrefix + ': ' + animationName : animationName
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (ANIMATION_REFERENCE_PROPERTIES.has(canonicalRuleKey)) {
|
|
154
|
+
css.animations.forEach((_, animationName)=>{
|
|
155
|
+
if (addedLabels.has(animationName)) return;
|
|
156
|
+
pushCompletionItem({
|
|
157
|
+
label: animationName,
|
|
158
|
+
kind: CompletionItemKind.Value,
|
|
159
|
+
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
160
|
+
ruleKey + ':' + animationName
|
|
161
|
+
], css)),
|
|
162
|
+
detail: canonicalRuleKey + ': ' + animationName
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
const usedKeys = new Set();
|
|
167
|
+
for (const variableNamespace of completionIndex.nativeVariableNamespacesByProperty.get(canonicalRuleKey) || []){
|
|
168
|
+
for (const variable of completionIndex.variables){
|
|
169
|
+
const variableName = getVariableKeyByNamespace(variable.name, variableNamespace);
|
|
170
|
+
if (variableName === undefined || usedKeys.has(variableName)) continue;
|
|
171
|
+
usedKeys.add(variableName);
|
|
172
|
+
addScopedVariableCompletionItem(variable, variableName);
|
|
173
|
+
}
|
|
145
174
|
}
|
|
146
175
|
/**
|
|
147
176
|
* Native values
|
|
148
177
|
*/ if (nativeKey) {
|
|
149
|
-
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
label: value
|
|
178
|
+
nativePropertyValues.forEach((value)=>{
|
|
179
|
+
if (addedLabels.has(value) || nativeKey === 'font' && typeof +value === 'number' || value.includes(' ')) return;
|
|
180
|
+
pushCompletionItem({
|
|
181
|
+
label: value,
|
|
153
182
|
kind: CompletionItemKind.Value,
|
|
154
|
-
sortText: NATIVE_PRIORITY + (value.
|
|
155
|
-
documentation:
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}, {
|
|
160
|
-
generatedCSS: generateCSS([
|
|
161
|
-
ruleKey + ':' + value.name
|
|
162
|
-
], css),
|
|
163
|
-
docs: '/reference/' + nativeKey
|
|
164
|
-
}),
|
|
165
|
-
detail: nativeKey + ': ' + value.name
|
|
183
|
+
sortText: NATIVE_PRIORITY + (value.startsWith('-') ? 'zz' + value.slice(1) : value),
|
|
184
|
+
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
185
|
+
ruleKey + ':' + value
|
|
186
|
+
], css)),
|
|
187
|
+
detail: nativeKey + ': ' + value
|
|
166
188
|
});
|
|
167
189
|
});
|
|
168
190
|
}
|
|
169
191
|
// global variables
|
|
170
|
-
|
|
192
|
+
completionIndex.variables.forEach((variable)=>{
|
|
171
193
|
const completionItem = generateVariableCompletionItem(variable);
|
|
172
194
|
if (completionItem) {
|
|
173
195
|
completionItem.sortText = GLOBAL_VARIABLE_PRIORITY + (completionItem.sortText || completionItem.label);
|
|
174
196
|
completionItem.detail = '(global) ' + completionItem.detail;
|
|
175
|
-
|
|
197
|
+
pushCompletionItem(completionItem);
|
|
176
198
|
}
|
|
177
199
|
});
|
|
178
200
|
return sortCompletionItems(completionItems);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { type CompletionItem } from 'vscode-languageserver-protocol';
|
|
2
|
-
import { MasterCSS } from '@master/css';
|
|
3
|
-
|
|
2
|
+
import { MasterCSS } from '@master/css-language';
|
|
3
|
+
import { type CompletionIndex } from './completion-index';
|
|
4
|
+
export default function querySyntaxCompletions(q?: string, css?: MasterCSS, completionIndex?: CompletionIndex): CompletionItem[] | undefined;
|