update settings schema
parent
e0ef982fd5
commit
a72226c141
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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[] = []
|
||||||
|
|
|
@ -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[] = []
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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[] = []
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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[] = []
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,10 @@ export type EditorState = {
|
||||||
type DiagnosticSeveritySetting = 'ignore' | 'warning' | 'error'
|
type DiagnosticSeveritySetting = 'ignore' | 'warning' | 'error'
|
||||||
|
|
||||||
export type Settings = {
|
export type Settings = {
|
||||||
|
editor: {
|
||||||
tabSize: number
|
tabSize: number
|
||||||
|
}
|
||||||
|
tailwindCSS: {
|
||||||
emmetCompletions: boolean
|
emmetCompletions: boolean
|
||||||
includeLanguages: Record<string, string>
|
includeLanguages: Record<string, string>
|
||||||
validate: boolean
|
validate: boolean
|
||||||
|
@ -51,6 +54,7 @@ export type Settings = {
|
||||||
classRegex: string[]
|
classRegex: string[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface FeatureFlags {
|
export interface FeatureFlags {
|
||||||
future: string[]
|
future: string[]
|
||||||
|
|
|
@ -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 }) => {
|
||||||
if (section === 'tailwindCSS') {
|
let scope: ConfigurationScope = folder
|
||||||
let scope = scopeUri
|
if (scopeUri) {
|
||||||
? {
|
let doc = Workspace.textDocuments.find((doc) => doc.uri.toString() === scopeUri)
|
||||||
languageId: Workspace.textDocuments.find(
|
if (doc) {
|
||||||
(doc) => doc.uri.toString() === scopeUri
|
scope = {
|
||||||
).languageId,
|
languageId: doc.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'],
|
||||||
|
|
|
@ -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([
|
||||||
|
connection.workspace.getConfiguration({
|
||||||
|
section: 'editor',
|
||||||
|
scopeUri: uri,
|
||||||
|
}),
|
||||||
|
connection.workspace.getConfiguration({
|
||||||
section: 'tailwindCSS',
|
section: 'tailwindCSS',
|
||||||
scopeUri: uri,
|
scopeUri: uri,
|
||||||
})
|
}),
|
||||||
|
])
|
||||||
|
let config: Settings = { editor, tailwindCSS }
|
||||||
documentSettingsCache.set(uri, config)
|
documentSettingsCache.set(uri, config)
|
||||||
return config
|
return config
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue