@unocss/autocomplete 0.53.1 → 0.53.4
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/dist/index.cjs +83 -23
- package/dist/index.d.ts +9 -4
- package/dist/index.mjs +84 -25
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -4,6 +4,43 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
const core = require('@unocss/core');
|
|
6
6
|
const lruCache = require('lru-cache');
|
|
7
|
+
const fzf = require('fzf');
|
|
8
|
+
|
|
9
|
+
function searchUsageBoundary(line, index) {
|
|
10
|
+
let start = index;
|
|
11
|
+
let end = index;
|
|
12
|
+
const regex = /[^\s>"'`;]/;
|
|
13
|
+
while (start && regex.test(line.charAt(start - 1)))
|
|
14
|
+
--start;
|
|
15
|
+
while (end < line.length && regex.test(line.charAt(end)))
|
|
16
|
+
++end;
|
|
17
|
+
return {
|
|
18
|
+
content: line.slice(start, end),
|
|
19
|
+
start,
|
|
20
|
+
end
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function searchAttrKey(content, cursor) {
|
|
24
|
+
const text = content.substring(0, cursor);
|
|
25
|
+
if (text.match(/(<\w+\s*)[^>]*$/) !== null)
|
|
26
|
+
return text.match(/\S+(?=\s*=\s*["']?[^"']*$)/)?.[0];
|
|
27
|
+
}
|
|
28
|
+
function cartesian(arr) {
|
|
29
|
+
if (arr.length < 2)
|
|
30
|
+
return arr;
|
|
31
|
+
return arr.reduce(
|
|
32
|
+
(a, b) => {
|
|
33
|
+
const ret = [];
|
|
34
|
+
a.forEach((a2) => {
|
|
35
|
+
b.forEach((b2) => {
|
|
36
|
+
ret.push(a2.concat([b2]));
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
return ret;
|
|
40
|
+
},
|
|
41
|
+
[[]]
|
|
42
|
+
);
|
|
43
|
+
}
|
|
7
44
|
|
|
8
45
|
const shorthands = {
|
|
9
46
|
num: `(${[0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 24, 36].join("|")})`,
|
|
@@ -31,6 +68,7 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
31
68
|
return shorthands[key];
|
|
32
69
|
});
|
|
33
70
|
handleGroups(template);
|
|
71
|
+
const fzf$1 = new fzf.Fzf(getAllCombination(parts));
|
|
34
72
|
return {
|
|
35
73
|
parts,
|
|
36
74
|
suggest
|
|
@@ -74,7 +112,9 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
74
112
|
}
|
|
75
113
|
);
|
|
76
114
|
}
|
|
77
|
-
function suggest(input) {
|
|
115
|
+
function suggest(input, matchType = "prefix") {
|
|
116
|
+
if (input.length && matchType === "fuzzy")
|
|
117
|
+
return fzf$1.find(input).map((i) => i.item);
|
|
78
118
|
let rest = input;
|
|
79
119
|
let matched = "";
|
|
80
120
|
let combinations = [];
|
|
@@ -130,32 +170,43 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
130
170
|
return combinations.map((i) => matched + i).filter((i) => i.length >= input.length);
|
|
131
171
|
}
|
|
132
172
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
173
|
+
function getValuesFromPartTemplate(part) {
|
|
174
|
+
if (part.type === "static")
|
|
175
|
+
return [part.value];
|
|
176
|
+
if (part.type === "theme") {
|
|
177
|
+
return part.objects.flatMap((i) => {
|
|
178
|
+
const keys = Object.keys(i).filter((i2) => i2 && i2[0] !== "_");
|
|
179
|
+
for (const key in i) {
|
|
180
|
+
const value = i[key];
|
|
181
|
+
if (value === null || value === void 0)
|
|
182
|
+
continue;
|
|
183
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
184
|
+
const subKeys = getValuesFromPartTemplate({
|
|
185
|
+
type: "theme",
|
|
186
|
+
objects: [value]
|
|
187
|
+
}).map((i2) => `${key}-${i2}`);
|
|
188
|
+
keys.push(...subKeys);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return keys;
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
if (part.type === "group")
|
|
195
|
+
return [...part.values];
|
|
196
|
+
return [];
|
|
147
197
|
}
|
|
148
|
-
function
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
198
|
+
function getAllCombination(parts) {
|
|
199
|
+
const values = parts.map((i) => getValuesFromPartTemplate(i));
|
|
200
|
+
const list = core.uniq(cartesian(values).flatMap((i) => i.join("").replace("-DEFAULT", "")));
|
|
201
|
+
return list;
|
|
152
202
|
}
|
|
153
203
|
|
|
154
|
-
function createAutocomplete(uno) {
|
|
204
|
+
function createAutocomplete(uno, options = {}) {
|
|
155
205
|
const templateCache = /* @__PURE__ */ new Map();
|
|
156
206
|
const cache = new lruCache.LRUCache({ max: 5e3 });
|
|
157
207
|
let staticUtils = [];
|
|
158
208
|
const templates = [];
|
|
209
|
+
const matchType = options.matchType ?? "prefix";
|
|
159
210
|
reset();
|
|
160
211
|
return {
|
|
161
212
|
suggest,
|
|
@@ -197,7 +248,7 @@ function createAutocomplete(uno) {
|
|
|
197
248
|
idx = 0;
|
|
198
249
|
const variantPrefix = input.slice(0, idx);
|
|
199
250
|
const variantSuffix = input.slice(idx + input.length);
|
|
200
|
-
|
|
251
|
+
let result = processSuggestions(
|
|
201
252
|
await Promise.all([
|
|
202
253
|
suggestSelf(processed),
|
|
203
254
|
suggestStatic(processed),
|
|
@@ -208,6 +259,12 @@ function createAutocomplete(uno) {
|
|
|
208
259
|
variantPrefix,
|
|
209
260
|
variantSuffix
|
|
210
261
|
);
|
|
262
|
+
if (matchType === "fuzzy") {
|
|
263
|
+
const fzf$1 = new fzf.Fzf(result, {
|
|
264
|
+
tiebreakers: [fzf.byStartAsc, fzf.byLengthAsc]
|
|
265
|
+
});
|
|
266
|
+
result = fzf$1.find(input).map((i) => i.item);
|
|
267
|
+
}
|
|
211
268
|
cache.set(input, result);
|
|
212
269
|
return result;
|
|
213
270
|
}
|
|
@@ -248,6 +305,8 @@ function createAutocomplete(uno) {
|
|
|
248
305
|
return i ? [input] : [];
|
|
249
306
|
}
|
|
250
307
|
async function suggestStatic(input) {
|
|
308
|
+
if (matchType === "fuzzy")
|
|
309
|
+
return staticUtils;
|
|
251
310
|
return staticUtils.filter((i) => i.startsWith(input));
|
|
252
311
|
}
|
|
253
312
|
async function suggestUnoCache(input) {
|
|
@@ -256,12 +315,12 @@ function createAutocomplete(uno) {
|
|
|
256
315
|
}
|
|
257
316
|
function suggestFromPreset(input) {
|
|
258
317
|
return templates.map(
|
|
259
|
-
(fn) => typeof fn === "function" ? fn(input) : getParsed(fn)(input)
|
|
318
|
+
(fn) => typeof fn === "function" ? fn(input) : getParsed(fn)(input, matchType)
|
|
260
319
|
) || [];
|
|
261
320
|
}
|
|
262
321
|
function suggestVariant(input, used) {
|
|
263
322
|
return uno.config.variants.filter((v) => v.autocomplete && (v.multiPass || !used.has(v))).flatMap((v) => core.toArray(v.autocomplete || [])).map(
|
|
264
|
-
(fn) => typeof fn === "function" ? fn(input) : getParsed(fn)(input)
|
|
323
|
+
(fn) => typeof fn === "function" ? fn(input) : getParsed(fn)(input, matchType)
|
|
265
324
|
);
|
|
266
325
|
}
|
|
267
326
|
function reset() {
|
|
@@ -289,6 +348,7 @@ function createAutocomplete(uno) {
|
|
|
289
348
|
}
|
|
290
349
|
}
|
|
291
350
|
|
|
351
|
+
exports.cartesian = cartesian;
|
|
292
352
|
exports.createAutocomplete = createAutocomplete;
|
|
293
353
|
exports.ignoredThemeKeys = ignoredThemeKeys;
|
|
294
354
|
exports.parseAutocomplete = parseAutocomplete;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { SuggestResult, AutoCompleteFunction, UnoGenerator } from '@unocss/core';
|
|
2
2
|
import { LRUCache } from 'lru-cache';
|
|
3
3
|
|
|
4
|
+
type AutoCompleteMatchType = 'prefix' | 'fuzzy';
|
|
5
|
+
interface AutocompleteOptions {
|
|
6
|
+
matchType?: AutoCompleteMatchType;
|
|
7
|
+
}
|
|
4
8
|
type AutocompleteTemplatePart = AutocompleteTemplateStatic | AutocompleteTemplateGroup | AutocompleteTemplateTheme;
|
|
5
9
|
interface AutocompleteTemplateStatic {
|
|
6
10
|
type: 'static';
|
|
@@ -16,10 +20,10 @@ interface AutocompleteTemplateTheme {
|
|
|
16
20
|
}
|
|
17
21
|
interface ParsedAutocompleteTemplate {
|
|
18
22
|
parts: AutocompleteTemplatePart[];
|
|
19
|
-
suggest(input: string): string[] | undefined;
|
|
23
|
+
suggest(input: string, matchType?: AutoCompleteMatchType): string[] | undefined;
|
|
20
24
|
}
|
|
21
25
|
interface UnocssAutocomplete {
|
|
22
|
-
suggest: (input: string) => Promise<string[]>;
|
|
26
|
+
suggest: (input: string, allowsEmptyInput?: boolean) => Promise<string[]>;
|
|
23
27
|
suggestInFile: (content: string, cursor: number) => Promise<SuggestResult>;
|
|
24
28
|
templates: (string | AutoCompleteFunction)[];
|
|
25
29
|
cache: LRUCache<string, string[]>;
|
|
@@ -27,7 +31,7 @@ interface UnocssAutocomplete {
|
|
|
27
31
|
enumerate: () => Promise<Set<string>>;
|
|
28
32
|
}
|
|
29
33
|
|
|
30
|
-
declare function createAutocomplete(uno: UnoGenerator): UnocssAutocomplete;
|
|
34
|
+
declare function createAutocomplete(uno: UnoGenerator, options?: AutocompleteOptions): UnocssAutocomplete;
|
|
31
35
|
|
|
32
36
|
declare const shorthands: Record<string, string>;
|
|
33
37
|
declare const ignoredThemeKeys: string[];
|
|
@@ -39,5 +43,6 @@ declare function searchUsageBoundary(line: string, index: number): {
|
|
|
39
43
|
end: number;
|
|
40
44
|
};
|
|
41
45
|
declare function searchAttrKey(content: string, cursor: number): string | undefined;
|
|
46
|
+
declare function cartesian<T>(arr: T[][]): T[][];
|
|
42
47
|
|
|
43
|
-
export { AutocompleteTemplateGroup, AutocompleteTemplatePart, AutocompleteTemplateStatic, AutocompleteTemplateTheme, ParsedAutocompleteTemplate, UnocssAutocomplete, createAutocomplete, ignoredThemeKeys, parseAutocomplete, searchAttrKey, searchUsageBoundary, shorthands };
|
|
48
|
+
export { AutoCompleteMatchType, AutocompleteOptions, AutocompleteTemplateGroup, AutocompleteTemplatePart, AutocompleteTemplateStatic, AutocompleteTemplateTheme, ParsedAutocompleteTemplate, UnocssAutocomplete, cartesian, createAutocomplete, ignoredThemeKeys, parseAutocomplete, searchAttrKey, searchUsageBoundary, shorthands };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
|
-
import { escapeRegExp, toArray
|
|
1
|
+
import { uniq, escapeRegExp, toArray } from '@unocss/core';
|
|
2
2
|
import { LRUCache } from 'lru-cache';
|
|
3
|
+
import { Fzf, byStartAsc, byLengthAsc } from 'fzf';
|
|
4
|
+
|
|
5
|
+
function searchUsageBoundary(line, index) {
|
|
6
|
+
let start = index;
|
|
7
|
+
let end = index;
|
|
8
|
+
const regex = /[^\s>"'`;]/;
|
|
9
|
+
while (start && regex.test(line.charAt(start - 1)))
|
|
10
|
+
--start;
|
|
11
|
+
while (end < line.length && regex.test(line.charAt(end)))
|
|
12
|
+
++end;
|
|
13
|
+
return {
|
|
14
|
+
content: line.slice(start, end),
|
|
15
|
+
start,
|
|
16
|
+
end
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function searchAttrKey(content, cursor) {
|
|
20
|
+
const text = content.substring(0, cursor);
|
|
21
|
+
if (text.match(/(<\w+\s*)[^>]*$/) !== null)
|
|
22
|
+
return text.match(/\S+(?=\s*=\s*["']?[^"']*$)/)?.[0];
|
|
23
|
+
}
|
|
24
|
+
function cartesian(arr) {
|
|
25
|
+
if (arr.length < 2)
|
|
26
|
+
return arr;
|
|
27
|
+
return arr.reduce(
|
|
28
|
+
(a, b) => {
|
|
29
|
+
const ret = [];
|
|
30
|
+
a.forEach((a2) => {
|
|
31
|
+
b.forEach((b2) => {
|
|
32
|
+
ret.push(a2.concat([b2]));
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
return ret;
|
|
36
|
+
},
|
|
37
|
+
[[]]
|
|
38
|
+
);
|
|
39
|
+
}
|
|
3
40
|
|
|
4
41
|
const shorthands = {
|
|
5
42
|
num: `(${[0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 24, 36].join("|")})`,
|
|
@@ -27,6 +64,7 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
27
64
|
return shorthands[key];
|
|
28
65
|
});
|
|
29
66
|
handleGroups(template);
|
|
67
|
+
const fzf = new Fzf(getAllCombination(parts));
|
|
30
68
|
return {
|
|
31
69
|
parts,
|
|
32
70
|
suggest
|
|
@@ -70,7 +108,9 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
70
108
|
}
|
|
71
109
|
);
|
|
72
110
|
}
|
|
73
|
-
function suggest(input) {
|
|
111
|
+
function suggest(input, matchType = "prefix") {
|
|
112
|
+
if (input.length && matchType === "fuzzy")
|
|
113
|
+
return fzf.find(input).map((i) => i.item);
|
|
74
114
|
let rest = input;
|
|
75
115
|
let matched = "";
|
|
76
116
|
let combinations = [];
|
|
@@ -126,32 +166,43 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
126
166
|
return combinations.map((i) => matched + i).filter((i) => i.length >= input.length);
|
|
127
167
|
}
|
|
128
168
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
169
|
+
function getValuesFromPartTemplate(part) {
|
|
170
|
+
if (part.type === "static")
|
|
171
|
+
return [part.value];
|
|
172
|
+
if (part.type === "theme") {
|
|
173
|
+
return part.objects.flatMap((i) => {
|
|
174
|
+
const keys = Object.keys(i).filter((i2) => i2 && i2[0] !== "_");
|
|
175
|
+
for (const key in i) {
|
|
176
|
+
const value = i[key];
|
|
177
|
+
if (value === null || value === void 0)
|
|
178
|
+
continue;
|
|
179
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
180
|
+
const subKeys = getValuesFromPartTemplate({
|
|
181
|
+
type: "theme",
|
|
182
|
+
objects: [value]
|
|
183
|
+
}).map((i2) => `${key}-${i2}`);
|
|
184
|
+
keys.push(...subKeys);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return keys;
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
if (part.type === "group")
|
|
191
|
+
return [...part.values];
|
|
192
|
+
return [];
|
|
143
193
|
}
|
|
144
|
-
function
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
194
|
+
function getAllCombination(parts) {
|
|
195
|
+
const values = parts.map((i) => getValuesFromPartTemplate(i));
|
|
196
|
+
const list = uniq(cartesian(values).flatMap((i) => i.join("").replace("-DEFAULT", "")));
|
|
197
|
+
return list;
|
|
148
198
|
}
|
|
149
199
|
|
|
150
|
-
function createAutocomplete(uno) {
|
|
200
|
+
function createAutocomplete(uno, options = {}) {
|
|
151
201
|
const templateCache = /* @__PURE__ */ new Map();
|
|
152
202
|
const cache = new LRUCache({ max: 5e3 });
|
|
153
203
|
let staticUtils = [];
|
|
154
204
|
const templates = [];
|
|
205
|
+
const matchType = options.matchType ?? "prefix";
|
|
155
206
|
reset();
|
|
156
207
|
return {
|
|
157
208
|
suggest,
|
|
@@ -193,7 +244,7 @@ function createAutocomplete(uno) {
|
|
|
193
244
|
idx = 0;
|
|
194
245
|
const variantPrefix = input.slice(0, idx);
|
|
195
246
|
const variantSuffix = input.slice(idx + input.length);
|
|
196
|
-
|
|
247
|
+
let result = processSuggestions(
|
|
197
248
|
await Promise.all([
|
|
198
249
|
suggestSelf(processed),
|
|
199
250
|
suggestStatic(processed),
|
|
@@ -204,6 +255,12 @@ function createAutocomplete(uno) {
|
|
|
204
255
|
variantPrefix,
|
|
205
256
|
variantSuffix
|
|
206
257
|
);
|
|
258
|
+
if (matchType === "fuzzy") {
|
|
259
|
+
const fzf = new Fzf(result, {
|
|
260
|
+
tiebreakers: [byStartAsc, byLengthAsc]
|
|
261
|
+
});
|
|
262
|
+
result = fzf.find(input).map((i) => i.item);
|
|
263
|
+
}
|
|
207
264
|
cache.set(input, result);
|
|
208
265
|
return result;
|
|
209
266
|
}
|
|
@@ -244,6 +301,8 @@ function createAutocomplete(uno) {
|
|
|
244
301
|
return i ? [input] : [];
|
|
245
302
|
}
|
|
246
303
|
async function suggestStatic(input) {
|
|
304
|
+
if (matchType === "fuzzy")
|
|
305
|
+
return staticUtils;
|
|
247
306
|
return staticUtils.filter((i) => i.startsWith(input));
|
|
248
307
|
}
|
|
249
308
|
async function suggestUnoCache(input) {
|
|
@@ -252,12 +311,12 @@ function createAutocomplete(uno) {
|
|
|
252
311
|
}
|
|
253
312
|
function suggestFromPreset(input) {
|
|
254
313
|
return templates.map(
|
|
255
|
-
(fn) => typeof fn === "function" ? fn(input) : getParsed(fn)(input)
|
|
314
|
+
(fn) => typeof fn === "function" ? fn(input) : getParsed(fn)(input, matchType)
|
|
256
315
|
) || [];
|
|
257
316
|
}
|
|
258
317
|
function suggestVariant(input, used) {
|
|
259
318
|
return uno.config.variants.filter((v) => v.autocomplete && (v.multiPass || !used.has(v))).flatMap((v) => toArray(v.autocomplete || [])).map(
|
|
260
|
-
(fn) => typeof fn === "function" ? fn(input) : getParsed(fn)(input)
|
|
319
|
+
(fn) => typeof fn === "function" ? fn(input) : getParsed(fn)(input, matchType)
|
|
261
320
|
);
|
|
262
321
|
}
|
|
263
322
|
function reset() {
|
|
@@ -285,4 +344,4 @@ function createAutocomplete(uno) {
|
|
|
285
344
|
}
|
|
286
345
|
}
|
|
287
346
|
|
|
288
|
-
export { createAutocomplete, ignoredThemeKeys, parseAutocomplete, searchAttrKey, searchUsageBoundary, shorthands };
|
|
347
|
+
export { cartesian, createAutocomplete, ignoredThemeKeys, parseAutocomplete, searchAttrKey, searchUsageBoundary, shorthands };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unocss/autocomplete",
|
|
3
|
-
"version": "0.53.
|
|
3
|
+
"version": "0.53.4",
|
|
4
4
|
"description": "Autocomplete utils for UnoCSS",
|
|
5
5
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,10 +33,11 @@
|
|
|
33
33
|
"dist"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"
|
|
36
|
+
"fzf": "^0.5.2",
|
|
37
|
+
"lru-cache": "^10.0.0"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
|
-
"@unocss/core": "0.53.
|
|
40
|
+
"@unocss/core": "0.53.4"
|
|
40
41
|
},
|
|
41
42
|
"scripts": {
|
|
42
43
|
"build": "unbuild",
|