forked from unocss/unocss
/
autocomplete.ts
84 lines (72 loc) · 2.27 KB
/
autocomplete.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import type { UnocssPluginContext } from '@unocss/core'
import { createAutocomplete } from '@unocss/autocomplete'
import type { CompletionItemProvider, ExtensionContext, Position, TextDocument } from 'vscode'
import { CompletionItem, CompletionItemKind, CompletionList, MarkdownString, Range, languages } from 'vscode'
import { getPrettiedMarkdown, isCssId } from './utils'
import { log } from './log'
const languageIds = [
'erb',
'haml',
'hbs',
'html',
'css',
'javascript',
'javascriptreact',
'markdown',
'ejs',
'php',
'svelte',
'typescript',
'typescriptreact',
'vue-html',
'vue',
]
const delimiters = ['-', ':']
export async function registerAutoComplete(
context: UnocssPluginContext,
ext: ExtensionContext,
) {
const { uno, filter } = context
const autoComplete = createAutocomplete(uno)
async function getMarkdown(util: string) {
return new MarkdownString(await getPrettiedMarkdown(uno, util))
}
const provider: CompletionItemProvider = {
async provideCompletionItems(doc: TextDocument, position: Position) {
const code = doc.getText()
const id = doc.uri.fsPath
if (!code || (!isCssId(id) && !filter(code, id)))
return null
try {
const result = await autoComplete.suggestInFile(code, doc.offsetAt(position))
log.appendLine(`[autocomplete] ${id} | ${result.suggestions.slice(0, 10).map(v => `[${v[0]}, ${v[1]}]`).join(', ')}`)
if (!result.suggestions.length)
return
return new CompletionList(result.suggestions.map(([value, label]) => {
const resolved = result.resolveReplacement(value)
const item = new CompletionItem(label, CompletionItemKind.EnumMember)
item.insertText = resolved.replacement
item.range = new Range(doc.positionAt(resolved.start), doc.positionAt(resolved.end))
return item
}), true)
}
catch (e) {
log.appendLine(`[error] ${String(e)}`)
return null
}
},
async resolveCompletionItem(item: CompletionItem) {
return {
...item,
documentation: await getMarkdown(item.label as string),
}
},
}
ext.subscriptions.push(
languages.registerCompletionItemProvider(
languageIds,
provider,
...delimiters,
),
)
}