Home

tailwind-ctp-intellisense @master - refs - log -
-
https://git.jolheiser.com/tailwind-ctp-intellisense.git
Tailwind intellisense + Catppuccin
tree log patch
add tree view
Brad Cornes <bradlc41@gmail.com>
6 years ago
21 changed files, 408 additions(+), 46 deletions(-)
package-lock.jsonpackage.jsonresources/icons/border_all.svgresources/icons/devices.svgresources/icons/flip_to_front.svgresources/icons/format_bold.svgresources/icons/format_line_spacing.svgresources/icons/format_size.svgresources/icons/layers.svgresources/icons/opacity.svgresources/icons/padding.svgresources/icons/palette.svgresources/icons/photo_size_select_large.svgresources/icons/rounded_corner.svgresources/icons/select_all.svgresources/icons/straighten.svgresources/icons/title.svgresources/icons/tracking.svgsrc/extension.tssrc/treeView.tssrc/util.ts
M package-lock.jsonpackage-lock.json
  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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
diff --git a/package-lock.json b/package-lock.json
index 39bb0b70d69321a1eb21e0e15fce69a7af3a4d7e..b11fdf5566db51dc3f42e78cb3533d620be13125 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -286,9 +286,9 @@       "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
       "dev": true
     },
     "@types/node": {
-      "version": "10.12.15",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.15.tgz",
-      "integrity": "sha512-9kROxduaN98QghwwHmxXO2Xz3MaWf+I1sLVAA6KJDF5xix+IyXVhds0MAfdNwtcpSrzhaTsNB0/jnL86fgUhqA==",
+      "version": "10.12.17",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.17.tgz",
+      "integrity": "sha512-umSCRkjWH70uNzFiOof5yxCqrMXIBJ9UJJUzbEsmtWt8apURQh06pylGMqnhdjHGJSeoBrhzk+mibu6NgL1oBA==",
       "dev": true
     },
     "@types/q": {
@@ -477,13 +477,13 @@       "integrity": "sha512-nEnWYfrBmA3taTiuiOoZYmgJ/CNrSoQLeLs29SeLcPu60yaw/mHDBHV0iOZ051fTvsTHxpCY+gXibqT9wbQYfg==",
       "dev": true
     },
     "autoprefixer": {
-      "version": "9.4.2",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.2.tgz",
-      "integrity": "sha512-tYQYJvZvqlJCzF+BLC//uAcdT/Yy4ik9bwZRXr/EehUJ/bjjpTthsWTy8dpowdoIE1sLCDf1ch4Eb2cOSzZC9w==",
+      "version": "9.4.3",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.3.tgz",
+      "integrity": "sha512-/XSnzDepRkAU//xLcXA/lUWxpsBuw0WiriAHOqnxkuCtzLhaz+fL4it4gp20BQ8n5SyLzK/FOc7A0+u/rti2FQ==",
       "dev": true,
       "requires": {
-        "browserslist": "^4.3.5",
-        "caniuse-lite": "^1.0.30000914",
+        "browserslist": "^4.3.6",
+        "caniuse-lite": "^1.0.30000921",
         "normalize-range": "^0.1.2",
         "num2fraction": "^1.2.2",
         "postcss": "^7.0.6",
@@ -856,7 +856,6 @@     "color": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/color/-/color-3.1.0.tgz",
       "integrity": "sha512-CwyopLkuRYO5ei2EpzpIh6LqJMt6Mt+jZhO5VI5f/wJLZriXQE32/SSqzmrh+QB+AZT81Cj8yv+7zwToW8ahZg==",
-      "dev": true,
       "requires": {
         "color-convert": "^1.9.1",
         "color-string": "^1.5.2"
@@ -866,7 +865,6 @@     "color-convert": {
       "version": "1.9.3",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
       "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-      "dev": true,
       "requires": {
         "color-name": "1.1.3"
       }
@@ -874,14 +872,12 @@     },
     "color-name": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-      "dev": true
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
     },
     "color-string": {
       "version": "1.5.3",
       "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
       "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
-      "dev": true,
       "requires": {
         "color-name": "^1.0.0",
         "simple-swizzle": "^0.2.2"
@@ -978,9 +974,9 @@         "safe-buffer": "~5.1.1"
       }
     },
     "core-js": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.0.tgz",
-      "integrity": "sha512-kLRC6ncVpuEW/1kwrOXYX6KQASCVtrh1gQr/UiaVgFlf9WE5Vp+lNe5+h3LuMr5PAucWnnEXwH0nQHRH/gpGtw==",
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz",
+      "integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==",
       "dev": true
     },
     "core-util-is": {
@@ -1394,6 +1390,11 @@       "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz",
       "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==",
       "dev": true
     },
+    "dlv": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.2.tgz",
+      "integrity": "sha512-xxD4VSH67GbRvSGUrckvha94RD7hjgOH7rqGxiytLpkaeMvixOHFZTGFK6EkIm3T761OVHT8ABHmGkq9gXgu6Q=="
+    },
     "dom-serializer": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
