vscode-css-languageservice 5.4.2 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/lib/esm/cssLanguageService.d.ts +37 -37
  3. package/lib/esm/cssLanguageService.js +72 -75
  4. package/lib/esm/cssLanguageTypes.d.ts +238 -238
  5. package/lib/esm/cssLanguageTypes.js +42 -42
  6. package/lib/esm/data/webCustomData.js +21965 -21965
  7. package/lib/esm/languageFacts/builtinData.js +142 -142
  8. package/lib/esm/languageFacts/colors.js +469 -472
  9. package/lib/esm/languageFacts/dataManager.js +88 -92
  10. package/lib/esm/languageFacts/dataProvider.js +73 -79
  11. package/lib/esm/languageFacts/entry.js +137 -138
  12. package/lib/esm/languageFacts/facts.js +8 -8
  13. package/lib/esm/parser/cssErrors.js +48 -50
  14. package/lib/esm/parser/cssNodes.js +1502 -2019
  15. package/lib/esm/parser/cssParser.js +1534 -1563
  16. package/lib/esm/parser/cssScanner.js +592 -599
  17. package/lib/esm/parser/cssSymbolScope.js +311 -341
  18. package/lib/esm/parser/lessParser.js +714 -740
  19. package/lib/esm/parser/lessScanner.js +57 -78
  20. package/lib/esm/parser/scssErrors.js +18 -20
  21. package/lib/esm/parser/scssParser.js +796 -818
  22. package/lib/esm/parser/scssScanner.js +95 -116
  23. package/lib/esm/services/cssCodeActions.js +77 -81
  24. package/lib/esm/services/cssCompletion.js +1054 -1149
  25. package/lib/esm/services/cssFolding.js +190 -193
  26. package/lib/esm/services/cssFormatter.js +136 -136
  27. package/lib/esm/services/cssHover.js +148 -151
  28. package/lib/esm/services/cssNavigation.js +378 -470
  29. package/lib/esm/services/cssSelectionRange.js +47 -47
  30. package/lib/esm/services/cssValidation.js +41 -44
  31. package/lib/esm/services/lessCompletion.js +378 -397
  32. package/lib/esm/services/lint.js +518 -532
  33. package/lib/esm/services/lintRules.js +76 -83
  34. package/lib/esm/services/lintUtil.js +196 -205
  35. package/lib/esm/services/pathCompletion.js +157 -231
  36. package/lib/esm/services/scssCompletion.js +354 -378
  37. package/lib/esm/services/scssNavigation.js +82 -154
  38. package/lib/esm/services/selectorPrinting.js +492 -536
  39. package/lib/esm/utils/arrays.js +40 -46
  40. package/lib/esm/utils/objects.js +11 -11
  41. package/lib/esm/utils/resources.js +11 -24
  42. package/lib/esm/utils/strings.js +102 -104
  43. package/lib/umd/cssLanguageService.d.ts +37 -37
  44. package/lib/umd/cssLanguageService.js +99 -102
  45. package/lib/umd/cssLanguageTypes.d.ts +238 -238
  46. package/lib/umd/cssLanguageTypes.js +89 -88
  47. package/lib/umd/data/webCustomData.js +21978 -21978
  48. package/lib/umd/languageFacts/builtinData.js +154 -154
  49. package/lib/umd/languageFacts/colors.js +492 -495
  50. package/lib/umd/languageFacts/dataManager.js +101 -104
  51. package/lib/umd/languageFacts/dataProvider.js +86 -91
  52. package/lib/umd/languageFacts/entry.js +152 -153
  53. package/lib/umd/languageFacts/facts.js +29 -29
  54. package/lib/umd/parser/cssErrors.js +61 -62
  55. package/lib/umd/parser/cssNodes.js +1587 -2034
  56. package/lib/umd/parser/cssParser.js +1547 -1575
  57. package/lib/umd/parser/cssScanner.js +606 -611
  58. package/lib/umd/parser/cssSymbolScope.js +328 -353
  59. package/lib/umd/parser/lessParser.js +727 -752
  60. package/lib/umd/parser/lessScanner.js +70 -90
  61. package/lib/umd/parser/scssErrors.js +31 -32
  62. package/lib/umd/parser/scssParser.js +809 -830
  63. package/lib/umd/parser/scssScanner.js +108 -128
  64. package/lib/umd/services/cssCodeActions.js +90 -93
  65. package/lib/umd/services/cssCompletion.js +1067 -1161
  66. package/lib/umd/services/cssFolding.js +203 -206
  67. package/lib/umd/services/cssFormatter.js +150 -150
  68. package/lib/umd/services/cssHover.js +161 -163
  69. package/lib/umd/services/cssNavigation.js +391 -482
  70. package/lib/umd/services/cssSelectionRange.js +60 -60
  71. package/lib/umd/services/cssValidation.js +54 -56
  72. package/lib/umd/services/lessCompletion.js +391 -409
  73. package/lib/umd/services/lint.js +531 -544
  74. package/lib/umd/services/lintRules.js +91 -95
  75. package/lib/umd/services/lintUtil.js +210 -218
  76. package/lib/umd/services/pathCompletion.js +171 -244
  77. package/lib/umd/services/scssCompletion.js +367 -390
  78. package/lib/umd/services/scssNavigation.js +95 -166
  79. package/lib/umd/services/selectorPrinting.js +510 -550
  80. package/lib/umd/utils/arrays.js +55 -61
  81. package/lib/umd/utils/objects.js +25 -25
  82. package/lib/umd/utils/resources.js +26 -39
  83. package/lib/umd/utils/strings.js +120 -122
  84. package/package.json +10 -10
