Fix CSS conflict diagnostics in semicolonless CSS documents (#771)
parent
8266d6b0aa
commit
9b47dd0597
|
@ -8,6 +8,7 @@ import * as semver from '../util/semver'
|
|||
import { closest } from '../util/closest'
|
||||
import { absoluteRange } from '../util/absoluteRange'
|
||||
import { getTextWithoutComments } from '../util/doc'
|
||||
import { isSemicolonlessCssLanguage } from '../util/languages'
|
||||
|
||||
export function getInvalidTailwindDirectiveDiagnostics(
|
||||
state: State,
|
||||
|
@ -28,13 +29,8 @@ export function getInvalidTailwindDirectiveDiagnostics(
|
|||
ranges.push(...boundaries.filter((b) => b.type === 'css').map(({ range }) => range))
|
||||
}
|
||||
|
||||
let notSemicolonLanguages = ['sass', 'sugarss', 'stylus']
|
||||
let regex: RegExp
|
||||
if (
|
||||
notSemicolonLanguages.includes(document.languageId) ||
|
||||
(state.editor &&
|
||||
notSemicolonLanguages.includes(state.editor.userLanguages[document.languageId]))
|
||||
) {
|
||||
if (isSemicolonlessCssLanguage(document.languageId, state.editor?.userLanguages)) {
|
||||
regex = /(?:\s|^)@tailwind\s+(?<value>[^\r\n]+)/g
|
||||
} else {
|
||||
regex = /(?:\s|^)@tailwind\s+(?<value>[^;]+)/g
|
||||
|
|
|
@ -11,6 +11,7 @@ import { getLanguageBoundaries } from './getLanguageBoundaries'
|
|||
import { resolveRange } from './resolveRange'
|
||||
import Regex from 'becke-ch--regex--s0-0-v1--base--pl--lib'
|
||||
import { getTextWithoutComments } from './doc'
|
||||
import { isSemicolonlessCssLanguage } from './languages'
|
||||
|
||||
export function findAll(re: RegExp, str: string): RegExpMatchArray[] {
|
||||
let match: RegExpMatchArray
|
||||
|
@ -91,12 +92,16 @@ export async function findClassNamesInDocument(
|
|||
)
|
||||
}
|
||||
|
||||
export function findClassListsInCssRange(doc: TextDocument, range?: Range): DocumentClassList[] {
|
||||
export function findClassListsInCssRange(
|
||||
state: State,
|
||||
doc: TextDocument,
|
||||
range?: Range
|
||||
): DocumentClassList[] {
|
||||
const text = getTextWithoutComments(doc, 'css', range)
|
||||
const matches = findAll(
|
||||
/(@apply\s+)(?<classList>[^;}]+?)(?<important>\s*!important)?\s*[;}]/g,
|
||||
text
|
||||
)
|
||||
let regex = isSemicolonlessCssLanguage(doc.languageId, state.editor?.userLanguages)
|
||||
? /(@apply\s+)(?<classList>[^}\r\n]+?)(?<important>\s*!important)?(?:\r|\n|}|$)/g
|
||||
: /(@apply\s+)(?<classList>[^;}]+?)(?<important>\s*!important)?\s*[;}]/g
|
||||
const matches = findAll(regex, text)
|
||||
const globalStart: Position = range ? range.start : { line: 0, character: 0 }
|
||||
|
||||
return matches.map((match) => {
|
||||
|
@ -292,7 +297,7 @@ export async function findClassListsInRange(
|
|||
): Promise<DocumentClassList[]> {
|
||||
let classLists: DocumentClassList[]
|
||||
if (mode === 'css') {
|
||||
classLists = findClassListsInCssRange(doc, range)
|
||||
classLists = findClassListsInCssRange(state, doc, range)
|
||||
} else {
|
||||
classLists = await findClassListsInHtmlRange(state, doc, mode, range)
|
||||
}
|
||||
|
@ -307,7 +312,7 @@ export async function findClassListsInDocument(
|
|||
doc: TextDocument
|
||||
): Promise<DocumentClassList[]> {
|
||||
if (isCssDoc(state, doc)) {
|
||||
return findClassListsInCssRange(doc)
|
||||
return findClassListsInCssRange(state, doc)
|
||||
}
|
||||
|
||||
let boundaries = getLanguageBoundaries(state, doc)
|
||||
|
@ -324,7 +329,7 @@ export async function findClassListsInDocument(
|
|||
)),
|
||||
...boundaries
|
||||
.filter((b) => b.type === 'css')
|
||||
.map(({ range }) => findClassListsInCssRange(doc, range)),
|
||||
.map(({ range }) => findClassListsInCssRange(state, doc, range)),
|
||||
await findCustomClassLists(state, doc),
|
||||
])
|
||||
)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import type { EditorState } from './state'
|
||||
|
||||
export const htmlLanguages = [
|
||||
'aspnetcorerazor',
|
||||
'astro',
|
||||
|
@ -57,3 +59,15 @@ export const jsLanguages = [
|
|||
export const specialLanguages = ['vue', 'svelte']
|
||||
|
||||
export const languages = [...cssLanguages, ...htmlLanguages, ...jsLanguages, ...specialLanguages]
|
||||
|
||||
const semicolonlessLanguages = ['sass', 'sugarss', 'stylus']
|
||||
|
||||
export function isSemicolonlessCssLanguage(
|
||||
languageId: string,
|
||||
userLanguages: EditorState['userLanguages'] = {}
|
||||
) {
|
||||
return (
|
||||
semicolonlessLanguages.includes(languageId) ||
|
||||
semicolonlessLanguages.includes(userLanguages[languageId])
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue