@master/css-language-service 2.0.0-rc.73 → 2.0.0-rc.74
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/LICENSE +21 -0
- package/dist/common.d.ts +2 -1
- package/dist/common.js +2 -0
- package/dist/core.d.ts +35 -32
- package/dist/core.js +107 -0
- package/dist/features/edit-syntax-colors.d.ts +8 -4
- package/dist/features/edit-syntax-colors.js +16 -0
- package/dist/features/inspect-syntax.d.ts +8 -4
- package/dist/features/inspect-syntax.js +37 -0
- package/dist/features/render-semantic-tokens.d.ts +9 -5
- package/dist/features/render-semantic-tokens.js +10 -0
- package/dist/features/render-syntax-colors.d.ts +8 -4
- package/dist/features/render-syntax-colors.js +93 -0
- package/dist/features/suggest-syntax.d.ts +9 -5
- package/dist/features/suggest-syntax.js +11 -0
- package/dist/index.d.ts +8 -7
- package/dist/index.js +8 -0
- package/dist/settings.d.ts +14 -11
- package/dist/settings.js +58 -0
- package/dist/utils/beautify-css.d.ts +4 -1
- package/dist/utils/beautify-css.js +10 -0
- package/dist/utils/completion-index.d.ts +37 -34
- package/dist/utils/completion-index.js +196 -0
- package/dist/utils/convert-color-token.d.ts +8 -4
- package/dist/utils/convert-color-token.js +47 -0
- package/dist/utils/create-css-markdown-documentation.d.ts +7 -4
- package/dist/utils/create-css-markdown-documentation.js +13 -0
- package/dist/utils/create-doc.d.ts +19 -15
- package/dist/utils/create-doc.js +21 -0
- package/dist/utils/get-class-completion-items.d.ts +8 -4
- package/dist/utils/get-class-completion-items.js +15 -0
- package/dist/utils/get-color-completion-items.d.ts +7 -3
- package/dist/utils/get-color-completion-items.js +22 -0
- package/dist/utils/get-position.d.ts +4 -1
- package/dist/utils/get-position.js +9 -0
- package/dist/utils/get-pseudo-class-completion-items.d.ts +8 -4
- package/dist/utils/get-pseudo-class-completion-items.js +64 -0
- package/dist/utils/get-pseudo-element-completion-items.d.ts +8 -4
- package/dist/utils/get-pseudo-element-completion-items.js +39 -0
- package/dist/utils/get-query-completion-items.d.ts +8 -4
- package/dist/utils/get-query-completion-items.js +62 -0
- package/dist/utils/get-range.d.ts +6 -2
- package/dist/utils/get-range.js +21 -0
- package/dist/utils/get-utility-info.d.ts +7 -3
- package/dist/utils/get-utility-info.js +16 -0
- package/dist/utils/get-value-completion-items.d.ts +8 -4
- package/dist/utils/get-value-completion-items.js +161 -0
- package/dist/utils/query-syntax-completions.d.ts +8 -4
- package/dist/utils/query-syntax-completions.js +78 -0
- package/dist/utils/regex.d.ts +4 -1
- package/dist/utils/{regex.mjs → regex.js} +2 -1
- package/dist/utils/sort-completion-items.d.ts +6 -2
- package/dist/utils/sort-completion-items.js +10 -0
- package/package.json +61 -1
- package/dist/common.mjs +0 -1
- package/dist/core.mjs +0 -116
- package/dist/features/edit-syntax-colors.mjs +0 -17
- package/dist/features/inspect-syntax.mjs +0 -54
- package/dist/features/render-semantic-tokens.mjs +0 -10
- package/dist/features/render-syntax-colors.mjs +0 -101
- package/dist/features/suggest-syntax.mjs +0 -18
- package/dist/index.mjs +0 -7
- package/dist/settings.mjs +0 -53
- package/dist/utils/beautify-css.mjs +0 -11
- package/dist/utils/completion-index.mjs +0 -269
- package/dist/utils/convert-color-token.mjs +0 -55
- package/dist/utils/create-css-markdown-documentation.mjs +0 -15
- package/dist/utils/create-doc.mjs +0 -21
- package/dist/utils/get-class-completion-items.mjs +0 -19
- package/dist/utils/get-color-completion-items.mjs +0 -24
- package/dist/utils/get-position.mjs +0 -10
- package/dist/utils/get-pseudo-class-completion-items.mjs +0 -68
- package/dist/utils/get-pseudo-element-completion-items.mjs +0 -43
- package/dist/utils/get-query-completion-items.mjs +0 -77
- package/dist/utils/get-range.mjs +0 -21
- package/dist/utils/get-utility-info.mjs +0 -19
- package/dist/utils/get-value-completion-items.mjs +0 -202
- package/dist/utils/query-syntax-completions.mjs +0 -94
- package/dist/utils/sort-completion-items.mjs +0 -11
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { generateCSS, createDefaultCSS } from '@master/css-language';
|
|
2
|
-
import { CompletionItemKind } from 'vscode-languageserver-protocol';
|
|
3
|
-
import sortCompletionItems from './sort-completion-items.mjs';
|
|
4
|
-
import createCSSMarkdownDocumentation from './create-css-markdown-documentation.mjs';
|
|
5
|
-
import { createCompletionIndex } from './completion-index.mjs';
|
|
6
|
-
|
|
7
|
-
const kind = CompletionItemKind.Function;
|
|
8
|
-
const functionalPseudoClassNames = new Set([
|
|
9
|
-
':current',
|
|
10
|
-
':dir',
|
|
11
|
-
':has',
|
|
12
|
-
':has-slotted',
|
|
13
|
-
':host',
|
|
14
|
-
':host-context',
|
|
15
|
-
':is',
|
|
16
|
-
':lang',
|
|
17
|
-
':local-link',
|
|
18
|
-
':not',
|
|
19
|
-
':nth',
|
|
20
|
-
':nth-child',
|
|
21
|
-
':nth-col',
|
|
22
|
-
':nth-last',
|
|
23
|
-
':nth-last-child',
|
|
24
|
-
':nth-last-col',
|
|
25
|
-
':nth-last-of-type',
|
|
26
|
-
':nth-of-type',
|
|
27
|
-
':of',
|
|
28
|
-
':state',
|
|
29
|
-
':where'
|
|
30
|
-
]);
|
|
31
|
-
function normalizeFunctionalPseudoClass(name) {
|
|
32
|
-
return functionalPseudoClassNames.has(name) ? name + '()' : name;
|
|
33
|
-
}
|
|
34
|
-
function getPseudoClassCompletionItems(css = createDefaultCSS(), syntax, completionIndex = createCompletionIndex(css)) {
|
|
35
|
-
const completionItems = completionIndex.pseudoClassNames.map((pseudoClassName)=>{
|
|
36
|
-
const name = normalizeFunctionalPseudoClass(pseudoClassName);
|
|
37
|
-
let sortText = name.startsWith(':-') ? 'yyyy' + name.slice(2) : 'yy' + name.replace(/^:/, '');
|
|
38
|
-
if (sortText.endsWith('()')) sortText = 'y' + sortText;
|
|
39
|
-
return {
|
|
40
|
-
label: name,
|
|
41
|
-
sortText,
|
|
42
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
43
|
-
syntax + name.slice(1)
|
|
44
|
-
], css, completionIndex.runtime)),
|
|
45
|
-
kind
|
|
46
|
-
};
|
|
47
|
-
});
|
|
48
|
-
for (const { token: name, selector } of completionIndex.pseudoClassSelectors){
|
|
49
|
-
if (name.startsWith('::')) continue;
|
|
50
|
-
const value = selector.replace(/&/g, '');
|
|
51
|
-
const label = normalizeFunctionalPseudoClass(name);
|
|
52
|
-
let sortText = label.startsWith(':-') ? 'yyyy' + label.slice(2) : 'yy' + label.replace(/^:/, '');
|
|
53
|
-
if (sortText.endsWith('()')) sortText = 'y' + sortText;
|
|
54
|
-
const completionItem = {
|
|
55
|
-
label,
|
|
56
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
57
|
-
syntax + label.slice(1)
|
|
58
|
-
], css, completionIndex.runtime)),
|
|
59
|
-
sortText,
|
|
60
|
-
kind,
|
|
61
|
-
detail: String(value)
|
|
62
|
-
};
|
|
63
|
-
completionItems.push(completionItem);
|
|
64
|
-
}
|
|
65
|
-
return sortCompletionItems(completionItems);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export { getPseudoClassCompletionItems as default };
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { generateCSS, createDefaultCSS } from '@master/css-language';
|
|
2
|
-
import { CompletionItemKind } from 'vscode-languageserver-protocol';
|
|
3
|
-
import sortCompletionItems from './sort-completion-items.mjs';
|
|
4
|
-
import createCSSMarkdownDocumentation from './create-css-markdown-documentation.mjs';
|
|
5
|
-
import { createCompletionIndex } from './completion-index.mjs';
|
|
6
|
-
|
|
7
|
-
const kind = CompletionItemKind.Function;
|
|
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;
|
|
11
|
-
let sortText = name.startsWith('::-') ? 'zzzz' + name.slice(3) : 'zz' + name.replace(/^::/, '');
|
|
12
|
-
if (sortText.endsWith('()')) sortText = 'z' + sortText;
|
|
13
|
-
return {
|
|
14
|
-
label: name,
|
|
15
|
-
sortText,
|
|
16
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
17
|
-
syntax + name.slice(2)
|
|
18
|
-
], css, completionIndex.runtime)),
|
|
19
|
-
kind
|
|
20
|
-
};
|
|
21
|
-
});
|
|
22
|
-
for (const variant of completionIndex.pseudoElementSelectors){
|
|
23
|
-
const selectorName = variant.token;
|
|
24
|
-
const selectorValue = variant.selector.replace(/&/g, '');
|
|
25
|
-
const name = selectorName.endsWith('(') ? selectorName + ')' : selectorName;
|
|
26
|
-
const value = typeof selectorValue === 'string' ? selectorValue.endsWith('(') ? selectorValue + ')' : selectorValue : selectorValue;
|
|
27
|
-
let sortText = name.startsWith('::-') ? 'zzzz' + name.slice(3) : 'zz' + name.replace(/^::/, '');
|
|
28
|
-
if (sortText.endsWith('()')) sortText = 'z' + sortText;
|
|
29
|
-
const completionItem = {
|
|
30
|
-
label: name,
|
|
31
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
32
|
-
syntax + name.slice(2)
|
|
33
|
-
], css, completionIndex.runtime)),
|
|
34
|
-
sortText,
|
|
35
|
-
kind,
|
|
36
|
-
detail: String(value)
|
|
37
|
-
};
|
|
38
|
-
completionItems.push(completionItem);
|
|
39
|
-
}
|
|
40
|
-
return sortCompletionItems(completionItems);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export { getPseudoElementCompletionItems as default };
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { AT_SIGN, QUERY_COMPARISON_OPERATORS, generateCSS, QUERY_LOGICAL_OPERATORS, generateAt, parseAt, createDefaultCSS, getSingleAtNumberRuleNode } from '@master/css-language';
|
|
2
|
-
import { CompletionItemKind } from 'vscode-languageserver-protocol';
|
|
3
|
-
import sortCompletionItems from './sort-completion-items.mjs';
|
|
4
|
-
import createCSSMarkdownDocumentation from './create-css-markdown-documentation.mjs';
|
|
5
|
-
import { createCompletionIndex } from './completion-index.mjs';
|
|
6
|
-
|
|
7
|
-
function getQueryCompletionItems(css = createDefaultCSS(), triggerCharacter = AT_SIGN, syntax, completionIndex = createCompletionIndex(css)) {
|
|
8
|
-
const completionItems = [];
|
|
9
|
-
if (!QUERY_COMPARISON_OPERATORS.includes(triggerCharacter)) {
|
|
10
|
-
[
|
|
11
|
-
'media',
|
|
12
|
-
'container',
|
|
13
|
-
'supports'
|
|
14
|
-
].forEach((name)=>{
|
|
15
|
-
completionItems.push({
|
|
16
|
-
label: triggerCharacter + name + '()',
|
|
17
|
-
filterText: name + '()',
|
|
18
|
-
insertText: name + '()',
|
|
19
|
-
sortText: name + '()',
|
|
20
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
21
|
-
syntax + name + '()'
|
|
22
|
-
], css, completionIndex.runtime))
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
const handleNumberNodes = (atRule, token)=>{
|
|
27
|
-
const numberNode = getSingleAtNumberRuleNode(atRule.nodes);
|
|
28
|
-
if (numberNode) {
|
|
29
|
-
const prevComparisonCharacter = syntax.charAt(syntax.length - 2);
|
|
30
|
-
const comparisonCharacter = prevComparisonCharacter === '>' || prevComparisonCharacter === '<' ? prevComparisonCharacter + triggerCharacter : triggerCharacter;
|
|
31
|
-
const text = generateAt(parseAt(comparisonCharacter + token, css));
|
|
32
|
-
completionItems.push({
|
|
33
|
-
label: comparisonCharacter + token,
|
|
34
|
-
sortText: CompletionItemKind.Keyword + comparisonCharacter + String(Math.round(numberNode.value)).padStart(12, '0'),
|
|
35
|
-
filterText: token,
|
|
36
|
-
insertText: token,
|
|
37
|
-
detail: text,
|
|
38
|
-
kind: CompletionItemKind.Keyword,
|
|
39
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
40
|
-
syntax + token
|
|
41
|
-
], css, completionIndex.runtime))
|
|
42
|
-
});
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
for (const [token, atRule] of completionIndex.atRules){
|
|
47
|
-
const completionItem = {
|
|
48
|
-
filterText: token,
|
|
49
|
-
insertText: token,
|
|
50
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
51
|
-
syntax + token
|
|
52
|
-
], css, completionIndex.runtime))
|
|
53
|
-
};
|
|
54
|
-
if ([
|
|
55
|
-
AT_SIGN,
|
|
56
|
-
...QUERY_LOGICAL_OPERATORS
|
|
57
|
-
].includes(triggerCharacter)) {
|
|
58
|
-
if (handleNumberNodes(atRule, token)) continue;
|
|
59
|
-
const text = generateAt(parseAt(triggerCharacter + token, css));
|
|
60
|
-
completionItems.push({
|
|
61
|
-
...completionItem,
|
|
62
|
-
label: triggerCharacter + token,
|
|
63
|
-
detail: text,
|
|
64
|
-
sortText: CompletionItemKind.Keyword + token,
|
|
65
|
-
kind: CompletionItemKind.Keyword,
|
|
66
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
67
|
-
syntax + token
|
|
68
|
-
], css, completionIndex.runtime))
|
|
69
|
-
});
|
|
70
|
-
} else if (QUERY_COMPARISON_OPERATORS.includes(triggerCharacter)) {
|
|
71
|
-
handleNumberNodes(atRule, token);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return sortCompletionItems(completionItems);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export { getQueryCompletionItems as default };
|
package/dist/utils/get-range.mjs
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
function getRange(searchString, doc) {
|
|
2
|
-
const text = doc.getText();
|
|
3
|
-
const regex = new RegExp(`(\\b(?:className|class)\\s*=\\s*(['"\`]))(.*?)\\2`, 'gs');
|
|
4
|
-
let match;
|
|
5
|
-
while((match = regex.exec(text)) !== null){
|
|
6
|
-
match[0];
|
|
7
|
-
const attrStartIndex = match.index + match[1].length;
|
|
8
|
-
const className = match[3];
|
|
9
|
-
const relativeIndex = className.indexOf(searchString);
|
|
10
|
-
if (relativeIndex !== -1) {
|
|
11
|
-
const absoluteIndex = attrStartIndex + relativeIndex;
|
|
12
|
-
return {
|
|
13
|
-
start: doc.positionAt(absoluteIndex),
|
|
14
|
-
end: doc.positionAt(absoluteIndex + searchString.length)
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
throw new Error(`Cannot find "${searchString}" in any class attribute.`);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export { getRange as default };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { getStaticUtilityDeclarations } from '@master/css-language';
|
|
2
|
-
|
|
3
|
-
function getUtilityInfo(utility) {
|
|
4
|
-
const declarations = getStaticUtilityDeclarations(utility);
|
|
5
|
-
const propsLength = Object.keys(declarations || {}).length;
|
|
6
|
-
const propName = Object.keys(declarations || {})[0];
|
|
7
|
-
const propValue = declarations?.[propName];
|
|
8
|
-
let detail;
|
|
9
|
-
/**
|
|
10
|
-
* Remaps to native CSS properties when only one property is declared
|
|
11
|
-
* */ if (propsLength === 1) {
|
|
12
|
-
detail = `${propName}: ${propValue}`;
|
|
13
|
-
}
|
|
14
|
-
return {
|
|
15
|
-
detail
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export { getUtilityInfo as default };
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import { CompletionItemKind } from 'vscode-languageserver-protocol';
|
|
2
|
-
import { getMdnPropertySyntax, getMdnPropertyValueNames, generateCSS, createDefaultCSS } from '@master/css-language';
|
|
3
|
-
import createCSSMarkdownDocumentation from './create-css-markdown-documentation.mjs';
|
|
4
|
-
import sortCompletionItems from './sort-completion-items.mjs';
|
|
5
|
-
import { createCompletionIndex } from './completion-index.mjs';
|
|
6
|
-
|
|
7
|
-
const SCOPED_VARIABLE_PRIORITY = 'aaaa';
|
|
8
|
-
const NATIVE_PRIORITY = 'ccccc';
|
|
9
|
-
const GLOBAL_VARIABLE_PRIORITY = 'zzzz';
|
|
10
|
-
const ANIMATION_REFERENCE_PROPERTIES = new Set([
|
|
11
|
-
'animation',
|
|
12
|
-
'animation-name'
|
|
13
|
-
]);
|
|
14
|
-
function getNumericSortValue(variable, rootSize) {
|
|
15
|
-
if (variable.numeric) {
|
|
16
|
-
switch(variable.numeric.unit){
|
|
17
|
-
case 'rem':
|
|
18
|
-
return variable.numeric.value * rootSize;
|
|
19
|
-
case undefined:
|
|
20
|
-
case '':
|
|
21
|
-
case 'px':
|
|
22
|
-
return variable.numeric.value;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
return typeof variable.value === 'number' ? variable.value : 0;
|
|
26
|
-
}
|
|
27
|
-
function getVariableKeyByNamespace(variableName, namespace) {
|
|
28
|
-
const negative = variableName.startsWith('-');
|
|
29
|
-
const positiveName = negative ? variableName.slice(1) : variableName;
|
|
30
|
-
if (positiveName !== namespace && !positiveName.startsWith(namespace + '-')) return;
|
|
31
|
-
const key = positiveName === namespace ? '' : positiveName.slice(namespace.length + 1);
|
|
32
|
-
return negative ? '-' + key : key;
|
|
33
|
-
}
|
|
34
|
-
function getValueCompletionItems(css = createDefaultCSS(), ruleKey, valuePrefix = '', completionIndex = createCompletionIndex(css)) {
|
|
35
|
-
const completionItems = [];
|
|
36
|
-
const addedLabels = new Set();
|
|
37
|
-
const canonicalRuleKey = completionIndex.keyAliases[ruleKey] || ruleKey;
|
|
38
|
-
const nativeUtilityKey = completionIndex.nativeUtilityKeys.get(canonicalRuleKey);
|
|
39
|
-
const nativeKey = nativeUtilityKey || (getMdnPropertySyntax(canonicalRuleKey) ? canonicalRuleKey : undefined);
|
|
40
|
-
const nativePropertyValues = getMdnPropertyValueNames(nativeKey);
|
|
41
|
-
const pushCompletionItem = (completionItem)=>{
|
|
42
|
-
completionItems.push(completionItem);
|
|
43
|
-
addedLabels.add(completionItem.label);
|
|
44
|
-
};
|
|
45
|
-
const generateVariableCompletionItem = (variable, { appliedValue, label, negative, scoped } = {})=>{
|
|
46
|
-
const nativePropertySyntax = getMdnPropertySyntax(variable.namespace) || getMdnPropertySyntax(nativeKey);
|
|
47
|
-
if (variable.type === 'number' && variable.name.startsWith('-') && nativePropertySyntax?.includes('absolute')) return;
|
|
48
|
-
const valueToken = appliedValue ?? (scoped ? variable.key : variable.name);
|
|
49
|
-
const documentation = createCSSMarkdownDocumentation(generateCSS([
|
|
50
|
-
ruleKey + ':' + valueToken
|
|
51
|
-
], css, completionIndex.runtime));
|
|
52
|
-
const completionItemLabel = label ?? variable.name;
|
|
53
|
-
const conflicted = addedLabels.has(completionItemLabel);
|
|
54
|
-
const completionItem = {
|
|
55
|
-
label: conflicted ? 'var(--' + completionItemLabel + ')' : completionItemLabel,
|
|
56
|
-
kind: CompletionItemKind.Value
|
|
57
|
-
};
|
|
58
|
-
if (conflicted) {
|
|
59
|
-
completionItem.documentation = createCSSMarkdownDocumentation(generateCSS([
|
|
60
|
-
ruleKey + ':' + completionItem.label
|
|
61
|
-
], css, completionIndex.runtime));
|
|
62
|
-
} else {
|
|
63
|
-
completionItem.documentation = createCSSMarkdownDocumentation(generateCSS([
|
|
64
|
-
ruleKey + ':' + valueToken
|
|
65
|
-
], css, completionIndex.runtime));
|
|
66
|
-
}
|
|
67
|
-
if (variable.namespace?.startsWith('color')) {
|
|
68
|
-
if (Object.keys(variable.modes || {}).length) {
|
|
69
|
-
completionItem.kind = CompletionItemKind.Color;
|
|
70
|
-
completionItem.detail = variable.name;
|
|
71
|
-
} else {
|
|
72
|
-
// todo: packages/core should support getTextByVariable(variable)
|
|
73
|
-
const configKey = 'variables.' + (variable.namespace ? variable.namespace + '.' + variable.key : variable.name);
|
|
74
|
-
const valueToken = variable.value ?? variable.name;
|
|
75
|
-
// detail is shown in the detail pane
|
|
76
|
-
// todo: variable.token should be recorded as original config variable
|
|
77
|
-
completionItem.detail = String(configKey);
|
|
78
|
-
completionItem.documentation = {
|
|
79
|
-
kind: 'markdown',
|
|
80
|
-
value: valueToken + '\n\n' + documentation?.value
|
|
81
|
-
};
|
|
82
|
-
completionItem.kind = CompletionItemKind.Color;
|
|
83
|
-
completionItem.sortText = 'color-' + variable.name.replace(/(.+?)-(\d+)/, (match, prefix, num)=>prefix + num.padStart(10, '0'));
|
|
84
|
-
}
|
|
85
|
-
} else if (variable.type === 'number') {
|
|
86
|
-
completionItem.detail = String(variable.name);
|
|
87
|
-
const value = getNumericSortValue(variable, css.settings.rootSize);
|
|
88
|
-
const sortValue = negative ? -Math.abs(value) : value;
|
|
89
|
-
completionItem.sortText = (variable.namespace || '') + (sortValue >= 0 ? String(sortValue).padStart(10, '0') : '-' + String(Math.abs(sortValue)).padStart(10, '0'));
|
|
90
|
-
} else {
|
|
91
|
-
completionItem.detail = String(variable.value || variable.name);
|
|
92
|
-
}
|
|
93
|
-
return completionItem;
|
|
94
|
-
};
|
|
95
|
-
const addScopedVariableCompletionItem = (variable, variableName)=>{
|
|
96
|
-
if (addedLabels.has(variableName)) return;
|
|
97
|
-
const completionItem = generateVariableCompletionItem(variable, {
|
|
98
|
-
scoped: true
|
|
99
|
-
});
|
|
100
|
-
if (completionItem) {
|
|
101
|
-
completionItem.label = variableName;
|
|
102
|
-
completionItem.sortText = SCOPED_VARIABLE_PRIORITY + (completionItem.sortText || variableName);
|
|
103
|
-
completionItem.detail = '(scope) ' + completionItem.detail;
|
|
104
|
-
pushCompletionItem(completionItem);
|
|
105
|
-
}
|
|
106
|
-
const negativeVariableName = '-' + variableName;
|
|
107
|
-
if (valuePrefix.startsWith('-') && variableName[0] !== '-' && variable.type === 'number' && !addedLabels.has(negativeVariableName)) {
|
|
108
|
-
const negativeCompletionItem = generateVariableCompletionItem(variable, {
|
|
109
|
-
appliedValue: negativeVariableName,
|
|
110
|
-
label: negativeVariableName,
|
|
111
|
-
negative: true,
|
|
112
|
-
scoped: true
|
|
113
|
-
});
|
|
114
|
-
if (negativeCompletionItem) {
|
|
115
|
-
negativeCompletionItem.sortText = SCOPED_VARIABLE_PRIORITY + (negativeCompletionItem.sortText || negativeVariableName);
|
|
116
|
-
negativeCompletionItem.detail = '(scope) ' + negativeCompletionItem.detail;
|
|
117
|
-
pushCompletionItem(negativeCompletionItem);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
/**
|
|
122
|
-
* Scoped variables
|
|
123
|
-
* @example box: + content -> box-sizing:content
|
|
124
|
-
*/ for (const { name, variable } of completionIndex.scopedVariablesByKey.get(canonicalRuleKey) || []){
|
|
125
|
-
addScopedVariableCompletionItem(variable, name);
|
|
126
|
-
}
|
|
127
|
-
for (const { value } of completionIndex.patternValuesByKey.get(canonicalRuleKey) || []){
|
|
128
|
-
if (addedLabels.has(value)) continue;
|
|
129
|
-
pushCompletionItem({
|
|
130
|
-
label: value,
|
|
131
|
-
kind: CompletionItemKind.Value,
|
|
132
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
133
|
-
ruleKey + ':' + value
|
|
134
|
-
], css, completionIndex.runtime)),
|
|
135
|
-
detail: canonicalRuleKey + ': ' + value
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* @example animation:fade|fast animate:fade animation-name:fade
|
|
140
|
-
*/ for (const animationUtility of completionIndex.animationUtilitiesByKey.get(canonicalRuleKey) || []){
|
|
141
|
-
css.animations.forEach((_, animationName)=>{
|
|
142
|
-
pushCompletionItem({
|
|
143
|
-
label: animationName,
|
|
144
|
-
kind: CompletionItemKind.Value,
|
|
145
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
146
|
-
ruleKey + ':' + animationName
|
|
147
|
-
], css, completionIndex.runtime)),
|
|
148
|
-
detail: animationUtility.detailPrefix ? animationUtility.detailPrefix + ': ' + animationName : animationName
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
if (ANIMATION_REFERENCE_PROPERTIES.has(canonicalRuleKey)) {
|
|
153
|
-
css.animations.forEach((_, animationName)=>{
|
|
154
|
-
if (addedLabels.has(animationName)) return;
|
|
155
|
-
pushCompletionItem({
|
|
156
|
-
label: animationName,
|
|
157
|
-
kind: CompletionItemKind.Value,
|
|
158
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
159
|
-
ruleKey + ':' + animationName
|
|
160
|
-
], css, completionIndex.runtime)),
|
|
161
|
-
detail: canonicalRuleKey + ': ' + animationName
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
const usedKeys = new Set();
|
|
166
|
-
for (const variableNamespace of completionIndex.nativeVariableNamespacesByProperty.get(canonicalRuleKey) || []){
|
|
167
|
-
for (const variable of completionIndex.variables){
|
|
168
|
-
const variableName = getVariableKeyByNamespace(variable.name, variableNamespace);
|
|
169
|
-
if (variableName === undefined || usedKeys.has(variableName)) continue;
|
|
170
|
-
usedKeys.add(variableName);
|
|
171
|
-
addScopedVariableCompletionItem(variable, variableName);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Native values
|
|
176
|
-
*/ if (nativeKey) {
|
|
177
|
-
nativePropertyValues.forEach((value)=>{
|
|
178
|
-
if (addedLabels.has(value) || nativeKey === 'font' && typeof +value === 'number' || value.includes(' ')) return;
|
|
179
|
-
pushCompletionItem({
|
|
180
|
-
label: value,
|
|
181
|
-
kind: CompletionItemKind.Value,
|
|
182
|
-
sortText: NATIVE_PRIORITY + (value.startsWith('-') ? 'zz' + value.slice(1) : value),
|
|
183
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
184
|
-
ruleKey + ':' + value
|
|
185
|
-
], css, completionIndex.runtime)),
|
|
186
|
-
detail: nativeKey + ': ' + value
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
// global variables
|
|
191
|
-
completionIndex.variables.forEach((variable)=>{
|
|
192
|
-
const completionItem = generateVariableCompletionItem(variable);
|
|
193
|
-
if (completionItem) {
|
|
194
|
-
completionItem.sortText = GLOBAL_VARIABLE_PRIORITY + (completionItem.sortText || completionItem.label);
|
|
195
|
-
completionItem.detail = '(global) ' + completionItem.detail;
|
|
196
|
-
pushCompletionItem(completionItem);
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
return sortCompletionItems(completionItems);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
export { getValueCompletionItems as default };
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { CompletionItemKind } from 'vscode-languageserver-protocol';
|
|
2
|
-
import getPseudoClassCompletionItems from './get-pseudo-class-completion-items.mjs';
|
|
3
|
-
import getPseudoElementCompletionItems from './get-pseudo-element-completion-items.mjs';
|
|
4
|
-
import { GROUP_TRIGGER_CHARACTER, AT_SIGN, SELECTOR_SIGNS, QUERY_COMPARISON_OPERATORS, QUERY_LOGICAL_OPERATORS, SELECTOR_TRIGGER_CHARACTERS, generateCSS, createDefaultCSS } from '@master/css-language';
|
|
5
|
-
import getClassCompletionItems from './get-class-completion-items.mjs';
|
|
6
|
-
import getValueCompletionItems from './get-value-completion-items.mjs';
|
|
7
|
-
import getQueryCompletionItems from './get-query-completion-items.mjs';
|
|
8
|
-
import createCSSMarkdownDocumentation from './create-css-markdown-documentation.mjs';
|
|
9
|
-
import { matchesIndexedName, createCompletionIndex } from './completion-index.mjs';
|
|
10
|
-
|
|
11
|
-
function querySyntaxCompletions(q = '', css = createDefaultCSS(), completionIndex = createCompletionIndex(css)) {
|
|
12
|
-
const fields = q.split(' ');
|
|
13
|
-
let field = fields[fields.length - 1];
|
|
14
|
-
const triggerCharacter = q.charAt(q.length - 1);
|
|
15
|
-
const invoked = triggerCharacter === ' ' || field.length === 0;
|
|
16
|
-
if (invoked || field === GROUP_TRIGGER_CHARACTER || triggerCharacter === ';') {
|
|
17
|
-
return getClassCompletionItems(css, completionIndex);
|
|
18
|
-
}
|
|
19
|
-
const isGroup = field.startsWith(GROUP_TRIGGER_CHARACTER);
|
|
20
|
-
if (isGroup) {
|
|
21
|
-
const declarationSeparatorMatches = Array.from(field.matchAll(/;(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/g));
|
|
22
|
-
if (declarationSeparatorMatches.length) {
|
|
23
|
-
field = field.slice(declarationSeparatorMatches[declarationSeparatorMatches.length - 1].index + 1);
|
|
24
|
-
} else {
|
|
25
|
-
field = field.slice(1);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
if (field.startsWith(AT_SIGN) || field.startsWith('~')) {
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
const keyMatch = field.match(/^[^'":\s]+:/);
|
|
32
|
-
const atMatches = Array.from(field.matchAll(/@(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/g));
|
|
33
|
-
const valueSeparatorMatch = field.match(/\|(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/g);
|
|
34
|
-
const atInvoked = atMatches.findIndex(({ index })=>index !== 0) !== -1;
|
|
35
|
-
const firstColonIndex = keyMatch ? keyMatch[0].length - 1 : -1;
|
|
36
|
-
const selectorInvokedRegex = new RegExp(`[${SELECTOR_SIGNS.join('')}](?=(?:[^'"]|'[^']*'|"[^"]*")*$)`);
|
|
37
|
-
const key = keyMatch ? keyMatch[0].slice(0, firstColonIndex) : undefined;
|
|
38
|
-
const isStyle = completionIndex.componentNames.some((eachStyleName)=>matchesIndexedName(field, eachStyleName));
|
|
39
|
-
const isUtility = completionIndex.utilityNames.some((eachUtilityName)=>matchesIndexedName(field, eachUtilityName));
|
|
40
|
-
// check by utilities and components
|
|
41
|
-
if (!isStyle && !isUtility) {
|
|
42
|
-
if (key === undefined && !valueSeparatorMatch) {
|
|
43
|
-
return getClassCompletionItems(css, completionIndex);
|
|
44
|
-
}
|
|
45
|
-
if (!atInvoked && !selectorInvokedRegex.test(field.slice(firstColonIndex + 1))) {
|
|
46
|
-
if (key && firstColonIndex !== -1) {
|
|
47
|
-
return getValueCompletionItems(css, key, field.slice(firstColonIndex + 1), completionIndex);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Not support conditional btn:hover and group
|
|
53
|
-
*/ if (isStyle || isGroup) return;
|
|
54
|
-
if (atInvoked && [
|
|
55
|
-
AT_SIGN,
|
|
56
|
-
...QUERY_COMPARISON_OPERATORS,
|
|
57
|
-
...QUERY_LOGICAL_OPERATORS
|
|
58
|
-
].includes(triggerCharacter)) {
|
|
59
|
-
return getQueryCompletionItems(css, triggerCharacter, field, completionIndex);
|
|
60
|
-
}
|
|
61
|
-
if (!atInvoked && SELECTOR_TRIGGER_CHARACTERS.includes(triggerCharacter)) {
|
|
62
|
-
const pseudoElementCompletionItems = getPseudoElementCompletionItems(css, field, completionIndex);
|
|
63
|
-
if (field.endsWith('::')) {
|
|
64
|
-
/**
|
|
65
|
-
* Consider trigger characters and fix insertText.
|
|
66
|
-
* @incorrect class="text-center::" -> class="text-center::::after"
|
|
67
|
-
* @correct class="text-center::" -> class="text-center::after"
|
|
68
|
-
*/ pseudoElementCompletionItems.forEach((completionItem)=>completionItem.insertText = completionItem.label.slice(2));
|
|
69
|
-
return pseudoElementCompletionItems;
|
|
70
|
-
} else {
|
|
71
|
-
const completionItems = getPseudoClassCompletionItems(css, field, completionIndex);
|
|
72
|
-
completionItems.push(...pseudoElementCompletionItems);
|
|
73
|
-
/**
|
|
74
|
-
* Consider trigger characters and fix insertText.
|
|
75
|
-
* @incorrect class="text-center:" -> class="text-center::active"
|
|
76
|
-
* @correct class="text-center:" -> class="text-center:active"
|
|
77
|
-
*/ if (triggerCharacter === ':') {
|
|
78
|
-
completionItems.forEach((completionItem)=>completionItem.insertText = completionItem.label.slice(1));
|
|
79
|
-
} else {
|
|
80
|
-
completionItems.push({
|
|
81
|
-
label: '.<class>',
|
|
82
|
-
insertText: '.',
|
|
83
|
-
documentation: createCSSMarkdownDocumentation(generateCSS([
|
|
84
|
-
field + '.class'
|
|
85
|
-
], css, completionIndex.runtime)),
|
|
86
|
-
kind: CompletionItemKind.Class
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
return completionItems;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export { querySyntaxCompletions as default };
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/* localeCompare equals to the real vscode completion items sorting */ function sortCompletionItems(items) {
|
|
2
|
-
return items.sort((a, b)=>{
|
|
3
|
-
const sortTextA = a.sortText || a.label;
|
|
4
|
-
const sortTextB = b.sortText || b.label;
|
|
5
|
-
return sortTextA.localeCompare(sortTextB, undefined, {
|
|
6
|
-
numeric: true
|
|
7
|
-
});
|
|
8
|
-
});
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export { sortCompletionItems as default };
|