From 4cee488fb4d03efa9b2b9c1c732f93a786eeb6fa Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Mon, 17 May 2021 12:38:52 +0100 Subject: [PATCH] =?UTF-8?q?fix=20@=E2=80=8Bvariants=20completions/diagnost?= =?UTF-8?q?ics=20in=20JIT=20mode=20(fixes=20#324)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/codeActions/provideInvalidApplyCodeActions.ts | 5 +---- .../src/completionProvider.ts | 8 +++++++- .../src/diagnostics/getInvalidScreenDiagnostics.ts | 6 ++---- .../src/diagnostics/getInvalidVariantDiagnostics.ts | 11 +++++++++-- .../tailwindcss-language-service/src/util/state.ts | 1 + src/server.ts | 4 +++- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts b/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts index 7e08d13..78cadb0 100644 --- a/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts +++ b/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts @@ -176,16 +176,13 @@ function classNameToAst( let context = meta.context let pseudo = meta.pseudo 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 = [] for (let i = 0; i < classNameParts.length - 1; i++) { let part = classNameParts[i] let common = globalContexts[part] if (!common) return null - if (screens.includes(part)) { + if (state.screens.includes(part)) { path.push(`@screen ${part}`) context = context.filter((con) => !common.includes(con)) } diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts index 10cfc37..103dba9 100644 --- a/packages/tailwindcss-language-service/src/completionProvider.ts +++ b/packages/tailwindcss-language-service/src/completionProvider.ts @@ -633,11 +633,17 @@ function provideVariantsDirectiveCompletions( if (/\s+/.test(parts[parts.length - 1])) return null + let possibleVariants = Object.keys(state.variants) const existingVariants = parts.slice(0, parts.length - 1) + if (state.jit) { + possibleVariants.unshift('responsive') + possibleVariants = possibleVariants.filter((v) => !state.screens.includes(v)) + } + return { isIncomplete: false, - items: Object.keys(state.variants) + items: possibleVariants .filter((v) => existingVariants.indexOf(v) === -1) .map((variant, index) => ({ // TODO: detail diff --git a/packages/tailwindcss-language-service/src/diagnostics/getInvalidScreenDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getInvalidScreenDiagnostics.ts index c49c871..5bb1e13 100644 --- a/packages/tailwindcss-language-service/src/diagnostics/getInvalidScreenDiagnostics.ts +++ b/packages/tailwindcss-language-service/src/diagnostics/getInvalidScreenDiagnostics.ts @@ -31,16 +31,14 @@ export function getInvalidScreenDiagnostics( let text = document.getText(range) let matches = findAll(/(?:\s|^)@screen\s+(?[^\s{]+)/g, text) - let screens = Object.keys(dlv(state.config, 'theme.screens', dlv(state.config, 'screens', {}))) - matches.forEach((match) => { - if (screens.includes(match.groups.screen)) { + if (state.screens.includes(match.groups.screen)) { return null } let message = `The screen '${match.groups.screen}' does not exist in your theme config.` let suggestions: string[] = [] - let suggestion = closest(match.groups.screen, screens) + let suggestion = closest(match.groups.screen, state.screens) if (suggestion) { suggestions.push(suggestion) diff --git a/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts index b419197..55cbce1 100644 --- a/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts +++ b/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts @@ -6,6 +6,7 @@ import { getLanguageBoundaries } from '../util/getLanguageBoundaries' import { findAll, indexToPosition } from '../util/find' import { closest } from '../util/closest' import { absoluteRange } from '../util/absoluteRange' +import dlv from 'dlv' export function getInvalidVariantDiagnostics( state: State, @@ -26,6 +27,12 @@ export function getInvalidVariantDiagnostics( 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) => { let text = document.getText(range) let matches = findAll(/(?:\s|^)@variants\s+(?[^{]+)/g, text) @@ -36,13 +43,13 @@ export function getInvalidVariantDiagnostics( for (let i = 0; i < variants.length; i += 2) { let variant = variants[i].trim() - if (Object.keys(state.variants).includes(variant)) { + if (possibleVariants.includes(variant)) { continue } let message = `The variant '${variant}' does not exist.` let suggestions: string[] = [] - let suggestion = closest(variant, Object.keys(state.variants)) + let suggestion = closest(variant, possibleVariants) if (suggestion) { suggestions.push(suggestion) diff --git a/packages/tailwindcss-language-service/src/util/state.ts b/packages/tailwindcss-language-service/src/util/state.ts index 826d50e..9d0b980 100644 --- a/packages/tailwindcss-language-service/src/util/state.ts +++ b/packages/tailwindcss-language-service/src/util/state.ts @@ -70,6 +70,7 @@ export interface State { separator?: string dependencies?: string[] plugins?: any + screens?: string[] variants?: Record modules?: { tailwindcss?: { version: string; module: any } diff --git a/src/server.ts b/src/server.ts index 38cb29f..1052baf 100644 --- a/src/server.ts +++ b/src/server.ts @@ -712,9 +712,11 @@ async function createProjectService( state.separator = typeof userSeperator === 'string' ? userSeperator : ':' state.plugins = await getPlugins(config) state.classNames = (await extractClassNames(postcssResult.root)) as ClassNames - 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 updateAllDiagnostics(state)