@@ -1466,9 +1467,9 @@         "safer-buffer": "^2.1.0"
       }
     },
     "electron-to-chromium": {
-      "version": "1.3.92",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.92.tgz",
-      "integrity": "sha512-En051LMzMl3/asMWGZEtU808HOoVWIpmmZx1Ep8N+TT9e7z/X8RcLeBU2kLSNLGQ+5SuKELzMx+MVuTBXk6Q9w==",
+      "version": "1.3.94",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.94.tgz",
+      "integrity": "sha512-miQqXALb6eBD3OetCtg3UM5XTLMwHISux0l6mh14iiV5SE+qvftgOCXT9Vvp53fWaCLET4sfA/SmIMYHXkaNmw==",
       "dev": true
     },
     "emojis-list": {
@@ -1948,9 +1949,9 @@       "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==",
       "dev": true
     },
     "globrex": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.1.tgz",
-      "integrity": "sha512-bqKcPhb+ZtrISivpu6oLmwIyINlPlzueO/BDCdfnzUeu7SYxnHTXmWP7uQI5PnQXc5yGXOscGBEGagloA2hcSw==",
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
+      "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
       "dev": true
     },
     "graceful-fs": {
@@ -2605,9 +2606,9 @@         "merge-stream": "^1.0.1"
       }
     },
     "js-base64": {
-      "version": "2.4.9",
-      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz",
-      "integrity": "sha512-xcinL3AuDJk7VSzsHgb9DvvIXayBbadtMZ4HFPx8rUszbW1MuNMlwYVC4zzCZ6e1sqZpnNS5ZFYOhXqA39T7LQ==",
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.0.tgz",
+      "integrity": "sha512-wlEBIZ5LP8usDylWbDNhKPEFVFdI5hCHpnVoT/Ysvoi/PRhJENm/Rlh9TvjYB38HFfKZN7OzEbRjmjvLkFw11g==",
       "dev": true
     },
     "js-tokens": {
@@ -2895,9 +2896,9 @@         "readable-stream": "^2.0.1"
       }
     },
     "microbundle": {
-      "version": "0.8.3",
-      "resolved": "https://registry.npmjs.org/microbundle/-/microbundle-0.8.3.tgz",
-      "integrity": "sha512-vJHzfwWFG4Q6Oly+gVE4mm/3t+eqtG+VeHaHNo5ev6i00XoMXJJ5RbTg7Rawh4r5ZkltjLEgk4kICk+4WUcj3w==",
+      "version": "0.8.4",
+      "resolved": "https://registry.npmjs.org/microbundle/-/microbundle-0.8.4.tgz",
+      "integrity": "sha512-5mBtwzCQPVlPUDDDG26NYyVado9SFcOirmOSVG96zObsKaaqmvaNSSfzFa/+5sb6Gc1T3Ty0o+0RDM/KYnD+9g==",
       "dev": true,
       "requires": {
         "@babel/core": "^7.1.6",
@@ -2906,7 +2907,7 @@         "@babel/plugin-syntax-jsx": "^7.0.0",
         "@babel/polyfill": "^7.0.0",
         "asyncro": "^3.0.0",
         "autoprefixer": "^9.0.0",
-        "babel-plugin-transform-async-to-promises": "^0.8.1",
+        "babel-plugin-transform-async-to-promises": "^0.8.3",
         "brotli-size": "^0.0.3",
         "camelcase": "^5.0.0",
         "chalk": "^2.4.0",
@@ -2921,6 +2922,7 @@         "rollup-plugin-bundle-size": "^1.0.1",
         "rollup-plugin-commonjs": "^9.0.0",
         "rollup-plugin-es3": "^1.1.0",
         "rollup-plugin-flow": "^1.1.1",
+        "rollup-plugin-json": "^3.1.0",
         "rollup-plugin-node-resolve": "^3.3.0",
         "rollup-plugin-postcss": "^1.6.1",
         "rollup-plugin-preserve-shebang": "^0.1.6",
@@ -3115,9 +3117,9 @@         "semver": "^5.4.1"
       }
     },
     "node-releases": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.1.tgz",
