vscode-css-languageservice 5.3.0 → 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 (87) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +1 -0
  3. package/lib/esm/beautify/beautify-css.js +57 -15
  4. package/lib/esm/cssLanguageService.d.ts +37 -37
  5. package/lib/esm/cssLanguageService.js +72 -75
  6. package/lib/esm/cssLanguageTypes.d.ts +238 -228
  7. package/lib/esm/cssLanguageTypes.js +42 -42
  8. package/lib/esm/data/webCustomData.js +21965 -21959
  9. package/lib/esm/languageFacts/builtinData.js +142 -142
  10. package/lib/esm/languageFacts/colors.js +469 -472
  11. package/lib/esm/languageFacts/dataManager.js +88 -92
  12. package/lib/esm/languageFacts/dataProvider.js +73 -79
  13. package/lib/esm/languageFacts/entry.js +137 -138
  14. package/lib/esm/languageFacts/facts.js +8 -8
  15. package/lib/esm/parser/cssErrors.js +48 -50
  16. package/lib/esm/parser/cssNodes.js +1502 -2019
  17. package/lib/esm/parser/cssParser.js +1534 -1566
  18. package/lib/esm/parser/cssScanner.js +592 -599
  19. package/lib/esm/parser/cssSymbolScope.js +311 -341
  20. package/lib/esm/parser/lessParser.js +714 -740
  21. package/lib/esm/parser/lessScanner.js +57 -78
  22. package/lib/esm/parser/scssErrors.js +18 -20
  23. package/lib/esm/parser/scssParser.js +796 -818
  24. package/lib/esm/parser/scssScanner.js +95 -116
  25. package/lib/esm/services/cssCodeActions.js +77 -81
  26. package/lib/esm/services/cssCompletion.js +1054 -1149
  27. package/lib/esm/services/cssFolding.js +190 -193
  28. package/lib/esm/services/cssFormatter.js +136 -117
  29. package/lib/esm/services/cssHover.js +148 -151
  30. package/lib/esm/services/cssNavigation.js +378 -470
  31. package/lib/esm/services/cssSelectionRange.js +47 -47
  32. package/lib/esm/services/cssValidation.js +41 -44
  33. package/lib/esm/services/lessCompletion.js +378 -397
  34. package/lib/esm/services/lint.js +518 -532
  35. package/lib/esm/services/lintRules.js +76 -83
  36. package/lib/esm/services/lintUtil.js +196 -205
  37. package/lib/esm/services/pathCompletion.js +157 -231
  38. package/lib/esm/services/scssCompletion.js +354 -378
  39. package/lib/esm/services/scssNavigation.js +82 -154
  40. package/lib/esm/services/selectorPrinting.js +492 -536
  41. package/lib/esm/utils/arrays.js +40 -46
  42. package/lib/esm/utils/objects.js +11 -11
  43. package/lib/esm/utils/resources.js +11 -24
  44. package/lib/esm/utils/strings.js +102 -104
  45. package/lib/umd/beautify/beautify-css.js +57 -15
  46. package/lib/umd/cssLanguageService.d.ts +37 -37
  47. package/lib/umd/cssLanguageService.js +99 -102
  48. package/lib/umd/cssLanguageTypes.d.ts +238 -228
  49. package/lib/umd/cssLanguageTypes.js +89 -88
  50. package/lib/umd/data/webCustomData.js +21978 -21972
  51. package/lib/umd/languageFacts/builtinData.js +154 -154
  52. package/lib/umd/languageFacts/colors.js +492 -495
  53. package/lib/umd/languageFacts/dataManager.js +101 -104
  54. package/lib/umd/languageFacts/dataProvider.js +86 -91
  55. package/lib/umd/languageFacts/entry.js +152 -153
  56. package/lib/umd/languageFacts/facts.js +29 -29
  57. package/lib/umd/parser/cssErrors.js +61 -62
  58. package/lib/umd/parser/cssNodes.js +1587 -2034
  59. package/lib/umd/parser/cssParser.js +1547 -1578
  60. package/lib/umd/parser/cssScanner.js +606 -611
  61. package/lib/umd/parser/cssSymbolScope.js +328 -353
  62. package/lib/umd/parser/lessParser.js +727 -752
  63. package/lib/umd/parser/lessScanner.js +70 -90
  64. package/lib/umd/parser/scssErrors.js +31 -32
  65. package/lib/umd/parser/scssParser.js +809 -830
  66. package/lib/umd/parser/scssScanner.js +108 -128
  67. package/lib/umd/services/cssCodeActions.js +90 -93
  68. package/lib/umd/services/cssCompletion.js +1067 -1161
  69. package/lib/umd/services/cssFolding.js +203 -206
  70. package/lib/umd/services/cssFormatter.js +150 -131
  71. package/lib/umd/services/cssHover.js +161 -163
  72. package/lib/umd/services/cssNavigation.js +391 -482
  73. package/lib/umd/services/cssSelectionRange.js +60 -60
  74. package/lib/umd/services/cssValidation.js +54 -56
  75. package/lib/umd/services/lessCompletion.js +391 -409
  76. package/lib/umd/services/lint.js +531 -544
  77. package/lib/umd/services/lintRules.js +91 -95
  78. package/lib/umd/services/lintUtil.js +210 -218
  79. package/lib/umd/services/pathCompletion.js +171 -244
  80. package/lib/umd/services/scssCompletion.js +367 -390
  81. package/lib/umd/services/scssNavigation.js +95 -166
  82. package/lib/umd/services/selectorPrinting.js +510 -550
  83. package/lib/umd/utils/arrays.js +55 -61
  84. package/lib/umd/utils/objects.js +25 -25
  85. package/lib/umd/utils/resources.js +26 -39
  86. package/lib/umd/utils/strings.js +120 -122
  87. package/package.json +11 -11
