add tree view

master
Brad Cornes 2018-12-28 18:38:12 +00:00
parent 99be4063c4
commit b1ee4759c5
21 changed files with 408 additions and 46 deletions

115
package-lock.json generated
View File

@ -286,9 +286,9 @@
"dev": true "dev": true
}, },
"@types/node": { "@types/node": {
"version": "10.12.15", "version": "10.12.17",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.15.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.17.tgz",
"integrity": "sha512-9kROxduaN98QghwwHmxXO2Xz3MaWf+I1sLVAA6KJDF5xix+IyXVhds0MAfdNwtcpSrzhaTsNB0/jnL86fgUhqA==", "integrity": "sha512-umSCRkjWH70uNzFiOof5yxCqrMXIBJ9UJJUzbEsmtWt8apURQh06pylGMqnhdjHGJSeoBrhzk+mibu6NgL1oBA==",
"dev": true "dev": true
}, },
"@types/q": { "@types/q": {
@ -477,13 +477,13 @@
"dev": true "dev": true
}, },
"autoprefixer": { "autoprefixer": {
"version": "9.4.2", "version": "9.4.3",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.2.tgz", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.3.tgz",
"integrity": "sha512-tYQYJvZvqlJCzF+BLC//uAcdT/Yy4ik9bwZRXr/EehUJ/bjjpTthsWTy8dpowdoIE1sLCDf1ch4Eb2cOSzZC9w==", "integrity": "sha512-/XSnzDepRkAU//xLcXA/lUWxpsBuw0WiriAHOqnxkuCtzLhaz+fL4it4gp20BQ8n5SyLzK/FOc7A0+u/rti2FQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"browserslist": "^4.3.5", "browserslist": "^4.3.6",
"caniuse-lite": "^1.0.30000914", "caniuse-lite": "^1.0.30000921",
"normalize-range": "^0.1.2", "normalize-range": "^0.1.2",
"num2fraction": "^1.2.2", "num2fraction": "^1.2.2",
"postcss": "^7.0.6", "postcss": "^7.0.6",
@ -856,7 +856,6 @@
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/color/-/color-3.1.0.tgz", "resolved": "https://registry.npmjs.org/color/-/color-3.1.0.tgz",
"integrity": "sha512-CwyopLkuRYO5ei2EpzpIh6LqJMt6Mt+jZhO5VI5f/wJLZriXQE32/SSqzmrh+QB+AZT81Cj8yv+7zwToW8ahZg==", "integrity": "sha512-CwyopLkuRYO5ei2EpzpIh6LqJMt6Mt+jZhO5VI5f/wJLZriXQE32/SSqzmrh+QB+AZT81Cj8yv+7zwToW8ahZg==",
"dev": true,
"requires": { "requires": {
"color-convert": "^1.9.1", "color-convert": "^1.9.1",
"color-string": "^1.5.2" "color-string": "^1.5.2"
@ -866,7 +865,6 @@
"version": "1.9.3", "version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": { "requires": {
"color-name": "1.1.3" "color-name": "1.1.3"
} }
@ -874,14 +872,12 @@
"color-name": { "color-name": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
"dev": true
}, },
"color-string": { "color-string": {
"version": "1.5.3", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
"integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
"dev": true,
"requires": { "requires": {
"color-name": "^1.0.0", "color-name": "^1.0.0",
"simple-swizzle": "^0.2.2" "simple-swizzle": "^0.2.2"
@ -978,9 +974,9 @@
} }
}, },
"core-js": { "core-js": {
"version": "2.6.0", "version": "2.6.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.0.tgz", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz",
"integrity": "sha512-kLRC6ncVpuEW/1kwrOXYX6KQASCVtrh1gQr/UiaVgFlf9WE5Vp+lNe5+h3LuMr5PAucWnnEXwH0nQHRH/gpGtw==", "integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==",
"dev": true "dev": true
}, },
"core-util-is": { "core-util-is": {
@ -1394,6 +1390,11 @@
"integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==",
"dev": true "dev": true
}, },
"dlv": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.2.tgz",
"integrity": "sha512-xxD4VSH67GbRvSGUrckvha94RD7hjgOH7rqGxiytLpkaeMvixOHFZTGFK6EkIm3T761OVHT8ABHmGkq9gXgu6Q=="
},
"dom-serializer": { "dom-serializer": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
@ -1466,9 +1467,9 @@
} }
}, },
"electron-to-chromium": { "electron-to-chromium": {
"version": "1.3.92", "version": "1.3.94",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.92.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.94.tgz",
"integrity": "sha512-En051LMzMl3/asMWGZEtU808HOoVWIpmmZx1Ep8N+TT9e7z/X8RcLeBU2kLSNLGQ+5SuKELzMx+MVuTBXk6Q9w==", "integrity": "sha512-miQqXALb6eBD3OetCtg3UM5XTLMwHISux0l6mh14iiV5SE+qvftgOCXT9Vvp53fWaCLET4sfA/SmIMYHXkaNmw==",
"dev": true "dev": true
}, },
"emojis-list": { "emojis-list": {
@ -1948,9 +1949,9 @@
"dev": true "dev": true
}, },
"globrex": { "globrex": {
"version": "0.1.1", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.1.tgz", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
"integrity": "sha512-bqKcPhb+ZtrISivpu6oLmwIyINlPlzueO/BDCdfnzUeu7SYxnHTXmWP7uQI5PnQXc5yGXOscGBEGagloA2hcSw==", "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
"dev": true "dev": true
}, },
"graceful-fs": { "graceful-fs": {
@ -2605,9 +2606,9 @@
} }
}, },
"js-base64": { "js-base64": {
"version": "2.4.9", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.0.tgz",
"integrity": "sha512-xcinL3AuDJk7VSzsHgb9DvvIXayBbadtMZ4HFPx8rUszbW1MuNMlwYVC4zzCZ6e1sqZpnNS5ZFYOhXqA39T7LQ==", "integrity": "sha512-wlEBIZ5LP8usDylWbDNhKPEFVFdI5hCHpnVoT/Ysvoi/PRhJENm/Rlh9TvjYB38HFfKZN7OzEbRjmjvLkFw11g==",
"dev": true "dev": true
}, },
"js-tokens": { "js-tokens": {
@ -2895,9 +2896,9 @@
} }
}, },
"microbundle": { "microbundle": {
"version": "0.8.3", "version": "0.8.4",
"resolved": "https://registry.npmjs.org/microbundle/-/microbundle-0.8.3.tgz", "resolved": "https://registry.npmjs.org/microbundle/-/microbundle-0.8.4.tgz",
"integrity": "sha512-vJHzfwWFG4Q6Oly+gVE4mm/3t+eqtG+VeHaHNo5ev6i00XoMXJJ5RbTg7Rawh4r5ZkltjLEgk4kICk+4WUcj3w==", "integrity": "sha512-5mBtwzCQPVlPUDDDG26NYyVado9SFcOirmOSVG96zObsKaaqmvaNSSfzFa/+5sb6Gc1T3Ty0o+0RDM/KYnD+9g==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/core": "^7.1.6", "@babel/core": "^7.1.6",
@ -2906,7 +2907,7 @@
"@babel/polyfill": "^7.0.0", "@babel/polyfill": "^7.0.0",
"asyncro": "^3.0.0", "asyncro": "^3.0.0",
"autoprefixer": "^9.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", "brotli-size": "^0.0.3",
"camelcase": "^5.0.0", "camelcase": "^5.0.0",
"chalk": "^2.4.0", "chalk": "^2.4.0",
@ -2921,6 +2922,7 @@
"rollup-plugin-commonjs": "^9.0.0", "rollup-plugin-commonjs": "^9.0.0",
"rollup-plugin-es3": "^1.1.0", "rollup-plugin-es3": "^1.1.0",
"rollup-plugin-flow": "^1.1.1", "rollup-plugin-flow": "^1.1.1",
"rollup-plugin-json": "^3.1.0",
"rollup-plugin-node-resolve": "^3.3.0", "rollup-plugin-node-resolve": "^3.3.0",
"rollup-plugin-postcss": "^1.6.1", "rollup-plugin-postcss": "^1.6.1",
"rollup-plugin-preserve-shebang": "^0.1.6", "rollup-plugin-preserve-shebang": "^0.1.6",
@ -3115,9 +3117,9 @@
} }
}, },
"node-releases": { "node-releases": {
"version": "1.1.1", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.1.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.2.tgz",
"integrity": "sha512-2UXrBr6gvaebo5TNF84C66qyJJ6r0kxBObgZIDX3D3/mt1ADKiHux3NJPWisq0wxvJJdkjECH+9IIKYViKj71Q==", "integrity": "sha512-j1gEV/zX821yxdWp/1vBMN0pSUjuH9oGUdLCb4PfUko6ZW7KdRs3Z+QGGwDUhYtSpQvdVVyLd2V0YvLsmdg5jQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"semver": "^5.3.0" "semver": "^5.3.0"
@ -3288,6 +3290,11 @@
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
"dev": true "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": { "p-queue": {
"version": "2.4.2", "version": "2.4.2",
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-2.4.2.tgz", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-2.4.2.tgz",
@ -3401,9 +3408,9 @@
} }
}, },
"postcss": { "postcss": {
"version": "7.0.6", "version": "7.0.7",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.6.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
"integrity": "sha512-Nq/rNjnHFcKgCDDZYO0lNsl6YWe6U7tTy+ESN+PnLxebL8uBtYX59HZqvrj7YLK5UCyll2hqDsJOo3ndzEW8Ug==", "integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
"dev": true, "dev": true,
"requires": { "requires": {
"chalk": "^2.4.1", "chalk": "^2.4.1",
@ -4819,12 +4826,12 @@
"dev": true "dev": true
}, },
"resolve": { "resolve": {
"version": "1.8.1", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz",
"integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"path-parse": "^1.0.5" "path-parse": "^1.0.6"
} }
}, },
"resolve-from": { "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": { "rollup-plugin-node-resolve": {
"version": "3.4.0", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.4.0.tgz", "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.4.0.tgz",
@ -6308,6 +6324,15 @@
"jsonfile": "^4.0.0", "jsonfile": "^4.0.0",
"universalify": "^0.1.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 @@
"version": "0.2.2", "version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
"integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
"dev": true,
"requires": { "requires": {
"is-arrayish": "^0.3.1" "is-arrayish": "^0.3.1"
}, },
@ -6401,8 +6425,7 @@
"is-arrayish": { "is-arrayish": {
"version": "0.3.2", "version": "0.3.2",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
"dev": true
} }
} }
}, },
@ -6730,6 +6753,14 @@
"globrex": "^0.1.1" "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": { "to-absolute-glob": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",

View File

@ -5,7 +5,7 @@
"version": "0.1.16", "version": "0.1.16",
"publisher": "bradlc", "publisher": "bradlc",
"engines": { "engines": {
"vscode": "^1.23.0" "vscode": "^1.30.0"
}, },
"categories": [ "categories": [
"Other" "Other"
@ -39,6 +39,20 @@
"source.css.postcss" "source.css.postcss"
] ]
} }
],
"views": {
"explorer": [
{
"id": "tailwindcssConfigExplorer",
"name": "Tailwind CSS"
}
]
},
"commands": [
{
"command": "tailwindcss.goToDefinition",
"title": "Go To Definition"
}
] ]
}, },
"preview": true, "preview": true,
@ -61,10 +75,13 @@
"url": "https://github.com/bradlc/vscode-tailwindcss.git" "url": "https://github.com/bradlc/vscode-tailwindcss.git"
}, },
"dependencies": { "dependencies": {
"color": "^3.1.0",
"dlv": "^1.1.2",
"tmp": "0.0.33",
"vscode-languageclient": "^5.2.1" "vscode-languageclient": "^5.2.1"
}, },
"devDependencies": { "devDependencies": {
"microbundle": "^0.8.3", "microbundle": "^0.8.4",
"vscode": "^1.1.26" "vscode": "^1.1.26"
} }
} }