@@ -1,378 +1,354 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Microsoft Corporation. All rights reserved.
3
- * Licensed under the MIT License. See License.txt in the project root for license information.
4
- *--------------------------------------------------------------------------------------------*/
5
- 'use strict';
6
- var __extends = (this && this.__extends) || (function () {
7
- var extendStatics = function (d, b) {
8
- extendStatics = Object.setPrototypeOf ||
9
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
10
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
11
- return extendStatics(d, b);
12
- };
13
- return function (d, b) {
14
- if (typeof b !== "function" && b !== null)
15
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
16
- extendStatics(d, b);
17
- function __() { this.constructor = d; }
18
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
19
- };
20
- })();
21
- import { CSSCompletion } from './cssCompletion';
22
- import * as nodes from '../parser/cssNodes';
23
- import { CompletionItemKind, TextEdit, InsertTextFormat } from '../cssLanguageTypes';
24
- import * as nls from 'vscode-nls';
25
- var localize = nls.loadMessageBundle();
26
- var SCSSCompletion = /** @class */ (function (_super) {
27
- __extends(SCSSCompletion, _super);
28
- function SCSSCompletion(lsServiceOptions, cssDataManager) {
29
- var _this = _super.call(this, '$', lsServiceOptions, cssDataManager) || this;
30
- addReferencesToDocumentation(SCSSCompletion.scssModuleLoaders);
31
- addReferencesToDocumentation(SCSSCompletion.scssModuleBuiltIns);
32
- return _this;
33
- }
34
- SCSSCompletion.prototype.isImportPathParent = function (type) {
35
- return type === nodes.NodeType.Forward
36
- || type === nodes.NodeType.Use
37
- || _super.prototype.isImportPathParent.call(this, type);
38
- };
39
- SCSSCompletion.prototype.getCompletionForImportPath = function (importPathNode, result) {
40
- var parentType = importPathNode.getParent().type;
41
- if (parentType === nodes.NodeType.Forward || parentType === nodes.NodeType.Use) {
42
- for (var _i = 0, _a = SCSSCompletion.scssModuleBuiltIns; _i < _a.length; _i++) {
43
- var p = _a[_i];
44
- var item = {
45
- label: p.label,
46
- documentation: p.documentation,
47
- textEdit: TextEdit.replace(this.getCompletionRange(importPathNode), "'".concat(p.label, "'")),
48
- kind: CompletionItemKind.Module
49
- };
50
- result.items.push(item);
51
- }
52
- }
53
- return _super.prototype.getCompletionForImportPath.call(this, importPathNode, result);
54
- };
55
- SCSSCompletion.prototype.createReplaceFunction = function () {
56
- var tabStopCounter = 1;
57
- return function (_match, p1) {
58
- return '\\' + p1 + ': ${' + tabStopCounter++ + ':' + (SCSSCompletion.variableDefaults[p1] || '') + '}';
59
- };
60
- };
61
- SCSSCompletion.prototype.createFunctionProposals = function (proposals, existingNode, sortToEnd, result) {
62
- for (var _i = 0, proposals_1 = proposals; _i < proposals_1.length; _i++) {
63
- var p = proposals_1[_i];
64
- var insertText = p.func.replace(/\[?(\$\w+)\]?/g, this.createReplaceFunction());
65
- var label = p.func.substr(0, p.func.indexOf('('));
66
- var item = {
67
- label: label,
68
- detail: p.func,
69
- documentation: p.desc,
70
- textEdit: TextEdit.replace(this.getCompletionRange(existingNode), insertText),
71
- insertTextFormat: InsertTextFormat.Snippet,
72
- kind: CompletionItemKind.Function
73
- };
74
- if (sortToEnd) {
75
- item.sortText = 'z';
76
- }
77
- result.items.push(item);
78
- }
79
- return result;
80
- };
81
- SCSSCompletion.prototype.getCompletionsForSelector = function (ruleSet, isNested, result) {
82
- this.createFunctionProposals(SCSSCompletion.selectorFuncs, null, true, result);
83
- return _super.prototype.getCompletionsForSelector.call(this, ruleSet, isNested, result);
84
- };
85
- SCSSCompletion.prototype.getTermProposals = function (entry, existingNode, result) {
86
- var functions = SCSSCompletion.builtInFuncs;
87
- if (entry) {
88
- functions = functions.filter(function (f) { return !f.type || !entry.restrictions || entry.restrictions.indexOf(f.type) !== -1; });
89
- }
90
- this.createFunctionProposals(functions, existingNode, true, result);
91
- return _super.prototype.getTermProposals.call(this, entry, existingNode, result);
92
- };
93
- SCSSCompletion.prototype.getColorProposals = function (entry, existingNode, result) {
94
- this.createFunctionProposals(SCSSCompletion.colorProposals, existingNode, false, result);
95
- return _super.prototype.getColorProposals.call(this, entry, existingNode, result);
96
- };
97
- SCSSCompletion.prototype.getCompletionsForDeclarationProperty = function (declaration, result) {
98
- this.getCompletionForAtDirectives(result);
99
- this.getCompletionsForSelector(null, true, result);
100
- return _super.prototype.getCompletionsForDeclarationProperty.call(this, declaration, result);
101
- };
102
- SCSSCompletion.prototype.getCompletionsForExtendsReference = function (_extendsRef, existingNode, result) {
103
- var symbols = this.getSymbolContext().findSymbolsAtOffset(this.offset, nodes.ReferenceType.Rule);
104
- for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) {
105
- var symbol = symbols_1[_i];
106
- var suggest = {
107
- label: symbol.name,
108
- textEdit: TextEdit.replace(this.getCompletionRange(existingNode), symbol.name),
109
- kind: CompletionItemKind.Function,
110
- };
111
- result.items.push(suggest);
112
- }
113
- return result;
114
- };
115
- SCSSCompletion.prototype.getCompletionForAtDirectives = function (result) {
116
- var _a;
117
- (_a = result.items).push.apply(_a, SCSSCompletion.scssAtDirectives);
118
- return result;
119
- };
120
- SCSSCompletion.prototype.getCompletionForTopLevel = function (result) {
121
- this.getCompletionForAtDirectives(result);
122
- this.getCompletionForModuleLoaders(result);
123
- _super.prototype.getCompletionForTopLevel.call(this, result);
124
- return result;
125
- };
126
- SCSSCompletion.prototype.getCompletionForModuleLoaders = function (result) {
127
- var _a;
128
- (_a = result.items).push.apply(_a, SCSSCompletion.scssModuleLoaders);
129
- return result;
130
- };
131
- SCSSCompletion.variableDefaults = {
132
- '$red': '1',
133
- '$green': '2',
134
- '$blue': '3',
135
- '$alpha': '1.0',
136
- '$color': '#000000',
137
- '$weight': '0.5',
138
- '$hue': '0',
139
- '$saturation': '0%',
140
- '$lightness': '0%',
141
- '$degrees': '0',
142
- '$amount': '0',
143
- '$string': '""',
144
- '$substring': '"s"',
145
- '$number': '0',
146
- '$limit': '1'
147
- };
148
- SCSSCompletion.colorProposals = [
149
- { func: 'red($color)', desc: localize('scss.builtin.red', 'Gets the red component of a color.') },
150
- { func: 'green($color)', desc: localize('scss.builtin.green', 'Gets the green component of a color.') },
151
- { func: 'blue($color)', desc: localize('scss.builtin.blue', 'Gets the blue component of a color.') },
152
- { func: 'mix($color, $color, [$weight])', desc: localize('scss.builtin.mix', 'Mixes two colors together.') },
153
- { func: 'hue($color)', desc: localize('scss.builtin.hue', 'Gets the hue component of a color.') },
154
- { func: 'saturation($color)', desc: localize('scss.builtin.saturation', 'Gets the saturation component of a color.') },
155
- { func: 'lightness($color)', desc: localize('scss.builtin.lightness', 'Gets the lightness component of a color.') },
156
- { func: 'adjust-hue($color, $degrees)', desc: localize('scss.builtin.adjust-hue', 'Changes the hue of a color.') },
157
- { func: 'lighten($color, $amount)', desc: localize('scss.builtin.lighten', 'Makes a color lighter.') },
158
- { func: 'darken($color, $amount)', desc: localize('scss.builtin.darken', 'Makes a color darker.') },
159
- { func: 'saturate($color, $amount)', desc: localize('scss.builtin.saturate', 'Makes a color more saturated.') },
160
- { func: 'desaturate($color, $amount)', desc: localize('scss.builtin.desaturate', 'Makes a color less saturated.') },
161
- { func: 'grayscale($color)', desc: localize('scss.builtin.grayscale', 'Converts a color to grayscale.') },
162
- { func: 'complement($color)', desc: localize('scss.builtin.complement', 'Returns the complement of a color.') },
163
- { func: 'invert($color)', desc: localize('scss.builtin.invert', 'Returns the inverse of a color.') },
164
- { func: 'alpha($color)', desc: localize('scss.builtin.alpha', 'Gets the opacity component of a color.') },
165
- { func: 'opacity($color)', desc: 'Gets the alpha component (opacity) of a color.' },
166
- { func: 'rgba($color, $alpha)', desc: localize('scss.builtin.rgba', 'Changes the alpha component for a color.') },
167
- { func: 'opacify($color, $amount)', desc: localize('scss.builtin.opacify', 'Makes a color more opaque.') },
168
- { func: 'fade-in($color, $amount)', desc: localize('scss.builtin.fade-in', 'Makes a color more opaque.') },
169
- { func: 'transparentize($color, $amount)', desc: localize('scss.builtin.transparentize', 'Makes a color more transparent.') },
170
- { func: 'fade-out($color, $amount)', desc: localize('scss.builtin.fade-out', 'Makes a color more transparent.') },
171
- { func: 'adjust-color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha])', desc: localize('scss.builtin.adjust-color', 'Increases or decreases one or more components of a color.') },
172
- { func: 'scale-color($color, [$red], [$green], [$blue], [$saturation], [$lightness], [$alpha])', desc: localize('scss.builtin.scale-color', 'Fluidly scales one or more properties of a color.') },
173
- { func: 'change-color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha])', desc: localize('scss.builtin.change-color', 'Changes one or more properties of a color.') },
174
- { func: 'ie-hex-str($color)', desc: localize('scss.builtin.ie-hex-str', 'Converts a color into the format understood by IE filters.') }
175
- ];
176
- SCSSCompletion.selectorFuncs = [
177
- { func: 'selector-nest($selectors…)', desc: localize('scss.builtin.selector-nest', 'Nests selector beneath one another like they would be nested in the stylesheet.') },
178
- { func: 'selector-append($selectors…)', desc: localize('scss.builtin.selector-append', 'Appends selectors to one another without spaces in between.') },
179
- { func: 'selector-extend($selector, $extendee, $extender)', desc: localize('scss.builtin.selector-extend', 'Extends $extendee with $extender within $selector.') },
180
- { func: 'selector-replace($selector, $original, $replacement)', desc: localize('scss.builtin.selector-replace', 'Replaces $original with $replacement within $selector.') },
181
- { func: 'selector-unify($selector1, $selector2)', desc: localize('scss.builtin.selector-unify', 'Unifies two selectors to produce a selector that matches elements matched by both.') },
182
- { func: 'is-superselector($super, $sub)', desc: localize('scss.builtin.is-superselector', 'Returns whether $super matches all the elements $sub does, and possibly more.') },
183
- { func: 'simple-selectors($selector)', desc: localize('scss.builtin.simple-selectors', 'Returns the simple selectors that comprise a compound selector.') },
184
- { func: 'selector-parse($selector)', desc: localize('scss.builtin.selector-parse', 'Parses a selector into the format returned by &.') }
185
- ];
186
- SCSSCompletion.builtInFuncs = [
187
- { func: 'unquote($string)', desc: localize('scss.builtin.unquote', 'Removes quotes from a string.') },
188
- { func: 'quote($string)', desc: localize('scss.builtin.quote', 'Adds quotes to a string.') },
189
- { func: 'str-length($string)', desc: localize('scss.builtin.str-length', 'Returns the number of characters in a string.') },
190
- { func: 'str-insert($string, $insert, $index)', desc: localize('scss.builtin.str-insert', 'Inserts $insert into $string at $index.') },
191
- { func: 'str-index($string, $substring)', desc: localize('scss.builtin.str-index', 'Returns the index of the first occurance of $substring in $string.') },
192
- { func: 'str-slice($string, $start-at, [$end-at])', desc: localize('scss.builtin.str-slice', 'Extracts a substring from $string.') },
193
- { func: 'to-upper-case($string)', desc: localize('scss.builtin.to-upper-case', 'Converts a string to upper case.') },
194
- { func: 'to-lower-case($string)', desc: localize('scss.builtin.to-lower-case', 'Converts a string to lower case.') },
195
- { func: 'percentage($number)', desc: localize('scss.builtin.percentage', 'Converts a unitless number to a percentage.'), type: 'percentage' },
196
- { func: 'round($number)', desc: localize('scss.builtin.round', 'Rounds a number to the nearest whole number.') },
197
- { func: 'ceil($number)', desc: localize('scss.builtin.ceil', 'Rounds a number up to the next whole number.') },
198
- { func: 'floor($number)', desc: localize('scss.builtin.floor', 'Rounds a number down to the previous whole number.') },
199
- { func: 'abs($number)', desc: localize('scss.builtin.abs', 'Returns the absolute value of a number.') },
200
- { func: 'min($numbers)', desc: localize('scss.builtin.min', 'Finds the minimum of several numbers.') },
201
- { func: 'max($numbers)', desc: localize('scss.builtin.max', 'Finds the maximum of several numbers.') },
202
- { func: 'random([$limit])', desc: localize('scss.builtin.random', 'Returns a random number.') },
203
- { func: 'length($list)', desc: localize('scss.builtin.length', 'Returns the length of a list.') },
204
- { func: 'nth($list, $n)', desc: localize('scss.builtin.nth', 'Returns a specific item in a list.') },
205
- { func: 'set-nth($list, $n, $value)', desc: localize('scss.builtin.set-nth', 'Replaces the nth item in a list.') },
206
- { func: 'join($list1, $list2, [$separator])', desc: localize('scss.builtin.join', 'Joins together two lists into one.') },
207
- { func: 'append($list1, $val, [$separator])', desc: localize('scss.builtin.append', 'Appends a single value onto the end of a list.') },
208
- { func: 'zip($lists)', desc: localize('scss.builtin.zip', 'Combines several lists into a single multidimensional list.') },
209
- { func: 'index($list, $value)', desc: localize('scss.builtin.index', 'Returns the position of a value within a list.') },
210
- { func: 'list-separator(#list)', desc: localize('scss.builtin.list-separator', 'Returns the separator of a list.') },
211
- { func: 'map-get($map, $key)', desc: localize('scss.builtin.map-get', 'Returns the value in a map associated with a given key.') },
212
- { func: 'map-merge($map1, $map2)', desc: localize('scss.builtin.map-merge', 'Merges two maps together into a new map.') },
213
- { func: 'map-remove($map, $keys)', desc: localize('scss.builtin.map-remove', 'Returns a new map with keys removed.') },
214
- { func: 'map-keys($map)', desc: localize('scss.builtin.map-keys', 'Returns a list of all keys in a map.') },
215
- { func: 'map-values($map)', desc: localize('scss.builtin.map-values', 'Returns a list of all values in a map.') },
216
- { func: 'map-has-key($map, $key)', desc: localize('scss.builtin.map-has-key', 'Returns whether a map has a value associated with a given key.') },
217
- { func: 'keywords($args)', desc: localize('scss.builtin.keywords', 'Returns the keywords passed to a function that takes variable arguments.') },
218
- { func: 'feature-exists($feature)', desc: localize('scss.builtin.feature-exists', 'Returns whether a feature exists in the current Sass runtime.') },
219
- { func: 'variable-exists($name)', desc: localize('scss.builtin.variable-exists', 'Returns whether a variable with the given name exists in the current scope.') },
220
- { func: 'global-variable-exists($name)', desc: localize('scss.builtin.global-variable-exists', 'Returns whether a variable with the given name exists in the global scope.') },
221
- { func: 'function-exists($name)', desc: localize('scss.builtin.function-exists', 'Returns whether a function with the given name exists.') },
222
- { func: 'mixin-exists($name)', desc: localize('scss.builtin.mixin-exists', 'Returns whether a mixin with the given name exists.') },
223
- { func: 'inspect($value)', desc: localize('scss.builtin.inspect', 'Returns the string representation of a value as it would be represented in Sass.') },
224
- { func: 'type-of($value)', desc: localize('scss.builtin.type-of', 'Returns the type of a value.') },
225
- { func: 'unit($number)', desc: localize('scss.builtin.unit', 'Returns the unit(s) associated with a number.') },
226
- { func: 'unitless($number)', desc: localize('scss.builtin.unitless', 'Returns whether a number has units.') },
227
- { func: 'comparable($number1, $number2)', desc: localize('scss.builtin.comparable', 'Returns whether two numbers can be added, subtracted, or compared.') },
228
- { func: 'call($name, $args…)', desc: localize('scss.builtin.call', 'Dynamically calls a Sass function.') }
229
- ];
230
- SCSSCompletion.scssAtDirectives = [
231
- {
232
- label: "@extend",
233
- documentation: localize("scss.builtin.@extend", "Inherits the styles of another selector."),
234
- kind: CompletionItemKind.Keyword
235
- },
236
- {
237
- label: "@at-root",
238
- documentation: localize("scss.builtin.@at-root", "Causes one or more rules to be emitted at the root of the document."),
239
- kind: CompletionItemKind.Keyword
240
- },
241
- {
242
- label: "@debug",
243
- documentation: localize("scss.builtin.@debug", "Prints the value of an expression to the standard error output stream. Useful for debugging complicated Sass files."),
244
- kind: CompletionItemKind.Keyword
245
- },
246
- {
247
- label: "@warn",
248
- documentation: localize("scss.builtin.@warn", "Prints the value of an expression to the standard error output stream. Useful for libraries that need to warn users of deprecations or recovering from minor mixin usage mistakes. Warnings can be turned off with the `--quiet` command-line option or the `:quiet` Sass option."),
249
- kind: CompletionItemKind.Keyword
250
- },
251
- {
252
- label: "@error",
253
- documentation: localize("scss.builtin.@error", "Throws the value of an expression as a fatal error with stack trace. Useful for validating arguments to mixins and functions."),
254
- kind: CompletionItemKind.Keyword
255
- },
256
- {
257
- label: "@if",
258
- documentation: localize("scss.builtin.@if", "Includes the body if the expression does not evaluate to `false` or `null`."),
259
- insertText: "@if ${1:expr} {\n\t$0\n}",
260
- insertTextFormat: InsertTextFormat.Snippet,
261
- kind: CompletionItemKind.Keyword
262
- },
263
- {
264
- label: "@for",
265
- documentation: localize("scss.builtin.@for", "For loop that repeatedly outputs a set of styles for each `$var` in the `from/through` or `from/to` clause."),
266
- insertText: "@for \\$${1:var} from ${2:start} ${3|to,through|} ${4:end} {\n\t$0\n}",
267
- insertTextFormat: InsertTextFormat.Snippet,
268
- kind: CompletionItemKind.Keyword
269
- },
270
- {
271
- label: "@each",
272
- documentation: localize("scss.builtin.@each", "Each loop that sets `$var` to each item in the list or map, then outputs the styles it contains using that value of `$var`."),
273
- insertText: "@each \\$${1:var} in ${2:list} {\n\t$0\n}",
274
- insertTextFormat: InsertTextFormat.Snippet,
275
- kind: CompletionItemKind.Keyword
276
- },
277
- {
278
- label: "@while",
279
- documentation: localize("scss.builtin.@while", "While loop that takes an expression and repeatedly outputs the nested styles until the statement evaluates to `false`."),
280
- insertText: "@while ${1:condition} {\n\t$0\n}",
281
- insertTextFormat: InsertTextFormat.Snippet,
282
- kind: CompletionItemKind.Keyword
283
- },
284
- {
285
- label: "@mixin",
286
- documentation: localize("scss.builtin.@mixin", "Defines styles that can be re-used throughout the stylesheet with `@include`."),
287
- insertText: "@mixin ${1:name} {\n\t$0\n}",
288
- insertTextFormat: InsertTextFormat.Snippet,
289
- kind: CompletionItemKind.Keyword
290
- },
291
- {
292
- label: "@include",
293
- documentation: localize("scss.builtin.@include", "Includes the styles defined by another mixin into the current rule."),
294
- kind: CompletionItemKind.Keyword
295
- },
296
- {
297
- label: "@function",
298
- documentation: localize("scss.builtin.@function", "Defines complex operations that can be re-used throughout stylesheets."),
299
- kind: CompletionItemKind.Keyword
300
- }
301
- ];
302
- SCSSCompletion.scssModuleLoaders = [
303
- {
304
- label: "@use",
305
- documentation: localize("scss.builtin.@use", "Loads mixins, functions, and variables from other Sass stylesheets as 'modules', and combines CSS from multiple stylesheets together."),
306
- references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/at-rules/use' }],
307
- insertText: "@use $0;",
308
- insertTextFormat: InsertTextFormat.Snippet,
309
- kind: CompletionItemKind.Keyword
310
- },
311
- {
312
- label: "@forward",
313
- documentation: localize("scss.builtin.@forward", "Loads a Sass stylesheet and makes its mixins, functions, and variables available when this stylesheet is loaded with the @use rule."),
314
- references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/at-rules/forward' }],
315
- insertText: "@forward $0;",
316
- insertTextFormat: InsertTextFormat.Snippet,
317
- kind: CompletionItemKind.Keyword
318
- },
319
- ];
320
- SCSSCompletion.scssModuleBuiltIns = [
321
- {
322
- label: 'sass:math',
323
- documentation: localize('scss.builtin.sass:math', 'Provides functions that operate on numbers.'),
324
- references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/math' }]
325
- },
326
- {
327
- label: 'sass:string',
328
- documentation: localize('scss.builtin.sass:string', 'Makes it easy to combine, search, or split apart strings.'),
329
- references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/string' }]
330
- },
331
- {
332
- label: 'sass:color',
333
- documentation: localize('scss.builtin.sass:color', 'Generates new colors based on existing ones, making it easy to build color themes.'),
334
- references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/color' }]
335
- },
336
- {
337
- label: 'sass:list',
338
- documentation: localize('scss.builtin.sass:list', 'Lets you access and modify values in lists.'),
339
- references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/list' }]
340
- },
341
- {
342
- label: 'sass:map',
343
- documentation: localize('scss.builtin.sass:map', 'Makes it possible to look up the value associated with a key in a map, and much more.'),
344
- references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/map' }]
345
- },
346
- {
347
- label: 'sass:selector',
348
- documentation: localize('scss.builtin.sass:selector', 'Provides access to Sass’s powerful selector engine.'),
349
- references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/selector' }]
350
- },
351
- {
352
- label: 'sass:meta',
353
- documentation: localize('scss.builtin.sass:meta', 'Exposes the details of Sass’s inner workings.'),
354
- references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/meta' }]
355
- },
356
- ];
357
- return SCSSCompletion;
358
- }(CSSCompletion));
359
- export { SCSSCompletion };
360
- /**
361
- * Todo @Pine: Remove this and do it through custom data
362
- */
363
- function addReferencesToDocumentation(items) {
364
- items.forEach(function (i) {
365
- if (i.documentation && i.references && i.references.length > 0) {
366
- var markdownDoc = typeof i.documentation === 'string'
367
- ? { kind: 'markdown', value: i.documentation }
368
- : { kind: 'markdown', value: i.documentation.value };
369
- markdownDoc.value += '\n\n';
370
- markdownDoc.value += i.references
371
- .map(function (r) {
372
- return "[".concat(r.name, "](").concat(r.url, ")");
373
- })
374
- .join(' | ');
375
- i.documentation = markdownDoc;
376
- }
377
- });
378
- }
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ 'use strict';
6
+ import { CSSCompletion } from './cssCompletion';
7
+ import * as nodes from '../parser/cssNodes';
8
+ import { CompletionItemKind, TextEdit, InsertTextFormat } from '../cssLanguageTypes';
9
+ import * as nls from 'vscode-nls';
10
+ const localize = nls.loadMessageBundle();
11
+ export class SCSSCompletion extends CSSCompletion {
12
+ constructor(lsServiceOptions, cssDataManager) {
13
+ super('$', lsServiceOptions, cssDataManager);
14
+ addReferencesToDocumentation(SCSSCompletion.scssModuleLoaders);
15
+ addReferencesToDocumentation(SCSSCompletion.scssModuleBuiltIns);
16
+ }
17
+ isImportPathParent(type) {
18
+ return type === nodes.NodeType.Forward
19
+ || type === nodes.NodeType.Use
20
+ || super.isImportPathParent(type);
21
+ }
22
+ getCompletionForImportPath(importPathNode, result) {
23
+ const parentType = importPathNode.getParent().type;
24
+ if (parentType === nodes.NodeType.Forward || parentType === nodes.NodeType.Use) {
25
+ for (let p of SCSSCompletion.scssModuleBuiltIns) {
26
+ const item = {
27
+ label: p.label,
28
+ documentation: p.documentation,
29
+ textEdit: TextEdit.replace(this.getCompletionRange(importPathNode), `'${p.label}'`),
30
+ kind: CompletionItemKind.Module
31
+ };
32
+ result.items.push(item);
33
+ }
34
+ }
35
+ return super.getCompletionForImportPath(importPathNode, result);
36
+ }
37
+ createReplaceFunction() {
38
+ let tabStopCounter = 1;
39
+ return (_match, p1) => {
40
+ return '\\' + p1 + ': ${' + tabStopCounter++ + ':' + (SCSSCompletion.variableDefaults[p1] || '') + '}';
41
+ };
42
+ }
43
+ createFunctionProposals(proposals, existingNode, sortToEnd, result) {
44
+ for (const p of proposals) {
45
+ const insertText = p.func.replace(/\[?(\$\w+)\]?/g, this.createReplaceFunction());
46
+ const label = p.func.substr(0, p.func.indexOf('('));
47
+ const item = {
48
+ label: label,
49
+ detail: p.func,
50
+ documentation: p.desc,
51
+ textEdit: TextEdit.replace(this.getCompletionRange(existingNode), insertText),
52
+ insertTextFormat: InsertTextFormat.Snippet,
53
+ kind: CompletionItemKind.Function
54
+ };
55
+ if (sortToEnd) {
56
+ item.sortText = 'z';
57
+ }
58
+ result.items.push(item);
59
+ }
60
+ return result;
61
+ }
62
+ getCompletionsForSelector(ruleSet, isNested, result) {
63
+ this.createFunctionProposals(SCSSCompletion.selectorFuncs, null, true, result);
64
+ return super.getCompletionsForSelector(ruleSet, isNested, result);
65
+ }
66
+ getTermProposals(entry, existingNode, result) {
67
+ let functions = SCSSCompletion.builtInFuncs;
68
+ if (entry) {
69
+ functions = functions.filter(f => !f.type || !entry.restrictions || entry.restrictions.indexOf(f.type) !== -1);
70
+ }
71
+ this.createFunctionProposals(functions, existingNode, true, result);
72
+ return super.getTermProposals(entry, existingNode, result);
73
+ }
74
+ getColorProposals(entry, existingNode, result) {
75
+ this.createFunctionProposals(SCSSCompletion.colorProposals, existingNode, false, result);
76
+ return super.getColorProposals(entry, existingNode, result);
77
+ }
78
+ getCompletionsForDeclarationProperty(declaration, result) {
79
+ this.getCompletionForAtDirectives(result);
80
+ this.getCompletionsForSelector(null, true, result);
81
+ return super.getCompletionsForDeclarationProperty(declaration, result);
82
+ }
83
+ getCompletionsForExtendsReference(_extendsRef, existingNode, result) {
84
+ const symbols = this.getSymbolContext().findSymbolsAtOffset(this.offset, nodes.ReferenceType.Rule);
85
+ for (const symbol of symbols) {
86
+ const suggest = {
87
+ label: symbol.name,
88
+ textEdit: TextEdit.replace(this.getCompletionRange(existingNode), symbol.name),
89
+ kind: CompletionItemKind.Function,
90
+ };
91
+ result.items.push(suggest);
92
+ }
93
+ return result;
94
+ }
95
+ getCompletionForAtDirectives(result) {
96
+ result.items.push(...SCSSCompletion.scssAtDirectives);
97
+ return result;
98
+ }
99
+ getCompletionForTopLevel(result) {
100
+ this.getCompletionForAtDirectives(result);
101
+ this.getCompletionForModuleLoaders(result);
102
+ super.getCompletionForTopLevel(result);
103
+ return result;
104
+ }
105
+ getCompletionForModuleLoaders(result) {
106
+ result.items.push(...SCSSCompletion.scssModuleLoaders);
107
+ return result;
108
+ }
109
+ }
110
+ SCSSCompletion.variableDefaults = {
111
+ '$red': '1',
112
+ '$green': '2',
113
+ '$blue': '3',
114
+ '$alpha': '1.0',
115
+ '$color': '#000000',
116
+ '$weight': '0.5',
117
+ '$hue': '0',
118
+ '$saturation': '0%',
119
+ '$lightness': '0%',
120
+ '$degrees': '0',
121
+ '$amount': '0',
122
+ '$string': '""',
123
+ '$substring': '"s"',
124
+ '$number': '0',
125
+ '$limit': '1'
126
+ };
127
+ SCSSCompletion.colorProposals = [
128
+ { func: 'red($color)', desc: localize('scss.builtin.red', 'Gets the red component of a color.') },
129
+ { func: 'green($color)', desc: localize('scss.builtin.green', 'Gets the green component of a color.') },
130
+ { func: 'blue($color)', desc: localize('scss.builtin.blue', 'Gets the blue component of a color.') },
131
+ { func: 'mix($color, $color, [$weight])', desc: localize('scss.builtin.mix', 'Mixes two colors together.') },
132
+ { func: 'hue($color)', desc: localize('scss.builtin.hue', 'Gets the hue component of a color.') },
133
+ { func: 'saturation($color)', desc: localize('scss.builtin.saturation', 'Gets the saturation component of a color.') },
134
+ { func: 'lightness($color)', desc: localize('scss.builtin.lightness', 'Gets the lightness component of a color.') },
135
+ { func: 'adjust-hue($color, $degrees)', desc: localize('scss.builtin.adjust-hue', 'Changes the hue of a color.') },
136
+ { func: 'lighten($color, $amount)', desc: localize('scss.builtin.lighten', 'Makes a color lighter.') },
137
+ { func: 'darken($color, $amount)', desc: localize('scss.builtin.darken', 'Makes a color darker.') },
138
+ { func: 'saturate($color, $amount)', desc: localize('scss.builtin.saturate', 'Makes a color more saturated.') },
139
+ { func: 'desaturate($color, $amount)', desc: localize('scss.builtin.desaturate', 'Makes a color less saturated.') },
140
+ { func: 'grayscale($color)', desc: localize('scss.builtin.grayscale', 'Converts a color to grayscale.') },
141
+ { func: 'complement($color)', desc: localize('scss.builtin.complement', 'Returns the complement of a color.') },
142
+ { func: 'invert($color)', desc: localize('scss.builtin.invert', 'Returns the inverse of a color.') },
143
+ { func: 'alpha($color)', desc: localize('scss.builtin.alpha', 'Gets the opacity component of a color.') },
144
+ { func: 'opacity($color)', desc: 'Gets the alpha component (opacity) of a color.' },
145
+ { func: 'rgba($color, $alpha)', desc: localize('scss.builtin.rgba', 'Changes the alpha component for a color.') },
146
+ { func: 'opacify($color, $amount)', desc: localize('scss.builtin.opacify', 'Makes a color more opaque.') },
147
+ { func: 'fade-in($color, $amount)', desc: localize('scss.builtin.fade-in', 'Makes a color more opaque.') },
148
+ { func: 'transparentize($color, $amount)', desc: localize('scss.builtin.transparentize', 'Makes a color more transparent.') },
149
+ { func: 'fade-out($color, $amount)', desc: localize('scss.builtin.fade-out', 'Makes a color more transparent.') },
150
+ { func: 'adjust-color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha])', desc: localize('scss.builtin.adjust-color', 'Increases or decreases one or more components of a color.') },
151
+ { func: 'scale-color($color, [$red], [$green], [$blue], [$saturation], [$lightness], [$alpha])', desc: localize('scss.builtin.scale-color', 'Fluidly scales one or more properties of a color.') },
152
+ { func: 'change-color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha])', desc: localize('scss.builtin.change-color', 'Changes one or more properties of a color.') },
153
+ { func: 'ie-hex-str($color)', desc: localize('scss.builtin.ie-hex-str', 'Converts a color into the format understood by IE filters.') }
154
+ ];
155
+ SCSSCompletion.selectorFuncs = [
156
+ { func: 'selector-nest($selectors…)', desc: localize('scss.builtin.selector-nest', 'Nests selector beneath one another like they would be nested in the stylesheet.') },
157
+ { func: 'selector-append($selectors…)', desc: localize('scss.builtin.selector-append', 'Appends selectors to one another without spaces in between.') },
158
+ { func: 'selector-extend($selector, $extendee, $extender)', desc: localize('scss.builtin.selector-extend', 'Extends $extendee with $extender within $selector.') },
159
+ { func: 'selector-replace($selector, $original, $replacement)', desc: localize('scss.builtin.selector-replace', 'Replaces $original with $replacement within $selector.') },
160
+ { func: 'selector-unify($selector1, $selector2)', desc: localize('scss.builtin.selector-unify', 'Unifies two selectors to produce a selector that matches elements matched by both.') },
161
+ { func: 'is-superselector($super, $sub)', desc: localize('scss.builtin.is-superselector', 'Returns whether $super matches all the elements $sub does, and possibly more.') },
162
+ { func: 'simple-selectors($selector)', desc: localize('scss.builtin.simple-selectors', 'Returns the simple selectors that comprise a compound selector.') },
163
+ { func: 'selector-parse($selector)', desc: localize('scss.builtin.selector-parse', 'Parses a selector into the format returned by &.') }
164
+ ];
165
+ SCSSCompletion.builtInFuncs = [
166
+ { func: 'unquote($string)', desc: localize('scss.builtin.unquote', 'Removes quotes from a string.') },
167
+ { func: 'quote($string)', desc: localize('scss.builtin.quote', 'Adds quotes to a string.') },
168
+ { func: 'str-length($string)', desc: localize('scss.builtin.str-length', 'Returns the number of characters in a string.') },
169
+ { func: 'str-insert($string, $insert, $index)', desc: localize('scss.builtin.str-insert', 'Inserts $insert into $string at $index.') },
170
+ { func: 'str-index($string, $substring)', desc: localize('scss.builtin.str-index', 'Returns the index of the first occurance of $substring in $string.') },
171
+ { func: 'str-slice($string, $start-at, [$end-at])', desc: localize('scss.builtin.str-slice', 'Extracts a substring from $string.') },
172
+ { func: 'to-upper-case($string)', desc: localize('scss.builtin.to-upper-case', 'Converts a string to upper case.') },
173
+ { func: 'to-lower-case($string)', desc: localize('scss.builtin.to-lower-case', 'Converts a string to lower case.') },
174
+ { func: 'percentage($number)', desc: localize('scss.builtin.percentage', 'Converts a unitless number to a percentage.'), type: 'percentage' },
175
+ { func: 'round($number)', desc: localize('scss.builtin.round', 'Rounds a number to the nearest whole number.') },
176
+ { func: 'ceil($number)', desc: localize('scss.builtin.ceil', 'Rounds a number up to the next whole number.') },
177
+ { func: 'floor($number)', desc: localize('scss.builtin.floor', 'Rounds a number down to the previous whole number.') },
178
+ { func: 'abs($number)', desc: localize('scss.builtin.abs', 'Returns the absolute value of a number.') },
179
+ { func: 'min($numbers)', desc: localize('scss.builtin.min', 'Finds the minimum of several numbers.') },
180
+ { func: 'max($numbers)', desc: localize('scss.builtin.max', 'Finds the maximum of several numbers.') },
181
+ { func: 'random([$limit])', desc: localize('scss.builtin.random', 'Returns a random number.') },
182
+ { func: 'length($list)', desc: localize('scss.builtin.length', 'Returns the length of a list.') },
183
+ { func: 'nth($list, $n)', desc: localize('scss.builtin.nth', 'Returns a specific item in a list.') },
184
+ { func: 'set-nth($list, $n, $value)', desc: localize('scss.builtin.set-nth', 'Replaces the nth item in a list.') },
185
+ { func: 'join($list1, $list2, [$separator])', desc: localize('scss.builtin.join', 'Joins together two lists into one.') },
186
+ { func: 'append($list1, $val, [$separator])', desc: localize('scss.builtin.append', 'Appends a single value onto the end of a list.') },
187
+ { func: 'zip($lists)', desc: localize('scss.builtin.zip', 'Combines several lists into a single multidimensional list.') },
188
+ { func: 'index($list, $value)', desc: localize('scss.builtin.index', 'Returns the position of a value within a list.') },
189
+ { func: 'list-separator(#list)', desc: localize('scss.builtin.list-separator', 'Returns the separator of a list.') },
190
+ { func: 'map-get($map, $key)', desc: localize('scss.builtin.map-get', 'Returns the value in a map associated with a given key.') },
191
+ { func: 'map-merge($map1, $map2)', desc: localize('scss.builtin.map-merge', 'Merges two maps together into a new map.') },
192
+ { func: 'map-remove($map, $keys)', desc: localize('scss.builtin.map-remove', 'Returns a new map with keys removed.') },
193
+ { func: 'map-keys($map)', desc: localize('scss.builtin.map-keys', 'Returns a list of all keys in a map.') },
194
+ { func: 'map-values($map)', desc: localize('scss.builtin.map-values', 'Returns a list of all values in a map.') },
195
+ { func: 'map-has-key($map, $key)', desc: localize('scss.builtin.map-has-key', 'Returns whether a map has a value associated with a given key.') },
196
+ { func: 'keywords($args)', desc: localize('scss.builtin.keywords', 'Returns the keywords passed to a function that takes variable arguments.') },
197
+ { func: 'feature-exists($feature)', desc: localize('scss.builtin.feature-exists', 'Returns whether a feature exists in the current Sass runtime.') },
198
+ { func: 'variable-exists($name)', desc: localize('scss.builtin.variable-exists', 'Returns whether a variable with the given name exists in the current scope.') },
199
+ { func: 'global-variable-exists($name)', desc: localize('scss.builtin.global-variable-exists', 'Returns whether a variable with the given name exists in the global scope.') },
200
+ { func: 'function-exists($name)', desc: localize('scss.builtin.function-exists', 'Returns whether a function with the given name exists.') },
201
+ { func: 'mixin-exists($name)', desc: localize('scss.builtin.mixin-exists', 'Returns whether a mixin with the given name exists.') },
202
+ { func: 'inspect($value)', desc: localize('scss.builtin.inspect', 'Returns the string representation of a value as it would be represented in Sass.') },
203
+ { func: 'type-of($value)', desc: localize('scss.builtin.type-of', 'Returns the type of a value.') },
204
+ { func: 'unit($number)', desc: localize('scss.builtin.unit', 'Returns the unit(s) associated with a number.') },
205
+ { func: 'unitless($number)', desc: localize('scss.builtin.unitless', 'Returns whether a number has units.') },
206
+ { func: 'comparable($number1, $number2)', desc: localize('scss.builtin.comparable', 'Returns whether two numbers can be added, subtracted, or compared.') },
207
+ { func: 'call($name, $args…)', desc: localize('scss.builtin.call', 'Dynamically calls a Sass function.') }
208
+ ];
209
+ SCSSCompletion.scssAtDirectives = [
210
+ {
211
+ label: "@extend",
212
+ documentation: localize("scss.builtin.@extend", "Inherits the styles of another selector."),
213
+ kind: CompletionItemKind.Keyword
214
+ },
215
+ {
216
+ label: "@at-root",
217
+ documentation: localize("scss.builtin.@at-root", "Causes one or more rules to be emitted at the root of the document."),
218
+ kind: CompletionItemKind.Keyword
219
+ },
220
+ {
221
+ label: "@debug",
222
+ documentation: localize("scss.builtin.@debug", "Prints the value of an expression to the standard error output stream. Useful for debugging complicated Sass files."),
223
+ kind: CompletionItemKind.Keyword
224
+ },
225
+ {
226
+ label: "@warn",
227
+ documentation: localize("scss.builtin.@warn", "Prints the value of an expression to the standard error output stream. Useful for libraries that need to warn users of deprecations or recovering from minor mixin usage mistakes. Warnings can be turned off with the `--quiet` command-line option or the `:quiet` Sass option."),
228
+ kind: CompletionItemKind.Keyword
229
+ },
230
+ {
231
+ label: "@error",
232
+ documentation: localize("scss.builtin.@error", "Throws the value of an expression as a fatal error with stack trace. Useful for validating arguments to mixins and functions."),
233
+ kind: CompletionItemKind.Keyword
234
+ },
235
+ {
236
+ label: "@if",
237
+ documentation: localize("scss.builtin.@if", "Includes the body if the expression does not evaluate to `false` or `null`."),
238
+ insertText: "@if ${1:expr} {\n\t$0\n}",
239
+ insertTextFormat: InsertTextFormat.Snippet,
240
+ kind: CompletionItemKind.Keyword
241
+ },
242
+ {
243
+ label: "@for",
244
+ documentation: localize("scss.builtin.@for", "For loop that repeatedly outputs a set of styles for each `$var` in the `from/through` or `from/to` clause."),
245
+ insertText: "@for \\$${1:var} from ${2:start} ${3|to,through|} ${4:end} {\n\t$0\n}",
246
+ insertTextFormat: InsertTextFormat.Snippet,
247
+ kind: CompletionItemKind.Keyword
248
+ },
249
+ {
250
+ label: "@each",
251
+ documentation: localize("scss.builtin.@each", "Each loop that sets `$var` to each item in the list or map, then outputs the styles it contains using that value of `$var`."),
252
+ insertText: "@each \\$${1:var} in ${2:list} {\n\t$0\n}",
253
+ insertTextFormat: InsertTextFormat.Snippet,
254
+ kind: CompletionItemKind.Keyword
255
+ },
256
+ {
257
+ label: "@while",
258
+ documentation: localize("scss.builtin.@while", "While loop that takes an expression and repeatedly outputs the nested styles until the statement evaluates to `false`."),
259
+ insertText: "@while ${1:condition} {\n\t$0\n}",
260
+ insertTextFormat: InsertTextFormat.Snippet,
261
+ kind: CompletionItemKind.Keyword
262
+ },
263
+ {
264
+ label: "@mixin",
265
+ documentation: localize("scss.builtin.@mixin", "Defines styles that can be re-used throughout the stylesheet with `@include`."),
266
+ insertText: "@mixin ${1:name} {\n\t$0\n}",
267
+ insertTextFormat: InsertTextFormat.Snippet,
268
+ kind: CompletionItemKind.Keyword
269
+ },
270
+ {
271
+ label: "@include",
272
+ documentation: localize("scss.builtin.@include", "Includes the styles defined by another mixin into the current rule."),
273
+ kind: CompletionItemKind.Keyword
274
+ },
275
+ {
276
+ label: "@function",
277
+ documentation: localize("scss.builtin.@function", "Defines complex operations that can be re-used throughout stylesheets."),
278
+ kind: CompletionItemKind.Keyword
279
+ }
280
+ ];
281
+ SCSSCompletion.scssModuleLoaders = [
282
+ {
283
+ label: "@use",
284
+ documentation: localize("scss.builtin.@use", "Loads mixins, functions, and variables from other Sass stylesheets as 'modules', and combines CSS from multiple stylesheets together."),
285
+ references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/at-rules/use' }],
286
+ insertText: "@use $0;",
287
+ insertTextFormat: InsertTextFormat.Snippet,
288
+ kind: CompletionItemKind.Keyword
289
+ },
290
+ {
291
+ label: "@forward",
292
+ documentation: localize("scss.builtin.@forward", "Loads a Sass stylesheet and makes its mixins, functions, and variables available when this stylesheet is loaded with the @use rule."),
293
+ references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/at-rules/forward' }],
294
+ insertText: "@forward $0;",
295
+ insertTextFormat: InsertTextFormat.Snippet,
296
+ kind: CompletionItemKind.Keyword
297
+ },
298
+ ];
299
+ SCSSCompletion.scssModuleBuiltIns = [
300
+ {
301
+ label: 'sass:math',
302
+ documentation: localize('scss.builtin.sass:math', 'Provides functions that operate on numbers.'),
303
+ references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/math' }]
304
+ },
305
+ {
306
+ label: 'sass:string',
307
+ documentation: localize('scss.builtin.sass:string', 'Makes it easy to combine, search, or split apart strings.'),
308
+ references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/string' }]
309
+ },
310
+ {
311
+ label: 'sass:color',
312
+ documentation: localize('scss.builtin.sass:color', 'Generates new colors based on existing ones, making it easy to build color themes.'),
313
+ references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/color' }]
314
+ },
315
+ {
316
+ label: 'sass:list',
317
+ documentation: localize('scss.builtin.sass:list', 'Lets you access and modify values in lists.'),
318
+ references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/list' }]
319
+ },
320
+ {
321
+ label: 'sass:map',
322
+ documentation: localize('scss.builtin.sass:map', 'Makes it possible to look up the value associated with a key in a map, and much more.'),
323
+ references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/map' }]
324
+ },
325
+ {
326
+ label: 'sass:selector',
327
+ documentation: localize('scss.builtin.sass:selector', 'Provides access to Sass’s powerful selector engine.'),
328
+ references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/selector' }]
329
+ },
330
+ {
331
+ label: 'sass:meta',
332
+ documentation: localize('scss.builtin.sass:meta', 'Exposes the details of Sass’s inner workings.'),
333
+ references: [{ name: 'Sass documentation', url: 'https://sass-lang.com/documentation/modules/meta' }]
334
+ },
335
+ ];
336
+ /**
337
+ * Todo @Pine: Remove this and do it through custom data
338
+ */
339
+ function addReferencesToDocumentation(items) {
340
+ items.forEach(i => {
341
+ if (i.documentation && i.references && i.references.length > 0) {
342
+ const markdownDoc = typeof i.documentation === 'string'
343
+ ? { kind: 'markdown', value: i.documentation }
344
+ : { kind: 'markdown', value: i.documentation.value };
345
+ markdownDoc.value += '\n\n';
346
+ markdownDoc.value += i.references
347
+ .map(r => {
348
+ return `[${r.name}](${r.url})`;
349
+ })
350
+ .join(' | ');
351
+ i.documentation = markdownDoc;
352
+ }
353
+ });
354
+ }