-      "integrity": "sha512-2UXrBr6gvaebo5TNF84C66qyJJ6r0kxBObgZIDX3D3/mt1ADKiHux3NJPWisq0wxvJJdkjECH+9IIKYViKj71Q==",
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.2.tgz",
+      "integrity": "sha512-j1gEV/zX821yxdWp/1vBMN0pSUjuH9oGUdLCb4PfUko6ZW7KdRs3Z+QGGwDUhYtSpQvdVVyLd2V0YvLsmdg5jQ==",
       "dev": true,
       "requires": {
         "semver": "^5.3.0"
@@ -3288,6 +3290,11 @@       "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
       "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
       "dev": true
     },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
+    },
     "p-queue": {
       "version": "2.4.2",
       "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-2.4.2.tgz",
@@ -3401,9 +3408,9 @@         "extend-shallow": "^1.1.2"
       }
     },
     "postcss": {
-      "version": "7.0.6",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.6.tgz",
-      "integrity": "sha512-Nq/rNjnHFcKgCDDZYO0lNsl6YWe6U7tTy+ESN+PnLxebL8uBtYX59HZqvrj7YLK5UCyll2hqDsJOo3ndzEW8Ug==",
+      "version": "7.0.7",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
+      "integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
       "dev": true,
       "requires": {
         "chalk": "^2.4.1",
@@ -4819,12 +4826,12 @@       "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=",
       "dev": true
     },
     "resolve": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
-      "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz",
+      "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==",
       "dev": true,
       "requires": {
-        "path-parse": "^1.0.5"
+        "path-parse": "^1.0.6"
       }
     },
     "resolve-from": {
@@ -4996,6 +5003,15 @@           }
         }
       }
     },
+    "rollup-plugin-json": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/rollup-plugin-json/-/rollup-plugin-json-3.1.0.tgz",
+      "integrity": "sha512-BlYk5VspvGpjz7lAwArVzBXR60JK+4EKtPkCHouAWg39obk9S61hZYJDBfMK+oitPdoe11i69TlxKlMQNFC/Uw==",
+      "dev": true,
+      "requires": {
+        "rollup-pluginutils": "^2.3.1"
+      }
+    },
     "rollup-plugin-node-resolve": {
       "version": "3.4.0",
       "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.4.0.tgz",
@@ -6308,6 +6324,15 @@             "graceful-fs": "^4.1.2",
             "jsonfile": "^4.0.0",
             "universalify": "^0.1.0"
           }
+        },
+        "resolve": {
+          "version": "1.8.1",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
+          "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+          "dev": true,
+          "requires": {
+            "path-parse": "^1.0.5"
+          }
         }
       }
     },
@@ -6393,7 +6418,6 @@     "simple-swizzle": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
       "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
-      "dev": true,
       "requires": {
         "is-arrayish": "^0.3.1"
       },
@@ -6401,8 +6425,7 @@       "dependencies": {
         "is-arrayish": {
           "version": "0.3.2",
           "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
-          "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
-          "dev": true
+          "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
         }
       }
     },
@@ -6728,6 +6751,14 @@       "dev": true,
       "requires": {
         "globalyzer": "^0.1.0",
         "globrex": "^0.1.1"
+      }
+    },
+    "tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "requires": {
+        "os-tmpdir": "~1.0.2"
       }
     },
     "to-absolute-glob": {
M package.jsonpackage.json
 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
diff --git a/package.json b/package.json
index 9f46fb415e42bd1cbc8c1f11d96f37699c278395..470c7bfed88f3737cf35c02d8a89c876e881c1a0 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@   "description": "Tailwind CSS class name completion",
   "version": "0.1.16",
   "publisher": "bradlc",
   "engines": {
-    "vscode": "^1.23.0"
+    "vscode": "^1.30.0"
   },
   "categories": [
     "Other"
@@ -39,6 +39,20 @@           "source.css.less",
           "source.css.postcss"
         ]
       }
