update settings schema

master
Brad Cornes 2021-05-04 12:40:50 +01:00
parent e0ef982fd5
commit a72226c141
16 changed files with 103 additions and 172 deletions

View File

@ -313,7 +313,7 @@ async function provideCustomClassNameCompletions(
position: Position position: Position
): Promise<CompletionList> { ): Promise<CompletionList> {
const settings = await state.editor.getConfiguration(document.uri) const settings = await state.editor.getConfiguration(document.uri)
const regexes = dlv(settings, 'experimental.classRegex', []) const regexes = dlv(settings, 'tailwindCSS.experimental.classRegex', [])
if (regexes.length === 0) return null if (regexes.length === 0) return null
const positionOffset = document.offsetAt(position) const positionOffset = document.offsetAt(position)
@ -853,7 +853,7 @@ async function provideEmmetCompletions(
position: Position position: Position
): Promise<CompletionList> { ): Promise<CompletionList> {
let settings = await state.editor.getConfiguration(document.uri) let settings = await state.editor.getConfiguration(document.uri)
if (settings.emmetCompletions !== true) return null if (settings.tailwindCSS.emmetCompletions !== true) return null
const isHtml = isHtmlContext(state, document, position) const isHtml = isHtmlContext(state, document, position)
const isJs = !isHtml && isJsContext(state, document, position) const isJs = !isHtml && isJsContext(state, document, position)
@ -980,9 +980,9 @@ export async function resolveCompletionItem(
if (!item.documentation) { if (!item.documentation) {
const settings = await state.editor.getConfiguration() const settings = await state.editor.getConfiguration()
const css = stringifyCss(item.data.join(':'), className, { const css = stringifyCss(item.data.join(':'), className, {
tabSize: dlv(settings, 'tabSize', 2), tabSize: dlv(settings, 'editor.tabSize', 2),
showPixelEquivalents: dlv(settings, 'showPixelEquivalents', true), showPixelEquivalents: dlv(settings, 'tailwindCSS.showPixelEquivalents', true),
rootFontSize: dlv(settings, 'rootFontSize', 16), rootFontSize: dlv(settings, 'tailwindCSS.rootFontSize', 16),
}) })
if (css) { if (css) {
item.documentation = { item.documentation = {
@ -1044,8 +1044,8 @@ async function getCssDetail(state: State, className: any): Promise<string> {
if (className.__rule === true) { if (className.__rule === true) {
const settings = await state.editor.getConfiguration() const settings = await state.editor.getConfiguration()
return stringifyDecls(removeMeta(className), { return stringifyDecls(removeMeta(className), {
showPixelEquivalents: dlv(settings, 'showPixelEquivalents', true), showPixelEquivalents: dlv(settings, 'tailwindCSS.showPixelEquivalents', true),
rootFontSize: dlv(settings, 'rootFontSize', 16), rootFontSize: dlv(settings, 'tailwindCSS.rootFontSize', 16),
}) })
} }
return null return null

View File

@ -24,7 +24,7 @@ export async function doValidate(
): Promise<AugmentedDiagnostic[]> { ): Promise<AugmentedDiagnostic[]> {
const settings = await state.editor.getConfiguration(document.uri) const settings = await state.editor.getConfiguration(document.uri)
return settings.validate return settings.tailwindCSS.validate
? [ ? [
...(only.includes(DiagnosticKind.CssConflict) ...(only.includes(DiagnosticKind.CssConflict)
? await getCssConflictDiagnostics(state, document, settings) ? await getCssConflictDiagnostics(state, document, settings)

View File

@ -13,7 +13,7 @@ export async function getCssConflictDiagnostics(
document: TextDocument, document: TextDocument,
settings: Settings settings: Settings
): Promise<CssConflictDiagnostic[]> { ): Promise<CssConflictDiagnostic[]> {
let severity = settings.lint.cssConflict let severity = settings.tailwindCSS.lint.cssConflict
if (severity === 'ignore') return [] if (severity === 'ignore') return []
let diagnostics: CssConflictDiagnostic[] = [] let diagnostics: CssConflictDiagnostic[] = []

View File

@ -13,7 +13,7 @@ export async function getIncorrectVariantOrderDiagnostics(
): Promise<IncorrectVariantOrderDiagnostic[]> { ): Promise<IncorrectVariantOrderDiagnostic[]> {
if (!state.jit) return [] if (!state.jit) return []
let severity = settings.lint.incorrectVariantOrder let severity = settings.tailwindCSS.lint.incorrectVariantOrder
if (severity === 'ignore') return [] if (severity === 'ignore') return []
let diagnostics: IncorrectVariantOrderDiagnostic[] = [] let diagnostics: IncorrectVariantOrderDiagnostic[] = []

View File

@ -9,16 +9,10 @@ export async function getInvalidApplyDiagnostics(
document: TextDocument, document: TextDocument,
settings: Settings settings: Settings
): Promise<InvalidApplyDiagnostic[]> { ): Promise<InvalidApplyDiagnostic[]> {
let severity = settings.lint.invalidApply let severity = settings.tailwindCSS.lint.invalidApply
if (severity === 'ignore') return [] if (severity === 'ignore') return []
const classNames = await findClassNamesInRange( const classNames = await findClassNamesInRange(state, document, undefined, 'css', false)
state,
document,
undefined,
'css',
false
)
let diagnostics: InvalidApplyDiagnostic[] = classNames.map((className) => { let diagnostics: InvalidApplyDiagnostic[] = classNames.map((className) => {
let result = validateApply(state, className.className) let result = validateApply(state, className.className)

View File

@ -24,9 +24,7 @@ function validateConfigPath(
state: State, state: State,
path: string | string[], path: string | string[],
base: string[] = [] base: string[] = []
): ): { isValid: true; value: any } | { isValid: false; reason: string; suggestions: string[] } {
| { isValid: true; value: any }
| { isValid: false; reason: string; suggestions: string[] } {
let keys = Array.isArray(path) ? path : stringToPath(path) let keys = Array.isArray(path) ? path : stringToPath(path)
let value = dlv(state.config, [...base, ...keys]) let value = dlv(state.config, [...base, ...keys])
let suggestions: string[] = [] let suggestions: string[] = []
@ -49,9 +47,7 @@ function validateConfigPath(
}) })
.slice(1) // skip original path .slice(1) // skip original path
return possibilities.find( return possibilities.find((possibility) => validateConfigPath(state, possibility, base).isValid)
(possibility) => validateConfigPath(state, possibility, base).isValid
)
} }
if (typeof value === 'undefined') { if (typeof value === 'undefined') {
@ -67,9 +63,7 @@ function validateConfigPath(
) )
) )
if (closestValidKey) { if (closestValidKey) {
suggestions.push( suggestions.push(pathToString([...keys.slice(0, keys.length - 1), closestValidKey]))
pathToString([...keys.slice(0, keys.length - 1), closestValidKey])
)
reason += ` Did you mean '${suggestions[0]}'?` reason += ` Did you mean '${suggestions[0]}'?`
} }
} else { } else {
@ -99,18 +93,14 @@ function validateConfigPath(
Array.isArray(value) Array.isArray(value)
) )
) { ) {
let reason = `'${pathToString( let reason = `'${pathToString(path)}' was found but does not resolve to a string.`
path
)}' was found but does not resolve to a string.`
if (isObject(value)) { if (isObject(value)) {
let validKeys = Object.keys(value).filter( let validKeys = Object.keys(value).filter(
(key) => validateConfigPath(state, [...keys, key], base).isValid (key) => validateConfigPath(state, [...keys, key], base).isValid
) )
if (validKeys.length) { if (validKeys.length) {
suggestions.push( suggestions.push(...validKeys.map((validKey) => pathToString([...keys, validKey])))
...validKeys.map((validKey) => pathToString([...keys, validKey]))
)
reason += ` Did you mean something like '${suggestions[0]}'?` reason += ` Did you mean something like '${suggestions[0]}'?`
} }
} }
@ -171,7 +161,7 @@ export function getInvalidConfigPathDiagnostics(
document: TextDocument, document: TextDocument,
settings: Settings settings: Settings
): InvalidConfigPathDiagnostic[] { ): InvalidConfigPathDiagnostic[] {
let severity = settings.lint.invalidConfigPath let severity = settings.tailwindCSS.lint.invalidConfigPath
if (severity === 'ignore') return [] if (severity === 'ignore') return []
let diagnostics: InvalidConfigPathDiagnostic[] = [] let diagnostics: InvalidConfigPathDiagnostic[] = []

View File

@ -13,7 +13,7 @@ export function getInvalidScreenDiagnostics(
document: TextDocument, document: TextDocument,
settings: Settings settings: Settings
): InvalidScreenDiagnostic[] { ): InvalidScreenDiagnostic[] {
let severity = settings.lint.invalidScreen let severity = settings.tailwindCSS.lint.invalidScreen
if (severity === 'ignore') return [] if (severity === 'ignore') return []
let diagnostics: InvalidScreenDiagnostic[] = [] let diagnostics: InvalidScreenDiagnostic[] = []
@ -31,9 +31,7 @@ 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( let screens = Object.keys(dlv(state.config, 'theme.screens', dlv(state.config, 'screens', {})))
dlv(state.config, 'theme.screens', dlv(state.config, 'screens', {}))
)
matches.forEach((match) => { matches.forEach((match) => {
if (screens.includes(match.groups.screen)) { if (screens.includes(match.groups.screen)) {

View File

@ -13,7 +13,7 @@ export function getInvalidTailwindDirectiveDiagnostics(
document: TextDocument, document: TextDocument,
settings: Settings settings: Settings
): InvalidTailwindDirectiveDiagnostic[] { ): InvalidTailwindDirectiveDiagnostic[] {
let severity = settings.lint.invalidTailwindDirective let severity = settings.tailwindCSS.lint.invalidTailwindDirective
if (severity === 'ignore') return [] if (severity === 'ignore') return []
let diagnostics: InvalidTailwindDirectiveDiagnostic[] = [] let diagnostics: InvalidTailwindDirectiveDiagnostic[] = []

View File

@ -12,7 +12,7 @@ export function getInvalidVariantDiagnostics(
document: TextDocument, document: TextDocument,
settings: Settings settings: Settings
): InvalidVariantDiagnostic[] { ): InvalidVariantDiagnostic[] {
let severity = settings.lint.invalidVariant let severity = settings.tailwindCSS.lint.invalidVariant
if (severity === 'ignore') return [] if (severity === 'ignore') return []
let diagnostics: InvalidVariantDiagnostic[] = [] let diagnostics: InvalidVariantDiagnostic[] = []
@ -32,8 +32,7 @@ export function getInvalidVariantDiagnostics(
matches.forEach((match) => { matches.forEach((match) => {
let variants = match.groups.variants.split(/(\s*,\s*)/) let variants = match.groups.variants.split(/(\s*,\s*)/)
let listStartIndex = let listStartIndex = match.index + match[0].length - match.groups.variants.length
match.index + match[0].length - match.groups.variants.length
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()
@ -50,8 +49,7 @@ export function getInvalidVariantDiagnostics(
message += ` Did you mean '${suggestion}'?` message += ` Did you mean '${suggestion}'?`
} }
let variantStartIndex = let variantStartIndex = listStartIndex + variants.slice(0, i).join('').length
listStartIndex + variants.slice(0, i).join('').length
diagnostics.push({ diagnostics.push({
code: DiagnosticKind.InvalidVariant, code: DiagnosticKind.InvalidVariant,

View File

@ -18,7 +18,7 @@ export async function getDocumentColors(
if (!state.enabled) return colors if (!state.enabled) return colors
let settings = await state.editor.getConfiguration(document.uri) let settings = await state.editor.getConfiguration(document.uri)
if (settings.colorDecorators === false) return colors if (settings.tailwindCSS.colorDecorators === false) return colors
let classLists = await findClassListsInDocument(state, document) let classLists = await findClassListsInDocument(state, document)
classLists.forEach((classList) => { classLists.forEach((classList) => {

View File

@ -106,9 +106,9 @@ async function provideClassNameHover(
className.className, className.className,
dlv(state.classNames.classNames, [...parts, '__info']), dlv(state.classNames.classNames, [...parts, '__info']),
{ {
tabSize: dlv(settings, 'tabSize', 2), tabSize: dlv(settings, 'editor.tabSize', 2),
showPixelEquivalents: dlv(settings, 'showPixelEquivalents', true), showPixelEquivalents: dlv(settings, 'tailwindCSS.showPixelEquivalents', true),
rootFontSize: dlv(settings, 'rootFontSize', 16), rootFontSize: dlv(settings, 'tailwindCSS.rootFontSize', 16),
} }
) )

View File

@ -1,20 +1,12 @@
import type { TextDocument, Range, Position } from 'vscode-languageserver' import type { TextDocument, Range, Position } from 'vscode-languageserver'
import { import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
DocumentClassName,
DocumentClassList,
State,
DocumentHelperFunction,
} from './state'
import lineColumn from 'line-column' import lineColumn from 'line-column'
import { isCssContext, isCssDoc } from './css' import { isCssContext, isCssDoc } from './css'
import { isHtmlContext, isHtmlDoc, isSvelteDoc, isVueDoc } from './html' import { isHtmlContext, isHtmlDoc, isSvelteDoc, isVueDoc } from './html'
import { isWithinRange } from './isWithinRange' import { isWithinRange } from './isWithinRange'
import { isJsContext, isJsDoc } from './js' import { isJsContext, isJsDoc } from './js'
import { flatten } from './array' import { flatten } from './array'
import { import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
getClassAttributeLexer,
getComputedClassAttributeLexer,
} from './lexers'
import { getLanguageBoundaries } from './getLanguageBoundaries' import { getLanguageBoundaries } from './getLanguageBoundaries'
import { resolveRange } from './resolveRange' import { resolveRange } from './resolveRange'
const dlv = require('dlv') const dlv = require('dlv')
@ -63,13 +55,11 @@ export function getClassNamesInClassList({
range: { range: {
start: { start: {
line: range.start.line + start.line, line: range.start.line + start.line,
character: character: (end.line === 0 ? range.start.character : 0) + start.character,
(end.line === 0 ? range.start.character : 0) + start.character,
}, },
end: { end: {
line: range.start.line + end.line, line: range.start.line + end.line,
character: character: (end.line === 0 ? range.start.character : 0) + end.character,
(end.line === 0 ? range.start.character : 0) + end.character,
}, },
}, },
}) })
@ -86,13 +76,7 @@ export async function findClassNamesInRange(
mode?: 'html' | 'css', mode?: 'html' | 'css',
includeCustom: boolean = true includeCustom: boolean = true
): Promise<DocumentClassName[]> { ): Promise<DocumentClassName[]> {
const classLists = await findClassListsInRange( const classLists = await findClassListsInRange(state, doc, range, mode, includeCustom)
state,
doc,
range,
mode,
includeCustom
)
return flatten(classLists.map(getClassNamesInClassList)) return flatten(classLists.map(getClassNamesInClassList))
} }
@ -104,10 +88,7 @@ export async function findClassNamesInDocument(
return flatten(classLists.map(getClassNamesInClassList)) return flatten(classLists.map(getClassNamesInClassList))
} }
export function findClassListsInCssRange( export function findClassListsInCssRange(doc: TextDocument, range?: Range): DocumentClassList[] {
doc: TextDocument,
range?: Range
): DocumentClassList[] {
const text = doc.getText(range) const text = doc.getText(range)
const matches = findAll( const matches = findAll(
/(@apply\s+)(?<classList>[^;}]+?)(?<important>\s*!important)?\s*[;}]/g, /(@apply\s+)(?<classList>[^;}]+?)(?<important>\s*!important)?\s*[;}]/g,
@ -117,23 +98,18 @@ export function findClassListsInCssRange(
return matches.map((match) => { return matches.map((match) => {
const start = indexToPosition(text, match.index + match[1].length) const start = indexToPosition(text, match.index + match[1].length)
const end = indexToPosition( const end = indexToPosition(text, match.index + match[1].length + match.groups.classList.length)
text,
match.index + match[1].length + match.groups.classList.length
)
return { return {
classList: match.groups.classList, classList: match.groups.classList,
important: Boolean(match.groups.important), important: Boolean(match.groups.important),
range: { range: {
start: { start: {
line: globalStart.line + start.line, line: globalStart.line + start.line,
character: character: (end.line === 0 ? globalStart.character : 0) + start.character,
(end.line === 0 ? globalStart.character : 0) + start.character,
}, },
end: { end: {
line: globalStart.line + end.line, line: globalStart.line + end.line,
character: character: (end.line === 0 ? globalStart.character : 0) + end.character,
(end.line === 0 ? globalStart.character : 0) + end.character,
}, },
}, },
} }
@ -146,7 +122,7 @@ async function findCustomClassLists(
range?: Range range?: Range
): Promise<DocumentClassList[]> { ): Promise<DocumentClassList[]> {
const settings = await state.editor.getConfiguration(doc.uri) const settings = await state.editor.getConfiguration(doc.uri)
const regexes = dlv(settings, 'experimental.classRegex', []) const regexes = dlv(settings, 'tailwindCSS.experimental.classRegex', [])
if (!Array.isArray(regexes) || regexes.length === 0) return [] if (!Array.isArray(regexes) || regexes.length === 0) return []
@ -155,17 +131,13 @@ async function findCustomClassLists(
for (let i = 0; i < regexes.length; i++) { for (let i = 0; i < regexes.length; i++) {
try { try {
let [containerRegex, classRegex] = Array.isArray(regexes[i]) let [containerRegex, classRegex] = Array.isArray(regexes[i]) ? regexes[i] : [regexes[i]]
? regexes[i]
: [regexes[i]]
containerRegex = createMultiRegexp(containerRegex) containerRegex = createMultiRegexp(containerRegex)
let containerMatch let containerMatch
while ((containerMatch = containerRegex.exec(text)) !== null) { while ((containerMatch = containerRegex.exec(text)) !== null) {
const searchStart = doc.offsetAt( const searchStart = doc.offsetAt(range?.start || { line: 0, character: 0 })
range?.start || { line: 0, character: 0 }
)
const matchStart = searchStart + containerMatch.start const matchStart = searchStart + containerMatch.start
const matchEnd = searchStart + containerMatch.end const matchEnd = searchStart + containerMatch.end
@ -173,9 +145,7 @@ async function findCustomClassLists(
classRegex = createMultiRegexp(classRegex) classRegex = createMultiRegexp(classRegex)
let classMatch let classMatch
while ( while ((classMatch = classRegex.exec(containerMatch.match)) !== null) {
(classMatch = classRegex.exec(containerMatch.match)) !== null
) {
const classMatchStart = matchStart + classMatch.start const classMatchStart = matchStart + classMatch.start
const classMatchEnd = matchStart + classMatch.end const classMatchEnd = matchStart + classMatch.end
result.push({ result.push({
@ -202,15 +172,9 @@ async function findCustomClassLists(
return result return result
} }
export function findClassListsInHtmlRange( export function findClassListsInHtmlRange(doc: TextDocument, range?: Range): DocumentClassList[] {
doc: TextDocument,
range?: Range
): DocumentClassList[] {
const text = doc.getText(range) const text = doc.getText(range)
const matches = findAll( const matches = findAll(/(?:\s|:|\()(?:class(?:Name)?|\[ngClass\])=['"`{]/g, text)
/(?:\s|:|\()(?:class(?:Name)?|\[ngClass\])=['"`{]/g,
text
)
const result: DocumentClassList[] = [] const result: DocumentClassList[] = []
matches.forEach((match) => { matches.forEach((match) => {
@ -274,12 +238,7 @@ export function findClassListsInHtmlRange(
) )
const end = indexToPosition( const end = indexToPosition(
text, text,
match.index + match.index + match[0].length - 1 + offset + value.length + afterOffset
match[0].length -
1 +
offset +
value.length +
afterOffset
) )
return { return {
@ -287,15 +246,11 @@ export function findClassListsInHtmlRange(
range: { range: {
start: { start: {
line: (range?.start.line || 0) + start.line, line: (range?.start.line || 0) + start.line,
character: character: (end.line === 0 ? range?.start.character || 0 : 0) + start.character,
(end.line === 0 ? range?.start.character || 0 : 0) +
start.character,
}, },
end: { end: {
line: (range?.start.line || 0) + end.line, line: (range?.start.line || 0) + end.line,
character: character: (end.line === 0 ? range?.start.character || 0 : 0) + end.character,
(end.line === 0 ? range?.start.character || 0 : 0) +
end.character,
}, },
}, },
} }
@ -320,10 +275,7 @@ export async function findClassListsInRange(
} else { } else {
classLists = findClassListsInHtmlRange(doc, range) classLists = findClassListsInHtmlRange(doc, range)
} }
return [ return [...classLists, ...(includeCustom ? await findCustomClassLists(state, doc, range) : [])]
...classLists,
...(includeCustom ? await findCustomClassLists(state, doc, range) : []),
]
} }
export async function findClassListsInDocument( export async function findClassListsInDocument(
@ -355,9 +307,7 @@ export function findHelperFunctionsInDocument(
let boundaries = getLanguageBoundaries(state, doc) let boundaries = getLanguageBoundaries(state, doc)
if (!boundaries) return [] if (!boundaries) return []
return flatten( return flatten(boundaries.css.map((range) => findHelperFunctionsInRange(doc, range)))
boundaries.css.map((range) => findHelperFunctionsInRange(doc, range))
)
} }
export function findHelperFunctionsInRange( export function findHelperFunctionsInRange(
@ -387,10 +337,7 @@ export function findHelperFunctionsInRange(
), ),
valueRange: resolveRange( valueRange: resolveRange(
{ {
start: indexToPosition( start: indexToPosition(text, startIndex + match.groups.helper.length + 1),
text,
startIndex + match.groups.helper.length + 1
),
end: indexToPosition( end: indexToPosition(
text, text,
startIndex + match.groups.helper.length + 1 + 1 + value.length + 1 startIndex + match.groups.helper.length + 1 + 1 + value.length + 1
@ -420,10 +367,7 @@ export async function findClassNameAtPosition(
if (isCssContext(state, doc, position)) { if (isCssContext(state, doc, position)) {
classNames = await findClassNamesInRange(state, doc, searchRange, 'css') classNames = await findClassNamesInRange(state, doc, searchRange, 'css')
} else if ( } else if (isHtmlContext(state, doc, position) || isJsContext(state, doc, position)) {
isHtmlContext(state, doc, position) ||
isJsContext(state, doc, position)
) {
classNames = await findClassNamesInRange(state, doc, searchRange, 'html') classNames = await findClassNamesInRange(state, doc, searchRange, 'html')
} }
@ -431,9 +375,7 @@ export async function findClassNameAtPosition(
return null return null
} }
const className = classNames.find(({ range }) => const className = classNames.find(({ range }) => isWithinRange(position, range))
isWithinRange(position, range)
)
if (!className) return null if (!className) return null

View File

@ -33,9 +33,9 @@ export function generateRules(state: State, classNames: string[]): { root: Root;
export async function stringifyRoot(state: State, root: Root, uri?: string): Promise<string> { export async function stringifyRoot(state: State, root: Root, uri?: string): Promise<string> {
let settings = await state.editor.getConfiguration(uri) let settings = await state.editor.getConfiguration(uri)
let tabSize = dlv(settings, 'tabSize', 2) let tabSize = dlv(settings, 'editor.tabSize', 2)
let showPixelEquivalents = dlv(settings, 'showPixelEquivalents', true) let showPixelEquivalents = dlv(settings, 'tailwindCSS.showPixelEquivalents', true)
let rootFontSize = dlv(settings, 'rootFontSize', 16) let rootFontSize = dlv(settings, 'tailwindCSS.rootFontSize', 16)
let clone = root let clone = root

View File

@ -31,24 +31,28 @@ export type EditorState = {
type DiagnosticSeveritySetting = 'ignore' | 'warning' | 'error' type DiagnosticSeveritySetting = 'ignore' | 'warning' | 'error'
export type Settings = { export type Settings = {
tabSize: number editor: {
emmetCompletions: boolean tabSize: number
includeLanguages: Record<string, string>
validate: boolean
showPixelEquivalents: boolean
rootFontSize: number
colorDecorators: boolean
lint: {
cssConflict: DiagnosticSeveritySetting
invalidApply: DiagnosticSeveritySetting
invalidScreen: DiagnosticSeveritySetting
invalidVariant: DiagnosticSeveritySetting
invalidConfigPath: DiagnosticSeveritySetting
invalidTailwindDirective: DiagnosticSeveritySetting
incorrectVariantOrder: DiagnosticSeveritySetting
} }
experimental: { tailwindCSS: {
classRegex: string[] emmetCompletions: boolean
includeLanguages: Record<string, string>
validate: boolean
showPixelEquivalents: boolean
rootFontSize: number
colorDecorators: boolean
lint: {
cssConflict: DiagnosticSeveritySetting
invalidApply: DiagnosticSeveritySetting
invalidScreen: DiagnosticSeveritySetting
invalidVariant: DiagnosticSeveritySetting
invalidConfigPath: DiagnosticSeveritySetting
invalidTailwindDirective: DiagnosticSeveritySetting
incorrectVariantOrder: DiagnosticSeveritySetting
}
experimental: {
classRegex: string[]
}
} }
} }

View File

@ -17,6 +17,7 @@ import {
Range, Range,
TextEditorDecorationType, TextEditorDecorationType,
RelativePattern, RelativePattern,
ConfigurationScope,
} from 'vscode' } from 'vscode'
import { LanguageClient, LanguageClientOptions, TransportKind } from 'vscode-languageclient/node' import { LanguageClient, LanguageClientOptions, TransportKind } from 'vscode-languageclient/node'
import { DEFAULT_LANGUAGES } from './lib/languages' import { DEFAULT_LANGUAGES } from './lib/languages'
@ -249,31 +250,28 @@ export function activate(context: ExtensionContext) {
return editableColors return editableColors
}, },
workspace: { workspace: {
configuration: (params, token, next) => { configuration: (params) => {
try { return params.items.map(({ section, scopeUri }) => {
return params.items.map(({ section, scopeUri }) => { let scope: ConfigurationScope = folder
if (section === 'tailwindCSS') { if (scopeUri) {
let scope = scopeUri let doc = Workspace.textDocuments.find((doc) => doc.uri.toString() === scopeUri)
? { if (doc) {
languageId: Workspace.textDocuments.find( scope = {
(doc) => doc.uri.toString() === scopeUri languageId: doc.languageId,
).languageId, }
}
: folder
let tabSize = Workspace.getConfiguration('editor', scope).get('tabSize') || 2
return { tabSize, ...Workspace.getConfiguration(section, scope) }
} }
throw Error() }
}) return Workspace.getConfiguration(section, scope)
} catch (_error) { })
return next(params, token)
}
}, },
}, },
}, },
initializationOptions: { initializationOptions: {
userLanguages: getUserLanguages(folder), userLanguages: getUserLanguages(folder),
configuration: Workspace.getConfiguration('tailwindCSS', folder), configuration: {
editor: Workspace.getConfiguration('editor', folder),
tailwindCSS: Workspace.getConfiguration('tailwindCSS', folder),
},
}, },
synchronize: { synchronize: {
configurationSection: ['editor', 'tailwindCSS'], configurationSection: ['editor', 'tailwindCSS'],

View File

@ -158,10 +158,17 @@ async function createProjectService(
if (documentSettingsCache.has(uri)) { if (documentSettingsCache.has(uri)) {
return documentSettingsCache.get(uri) return documentSettingsCache.get(uri)
} }
let config = await connection.workspace.getConfiguration({ let [editor, tailwindCSS] = await Promise.all([
section: 'tailwindCSS', connection.workspace.getConfiguration({
scopeUri: uri, section: 'editor',
}) scopeUri: uri,
}),
connection.workspace.getConfiguration({
section: 'tailwindCSS',
scopeUri: uri,
}),
])
let config: Settings = { editor, tailwindCSS }
documentSettingsCache.set(uri, config) documentSettingsCache.set(uri, config)
return config return config
}, },