@@ -1,244 +1,171 @@
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
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
- return new (P || (P = Promise))(function (resolve, reject) {
8
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
- step((generator = generator.apply(thisArg, _arguments || [])).next());
12
- });
13
- };
14
- var __generator = (this && this.__generator) || function (thisArg, body) {
15
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
16
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
17
- function verb(n) { return function (v) { return step([n, v]); }; }
18
- function step(op) {
19
- if (f) throw new TypeError("Generator is already executing.");
20
- while (_) try {
21
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
22
- if (y = 0, t) op = [op[0] & 2, t.value];
23
- switch (op[0]) {
24
- case 0: case 1: t = op; break;
25
- case 4: _.label++; return { value: op[1], done: false };
26
- case 5: _.label++; y = op[1]; op = [0]; continue;
27
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
28
- default:
29
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
30
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
31
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
32
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
33
- if (t[2]) _.ops.pop();
34
- _.trys.pop(); continue;
35
- }
36
- op = body.call(thisArg, _);
37
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
38
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
39
- }
40
- };
41
- (function (factory) {
42
- if (typeof module === "object" && typeof module.exports === "object") {
43
- var v = factory(require, exports);
44
- if (v !== undefined) module.exports = v;
45
- }
46
- else if (typeof define === "function" && define.amd) {
47
- define(["require", "exports", "../cssLanguageTypes", "../utils/strings", "../utils/resources"], factory);
48
- }
49
- })(function (require, exports) {
50
- "use strict";
51
- Object.defineProperty(exports, "__esModule", { value: true });
52
- exports.PathCompletionParticipant = void 0;
53
- var cssLanguageTypes_1 = require("../cssLanguageTypes");
54
- var strings_1 = require("../utils/strings");
55
- var resources_1 = require("../utils/resources");
56
- var PathCompletionParticipant = /** @class */ (function () {
57
- function PathCompletionParticipant(readDirectory) {
58
- this.readDirectory = readDirectory;
59
- this.literalCompletions = [];
60
- this.importCompletions = [];
61
- }
62
- PathCompletionParticipant.prototype.onCssURILiteralValue = function (context) {
63
- this.literalCompletions.push(context);
64
- };
65
- PathCompletionParticipant.prototype.onCssImportPath = function (context) {
66
- this.importCompletions.push(context);
67
- };
68
- PathCompletionParticipant.prototype.computeCompletions = function (document, documentContext) {
69
- return __awaiter(this, void 0, void 0, function () {
70
- var result, _i, _a, literalCompletion, uriValue, fullValue, items, _b, items_1, item, _c, _d, importCompletion, pathValue, fullValue, suggestions, _e, suggestions_1, item;
71
- return __generator(this, function (_f) {
72
- switch (_f.label) {
73
- case 0:
74
- result = { items: [], isIncomplete: false };
75
- _i = 0, _a = this.literalCompletions;
76
- _f.label = 1;
77
- case 1:
78
- if (!(_i < _a.length)) return [3 /*break*/, 5];
79
- literalCompletion = _a[_i];
80
- uriValue = literalCompletion.uriValue;
81
- fullValue = stripQuotes(uriValue);
82
- if (!(fullValue === '.' || fullValue === '..')) return [3 /*break*/, 2];
83
- result.isIncomplete = true;
84
- return [3 /*break*/, 4];
85
- case 2: return [4 /*yield*/, this.providePathSuggestions(uriValue, literalCompletion.position, literalCompletion.range, document, documentContext)];
86
- case 3:
87
- items = _f.sent();
88
- for (_b = 0, items_1 = items; _b < items_1.length; _b++) {
89
- item = items_1[_b];
90
- result.items.push(item);
91
- }
92
- _f.label = 4;
93
- case 4:
94
- _i++;
95
- return [3 /*break*/, 1];
96
- case 5:
97
- _c = 0, _d = this.importCompletions;
98
- _f.label = 6;
99
- case 6:
100
- if (!(_c < _d.length)) return [3 /*break*/, 10];
101
- importCompletion = _d[_c];
102
- pathValue = importCompletion.pathValue;
103
- fullValue = stripQuotes(pathValue);
104
- if (!(fullValue === '.' || fullValue === '..')) return [3 /*break*/, 7];
105
- result.isIncomplete = true;
106
- return [3 /*break*/, 9];
107
- case 7: return [4 /*yield*/, this.providePathSuggestions(pathValue, importCompletion.position, importCompletion.range, document, documentContext)];
108
- case 8:
109
- suggestions = _f.sent();
110
- if (document.languageId === 'scss') {
111
- suggestions.forEach(function (s) {
112
- if ((0, strings_1.startsWith)(s.label, '_') && (0, strings_1.endsWith)(s.label, '.scss')) {
113
- if (s.textEdit) {
114
- s.textEdit.newText = s.label.slice(1, -5);
115
- }
116
- else {
117
- s.label = s.label.slice(1, -5);
118
- }
119
- }
120
- });
121
- }
122
- for (_e = 0, suggestions_1 = suggestions; _e < suggestions_1.length; _e++) {
123
- item = suggestions_1[_e];
124
- result.items.push(item);
125
- }
126
- _f.label = 9;
127
- case 9:
128
- _c++;
129
- return [3 /*break*/, 6];
130
- case 10: return [2 /*return*/, result];
131
- }
132
- });
133
- });
134
- };
135
- PathCompletionParticipant.prototype.providePathSuggestions = function (pathValue, position, range, document, documentContext) {
136
- return __awaiter(this, void 0, void 0, function () {
137
- var fullValue, isValueQuoted, valueBeforeCursor, currentDocUri, fullValueRange, replaceRange, valueBeforeLastSlash, parentDir, result, infos, _i, infos_1, _a, name, type, e_1;
138
- return __generator(this, function (_b) {
139
- switch (_b.label) {
140
- case 0:
141
- fullValue = stripQuotes(pathValue);
142
- isValueQuoted = (0, strings_1.startsWith)(pathValue, "'") || (0, strings_1.startsWith)(pathValue, "\"");
143
- valueBeforeCursor = isValueQuoted
144
- ? fullValue.slice(0, position.character - (range.start.character + 1))
145
- : fullValue.slice(0, position.character - range.start.character);
146
- currentDocUri = document.uri;
147
- fullValueRange = isValueQuoted ? shiftRange(range, 1, -1) : range;
148
- replaceRange = pathToReplaceRange(valueBeforeCursor, fullValue, fullValueRange);
149
- valueBeforeLastSlash = valueBeforeCursor.substring(0, valueBeforeCursor.lastIndexOf('/') + 1);
150
- parentDir = documentContext.resolveReference(valueBeforeLastSlash || '.', currentDocUri);
151
- if (!parentDir) return [3 /*break*/, 4];
152
- _b.label = 1;
153
- case 1:
154
- _b.trys.push([1, 3, , 4]);
155
- result = [];
156
- return [4 /*yield*/, this.readDirectory(parentDir)];
157
- case 2:
158
- infos = _b.sent();
159
- for (_i = 0, infos_1 = infos; _i < infos_1.length; _i++) {
160
- _a = infos_1[_i], name = _a[0], type = _a[1];
161
- // Exclude paths that start with `.`
162
- if (name.charCodeAt(0) !== CharCode_dot && (type === cssLanguageTypes_1.FileType.Directory || (0, resources_1.joinPath)(parentDir, name) !== currentDocUri)) {
163
- result.push(createCompletionItem(name, type === cssLanguageTypes_1.FileType.Directory, replaceRange));
164
- }
165
- }
166
- return [2 /*return*/, result];
167
- case 3:
168
- e_1 = _b.sent();
169
- return [3 /*break*/, 4];
170
- case 4: return [2 /*return*/, []];
171
- }
172
- });
173
- });
174
- };
175
- return PathCompletionParticipant;
176
- }());
177
- exports.PathCompletionParticipant = PathCompletionParticipant;
178
- var CharCode_dot = '.'.charCodeAt(0);
179
- function stripQuotes(fullValue) {
180
- if ((0, strings_1.startsWith)(fullValue, "'") || (0, strings_1.startsWith)(fullValue, "\"")) {
181
- return fullValue.slice(1, -1);
182
- }
183
- else {
184
- return fullValue;
185
- }
186
- }
187
- function pathToReplaceRange(valueBeforeCursor, fullValue, fullValueRange) {
188
- var replaceRange;
189
- var lastIndexOfSlash = valueBeforeCursor.lastIndexOf('/');
190
- if (lastIndexOfSlash === -1) {
191
- replaceRange = fullValueRange;
192
- }
193
- else {
194
- // For cases where cursor is in the middle of attribute value, like <script src="./s|rc/test.js">
195
- // Find the last slash before cursor, and calculate the start of replace range from there
196
- var valueAfterLastSlash = fullValue.slice(lastIndexOfSlash + 1);
197
- var startPos = shiftPosition(fullValueRange.end, -valueAfterLastSlash.length);
198
- // If whitespace exists, replace until it
199
- var whitespaceIndex = valueAfterLastSlash.indexOf(' ');
200
- var endPos = void 0;
201
- if (whitespaceIndex !== -1) {
202
- endPos = shiftPosition(startPos, whitespaceIndex);
203
- }
204
- else {
205
- endPos = fullValueRange.end;
206
- }
207
- replaceRange = cssLanguageTypes_1.Range.create(startPos, endPos);
208
- }
209
- return replaceRange;
210
- }
211
- function createCompletionItem(name, isDir, replaceRange) {
212
- if (isDir) {
213
- name = name + '/';
214
- return {
215
- label: escapePath(name),
216
- kind: cssLanguageTypes_1.CompletionItemKind.Folder,
217
- textEdit: cssLanguageTypes_1.TextEdit.replace(replaceRange, escapePath(name)),
218
- command: {
219
- title: 'Suggest',
220
- command: 'editor.action.triggerSuggest'
221
- }
222
- };
223
- }
224
- else {
225
- return {
226
- label: escapePath(name),
227
- kind: cssLanguageTypes_1.CompletionItemKind.File,
228
- textEdit: cssLanguageTypes_1.TextEdit.replace(replaceRange, escapePath(name))
229
- };
230
- }
231
- }
232
- // Escape https://www.w3.org/TR/CSS1/#url
233
- function escapePath(p) {
234
- return p.replace(/(\s|\(|\)|,|"|')/g, '\\$1');
235
- }
236
- function shiftPosition(pos, offset) {
237
- return cssLanguageTypes_1.Position.create(pos.line, pos.character + offset);
238
- }
239
- function shiftRange(range, startOffset, endOffset) {
240
- var start = shiftPosition(range.start, startOffset);
241
- var end = shiftPosition(range.end, endOffset);
242
- return cssLanguageTypes_1.Range.create(start, end);
243
- }
244
- });
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
+ (function (factory) {
6
+ if (typeof module === "object" && typeof module.exports === "object") {
7
+ var v = factory(require, exports);
8
+ if (v !== undefined) module.exports = v;
9
+ }
10
+ else if (typeof define === "function" && define.amd) {
11
+ define(["require", "exports", "../cssLanguageTypes", "../utils/strings", "../utils/resources"], factory);
12
+ }
13
+ })(function (require, exports) {
14
+ "use strict";
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.PathCompletionParticipant = void 0;
17
+ const cssLanguageTypes_1 = require("../cssLanguageTypes");
18
+ const strings_1 = require("../utils/strings");
19
+ const resources_1 = require("../utils/resources");
20
+ class PathCompletionParticipant {
21
+ constructor(readDirectory) {
22
+ this.readDirectory = readDirectory;
23
+ this.literalCompletions = [];
24
+ this.importCompletions = [];
25
+ }
26
+ onCssURILiteralValue(context) {
27
+ this.literalCompletions.push(context);
28
+ }
29
+ onCssImportPath(context) {
30
+ this.importCompletions.push(context);
31
+ }
32
+ async computeCompletions(document, documentContext) {
33
+ const result = { items: [], isIncomplete: false };
34
+ for (const literalCompletion of this.literalCompletions) {
35
+ const uriValue = literalCompletion.uriValue;
36
+ const fullValue = stripQuotes(uriValue);
37
+ if (fullValue === '.' || fullValue === '..') {
38
+ result.isIncomplete = true;
39
+ }
40
+ else {
41
+ const items = await this.providePathSuggestions(uriValue, literalCompletion.position, literalCompletion.range, document, documentContext);
42
+ for (let item of items) {
43
+ result.items.push(item);
44
+ }
45
+ }
46
+ }
47
+ for (const importCompletion of this.importCompletions) {
48
+ const pathValue = importCompletion.pathValue;
49
+ const fullValue = stripQuotes(pathValue);
50
+ if (fullValue === '.' || fullValue === '..') {
51
+ result.isIncomplete = true;
52
+ }
53
+ else {
54
+ let suggestions = await this.providePathSuggestions(pathValue, importCompletion.position, importCompletion.range, document, documentContext);
55
+ if (document.languageId === 'scss') {
56
+ suggestions.forEach(s => {
57
+ if ((0, strings_1.startsWith)(s.label, '_') && (0, strings_1.endsWith)(s.label, '.scss')) {
58
+ if (s.textEdit) {
59
+ s.textEdit.newText = s.label.slice(1, -5);
60
+ }
61
+ else {
62
+ s.label = s.label.slice(1, -5);
63
+ }
64
+ }
65
+ });
66
+ }
67
+ for (let item of suggestions) {
68
+ result.items.push(item);
69
+ }
70
+ }
71
+ }
72
+ return result;
73
+ }
74
+ async providePathSuggestions(pathValue, position, range, document, documentContext) {
75
+ const fullValue = stripQuotes(pathValue);
76
+ const isValueQuoted = (0, strings_1.startsWith)(pathValue, `'`) || (0, strings_1.startsWith)(pathValue, `"`);
77
+ const valueBeforeCursor = isValueQuoted
78
+ ? fullValue.slice(0, position.character - (range.start.character + 1))
79
+ : fullValue.slice(0, position.character - range.start.character);
80
+ const currentDocUri = document.uri;
81
+ const fullValueRange = isValueQuoted ? shiftRange(range, 1, -1) : range;
82
+ const replaceRange = pathToReplaceRange(valueBeforeCursor, fullValue, fullValueRange);
83
+ const valueBeforeLastSlash = valueBeforeCursor.substring(0, valueBeforeCursor.lastIndexOf('/') + 1); // keep the last slash
84
+ let parentDir = documentContext.resolveReference(valueBeforeLastSlash || '.', currentDocUri);
85
+ if (parentDir) {
86
+ try {
87
+ const result = [];
88
+ const infos = await this.readDirectory(parentDir);
89
+ for (const [name, type] of infos) {
90
+ // Exclude paths that start with `.`
91
+ if (name.charCodeAt(0) !== CharCode_dot && (type === cssLanguageTypes_1.FileType.Directory || (0, resources_1.joinPath)(parentDir, name) !== currentDocUri)) {
92
+ result.push(createCompletionItem(name, type === cssLanguageTypes_1.FileType.Directory, replaceRange));
93
+ }
94
+ }
95
+ return result;
96
+ }
97
+ catch (e) {
98
+ // ignore
99
+ }
100
+ }
101
+ return [];
102
+ }
103
+ }
104
+ exports.PathCompletionParticipant = PathCompletionParticipant;
105
+ const CharCode_dot = '.'.charCodeAt(0);
106
+ function stripQuotes(fullValue) {
107
+ if ((0, strings_1.startsWith)(fullValue, `'`) || (0, strings_1.startsWith)(fullValue, `"`)) {
108
+ return fullValue.slice(1, -1);
109
+ }
110
+ else {
111
+ return fullValue;
112
+ }
113
+ }
114
+ function pathToReplaceRange(valueBeforeCursor, fullValue, fullValueRange) {
115
+ let replaceRange;
116
+ const lastIndexOfSlash = valueBeforeCursor.lastIndexOf('/');
117
+ if (lastIndexOfSlash === -1) {
118
+ replaceRange = fullValueRange;
119
+ }
120
+ else {
121
+ // For cases where cursor is in the middle of attribute value, like <script src="./s|rc/test.js">
122
+ // Find the last slash before cursor, and calculate the start of replace range from there
123
+ const valueAfterLastSlash = fullValue.slice(lastIndexOfSlash + 1);
124
+ const startPos = shiftPosition(fullValueRange.end, -valueAfterLastSlash.length);
125
+ // If whitespace exists, replace until it
126
+ const whitespaceIndex = valueAfterLastSlash.indexOf(' ');
127
+ let endPos;
128
+ if (whitespaceIndex !== -1) {
129
+ endPos = shiftPosition(startPos, whitespaceIndex);
130
+ }
131
+ else {
132
+ endPos = fullValueRange.end;
133
+ }
134
+ replaceRange = cssLanguageTypes_1.Range.create(startPos, endPos);
135
+ }
136
+ return replaceRange;
137
+ }
138
+ function createCompletionItem(name, isDir, replaceRange) {
139
+ if (isDir) {
140
+ name = name + '/';
141
+ return {
142
+ label: escapePath(name),
143
+ kind: cssLanguageTypes_1.CompletionItemKind.Folder,
144
+ textEdit: cssLanguageTypes_1.TextEdit.replace(replaceRange, escapePath(name)),
145
+ command: {
146
+ title: 'Suggest',
147
+ command: 'editor.action.triggerSuggest'
148
+ }
149
+ };
150
+ }
151
+ else {
152
+ return {
153
+ label: escapePath(name),
154
+ kind: cssLanguageTypes_1.CompletionItemKind.File,
155
+ textEdit: cssLanguageTypes_1.TextEdit.replace(replaceRange, escapePath(name))
156
+ };
157
+ }
158
+ }
159
+ // Escape https://www.w3.org/TR/CSS1/#url
160
+ function escapePath(p) {
161
+ return p.replace(/(\s|\(|\)|,|"|')/g, '\\$1');
162
+ }
163
+ function shiftPosition(pos, offset) {
164
+ return cssLanguageTypes_1.Position.create(pos.line, pos.character + offset);
165
+ }
166
+ function shiftRange(range, startOffset, endOffset) {
167
+ const start = shiftPosition(range.start, startOffset);
168
+ const end = shiftPosition(range.end, endOffset);
169
+ return cssLanguageTypes_1.Range.create(start, end);
170
+ }
171
+ });