+    ],
+    "views": {
+      "explorer": [
+        {
+          "id": "tailwindcssConfigExplorer",
+          "name": "Tailwind CSS"
+        }
+      ]
+    },
+    "commands": [
+      {
+        "command": "tailwindcss.goToDefinition",
+        "title": "Go To Definition"
+      }
     ]
   },
   "preview": true,
@@ -61,10 +75,13 @@     "type": "git",
     "url": "https://github.com/bradlc/vscode-tailwindcss.git"
   },
   "dependencies": {
+    "color": "^3.1.0",
+    "dlv": "^1.1.2",
+    "tmp": "0.0.33",
     "vscode-languageclient": "^5.2.1"
   },
   "devDependencies": {
-    "microbundle": "^0.8.3",
+    "microbundle": "^0.8.4",
     "vscode": "^1.1.26"
   }
 }
I resources/icons/border_all.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/border_all.svg b/resources/icons/border_all.svg
new file mode 100644
index 0000000000000000000000000000000000000000..26405e581ed51f822a5e619b5d2d8bd094252bb1
--- /dev/null
+++ b/resources/icons/border_all.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><path d="M3 3v18h18V3H3zm8 16H5v-6h6v6zm0-8H5V5h6v6zm8 8h-6v-6h6v6zm0-8h-6V5h6v6z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
I resources/icons/devices.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/devices.svg b/resources/icons/devices.svg
new file mode 100644
index 0000000000000000000000000000000000000000..c60e541621e543fbf321983c2c46feec3937167c
--- /dev/null
+++ b/resources/icons/devices.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><path d="M4 6h18V4H4c-1.1 0-2 .9-2 2v11H0v3h14v-3H4V6zm19 2h-6c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zm-1 9h-4v-7h4v7z"/></svg>
I resources/icons/flip_to_front.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/flip_to_front.svg b/resources/icons/flip_to_front.svg
new file mode 100644
index 0000000000000000000000000000000000000000..3c4358adf90ec2ae5df8acba4d7888c4e2bd8a08
--- /dev/null
+++ b/resources/icons/flip_to_front.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><g transform="translate(24,0) scale(-1,1)"><path d="M0 0h24v24H0z" fill="none"/><path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm2 4v-2H3c0 1.1.89 2 2 2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-18H9c-1.11 0-2 .9-2 2v10c0 1.1.89 2 2 2h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12H9V5h10v10zm-8 6h2v-2h-2v2zm-4 0h2v-2H7v2z"/></g></svg>
I resources/icons/format_bold.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/format_bold.svg b/resources/icons/format_bold.svg
new file mode 100644
index 0000000000000000000000000000000000000000..a661435e4a27f994cd738f0b6d3d78000d8fb82d
--- /dev/null
+++ b/resources/icons/format_bold.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
I resources/icons/format_line_spacing.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/format_line_spacing.svg b/resources/icons/format_line_spacing.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d0ff5b1b0fcb1bad31283914fbf17de6ad34bca3
--- /dev/null
+++ b/resources/icons/format_line_spacing.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><path d="M6 7h2.5L5 3.5 1.5 7H4v10H1.5L5 20.5 8.5 17H6V7zm4-2v2h12V5H10zm0 14h12v-2H10v2zm0-6h12v-2H10v2z"/></svg>
I resources/icons/format_size.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/format_size.svg b/resources/icons/format_size.svg
new file mode 100644
index 0000000000000000000000000000000000000000..7cbca4247aa849a9b1cd1f5513bb730444ac1b5b
--- /dev/null
+++ b/resources/icons/format_size.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><path d="M0 0h24v24H0z" fill="none"/><path d="M9 4v3h5v12h3V7h5V4H9zm-6 8h3v7h3v-7h3V9H3v3z"/></svg>
I resources/icons/layers.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/layers.svg b/resources/icons/layers.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2866f6c871abe5270dab179d514a12692676c2fc
--- /dev/null
+++ b/resources/icons/layers.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><path d="M11.99 18.54l-7.37-5.73L3 14.07l9 7 9-7-1.63-1.27-7.38 5.74zM12 16l7.36-5.73L21 9l-9-7-9 7 1.63 1.27L12 16z"/></svg>
I resources/icons/opacity.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/opacity.svg b/resources/icons/opacity.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2d0253e30f54f55ae86a378ec801fef03309d676
--- /dev/null
+++ b/resources/icons/opacity.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><path d="M17.66 8L12 2.35 6.34 8C4.78 9.56 4 11.64 4 13.64s.78 4.11 2.34 5.67 3.61 2.35 5.66 2.35 4.1-.79 5.66-2.35S20 15.64 20 13.64 19.22 9.56 17.66 8zM6 14c.01-2 .62-3.27 1.76-4.4L12 5.27l4.24 4.38C17.38 10.77 17.99 12 18 14H6z"/></svg>
I resources/icons/padding.svg
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
diff --git a/resources/icons/padding.svg b/resources/icons/padding.svg
new file mode 100644
index 0000000000000000000000000000000000000000..c539617cf3a72398d94025300052b7498129df63
--- /dev/null
+++ b/resources/icons/padding.svg
@@ -0,0 +1,11 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3" xmlns="http://www.w3.org/2000/svg">
+  <path d="M9 9H7C7 7.9 7.9 7 9 7V9Z"/>
+  <path d="M15 9L15 7C16.1 7 17 7.9 17 9L15 9Z"/>
+  <path d="M9 15L9 17C7.9 17 7 16.1 7 15L9 15Z"/>
+  <path d="M15 15L17 15C17 16.1 16.1 17 15 17L15 15Z"/>
+  <path fill-rule="evenodd" clip-rule="evenodd" d="M21 3H3V21H21V3ZM19 5H5V19H19V5Z"/>
+  <rect x="11" y="7" width="2" height="2"/>
+  <rect x="7" y="11" width="2" height="2"/>
+  <rect x="11" y="15" width="2" height="2"/>
+  <rect x="15" y="11" width="2" height="2"/>
+</svg>
I resources/icons/palette.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/palette.svg b/resources/icons/palette.svg
new file mode 100644
index 0000000000000000000000000000000000000000..c1b18fbb8ac716eb0c58c35d11b86349edc0d1db
--- /dev/null
+++ b/resources/icons/palette.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></svg>
I resources/icons/photo_size_select_large.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/photo_size_select_large.svg b/resources/icons/photo_size_select_large.svg
new file mode 100644
index 0000000000000000000000000000000000000000..3c269bb6d43ee4376b0b991d49ee8f6e633d58e1
--- /dev/null
+++ b/resources/icons/photo_size_select_large.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><path d="M21 15h2v2h-2v-2zm0-4h2v2h-2v-2zm2 8h-2v2c1 0 2-1 2-2zM13 3h2v2h-2V3zm8 4h2v2h-2V7zm0-4v2h2c0-1-1-2-2-2zM1 7h2v2H1V7zm16-4h2v2h-2V3zm0 16h2v2h-2v-2zM3 3C2 3 1 4 1 5h2V3zm6 0h2v2H9V3zM5 3h2v2H5V3zm-4 8v8c0 1.1.9 2 2 2h12V11H1zm2 8l2.5-3.21 1.79 2.15 2.5-3.22L13 19H3z"/></svg>
I resources/icons/rounded_corner.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/rounded_corner.svg b/resources/icons/rounded_corner.svg
new file mode 100644
index 0000000000000000000000000000000000000000..31c3f59f63930292032dd7c2f34d02351ea8afa9
--- /dev/null
+++ b/resources/icons/rounded_corner.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><defs><path id="a" d="M0 0h24v24H0V0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path clip-path="url(#b)" d="M19 19h2v2h-2v-2zm0-2h2v-2h-2v2zM3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm0-4h2V3H3v2zm4 0h2V3H7v2zm8 16h2v-2h-2v2zm-4 0h2v-2h-2v2zm4 0h2v-2h-2v2zm-8 0h2v-2H7v2zm-4 0h2v-2H3v2zM21 8c0-2.76-2.24-5-5-5h-5v2h5c1.65 0 3 1.35 3 3v5h2V8z"/></svg>
I resources/icons/select_all.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/select_all.svg b/resources/icons/select_all.svg
new file mode 100644
index 0000000000000000000000000000000000000000..40e00727a4db0d8b7d567d48ecb7d45310608eaf
--- /dev/null
+++ b/resources/icons/select_all.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><path d="M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z"/></svg>
I resources/icons/straighten.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/straighten.svg b/resources/icons/straighten.svg
new file mode 100644
index 0000000000000000000000000000000000000000..ff76d0f4ac3e6197c9074477eec6ae8c9629784e
--- /dev/null
+++ b/resources/icons/straighten.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><path d="M21 6H3c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 10H3V8h2v4h2V8h2v4h2V8h2v4h2V8h2v4h2V8h2v8z"/></svg>
I resources/icons/title.svg
1
2
3
4
5
6
7
diff --git a/resources/icons/title.svg b/resources/icons/title.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2fae722ac9a570e1faed4e341be916a86cac0b41
--- /dev/null
+++ b/resources/icons/title.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3"><path d="M5 4v3h5.5v12h3V7H19V4z"/></svg>
I resources/icons/tracking.svg
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
diff --git a/resources/icons/tracking.svg b/resources/icons/tracking.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d75b8e3c3bd32f769406f3b4ef483e45ec5aae63
--- /dev/null
+++ b/resources/icons/tracking.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="#44a8b3" xmlns="http://www.w3.org/2000/svg">
+<path d="M11 2L5.5 16H7.75L8.87 13H15.12L16.24 16H18.49L13 2H11ZM9.62 11L12 4.67L14.38 11H9.62V11Z"/>
+<path d="M17.5 24L17.5 21.5L6.5 21.5L6.5 24L3 20.5L6.5 17L6.5 19.5L17.5 19.5L17.5 17L21 20.5L17.5 24Z"/>
+</svg>
M src/extension.tssrc/extension.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
diff --git a/src/extension.ts b/src/extension.ts
index 1d3abec27e58559cfefc51ff68b3b8525ca33337..9429c41ae405b98211d49dd9899ce3167dce8261 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -7,9 +7,14 @@   workspace as Workspace,
   window as Window,
   ExtensionContext,
   TextDocument,
+  TextEditor,
   OutputChannel,
   WorkspaceFolder,
-  Uri
+  Uri,
+  commands,
+  Selection,
+  Position,
+  Range
 } from 'vscode'
 
 import {
@@ -18,6 +23,10 @@   LanguageClientOptions,
   TransportKind
 } from 'vscode-languageclient'
 
