fix @​variants completions/diagnostics in JIT mode (fixes #324)

master
Brad Cornes 2021-05-17 12:38:52 +01:00
parent 533c2a0a91
commit 4cee488fb4
6 changed files with 23 additions and 12 deletions

View File

@ -176,16 +176,13 @@ function classNameToAst(
let context = meta.context let context = meta.context
let pseudo = meta.pseudo let pseudo = meta.pseudo
const globalContexts = state.classNames.context const globalContexts = state.classNames.context
let screens = dlv(state.config, 'theme.screens', dlv(state.config, 'screens', {}))
if (!isObject(screens)) screens = {}
screens = Object.keys(screens)
const path = [] const path = []
for (let i = 0; i < classNameParts.length - 1; i++) { for (let i = 0; i < classNameParts.length - 1; i++) {
let part = classNameParts[i] let part = classNameParts[i]
let common = globalContexts[part] let common = globalContexts[part]
if (!common) return null if (!common) return null
if (screens.includes(part)) { if (state.screens.includes(part)) {
path.push(`@screen ${part}`) path.push(`@screen ${part}`)
context = context.filter((con) => !common.includes(con)) context = context.filter((con) => !common.includes(con))
} }

View File

@ -633,11 +633,17 @@ function provideVariantsDirectiveCompletions(
if (/\s+/.test(parts[parts.length - 1])) return null if (/\s+/.test(parts[parts.length - 1])) return null
let possibleVariants = Object.keys(state.variants)
const existingVariants = parts.slice(0, parts.length - 1) const existingVariants = parts.slice(0, parts.length - 1)
if (state.jit) {
possibleVariants.unshift('responsive')
possibleVariants = possibleVariants.filter((v) => !state.screens.includes(v))
}
return { return {
isIncomplete: false, isIncomplete: false,
items: Object.keys(state.variants) items: possibleVariants
.filter((v) => existingVariants.indexOf(v) === -1) .filter((v) => existingVariants.indexOf(v) === -1)
.map((variant, index) => ({ .map((variant, index) => ({
// TODO: detail // TODO: detail

View File

@ -31,16 +31,14 @@ export function getInvalidScreenDiagnostics(
let text = document.getText(range) let text = document.getText(range)
let matches = findAll(/(?:\s|^)@screen\s+(?<screen>[^\s{]+)/g, text) let matches = findAll(/(?:\s|^)@screen\s+(?<screen>[^\s{]+)/g, text)
let screens = Object.keys(dlv(state.config, 'theme.screens', dlv(state.config, 'screens', {})))
matches.forEach((match) => { matches.forEach((match) => {
if (screens.includes(match.groups.screen)) { if (state.screens.includes(match.groups.screen)) {
return null return null
} }
let message = `The screen '${match.groups.screen}' does not exist in your theme config.` let message = `The screen '${match.groups.screen}' does not exist in your theme config.`
let suggestions: string[] = [] let suggestions: string[] = []
let suggestion = closest(match.groups.screen, screens) let suggestion = closest(match.groups.screen, state.screens)
if (suggestion) { if (suggestion) {
suggestions.push(suggestion) suggestions.push(suggestion)

View File

@ -6,6 +6,7 @@ import { getLanguageBoundaries } from '../util/getLanguageBoundaries'
import { findAll, indexToPosition } from '../util/find' import { findAll, indexToPosition } from '../util/find'
import { closest } from '../util/closest' import { closest } from '../util/closest'
import { absoluteRange } from '../util/absoluteRange' import { absoluteRange } from '../util/absoluteRange'
import dlv from 'dlv'
export function getInvalidVariantDiagnostics( export function getInvalidVariantDiagnostics(
state: State, state: State,
@ -26,6 +27,12 @@ export function getInvalidVariantDiagnostics(
ranges.push(...boundaries.css) ranges.push(...boundaries.css)
} }
let possibleVariants = Object.keys(state.variants)
if (state.jit) {
possibleVariants.unshift('responsive')
possibleVariants = possibleVariants.filter((v) => !state.screens.includes(v))
}
ranges.forEach((range) => { ranges.forEach((range) => {
let text = document.getText(range) let text = document.getText(range)
let matches = findAll(/(?:\s|^)@variants\s+(?<variants>[^{]+)/g, text) let matches = findAll(/(?:\s|^)@variants\s+(?<variants>[^{]+)/g, text)
@ -36,13 +43,13 @@ export function getInvalidVariantDiagnostics(
for (let i = 0; i < variants.length; i += 2) { for (let i = 0; i < variants.length; i += 2) {
let variant = variants[i].trim() let variant = variants[i].trim()
if (Object.keys(state.variants).includes(variant)) { if (possibleVariants.includes(variant)) {
continue continue
} }
let message = `The variant '${variant}' does not exist.` let message = `The variant '${variant}' does not exist.`
let suggestions: string[] = [] let suggestions: string[] = []
let suggestion = closest(variant, Object.keys(state.variants)) let suggestion = closest(variant, possibleVariants)
if (suggestion) { if (suggestion) {
suggestions.push(suggestion) suggestions.push(suggestion)

View File

@ -70,6 +70,7 @@ export interface State {
separator?: string separator?: string
dependencies?: string[] dependencies?: string[]
plugins?: any plugins?: any
screens?: string[]
variants?: Record<string, string | null> variants?: Record<string, string | null>
modules?: { modules?: {
tailwindcss?: { version: string; module: any } tailwindcss?: { version: string; module: any }

View File

@ -712,9 +712,11 @@ async function createProjectService(
state.separator = typeof userSeperator === 'string' ? userSeperator : ':' state.separator = typeof userSeperator === 'string' ? userSeperator : ':'
state.plugins = await getPlugins(config) state.plugins = await getPlugins(config)
state.classNames = (await extractClassNames(postcssResult.root)) as ClassNames state.classNames = (await extractClassNames(postcssResult.root)) as ClassNames
state.variants = getVariants(state) state.variants = getVariants(state)
let screens = dlv(state.config, 'theme.screens', dlv(state.config, 'screens', {}))
state.screens = isObject(screens) ? Object.keys(screens) : []
state.enabled = true state.enabled = true
updateAllDiagnostics(state) updateAllDiagnostics(state)