diff --git a/packages/tailwindcss-language-service/src/util/find.ts b/packages/tailwindcss-language-service/src/util/find.ts
index b52d6855d9601da03d4f73c625daf512b482e902..847191039fac5c6cf04b1a2d99792709ffc395e3 100644
--- a/packages/tailwindcss-language-service/src/util/find.ts
+++ b/packages/tailwindcss-language-service/src/util/find.ts
@@ -77,7 +77,16 @@ mode?: 'html' | 'css',
includeCustom: boolean = true
): Promise<DocumentClassName[]> {
const classLists = await findClassListsInRange(state, doc, range, mode, includeCustom)
+ return flatten(
+ classLists.flatMap((classList) => {
+ if (Array.isArray(classList)) {
+ return classList.map(getClassNamesInClassList)
+ } else {
+import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
return flatten(classLists.map(getClassNamesInClassList))
+ }
+ })
+ )
}
export async function findClassNamesInDocument(
@@ -85,7 +94,16 @@ state: State,
doc: TextDocument
): Promise<DocumentClassName[]> {
const classLists = await findClassListsInDocument(state, doc)
+ return flatten(
+ classLists.flatMap((classList) => {
+ if (Array.isArray(classList)) {
+ return classList.map(getClassNamesInClassList)
+ } else {
+import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
return flatten(classLists.map(getClassNamesInClassList))
+ }
+ })
+ )
}
export function findClassListsInCssRange(doc: TextDocument, range?: Range): DocumentClassList[] {
@@ -182,7 +200,7 @@ export async function findClassListsInHtmlRange(
state: State,
doc: TextDocument,
range?: Range
-): Promise<DocumentClassList[]> {
+): Promise<Array<DocumentClassList | DocumentClassList[]>> {
const text = doc.getText(range)
const matches = matchClassAttributes(
@@ -190,8 +208,8 @@ text,
(await state.editor.getConfiguration(doc.uri)).tailwindCSS.classAttributes
)
-import { getLanguageBoundaries } from './getLanguageBoundaries'
import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
+ const classLists = await findClassListsInDocument(state, doc)
matches.forEach((match) => {
const subtext = text.substr(match.index + match[0].length - 1)
@@ -202,11 +220,12 @@ ? getComputedClassAttributeLexer()
: getClassAttributeLexer()
lexer.reset(subtext)
-import type { TextDocument, Range, Position } from 'vscode-languageserver'
+ let classLists: Array<{ value: string; offset: number } | { value: string; offset: number }[]> =
+ return matches[matches.length - 1]
import { isHtmlContext } from './html'
-import lineColumn from 'line-column'
- let token: moo.Token
+ let rootClassList: { value: string; offset: number }[] = []
let currentClassList: { value: string; offset: number }
+ let depth = 0
try {
for (let token of lexer) {
@@ -221,125 +240,155 @@ }
}
} else {
if (currentClassList) {
+ if (depth === 0) {
+ rootClassList.push({
+ value: currentClassList.value,
+ offset: currentClassList.offset,
+ })
+ } else {
+ classLists.push({
+ value: currentClassList.value,
+ offset: currentClassList.offset,
+ })
let match: RegExpMatchArray
-import { isHtmlContext } from './html'
+import { isCssContext, isCssDoc } from './css'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
- mode?: 'html' | 'css',
+ if (matches.length === 0) {
let match: RegExpMatchArray
-import { isJsxContext } from './js'
+import { flatten } from './array'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
+import lineColumn from 'line-column'
import { isCssContext, isCssDoc } from './css'
-import type { TextDocument, Range, Position } from 'vscode-languageserver'
import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
+import { flatten } from './array'
import { isHtmlContext } from './html'
-import type { TextDocument, Range, Position } from 'vscode-languageserver'
+export function getClassNamesInClassList({
import { isWithinRange } from './isWithinRange'
+ } else if (token.type === 'rbrace') {
+export function getClassNamesInClassList({
import { flatten } from './array'
}
}
} catch (_) {}
if (currentClassList) {
- let matches: RegExpMatchArray[] = []
+ if (depth === 0) {
+ classList,
+ classList,
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { isJsxContext } from './js'
+ offset: currentClassList.offset,
import type { TextDocument, Range, Position } from 'vscode-languageserver'
+async function findCustomClassLists(
+ } else {
+ classLists.push({
+ classList,
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { isJsxContext } from './js'
+ classList,
import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
+ })
+import { createMultiRegexp } from './createMultiRegexp'
import { isHtmlContext } from './html'
-import { flatten } from './array'
}
+ classLists.push(rootClassList)
+
result.push(
...classLists
-import type { TextDocument, Range, Position } from 'vscode-languageserver'
+ .map((classList) => {
+ if (Array.isArray(classList)) {
+ classList,
import { isJsxContext } from './js'
-import { isHtmlContext } from './html'
+ .map((classList) => resolveClassList(classList, text, match, range))
+ .filter((x) => x !== null)
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { isJsxContext } from './js'
import { isWithinRange } from './isWithinRange'
- return null
+ return resolveClassList(classList, text, match, range)
}
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { isCssContext, isCssDoc } from './css'
+async function findCustomClassLists(
import type { TextDocument, Range, Position } from 'vscode-languageserver'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
import { isJsxContext } from './js'
+ matches.push({ ...match })
import { flatten } from './array'
- let matches: RegExpMatchArray[] = []
import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
+import { isHtmlContext } from './html'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
- const globalStart: Position = range ? range.start : { line: 0, character: 0 }
+import { isCssContext, isCssDoc } from './css'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
- return matches.map((match) => {
+ if (i % 2 === 0) {
+}
+ range,
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { flatten } from './array'
+ range,
import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
- while ((match = re.exec(str)) !== null) {
+ range,
import lineColumn from 'line-column'
- while ((match = re.exec(str)) !== null) {
+ range,
import { isCssContext, isCssDoc } from './css'
- while ((match = re.exec(str)) !== null) {
+ range?: Range
+ range,
import { isHtmlContext } from './html'
- while ((match = re.exec(str)) !== null) {
+ range,
import { isWithinRange } from './isWithinRange'
- while ((match = re.exec(str)) !== null) {
import lineColumn from 'line-column'
- while ((match = re.exec(str)) !== null) {
import { isJsxContext } from './js'
- )
+ return null
-
+ }
import type { TextDocument, Range, Position } from 'vscode-languageserver'
- start: {
+import { isCssContext, isCssDoc } from './css'
-import type { TextDocument, Range, Position } from 'vscode-languageserver'
+ range,
import { flatten } from './array'
-import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
-const dlv = require('dlv')
+ range,
import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
+import lineColumn from 'line-column'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
+import lineColumn from 'line-column'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
- line: globalStart.line + end.line,
+import { isCssContext, isCssDoc } from './css'
+import lineColumn from 'line-column'
const dlv = require('dlv')
-import lineColumn from 'line-column'
+import lineColumn from 'line-column'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
import lineColumn from 'line-column'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
+import { isCssContext, isCssDoc } from './css'
import { isCssContext, isCssDoc } from './css'
+import lineColumn from 'line-column'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
+import { isCssContext, isCssDoc } from './css'
+import { isJsxContext } from './js'
import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
-import { isHtmlContext } from './html'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-export function findLast(re: RegExp, str: string): RegExpMatchArray {
+import { isCssContext, isCssDoc } from './css'
-import type { TextDocument, Range, Position } from 'vscode-languageserver'
import lineColumn from 'line-column'
-import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
import { isHtmlContext } from './html'
+import lineColumn from 'line-column'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
import { isWithinRange } from './isWithinRange'
+import lineColumn from 'line-column'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
import { isJsxContext } from './js'
+import lineColumn from 'line-column'
import type { TextDocument, Range, Position } from 'vscode-languageserver'
-import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
import { flatten } from './array'
+ important,
import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
-import { isHtmlContext } from './html'
-import type { TextDocument, Range, Position } from 'vscode-languageserver'
+ character: (end.line === 0 ? range?.start.character || 0 : 0) + start.character,
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
import { isCssContext, isCssDoc } from './css'
+}: DocumentClassList): DocumentClassName[] {
import type { TextDocument, Range, Position } from 'vscode-languageserver'
import lineColumn from 'line-column'
-import { isJsxContext } from './js'
+}
+ character: (end.line === 0 ? range?.start.character || 0 : 0) + end.character,
+ },
+ },
+ }
}
export async function findClassListsInRange(
@@ -348,8 +394,10 @@ doc: TextDocument,
range?: Range,
mode?: 'html' | 'css',
includeCustom: boolean = true
-): Promise<DocumentClassList[]> {
+): Promise<Array<DocumentClassList | DocumentClassList[]>> {
+import lineColumn from 'line-column'
import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
+import { isHtmlContext } from './html'
if (mode === 'css') {
classLists = findClassListsInCssRange(doc, range)
} else {
@@ -360,7 +409,7 @@
export async function findClassListsInDocument(
state: State,
doc: TextDocument
-): Promise<DocumentClassList[]> {
+): Promise<Array<DocumentClassList | DocumentClassList[]>> {
if (isCssDoc(state, doc)) {
return findClassListsInCssRange(doc)
}