+import { createTreeView } from './treeView'
+
+const CONFIG_GLOB =
+  '**/{tailwind,tailwind.config,tailwind-config,.tailwindrc}.js'
 let LANGUAGES: string[] = ['html']
 
 let defaultClient: LanguageClient
@@ -60,13 +69,34 @@   }
   return folder
 }
 
-export function activate(context: ExtensionContext) {
+export async function activate(context: ExtensionContext) {
   // let module = context.asAbsolutePath(path.join('server', 'out', 'server.js'))
   let module = '/Users/brad/Code/tailwindcss-language-server/dist/index.js'
   let outputChannel: OutputChannel = Window.createOutputChannel(
     'lsp-multi-server-example'
   )
 
+  let files = await Workspace.findFiles(CONFIG_GLOB, '**/node_modules/**', 1)
+
+  if (!files.length) return
+
+  let configPath = files[0].fsPath
+  delete require.cache[configPath]
+
+  let refresh = createTreeView(configPath)
+  commands.registerCommand('tailwindcss.goToDefinition', () => {
+    // refresh()
+    // Window.showInformationMessage('Hello World!')
+    Workspace.openTextDocument(files[0]).then((doc: TextDocument) => {
+      Window.showTextDocument(doc).then((editor: TextEditor) => {
+        let start = new Position(0, 0)
+        let end = new Position(0, 0)
+        editor.revealRange(new Range(start, end))
+        editor.selection = new Selection(start, end)
+      })
+    })
+  })
+
   function didOpenTextDocument(document: TextDocument): void {
     if (
       document.uri.scheme !== 'file' ||
@@ -109,6 +139,11 @@         'LSP Multi Server Example',
         serverOptions,
         clientOptions
       )
+      // client.onReady().then(() => {
+      //   client.onNotification('tailwind/loaded', () => {
+      //     console.log('loaded')
+      //   })
+      // })
       client.start()
       clients.set(folder.uri.toString(), client)
     }
I src/treeView.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
 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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
diff --git a/src/treeView.ts b/src/treeView.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6931c6cad12fd3fbc3a609dd3655e26d57d52cf4
--- /dev/null
+++ b/src/treeView.ts
@@ -0,0 +1,219 @@
+import {
+  TreeDataProvider,
+  TreeItem,
+  TreeItemCollapsibleState,
+  window as Window,
+  Command,
+  Event,
+  EventEmitter
+} from 'vscode'
+import { getSvgColorFromValue, createTempFile } from './util'
+import dlv from 'dlv'
+import * as path from 'path'
+
+const ICONS = {
+  colors: 'palette.svg',
+  backgroundColors: 'palette.svg',
+  borderColors: 'palette.svg',
+  textColors: 'palette.svg',
+  svgFill: 'palette.svg',
+  svgStroke: 'palette.svg',
+  screens: 'devices.svg',
+  textSizes: 'format_size.svg',
+  fonts: 'title.svg',
+  fontWeights: 'format_bold.svg',
+  zIndex: 'layers.svg',
+  borderWidths: 'border_all.svg',
+  shadows: 'flip_to_front.svg',
+  borderRadius: 'rounded_corner.svg',
+  width: 'straighten.svg',
+  minWidth: 'straighten.svg',
+  maxWidth: 'straighten.svg',
+  height: 'straighten.svg',
+  minHeight: 'straighten.svg',
+  maxHeight: 'straighten.svg',
+  opacity: 'opacity.svg',
+  leading: 'format_line_spacing.svg',
+  backgroundSize: 'photo_size_select_large.svg',
+  padding: 'padding.svg',
+  margin: 'select_all.svg',
+  negativeMargin: 'select_all.svg',
+  tracking: 'tracking.svg'
+}
+
+function configValueToString(value: any): string {
+  if (Array.isArray(value)) {
+    return value.join(', ')
+  }
+  return value.toString()
+}
+
+function isObject(val: any): boolean {
+  return val != null && typeof val === 'object' && Array.isArray(val) === false
+}
+
+class ConfigItem extends TreeItem {
+  constructor(
+    public label: string,
+    public key: string[],
+    public collapsibleState: TreeItemCollapsibleState,
+    public description?: string,
+    public iconPath?: string,
+    public command?: Command
+  ) {
+    super(label, collapsibleState)
+    this.key = key
+    this.description = description
+    this.iconPath = iconPath
+  }
+}
+
+class TailwindDataProvider implements TreeDataProvider<ConfigItem> {
+  private _onDidChangeTreeData: EventEmitter<ConfigItem | null> = new EventEmitter<ConfigItem | null>()
+  readonly onDidChangeTreeData: Event<ConfigItem | null> = this
+    ._onDidChangeTreeData.event
+
+  private config: any
+
+  constructor(public configPath: string) {
+    this.config = require(configPath)
+  }
+  public refresh(configPath?: string): void {
+    if (configPath) this.configPath = configPath
+    delete require.cache[this.configPath]
+    this.config = require(this.configPath)
+    this._onDidChangeTreeData.fire()
+  }
+  getTreeItem(element: ConfigItem): ConfigItem {
+    return element
+  }
+  async getChildren(element: ConfigItem): Promise<ConfigItem[]> {
+    let command = {
+      command: 'tailwindcss.goToDefinition',
+      title: 'Go To Definition'
+    }
+    if (element) {
+      let item = dlv(this.config, element.key)
+      let children = Object.keys(item).map(key => {
+        let isObj = isObject(item[key])
+        let child = new ConfigItem(
+          key,
+          element.key.concat(key),
+          isObj
+            ? TreeItemCollapsibleState.Collapsed
+            : TreeItemCollapsibleState.None,
+          isObj ? undefined : configValueToString(item[key]),
+          undefined,
+          isObj ? undefined : command
+        )
+        let color = getSvgColorFromValue(item[key])
+
+        if (color) {
+          return createTempFile(
+            `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><rect x="3.45" y="3.45" width="9.1" height="9.1" fill="${color}" /><rect x="2.8" y="2.8" width="10.4" height="10.4" fill="none" stroke="black" stroke-width="1.3" /></svg>`,
+            { postfix: '.svg' }
+          ).then(iconPath => {
+            child.iconPath = iconPath
+            return child
+          })
+        }
+
+        return child
+      })
+      return Promise.all(children)
+    }
+
+    return Object.keys(this.config)
+      .filter(key => ['modules', 'plugins', 'options'].indexOf(key) === -1)
+      .map(
+        key =>
+          new ConfigItem(
+            key,
+            [key],
+            isObject(this.config[key])
+              ? TreeItemCollapsibleState.Collapsed
+              : TreeItemCollapsibleState.None,
+            isObject(this.config[key])
+              ? undefined
+              : configValueToString(this.config[key]),
+            ICONS[key]
+              ? path.join(
+                  __filename,
+                  '..',
+                  '..',
+                  'resources',
+                  'icons',
+                  ICONS[key]
+                )
+              : undefined,
+            isObject(this.config[key]) ? undefined : command
+          )
+      )
+  }
+}
+
+function treeDataProvider1(config): TreeDataProvider<TreeItem> {
+  return {
+    getChildren: async (element): Promise<TreeItem[]> => {
+      if (element) {
+        let child = dlv(config, element.label, {})
+        let items = Object.keys(child).map(key => {
+          let color = getSvgColorFromValue(child[key])
+
+          if (color) {
+            return createTempFile(
+              `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><rect x="3.45" y="3.45" width="9.1" height="9.1" fill="${color}" /><rect x="2.8" y="2.8" width="10.4" height="10.4" fill="none" stroke="black" stroke-width="1.3" /></svg>`,
+              { postfix: '.svg' }
+            ).then(iconPath => ({
+              label: key,
+              description: configValueToString(child[key]),
+              iconPath
+            }))
+          }
+
+          return Promise.resolve({
+            label: key,
+            description: configValueToString(child[key])
+          })
+        })
+        return Promise.all(items)
+      }
+
+      return Object.keys(config)
+        .filter(key => ['modules', 'plugins', 'options'].indexOf(key) === -1)
+        .map(key => ({
+          label: key,
+          collapsibleState: isObject(config[key])
+            ? TreeItemCollapsibleState.Collapsed
+            : TreeItemCollapsibleState.None,
+          description: isObject(config[key])
+            ? undefined
+            : configValueToString(config[key]),
+          iconPath: ICONS[key]
+            ? path.join(
+                __filename,
+                '..',
+                '..',
+                'resources',
+                'icons',
+                ICONS[key]
+              )
+            : undefined
+        }))
+    },
+    getTreeItem: (element: TreeItem): TreeItem => {
+      return element
+    }
+  }
+}
+
+export function createTreeView(configPath) {
+  let provider = new TailwindDataProvider(configPath)
+  let view = Window.createTreeView('tailwindcssConfigExplorer', {
+    treeDataProvider: provider,
+    showCollapseAll: true
+  })
+  view.reveal(undefined)
+
+  return () => provider.refresh()
+}
I src/util.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
diff --git a/src/util.ts b/src/util.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5d3f624607ddb7384776f0bbc2145e366ef428cb
--- /dev/null
+++ b/src/util.ts
@@ -0,0 +1,31 @@
+import * as fs from 'fs'
+import Color from 'color'
+import tmp from 'tmp'
+
+export function createTempFile(content: string, options = {}): Promise<string> {
+  return new Promise((resolve, reject) => {
+    tmp.file(options, (err, path) => {
+      if (err) return reject(err)
+      fs.writeFile(path, content, 'utf8', err => {
+        if (err) return reject(err)
+        resolve(path)
+      })
+    })
+  })
+}
+
+export function getSvgColorFromValue(value: string): string {
+  if (typeof value !== 'string') return null
+
+  if (value === 'transparent') {
+    return 'none'
+  }
+
+  try {
+    let parsed = Color(value)
+    if (parsed.valpha === 0) return 'none'
+    return parsed.rgb().string()
+  } catch (err) {
+    return null
+  }
+}