@unocss/autocomplete 0.29.0 → 0.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,60 @@
1
1
  # @unocss/autocomplete
2
2
 
3
- Autocomplete utils for UnoCSS.
3
+ Autocomplete utils for UnoCSS. This is embedded in [the playground](https://unocss.antfu.me/) and [the VS Code extension](https://github.com/unocss/unocss/tree/main/packages/vscode).
4
4
 
5
- > WIP
5
+ ## Syntax
6
+
7
+ To add autocomplete support to your custom rules:
8
+
9
+ ### Static Rules
10
+
11
+ Static rules like this will just works without any configuration.
12
+
13
+ ```ts
14
+ rules: [
15
+ ['flex', { display: 'flex' }]
16
+ ]
17
+ ```
18
+
19
+ ### Dynamic Rules
20
+
21
+ For dynamic rules, you can provide an extra `meta` object to the rule and specify the autocomplete template.
22
+
23
+ ```ts
24
+ rules: [
25
+ [
26
+ /^m-(\d)$/,
27
+ ([, d]) => ({ margin: `${d / 4}rem` }),
28
+ { autocomplete: 'm-<num>' }, // <-- this
29
+ ],
30
+ ]
31
+ ```
32
+
33
+ The template uses a simle DSL to specify the autocomplete suggestions. The syntax is:
34
+
35
+ - `(...|...)`: logic OR groups. `|` as the separator. Will be used as suggestions when the some of the groups match.
36
+ - `<...>`: built-in short hands. currently supports `<num>`, `<precent>` and `<directions>`
37
+ - `$...`: theme infering. for example, `$colors` will list all the properties of the `colors` object of the theme.
38
+
39
+ For examples:
40
+
41
+ ###### Example 1
42
+
43
+ - **Template**: `(border|b)-(solid|dashed|dotted|double|hidden|none)`
44
+ - **Input**: `b-do`
45
+ - **Suggestions**: `b-dashed`, `b-double`
46
+
47
+ ###### Example 2
48
+
49
+ - **Template**: `m-<num>`
50
+ - **Input**: `m-`
51
+ - **Suggestions**: `m-1`, `m-2`, `m-3` ...
52
+
53
+ ###### Example 3
54
+
55
+ - **Template**: `text-$colors`
56
+ - **Input**: `text-r`
57
+ - **Suggestions**: `text-red`, `text-rose` ...
6
58
 
7
59
  ## License
8
60
 
package/dist/index.cjs CHANGED
@@ -14,6 +14,7 @@ const shorthands = {
14
14
  precent: `(${[0, 25, 50, 45, 100].join("|")})`,
15
15
  directions: "(x|y|t|b|l|r|s|e)"
16
16
  };
17
+ const ignoredThemeKeys = ["DEFAULT"];
17
18
  function handleRegexMatch(str, regex, onMatched, onNotMatched) {
18
19
  let lastIndex = 0;
19
20
  Array.from(str.matchAll(regex)).forEach((m) => {
@@ -88,7 +89,7 @@ function parseAutocomplete(template, theme = {}) {
88
89
  break;
89
90
  }
90
91
  } else if (part.type === "theme") {
91
- const keys = part.objects.flatMap((i) => Object.keys(i));
92
+ const keys = part.objects.flatMap((i) => Object.keys(i)).filter((i) => i && !ignoredThemeKeys.includes(i) && i[0] !== "_");
92
93
  const fullMatched = keys.find((i) => i && rest.startsWith(i));
93
94
  if (fullMatched != null) {
94
95
  matched += fullMatched;
@@ -122,6 +123,13 @@ function createAutocomplete(uno) {
122
123
  const cache = new LRU__default({ max: 1e3 });
123
124
  let staticUtils = [];
124
125
  let templates = [];
126
+ reset();
127
+ return {
128
+ suggest,
129
+ templates,
130
+ cache,
131
+ reset
132
+ };
125
133
  function getParsed(template) {
126
134
  if (!templateCache.has(template))
127
135
  templateCache.set(template, parseAutocomplete(template, uno.config.theme));
@@ -132,11 +140,11 @@ function createAutocomplete(uno) {
132
140
  return [];
133
141
  if (cache.has(input))
134
142
  return cache.get(input);
135
- const result = await Promise.all([
143
+ const result = processSuggestions(await Promise.all([
136
144
  suggestSelf(input),
137
145
  suggestStatic(input),
138
146
  ...suggestFromPreset(input)
139
- ]).then((i) => core.uniq(i.flat()).sort().filter(Boolean));
147
+ ]));
140
148
  cache.set(input, result);
141
149
  return result;
142
150
  }
@@ -159,21 +167,24 @@ function createAutocomplete(uno) {
159
167
  ...uno.config.rulesDynamic.flatMap((i) => core.toArray(i?.[2]?.autocomplete || []))
160
168
  ];
161
169
  }
162
- reset();
163
- return {
164
- suggest,
165
- templates,
166
- cache,
167
- reset
168
- };
170
+ function processSuggestions(suggestions) {
171
+ return core.uniq(suggestions.flat()).filter((i) => !!(i && !i.match(/[:-]$/))).sort((a, b) => {
172
+ const numA = +(a.match(/\d+$/)?.[0] || NaN);
173
+ const numB = +(b.match(/\d+$/)?.[0] || NaN);
174
+ if (!Number.isNaN(numA) && !Number.isNaN(numB))
175
+ return numA - numB;
176
+ return a.localeCompare(b);
177
+ });
178
+ }
169
179
  }
170
180
 
171
181
  function searchUsageBoundary(line, index) {
172
182
  let start = index;
173
183
  let end = index;
174
- while (start && /[^\s"']/.test(line.charAt(start - 1)))
184
+ const regex = /[^\s>"'`]/;
185
+ while (start && regex.test(line.charAt(start - 1)))
175
186
  --start;
176
- while (end < line.length && /[^\s"']/.test(line.charAt(end)))
187
+ while (end < line.length && regex.test(line.charAt(end)))
177
188
  ++end;
178
189
  return {
179
190
  content: line.slice(start, end),
@@ -183,5 +194,7 @@ function searchUsageBoundary(line, index) {
183
194
  }
184
195
 
185
196
  exports.createAutocomplete = createAutocomplete;
197
+ exports.ignoredThemeKeys = ignoredThemeKeys;
186
198
  exports.parseAutocomplete = parseAutocomplete;
187
199
  exports.searchUsageBoundary = searchUsageBoundary;
200
+ exports.shorthands = shorthands;
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { UnoGenerator, AutoCompleteFunction } from '@unocss/core';
2
2
  import LRU from 'lru-cache';
3
3
 
4
4
  declare function createAutocomplete(uno: UnoGenerator): {
5
- suggest: (input: string) => Promise<string[] | undefined>;
5
+ suggest: (input: string) => Promise<string[]>;
6
6
  templates: (string | AutoCompleteFunction)[];
7
7
  cache: LRU<string, string[]>;
8
8
  reset: () => void;
@@ -26,6 +26,8 @@ interface ParsedAutocompleteTemplate {
26
26
  suggest(input: string): string[] | undefined;
27
27
  }
28
28
 
29
+ declare const shorthands: Record<string, string>;
30
+ declare const ignoredThemeKeys: string[];
29
31
  declare function parseAutocomplete(template: string, theme?: any): ParsedAutocompleteTemplate;
30
32
 
31
33
  declare function searchUsageBoundary(line: string, index: number): {
@@ -34,4 +36,4 @@ declare function searchUsageBoundary(line: string, index: number): {
34
36
  end: number;
35
37
  };
36
38
 
37
- export { AutocompleteTemplateGroup, AutocompleteTemplatePart, AutocompleteTemplateStatic, AutocompleteTemplateTheme, ParsedAutocompleteTemplate, createAutocomplete, parseAutocomplete, searchUsageBoundary };
39
+ export { AutocompleteTemplateGroup, AutocompleteTemplatePart, AutocompleteTemplateStatic, AutocompleteTemplateTheme, ParsedAutocompleteTemplate, createAutocomplete, ignoredThemeKeys, parseAutocomplete, searchUsageBoundary, shorthands };
package/dist/index.mjs CHANGED
@@ -6,6 +6,7 @@ const shorthands = {
6
6
  precent: `(${[0, 25, 50, 45, 100].join("|")})`,
7
7
  directions: "(x|y|t|b|l|r|s|e)"
8
8
  };
9
+ const ignoredThemeKeys = ["DEFAULT"];
9
10
  function handleRegexMatch(str, regex, onMatched, onNotMatched) {
10
11
  let lastIndex = 0;
11
12
  Array.from(str.matchAll(regex)).forEach((m) => {
@@ -80,7 +81,7 @@ function parseAutocomplete(template, theme = {}) {
80
81
  break;
81
82
  }
82
83
  } else if (part.type === "theme") {
83
- const keys = part.objects.flatMap((i) => Object.keys(i));
84
+ const keys = part.objects.flatMap((i) => Object.keys(i)).filter((i) => i && !ignoredThemeKeys.includes(i) && i[0] !== "_");
84
85
  const fullMatched = keys.find((i) => i && rest.startsWith(i));
85
86
  if (fullMatched != null) {
86
87
  matched += fullMatched;
@@ -114,6 +115,13 @@ function createAutocomplete(uno) {
114
115
  const cache = new LRU({ max: 1e3 });
115
116
  let staticUtils = [];
116
117
  let templates = [];
118
+ reset();
119
+ return {
120
+ suggest,
121
+ templates,
122
+ cache,
123
+ reset
124
+ };
117
125
  function getParsed(template) {
118
126
  if (!templateCache.has(template))
119
127
  templateCache.set(template, parseAutocomplete(template, uno.config.theme));
@@ -124,11 +132,11 @@ function createAutocomplete(uno) {
124
132
  return [];
125
133
  if (cache.has(input))
126
134
  return cache.get(input);
127
- const result = await Promise.all([
135
+ const result = processSuggestions(await Promise.all([
128
136
  suggestSelf(input),
129
137
  suggestStatic(input),
130
138
  ...suggestFromPreset(input)
131
- ]).then((i) => uniq(i.flat()).sort().filter(Boolean));
139
+ ]));
132
140
  cache.set(input, result);
133
141
  return result;
134
142
  }
@@ -151,21 +159,24 @@ function createAutocomplete(uno) {
151
159
  ...uno.config.rulesDynamic.flatMap((i) => toArray(i?.[2]?.autocomplete || []))
152
160
  ];
153
161
  }
154
- reset();
155
- return {
156
- suggest,
157
- templates,
158
- cache,
159
- reset
160
- };
162
+ function processSuggestions(suggestions) {
163
+ return uniq(suggestions.flat()).filter((i) => !!(i && !i.match(/[:-]$/))).sort((a, b) => {
164
+ const numA = +(a.match(/\d+$/)?.[0] || NaN);
165
+ const numB = +(b.match(/\d+$/)?.[0] || NaN);
166
+ if (!Number.isNaN(numA) && !Number.isNaN(numB))
167
+ return numA - numB;
168
+ return a.localeCompare(b);
169
+ });
170
+ }
161
171
  }
162
172
 
163
173
  function searchUsageBoundary(line, index) {
164
174
  let start = index;
165
175
  let end = index;
166
- while (start && /[^\s"']/.test(line.charAt(start - 1)))
176
+ const regex = /[^\s>"'`]/;
177
+ while (start && regex.test(line.charAt(start - 1)))
167
178
  --start;
168
- while (end < line.length && /[^\s"']/.test(line.charAt(end)))
179
+ while (end < line.length && regex.test(line.charAt(end)))
169
180
  ++end;
170
181
  return {
171
182
  content: line.slice(start, end),
@@ -174,4 +185,4 @@ function searchUsageBoundary(line, index) {
174
185
  };
175
186
  }
176
187
 
177
- export { createAutocomplete, parseAutocomplete, searchUsageBoundary };
188
+ export { createAutocomplete, ignoredThemeKeys, parseAutocomplete, searchUsageBoundary, shorthands };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unocss/autocomplete",
3
- "version": "0.29.0",
3
+ "version": "0.29.1",
4
4
  "description": "Autocomplete utils for UnoCSS",
5
5
  "keywords": [
6
6
  "unocss",
@@ -36,11 +36,11 @@
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/lru-cache": "^7.4.0",
39
- "@unocss/core": "0.29.0"
39
+ "@unocss/core": "0.29.1"
40
40
  },
41
41
  "scripts": {
42
42
  "build": "unbuild",
43
43
  "stub": "unbuild --stub"
44
44
  },
45
- "readme": "# @unocss/autocomplete\n\nAutocomplete utils for UnoCSS.\n\n> WIP\n\n## License\n\nMIT License © 2021-PRESENT [Anthony Fu](https://github.com/antfu)\n"
45
+ "readme": "# @unocss/autocomplete\n\nAutocomplete utils for UnoCSS. This is embedded in [the playground](https://unocss.antfu.me/) and [the VS Code extension](https://github.com/unocss/unocss/tree/main/packages/vscode).\n\n## Syntax\n\nTo add autocomplete support to your custom rules:\n\n### Static Rules\n\nStatic rules like this will just works without any configuration.\n\n```ts\nrules: [\n ['flex', { display: 'flex' }]\n]\n```\n\n### Dynamic Rules\n\nFor dynamic rules, you can provide an extra `meta` object to the rule and specify the autocomplete template.\n\n```ts\nrules: [\n [\n /^m-(\\d)$/,\n ([, d]) => ({ margin: `${d / 4}rem` }),\n { autocomplete: 'm-<num>' }, // <-- this\n ],\n]\n```\n\nThe template uses a simle DSL to specify the autocomplete suggestions. The syntax is:\n\n- `(...|...)`: logic OR groups. `|` as the separator. Will be used as suggestions when the some of the groups match.\n- `<...>`: built-in short hands. currently supports `<num>`, `<precent>` and `<directions>`\n- `$...`: theme infering. for example, `$colors` will list all the properties of the `colors` object of the theme.\n\nFor examples:\n\n###### Example 1\n\n- **Template**: `(border|b)-(solid|dashed|dotted|double|hidden|none)`\n- **Input**: `b-do`\n- **Suggestions**: `b-dashed`, `b-double`\n\n###### Example 2\n\n- **Template**: `m-<num>`\n- **Input**: `m-`\n- **Suggestions**: `m-1`, `m-2`, `m-3` ...\n\n###### Example 3\n\n- **Template**: `text-$colors`\n- **Input**: `text-r`\n- **Suggestions**: `text-red`, `text-rose` ...\n\n## License\n\nMIT License © 2021-PRESENT [Anthony Fu](https://github.com/antfu)\n"
46
46
  }