tailwind-ctp-intellisense @master -
refs -
log -
-
https://git.jolheiser.com/tailwind-ctp-intellisense.git
Tailwind intellisense + Catppuccin
fix error when using @​apply in plugins (#255)
5 changed files, 195 additions(+), 110 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 10a5306da6cdb74be1dca444ac0b6e29335c5797..e3f10cb9fbc2085cacbbc4e9b681e8e3e7fa9894 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6295,6 +6295,14 @@ "engines": {
"node": ">=6"
}
},
+ "node_modules/klona": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz",
+ "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/language-subtag-registry": {
"version": "0.3.20",
"license": "ODC-By-1.0"
@@ -12158,7 +12166,7 @@ }
},
"packages/tailwindcss-intellisense": {
"name": "vscode-tailwindcss",
- "version": "0.5.6",
+ "version": "0.5.7",
"license": "MIT",
"dependencies": {
"@types/debounce": "^1.2.0",
@@ -12179,6 +12187,7 @@ "find-up": "^5.0.0",
"glob-exec": "^0.1.1",
"import-from": "^3.0.0",
"jest": "^25.5.4",
+ "klona": "^2.0.4",
"mitt": "^1.2.0",
"normalize-path": "^3.0.0",
"pkg-up": "^3.1.0",
@@ -12188,7 +12197,7 @@ "resolve-from": "^5.0.0",
"rimraf": "^3.0.2",
"semver": "^7.3.2",
"stack-trace": "0.0.10",
- "tailwindcss-language-service": "0.0.10",
+ "tailwindcss-language-service": "0.0.11",
"terser": "^4.6.12",
"tiny-invariant": "^1.1.0",
"tslint": "^5.16.0",
@@ -12262,9 +12271,9 @@ "url": "https://github.com/sponsors/sindresorhus"
}
},
"packages/tailwindcss-intellisense/node_modules/tailwindcss-language-service": {
- "version": "0.0.10",
- "resolved": "https://registry.npmjs.org/tailwindcss-language-service/-/tailwindcss-language-service-0.0.10.tgz",
- "integrity": "sha512-qE2blv1x8wxSUN+PH1kjvN28UjNKhrZeZcAFHL4X35jtTbGZ2X//b1Ya+NOK5hLOFWinHPxR9PB/WeNuOSn/sQ==",
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/tailwindcss-language-service/-/tailwindcss-language-service-0.0.11.tgz",
+ "integrity": "sha512-dIOvB4CveOkz6DPYz0lqMbQHz4pEBiuTQcBMi86e+xoyW6OwosEj3k3ds6+pwra+ZN4SScxHdru63bGjWM5fiQ==",
"dependencies": {
"@ctrl/tinycolor": "^3.1.4",
"@types/moo": "^0.5.3",
@@ -12304,7 +12313,7 @@ "node": ">=4.2.0"
}
},
"packages/tailwindcss-language-service": {
- "version": "0.0.10",
+ "version": "0.0.11",
"dependencies": {
"@ctrl/tinycolor": "^3.1.4",
"@types/moo": "^0.5.3",
@@ -16490,6 +16499,11 @@ },
"kleur": {
"version": "3.0.3"
},
+ "klona": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz",
+ "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA=="
+ },
"language-subtag-registry": {
"version": "0.3.20"
},
@@ -20269,6 +20283,7 @@ "find-up": "^5.0.0",
"glob-exec": "^0.1.1",
"import-from": "^3.0.0",
"jest": "^25.5.4",
+ "klona": "^2.0.4",
"mitt": "^1.2.0",
"normalize-path": "^3.0.0",
"pkg-up": "^3.1.0",
@@ -20278,7 +20293,7 @@ "resolve-from": "^5.0.0",
"rimraf": "^3.0.2",
"semver": "^7.3.2",
"stack-trace": "0.0.10",
- "tailwindcss-language-service": "0.0.10",
+ "tailwindcss-language-service": "0.0.11",
"terser": "^4.6.12",
"tiny-invariant": "^1.1.0",
"tslint": "^5.16.0",
@@ -20325,9 +20340,9 @@ "p-limit": "^3.0.2"
}
},
"tailwindcss-language-service": {
- "version": "0.0.10",
- "resolved": "https://registry.npmjs.org/tailwindcss-language-service/-/tailwindcss-language-service-0.0.10.tgz",
- "integrity": "sha512-qE2blv1x8wxSUN+PH1kjvN28UjNKhrZeZcAFHL4X35jtTbGZ2X//b1Ya+NOK5hLOFWinHPxR9PB/WeNuOSn/sQ==",
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/tailwindcss-language-service/-/tailwindcss-language-service-0.0.11.tgz",
+ "integrity": "sha512-dIOvB4CveOkz6DPYz0lqMbQHz4pEBiuTQcBMi86e+xoyW6OwosEj3k3ds6+pwra+ZN4SScxHdru63bGjWM5fiQ==",
"requires": {
"@ctrl/tinycolor": "^3.1.4",
"@types/moo": "^0.5.3",
diff --git a/packages/tailwindcss-intellisense/package-lock.json b/packages/tailwindcss-intellisense/package-lock.json
index 814b1669e651120d49549d18a8315b6b3ba5ed09..4fee91be424210ba287d6e9de9732e8bb47b39f2 100644
--- a/packages/tailwindcss-intellisense/package-lock.json
+++ b/packages/tailwindcss-intellisense/package-lock.json
@@ -27,6 +27,7 @@ "find-up": "^5.0.0",
"glob-exec": "^0.1.1",
"import-from": "^3.0.0",
"jest": "^25.5.4",
+ "klona": "^2.0.4",
"mitt": "^1.2.0",
"normalize-path": "^3.0.0",
"pkg-up": "^3.1.0",
@@ -7105,6 +7106,14 @@ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
"integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
"engines": {
"node": ">=6"
+ }
+ },
+ "node_modules/klona": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz",
+ "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==",
+ "engines": {
+ "node": ">= 8"
}
},
"node_modules/language-subtag-registry": {
@@ -19306,6 +19315,11 @@ "kleur": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
"integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="
+ },
+ "klona": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz",
+ "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA=="
},
"language-subtag-registry": {
"version": "0.3.21",
diff --git a/packages/tailwindcss-intellisense/package.json b/packages/tailwindcss-intellisense/package.json
index 5e917bc75150cdf5ae03a4d46c4f09e783e8b8a9..80a129ff15a62dfc4b71f3878f1b1e753b192485 100755
--- a/packages/tailwindcss-intellisense/package.json
+++ b/packages/tailwindcss-intellisense/package.json
@@ -197,6 +197,7 @@ "find-up": "^5.0.0",
"glob-exec": "^0.1.1",
"import-from": "^3.0.0",
"jest": "^25.5.4",
+ "klona": "^2.0.4",
"mitt": "^1.2.0",
"normalize-path": "^3.0.0",
"pkg-up": "^3.1.0",
diff --git a/packages/tailwindcss-intellisense/src/class-names/extractClassNames.js b/packages/tailwindcss-intellisense/src/class-names/extractClassNames.js
index 35e14eb8b4b72866b9615ca9637ee74ec3f2a5c8..6079ca341920d519018725662ccdb61e564e1d7d 100644
--- a/packages/tailwindcss-intellisense/src/class-names/extractClassNames.js
+++ b/packages/tailwindcss-intellisense/src/class-names/extractClassNames.js
@@ -44,93 +44,100 @@
return classNames
}
-async function process(groups) {
+async function process(root) {
const tree = {}
const commonContext = {}
- groups.forEach((group) => {
- group.root.walkRules((rule) => {
- const classNames = getClassNamesFromSelector(rule.selector)
+ let layer
+
+ root.walk((node) => {
+ if (node.type === 'comment') {
+ let match = node.text.trim().match(/^__tw_intellisense_layer_([a-z]+)__$/)
+ if (match === null) return
+ layer = match[1]
+ node.remove()
+ return
+ }
+
+ if (node.type !== 'rule') return
+
+ const rule = node
+ const classNames = getClassNamesFromSelector(rule.selector)
- const decls = {}
- rule.walkDecls((decl) => {
- if (decls[decl.prop]) {
- decls[decl.prop] = [
- ...(Array.isArray(decls[decl.prop])
- ? decls[decl.prop]
- : [decls[decl.prop]]),
- decl.value,
- ]
- } else {
- decls[decl.prop] = decl.value
- }
- })
+ const decls = {}
+ rule.walkDecls((decl) => {
+ if (decls[decl.prop]) {
+ decls[decl.prop] = [
+ ...(Array.isArray(decls[decl.prop])
+ ? decls[decl.prop]
+ : [decls[decl.prop]]),
+ decl.value,
+ ]
+ } else {
+ decls[decl.prop] = decl.value
+ }
+ })
- let p = rule
- const keys = []
- while (p.parent.type !== 'root') {
- p = p.parent
- if (p.type === 'atrule') {
- keys.push(`@${p.name} ${p.params}`)
- }
+ let p = rule
+ const keys = []
+ while (p.parent.type !== 'root') {
+ p = p.parent
+ if (p.type === 'atrule') {
+ keys.push(`@${p.name} ${p.params}`)
}
+ }
- for (let i = 0; i < classNames.length; i++) {
- const context = keys.concat([])
- const baseKeys = classNames[i].className.split('__TAILWIND_SEPARATOR__')
- const contextKeys = baseKeys.slice(0, baseKeys.length - 1)
- const index = []
+ for (let i = 0; i < classNames.length; i++) {
+ const context = keys.concat([])
+ const baseKeys = classNames[i].className.split(/__TWSEP__.*?__TWSEP__/)
+ const contextKeys = baseKeys.slice(0, baseKeys.length - 1)
+ const index = []
- const existing = dlv(tree, [...baseKeys, '__info'])
- if (typeof existing !== 'undefined') {
- if (Array.isArray(existing)) {
- index.push(existing.length)
- } else {
- dset(tree, [...baseKeys, '__info'], [existing])
- index.push(1)
- }
+ const existing = dlv(tree, [...baseKeys, '__info'])
+ if (typeof existing !== 'undefined') {
+ if (Array.isArray(existing)) {
+ index.push(existing.length)
+ } else {
+ dset(tree, [...baseKeys, '__info'], [existing])
+ index.push(1)
}
- if (classNames[i].__rule) {
- dset(tree, [...baseKeys, '__info', ...index, '__rule'], true)
- dset(
- tree,
- [...baseKeys, '__info', ...index, '__source'],
- group.source
- )
+ }
+ if (classNames[i].__rule) {
+ dset(tree, [...baseKeys, '__info', ...index, '__rule'], true)
+ dset(tree, [...baseKeys, '__info', ...index, '__source'], layer)
- dsetEach(tree, [...baseKeys, '__info', ...index], decls)
- }
- dset(
- tree,
- [...baseKeys, '__info', ...index, '__pseudo'],
- classNames[i].__pseudo
- )
- dset(
- tree,
- [...baseKeys, '__info', ...index, '__scope'],
- classNames[i].scope
- )
- dset(
- tree,
- [...baseKeys, '__info', ...index, '__context'],
- context.concat([]).reverse()
- )
+ dsetEach(tree, [...baseKeys, '__info', ...index], decls)
+ }
+ dset(
+ tree,
+ [...baseKeys, '__info', ...index, '__pseudo'],
+ classNames[i].__pseudo
+ )
+ dset(
+ tree,
+ [...baseKeys, '__info', ...index, '__scope'],
+ classNames[i].scope
+ )
+ dset(
+ tree,
+ [...baseKeys, '__info', ...index, '__context'],
+ context.concat([]).reverse()
+ )
- // common context
- context.push(...classNames[i].__pseudo.map((x) => `&${x}`))
+ // common context
+ context.push(...classNames[i].__pseudo.map((x) => `&${x}`))
- for (let i = 0; i < contextKeys.length; i++) {
- if (typeof commonContext[contextKeys[i]] === 'undefined') {
- commonContext[contextKeys[i]] = context
- } else {
- commonContext[contextKeys[i]] = intersection(
- commonContext[contextKeys[i]],
- context
- )
- }
+ for (let i = 0; i < contextKeys.length; i++) {
+ if (typeof commonContext[contextKeys[i]] === 'undefined') {
+ commonContext[contextKeys[i]] = context
+ } else {
+ commonContext[contextKeys[i]] = intersection(
+ commonContext[contextKeys[i]],
+ context
+ )
}
}
- })
+ }
})
return { classNames: tree, context: commonContext }
diff --git a/packages/tailwindcss-intellisense/src/class-names/index.js b/packages/tailwindcss-intellisense/src/class-names/index.js
index e8034c45269416cd66518340886c3b7394a6de5d..06177bd14f57133c1098bfaabf1064c42dd7af42 100644
--- a/packages/tailwindcss-intellisense/src/class-names/index.js
+++ b/packages/tailwindcss-intellisense/src/class-names/index.js
@@ -16,6 +16,7 @@ import glob from 'fast-glob'
import normalizePath from 'normalize-path'
import { withUserEnvironment } from './environment'
import execa from 'execa'
+import { klona } from 'klona/full'
function arraysEqual(arr1, arr2) {
return (
@@ -71,7 +72,13 @@ let userPurge
let hook = Hook(fs.realpathSync(configPath), (exports) => {
userSeperator = dlv(exports, sepLocation)
userPurge = exports.purge
- dset(exports, sepLocation, '__TAILWIND_SEPARATOR__')
+ dset(
+ exports,
+ sepLocation,
+ `__TWSEP__${
+ typeof userSeperator === 'undefined' ? ':' : userSeperator
+ }__TWSEP__`
+ )
exports.purge = {}
return exports
})
@@ -89,15 +96,17 @@
hook.unwatch()
const {
- base,
- components,
- utilities,
+ postcssResult,
resolvedConfig,
browserslist,
postcss,
} = await withPackages(
- configDir,
- cwd,
+ {
+ configDir,
+ cwd,
+ userSeperator,
+ version,
+ },
async ({
postcss,
tailwindcss,
@@ -106,27 +115,23 @@ browserslistArgs,
}) => {
let postcssResult
try {
- postcssResult = await Promise.all(
+ postcssResult = await postcss([tailwindcss(configPath)]).process(
[
semver.gte(version, '0.99.0') ? 'base' : 'preflight',
'components',
'utilities',
- ].map((group) =>
- postcss([tailwindcss(configPath)]).process(
- `@tailwind ${group};`,
- {
- from: undefined,
- }
- )
- )
+ ]
+ .map((x) => `/*__tw_intellisense_layer_${x}__*/\n@tailwind ${x};`)
+ .join('\n'),
+ {
+ from: undefined,
+ }
)
} catch (error) {
throw error
} finally {
hook.unhook()
}
-
- const [base, components, utilities] = postcssResult
if (typeof userSeperator !== 'undefined') {
dset(config, sepLocation, userSeperator)
@@ -168,9 +173,7 @@ }
}
return {
- base,
- components,
- utilities,
+ postcssResult,
resolvedConfig,
postcss,
browserslist,
@@ -183,11 +186,7 @@ version,
configPath,
config: resolvedConfig,
separator: typeof userSeperator === 'undefined' ? ':' : userSeperator,
- classNames: await extractClassNames([
- { root: base.root, source: 'base' },
- { root: components.root, source: 'components' },
- { root: utilities.root, source: 'utilities' },
- ]),
+ classNames: await extractClassNames(postcssResult.root),
dependencies: hook.deps,
plugins: getPlugins(config),
variants: getVariants({ config, version, postcss, browserslist }),
@@ -262,10 +261,10 @@ return { version, featureFlags, tailwindBase }
})
}
-function withPackages(configDir, root, cb) {
+function withPackages({ configDir, cwd, userSeperator, version }, cb) {
return withUserEnvironment(
configDir,
- root,
+ cwd,
async ({ isPnp, require, resolve }) => {
const tailwindBase = path.dirname(resolve('tailwindcss/package.json'))
const postcss = require('postcss', tailwindBase)
@@ -289,6 +288,55 @@ browserslistCommand = process.execPath
browserslistArgs = [browserslistBin]
}
} catch (_) {}
+
+ if (semver.gte(version, '1.7.0')) {
+ const applyComplexClasses = semver.gte(version, '1.99.0')
+ ? require('./lib/lib/substituteClassApplyAtRules', tailwindBase)
+ : require('./lib/flagged/applyComplexClasses', tailwindBase)
+
+ if (!applyComplexClasses.default.__patched) {
+ let _applyComplexClasses = applyComplexClasses.default
+ applyComplexClasses.default = (config, ...args) => {
+ let configClone = klona(config)
+ configClone.separator =
+ typeof userSeperator === 'undefined' ? ':' : userSeperator
+
+ let fn = _applyComplexClasses(configClone, ...args)
+
+ return async (css) => {
+ css.walkRules((rule) => {
+ const newSelector = rule.selector.replace(
+ /__TWSEP__(.*?)__TWSEP__/g,
+ '$1'
+ )
+ if (newSelector !== rule.selector) {
+ rule.before(
+ postcss.comment({
+ text: '__ORIGINAL_SELECTOR__:' + rule.selector,
+ })
+ )
+ rule.selector = newSelector
+ }
+ })
+
+ await fn(css)
+
+ css.walkComments((comment) => {
+ if (comment.text.startsWith('__ORIGINAL_SELECTOR__:')) {
+ comment.next().selector = comment.text.replace(
+ /^__ORIGINAL_SELECTOR__:/,
+ ''
+ )
+ comment.remove()
+ }
+ })
+
+ return css
+ }
+ }
+ applyComplexClasses.default.__patched = true
+ }
+ }
return cb({ postcss, tailwindcss, browserslistCommand, browserslistArgs })
}