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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
diff --git a/src/extension.ts b/src/extension.ts
index 434792823a14a7e10fb27668aea1e8a91b832ab4..0c59ad4e9246207b6dc8a4b69647fb26176a7386 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -143,7 +143,7 @@ })
}
function depthOf(obj) {
- if (typeof obj !== 'object') return 0
+ if (typeof obj !== 'object' || Array.isArray(obj)) return 0
let level = 1
@@ -207,10 +207,47 @@
return items
}
+function createConfigItems(config) {
+ let items = {}
+ let i = 0
+
+ Object.keys(config).forEach(key => {
+ let item = new vscode.CompletionItem(
+ key,
+ vscode.CompletionItemKind.Constant
+ )
+
+ if (depthOf(config[key]) === 0) {
+ if (key === 'plugins') return
+
+ item.filterText = item.insertText = `.${key}`
+ item.sortText = naturalExpand(i.toString())
+ if (typeof config[key] === 'string' || typeof config[key] === 'number') {
+ item.detail = config[key]
+ } else if (Array.isArray(config[key])) {
+ item.detail = stringifyArray(config[key])
+ }
+ items[key] = { item }
+ } else {
+ if (key === 'modules' || key === 'options') return
+
+ item.filterText = item.insertText = `${key}.`
+ item.sortText = naturalExpand(i.toString())
+ item.command = { title: '', command: 'editor.action.triggerSuggest' }
+ items[key] = { item, children: createConfigItems(config[key]) }
+ }
+
+ i++
+ })
+
+ return items
+}
+
class TailwindIntellisense {
private _completionProviders: vscode.Disposable[]
private _disposable: vscode.Disposable
private _items
+ private _configItems
constructor(tailwind) {
if (tailwind) {
@@ -226,6 +263,7 @@
if (separator !== ':') return
this._items = createItems(tailwind.classNames, separator, tailwind.config)
+ this._configItems = createConfigItems(tailwind.config)
this._completionProviders = []
@@ -276,6 +314,47 @@ tailwind.config
)
)
+ this._completionProviders.push(
+ vscode.languages.registerCompletionItemProvider(
+ ['css', 'sass', 'scss'],
+ {
+ provideCompletionItems: (
+ document: vscode.TextDocument,
+ position: vscode.Position
+ ): vscode.CompletionItem[] => {
+ const range: vscode.Range = new vscode.Range(
+ new vscode.Position(Math.max(position.line - 5, 0), 0),
+ position
+ )
+ const text: string = document.getText(range)
+
+ let matches = text.match(/config\(["']([^"']*)$/)
+
+ if (!matches) return []
+
+ let objPath =
+ matches[1]
+ .replace(/\.[^.]*$/, '')
+ .replace('.', '.children.')
+ .trim() + '.children'
+ let foo = dlv(this._configItems, objPath)
+
+ if (foo) {
+ console.log(Object.keys(foo).map(x => foo[x].item))
+ return Object.keys(foo).map(x => foo[x].item)
+ }
+
+ return Object.keys(this._configItems).map(
+ x => this._configItems[x].item
+ )
+ }
+ },
+ "'",
+ '"',
+ '.'
+ )
+ )
+
this._disposable = vscode.Disposable.from(...this._completionProviders)
}
@@ -285,3 +364,25 @@ this._disposable.dispose()
}
}
}
+
+function pad(n) {
+ return ('00000000' + n).substr(-8)
+}
+
+function naturalExpand(a: string) {
+ return a.replace(/\d+/g, pad)
+}
+
+function stringifyArray(arr: Array<any>): string {
+ return arr
+ .reduce((acc, curr) => {
+ let str = curr.toString()
+ if (str.includes(' ')) {
+ acc.push(`"${str.replace(/\s\s+/g, ' ')}"`)
+ } else {
+ acc.push(str)
+ }
+ return acc
+ }, [])
+ .join(', ')
+}
|