View File

@ -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>

After

Width:  |  Height:  |  Size: 226 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 258 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 410 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 383 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 213 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 199 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 224 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 338 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 567 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 569 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 383 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 528 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 421 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 238 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 140 B

View File

@ -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>

After

Width:  |  Height:  |  Size: 313 B

View File

@ -7,9 +7,14 @@ import {
window as Window, window as Window,
ExtensionContext, ExtensionContext,
TextDocument, TextDocument,
TextEditor,
OutputChannel, OutputChannel,
WorkspaceFolder, WorkspaceFolder,
Uri Uri,
commands,
Selection,
Position,
Range
} from 'vscode' } from 'vscode'
import { import {
@ -18,6 +23,10 @@ import {
TransportKind TransportKind
} from 'vscode-languageclient' } from 'vscode-languageclient'
import { createTreeView } from './treeView'
const CONFIG_GLOB =
'**/{tailwind,tailwind.config,tailwind-config,.tailwindrc}.js'
let LANGUAGES: string[] = ['html'] let LANGUAGES: string[] = ['html']
let defaultClient: LanguageClient let defaultClient: LanguageClient
@ -60,13 +69,34 @@ function getOuterMostWorkspaceFolder(folder: WorkspaceFolder): WorkspaceFolder {
return folder 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 = context.asAbsolutePath(path.join('server', 'out', 'server.js'))
let module = '/Users/brad/Code/tailwindcss-language-server/dist/index.js' let module = '/Users/brad/Code/tailwindcss-language-server/dist/index.js'
let outputChannel: OutputChannel = Window.createOutputChannel( let outputChannel: OutputChannel = Window.createOutputChannel(
'lsp-multi-server-example' '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 { function didOpenTextDocument(document: TextDocument): void {
if ( if (
document.uri.scheme !== 'file' || document.uri.scheme !== 'file' ||
@ -109,6 +139,11 @@ export function activate(context: ExtensionContext) {
serverOptions, serverOptions,
clientOptions clientOptions
) )
// client.onReady().then(() => {
// client.onNotification('tailwind/loaded', () => {
// console.log('loaded')
// })
// })
client.start() client.start()
clients.set(folder.uri.toString(), client) clients.set(folder.uri.toString(), client)
} }

219
src/treeView.ts 100644
View File

@ -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()
}

31
src/util.ts 100644
View File

@ -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
}
}