tailwind-ctp-intellisense @master -
refs -
log -
-
https://git.jolheiser.com/tailwind-ctp-intellisense.git
Tailwind intellisense + Catppuccin
feat: Yarn PnP support
Signature
-----BEGIN PGP SIGNATURE-----
iQEzBAABCgAdFiEEk3sBiNAb7hmW2YbuKyWUkXQXjr0FAl9Hps4ACgkQKyWUkXQX
jr3xeAf6A1/IFTEJMklGUbuO6FZvA0Zqfh8/1bl1qnUCClXi84dJnEg4g2Xm7daE
JLIGpSXLNbt+akj/wMhTmDQmqSXFHEC8eOFYM9HbhaVf/Y3oJSTspEXhd50wxywM
Wa0RrXtRBKlAV5HQ8rzLDMgW680krjgEzboxj1gkgA4FY2uNFtuhrdf5DzOocD0z
CoFY4SA/J+lN1dq+9bpTr6xvFi2unu+gUntq9bfenKoAq4pk0wDOg+GsTLKu3rGr
VyhHL2njGApZQIlbtfz7CZSf7VVi7ZFLWOjF2tW90XfIegcqD8Fu1PqALZnEohHM
QUABNGGHAavdXmeHCk1sYZIbJAgWkA==
=aD1A
-----END PGP SIGNATURE-----
6 changed files, 277 additions(+), 139 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 0132369f090b5354de11100221ba2f827c6daa8c..9dcd203aa2b7aac7a6cda3a5ee3556bce87fbf9f 100755
--- a/package-lock.json
+++ b/package-lock.json
@@ -2512,12 +2512,13 @@ "to-regex-range": "^5.0.1"
}
},
"find-up": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
- "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dev": true,
"requires": {
- "locate-path": "^3.0.0"
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
}
},
"for-in": {
@@ -4827,13 +4828,12 @@ "uc.micro": "^1.0.1"
}
},
"locate-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
- "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"requires": {
- "p-locate": "^3.0.0",
- "path-exists": "^3.0.0"
+ "p-locate": "^5.0.0"
}
},
"lodash": {
@@ -5319,12 +5319,23 @@ "p-try": "^2.0.0"
}
},
"p-locate": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
- "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
"requires": {
- "p-limit": "^2.0.0"
+ "p-limit": "^3.0.2"
+ },
+ "dependencies": {
+ "p-limit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz",
+ "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ }
}
},
"p-try": {
@@ -5376,9 +5387,9 @@ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
"dev": true
},
"path-exists": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
- "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
},
"path-is-absolute": {
@@ -5484,6 +5495,42 @@ "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==",
"dev": true,
"requires": {
"find-up": "^3.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ }
}
},
"pn": {
@@ -7243,6 +7290,42 @@ "string-width": "^3.0.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^13.1.2"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ }
}
},
"yargs-parser": {
diff --git a/package.json b/package.json
index ff6fe7864208f75a15f9d2db8d104adfa4f36150..e6569ff47435e9dffa3407c852dea8f7fe1ab649 100755
--- a/package.json
+++ b/package.json
@@ -189,6 +189,7 @@ "dlv": "^1.1.3",
"dset": "^2.0.1",
"esm": "^3.2.25",
"fast-glob": "^3.2.4",
+ "find-up": "^5.0.0",
"glob-exec": "^0.1.1",
"globalyzer": "^0.1.4",
"globrex": "^0.1.2",
@@ -216,5 +217,6 @@ "vscode-emmet-helper-bundled": "0.0.1",
"vscode-languageclient": "^5.2.1",
"vscode-languageserver": "^5.2.1",
"vscode-uri": "^2.1.1"
- }
+ },
+ "dependencies": {}
}
diff --git a/src/class-names/environment.js b/src/class-names/environment.js
new file mode 100644
index 0000000000000000000000000000000000000000..6364d551ae005289c06af55d771f0b9bb16156dd
--- /dev/null
+++ b/src/class-names/environment.js
@@ -0,0 +1,71 @@
+import * as path from 'path'
+import Module from 'module'
+import findUp from 'find-up'
+import resolveFrom from 'resolve-from'
+import importFrom from 'import-from'
+
+export function withUserEnvironment(base, cb) {
+ const pnpPath = findUp.sync('.pnp.js', { cwd: base })
+ if (pnpPath) {
+ return withPnpEnvironment(pnpPath, cb)
+ }
+ return withNonPnpEnvironment(base, cb)
+}
+
+function withPnpEnvironment(pnpPath, cb) {
+ const basePath = path.dirname(pnpPath)
+
+ // pnp will patch `module` and `fs` to load package in pnp environment
+ // backup the functions which will be patched here
+ const originalModule = Object.create(null)
+ originalModule._load = Module._load
+ originalModule._resolveFilename = Module._resolveFilename
+ originalModule._findPath = Module._findPath
+
+ const pnpapi = __non_webpack_require__(pnpPath)
+
+ // get into pnp environment
+ pnpapi.setup()
+
+ // restore the patched function, we can not load any package after called this
+ const restore = () => Object.assign(Module, originalModule)
+
+ const pnpResolve = (request, from = basePath) => {
+ return pnpapi.resolveRequest(request, from + '/')
+ }
+
+ const pnpRequire = (request, from) => {
+ return __non_webpack_require__(pnpResolve(request, from))
+ }
+
+ const res = cb({ resolve: pnpResolve, require: pnpRequire })
+
+ // check if it return a thenable
+ if (res != null && res.then) {
+ return res.then(
+ (x) => {
+ restore()
+ return x
+ },
+ (err) => {
+ restore()
+ throw err
+ }
+ )
+ }
+
+ restore()
+
+ return res
+}
+
+function withNonPnpEnvironment(base, cb) {
+ return cb({
+ require(request, from = base) {
+ return importFrom(from, request)
+ },
+ resolve(request, from = base) {
+ return resolveFrom(from, request)
+ },
+ })
+}
diff --git a/src/class-names/getPlugins.js b/src/class-names/getPlugins.js
index 1fa3e50458f82284ed466a4f27251857d2dc76f1..23941feb6654e1cfe59cccab9b65caec8e96d4e2 100644
--- a/src/class-names/getPlugins.js
+++ b/src/class-names/getPlugins.js
@@ -2,22 +2,18 @@ import * as path from 'path'
import stackTrace from 'stack-trace'
import pkgUp from 'pkg-up'
import { isObject } from './isObject'
-import resolveFrom from 'resolve-from'
-import importFrom from 'import-from'
+import { withUserEnvironment } from './environment'
export async function getBuiltInPlugins({ cwd, resolvedConfig }) {
- const tailwindBase = path.dirname(
- resolveFrom(cwd, 'tailwindcss/package.json')
- )
-
- try {
- // TODO: add v0 support ("generators")
- return importFrom(tailwindBase, './lib/corePlugins.js').default({
- corePlugins: resolvedConfig.corePlugins,
- })
- } catch (_) {
- return []
- }
+ return withUserEnvironment(cwd, ({ require }) => {
+ try {
+ return require('tailwindcss/lib/corePlugins.js').default({
+ corePlugins: resolvedConfig.corePlugins,
+ })
+ } catch (_) {
+ return []
+ }
+ })
}
export default function getPlugins(config) {
@@ -34,19 +30,12 @@ pluginConfig = {}
}
let contributes = {
- theme: isObject(pluginConfig.theme)
- ? Object.keys(pluginConfig.theme)
- : [],
- variants: isObject(pluginConfig.variants)
- ? Object.keys(pluginConfig.variants)
- : [],
+ theme: isObject(pluginConfig.theme) ? Object.keys(pluginConfig.theme) : [],
+ variants: isObject(pluginConfig.variants) ? Object.keys(pluginConfig.variants) : [],
}
const fn = plugin.handler || plugin
- const fnName =
- typeof fn.name === 'string' && fn.name !== 'handler' && fn.name !== ''
- ? fn.name
- : null
+ const fnName = typeof fn.name === 'string' && fn.name !== 'handler' && fn.name !== '' ? fn.name : null
try {
fn()
diff --git a/src/class-names/index.js b/src/class-names/index.js
index 773faee0927bf1e835a0949695888b6a5200aa63..b7a63c69a01328c9be1035e42dbe1df9dfbc3b27 100644
--- a/src/class-names/index.js
+++ b/src/class-names/index.js
@@ -2,8 +2,6 @@ import extractClassNames from './extractClassNames'
import Hook from './hook'
import dlv from 'dlv'
import dset from 'dset'
-import resolveFrom from 'resolve-from'
-import importFrom from 'import-from'
import chokidar from 'chokidar'
import semver from 'semver'
import invariant from 'tiny-invariant'
@@ -15,28 +13,16 @@ import * as fs from 'fs'
import { getUtilityConfigMap } from './getUtilityConfigMap'
import glob from 'fast-glob'
import normalizePath from 'normalize-path'
+import { withUserEnvironment } from './environment'
function arraysEqual(arr1, arr2) {
- return (
- JSON.stringify(arr1.concat([]).sort()) ===
- JSON.stringify(arr2.concat([]).sort())
- )
+ return JSON.stringify(arr1.concat([]).sort()) === JSON.stringify(arr2.concat([]).sort())
}
-const CONFIG_GLOB =
- '**/{tailwind,tailwind.config,tailwind-config,.tailwindrc}.js'
+const CONFIG_GLOB = '**/{tailwind,tailwind.config,tailwind-config,.tailwindrc}.js'
-export default async function getClassNames(
- cwd = process.cwd(),
- { onChange = () => {} } = {}
-) {
+export default async function getClassNames(cwd = process.cwd(), { onChange = () => {} } = {}) {
async function run() {
- let postcss
- let tailwindcss
- let browserslistModule
- let version
- let featureFlags = { future: [], experimental: [] }
-
const configPaths = (
await glob(CONFIG_GLOB, {
cwd,
@@ -53,25 +39,9 @@
invariant(configPaths.length > 0, 'No Tailwind CSS config found.')
const configPath = configPaths[0]
const configDir = path.dirname(configPath)
- const tailwindBase = path.dirname(
- resolveFrom(configDir, 'tailwindcss/package.json')
- )
- postcss = importFrom(tailwindBase, 'postcss')
- tailwindcss = importFrom(configDir, 'tailwindcss')
- version = importFrom(configDir, 'tailwindcss/package.json').version
+ const { version, featureFlags = { future: [], experimental: [] } } = loadMeta(configDir)
- try {
- // this is not required
- browserslistModule = importFrom(tailwindBase, 'browserslist')
- } catch (_) {}
-
- try {
- featureFlags = importFrom(tailwindBase, './lib/featureFlags.js').default
- } catch (_) {}
-
- const sepLocation = semver.gte(version, '0.99.0')
- ? ['separator']
- : ['options', 'separator']
+ const sepLocation = semver.gte(version, '0.99.0') ? ['separator'] : ['options', 'separator']
let userSeperator
let userPurge
let hook = Hook(fs.realpathSync(configPath), (exports) => {
@@ -94,45 +64,52 @@ }
hook.unwatch()
- let postcssResult
+ const { base, components, utilities, resolvedConfig, browserslist, postcss } = await withPackages(
+ configDir,
+ async ({ postcss, tailwindcss, browserslistModule }) => {
+ let postcssResult
+ try {
+ postcssResult = await Promise.all(
+ [semver.gte(version, '0.99.0') ? 'base' : 'preflight', 'components', 'utilities'].map((group) =>
+ postcss([tailwindcss(configPath)]).process(`@tailwind ${group};`, {
+ from: undefined,
+ })
+ )
+ )
+ } finally {
+ hook.unhook()
+ }
- try {
- postcssResult = await Promise.all(
- [
- semver.gte(version, '0.99.0') ? 'base' : 'preflight',
- 'components',
- 'utilities',
- ].map((group) =>
- postcss([tailwindcss(configPath)]).process(`@tailwind ${group};`, {
- from: undefined,
- })
- )
- )
- } catch (error) {
- throw error
- } finally {
- hook.unhook()
- }
+ const [base, components, utilities] = postcssResult
- const [base, components, utilities] = postcssResult
+ if (typeof userSeperator !== 'undefined') {
+ dset(config, sepLocation, userSeperator)
+ } else {
+ delete config[sepLocation]
+ }
+ if (typeof userPurge !== 'undefined') {
+ config.purge = userPurge
+ } else {
+ delete config.purge
+ }
- if (typeof userSeperator !== 'undefined') {
- dset(config, sepLocation, userSeperator)
- } else {
- delete config[sepLocation]
- }
- if (typeof userPurge !== 'undefined') {
- config.purge = userPurge
- } else {
- delete config.purge
- }
+ const resolvedConfig = resolveConfig({ cwd: configDir, config })
+ const browserslist = browserslistModule
+ ? browserslistModule(undefined, {
+ path: configDir,
+ })
+ : []
- const resolvedConfig = resolveConfig({ cwd: configDir, config })
- const browserslist = browserslistModule
- ? browserslistModule(undefined, {
- path: configDir,
- })
- : []
+ return {
+ base,
+ components,
+ utilities,
+ resolvedConfig,
+ postcss,
+ browserslist,
+ }
+ }
+ )
return {
version,
@@ -154,7 +131,6 @@ postcss,
browserslist,
}),
modules: {
- tailwindcss,
postcss,
},
featureFlags,
@@ -164,10 +140,7 @@
let watcher
function watch(files = []) {
unwatch()
- watcher = chokidar
- .watch(files, { cwd })
- .on('change', handleChange)
- .on('unlink', handleChange)
+ watcher = chokidar.watch(files, { cwd }).on('change', handleChange).on('unlink', handleChange)
}
function unwatch() {
if (watcher) {
@@ -193,7 +166,8 @@
let result
try {
result = await run()
- } catch (_) {
+ } catch (e) {
+ console.log(e)
return null
}
@@ -201,3 +175,31 @@ watch([result.configPath, ...result.dependencies])
return result
}
+
+function loadMeta(configDir) {
+ return withUserEnvironment(configDir, ({ require, resolve }) => {
+ const version = require('tailwindcss/package.json').version
+ let featureFlags
+
+ try {
+ featureFlags = require('tailwindcss/lib/featureFlags.js').default
+ } catch (_) {}
+
+ return { version, featureFlags }
+ })
+}
+
+function withPackages(configDir, cb) {
+ return withUserEnvironment(configDir, async ({ require, resolve }) => {
+ const tailwindBase = path.dirname(resolve('tailwindcss/package.json'))
+ const postcss = require('postcss', tailwindBase)
+ const tailwindcss = require('tailwindcss')
+ let browserslistModule
+ try {
+ // this is not required
+ browserslistModule = require('browserslist', tailwindBase)
+ } catch (_) {}
+
+ return cb({ postcss, tailwindcss, browserslistModule })
+ })
+}
diff --git a/src/class-names/resolveConfig.js b/src/class-names/resolveConfig.js
index 49a31546ef78ffbbec10b5d55dabb74b798a15e8..48aac871d5f0ed3e3e69488f2c2d0879fd7f7bf9 100644
--- a/src/class-names/resolveConfig.js
+++ b/src/class-names/resolveConfig.js
@@ -1,14 +1,8 @@
-import resolveFrom from 'resolve-from'
-import importFrom from 'import-from'
import * as path from 'path'
import decache from './decache'
+import { withUserEnvironment } from './environment'
export default function resolveConfig({ cwd, config }) {
- const tailwindBase = path.dirname(
- resolveFrom(cwd, 'tailwindcss/package.json')
- )
- let resolve = (x) => x
-
if (typeof config === 'string') {
if (!cwd) {
cwd = path.dirname(config)
@@ -17,21 +11,18 @@ decache(config)
config = __non_webpack_require__(config)
}
- try {
- resolve = importFrom(tailwindBase, './resolveConfig.js')
- } catch (_) {
+ let resolve = (x) => x
+ withUserEnvironment(cwd, ({ require }) => {
try {
- const resolveConfig = importFrom(
- tailwindBase,
- './lib/util/resolveConfig.js'
- )
- const defaultConfig = importFrom(
- tailwindBase,
- './stubs/defaultConfig.stub.js'
- )
- resolve = (config) => resolveConfig([config, defaultConfig])
- } catch (_) {}
- }
+ resolve = require('tailwindcss/resolveConfig.js')
+ } catch (_) {
+ try {
+ const resolveConfig = require('tailwindcss/lib/util/resolveConfig.js')
+ const defaultConfig = require('tailwindcss/stubs/defaultConfig.stub.js')
+ resolve = (config) => resolveConfig([config, defaultConfig])
+ } catch (_) {}
+ }
+ })
return resolve(config)
}