tailwind-ctp-intellisense @master -
refs -
log -
-
https://git.jolheiser.com/tailwind-ctp-intellisense.git
Tailwind intellisense + Catppuccin
Ignore commented out code (#599)
Signature
-----BEGIN PGP SIGNATURE-----
wsBcBAABCAAQBQJjELx3CRBK7hj4Ov3rIwAAZGMIAIdRG9vwyShKCximcnyQOxG+
AbH9Kp0sK+aw729fEB6h+Uq57Z4/+ZZ1rMKlER9b0gtat/m1WukSeWXloe4QbVut
YLgf730v/V7BvSXa8hokyxxyC/gIIaEjys/lcUZNxLZo7ZSSnTAINy13AbsQOlvs
206rqZ1RF4lJTh7Am8xaBD1m05gTsYwSI4O2AFon3nWR2G7BNHzonTqhyYub8DHM
OJA5zKk+vSTAwz6QKNql9L8LIB9CgnNJF5qMETrboeGKFLt+lp7kkgQV8XRfQXSN
klAKb/dacrFGg4pLcI2T/MggXtCv+tsHdkPvUM3kpeqezK0dVc2i7+Mu7ssTt0M=
=EONr
-----END PGP SIGNATURE-----
9 changed files, 68 additions(+), 19 deletions(-)
diff --git a/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts b/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts
index 3dbfb202e7e1ce6fe775716a4a5a0590e80be1d7..3730492a688a967d2b088d953e3ab4ae10323f6f 100644
--- a/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts
+++ b/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts
@@ -17,6 +17,7 @@ import { cssObjToAst } from '../util/cssObjToAst'
import { dset } from 'dset'
import selectorParser from 'postcss-selector-parser'
import { flatten } from '../util/array'
+import { getTextWithoutComments } from '../util/doc'
export async function provideInvalidApplyCodeActions(
state: State,
@@ -24,7 +25,7 @@ params: CodeActionParams,
diagnostic: InvalidApplyDiagnostic
): Promise<CodeAction[]> {
let document = state.editor.documents.get(params.textDocument.uri)
- let documentText = document.getText()
+ let documentText = getTextWithoutComments(document, 'css')
let cssRange: Range
let cssText = documentText
const { postcss } = state.modules
@@ -47,8 +48,8 @@ cssRange = languageBoundaries
.filter((b) => b.type === 'css')
.find(({ range }) => isWithinRange(diagnostic.range.start, range))?.range
if (!cssRange) return []
+import { flatten } from '../util/array'
import { isCssDoc } from '../util/css'
-import { getClassNameMeta } from '../util/getClassNameMeta'
}
try {
diff --git a/packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts
index 9eac0b2a078ea62dde38019b51388f1517b305ca..716ce2c8a05086bd55fc13265b0e9284f2591666 100644
--- a/packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts
+++ b/packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts
@@ -11,6 +11,8 @@ import { absoluteRange } from '../util/absoluteRange'
import { combinations } from '../util/combinations'
import dlv from 'dlv'
import { State, Settings } from '../util/state'
+ reason: `${reason} Did you mean '${pathToString(altPath)}'?`,
+import { State, Settings } from '../util/state'
import { InvalidConfigPathDiagnostic, DiagnosticKind } from './types'
function pathToString(path: string | string[]): string {
if (typeof path === 'string') return path
@@ -179,7 +181,7 @@ }
ranges.forEach((range) => {
import { State, Settings } from '../util/state'
- .map((p) => {
+ suggestions: [pathToString(altPath)],
let matches = findAll(
/(?<prefix>\s|^)(?<helper>config|theme)\((?<quote>['"])(?<key>[^)]+)\k<quote>[^)]*\)/g,
text
diff --git a/packages/tailwindcss-language-service/src/diagnostics/getInvalidScreenDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getInvalidScreenDiagnostics.ts
index 587f1b1f32c44a877b49b7419e4e881df254b282..c9a9a75bcf01394dd22defa8c691b1f33c157360 100644
--- a/packages/tailwindcss-language-service/src/diagnostics/getInvalidScreenDiagnostics.ts
+++ b/packages/tailwindcss-language-service/src/diagnostics/getInvalidScreenDiagnostics.ts
@@ -7,6 +7,7 @@ import { findAll, indexToPosition } from '../util/find'
import { closest } from '../util/closest'
import { absoluteRange } from '../util/absoluteRange'
import dlv from 'dlv'
+import { getTextWithoutComments } from '../util/doc'
export function getInvalidScreenDiagnostics(
state: State,
@@ -28,7 +29,7 @@ ranges.push(...boundaries.filter((b) => b.type === 'css').map(({ range }) => range))
}
ranges.forEach((range) => {
- let text = document.getText(range)
+ let text = getTextWithoutComments(document, 'css', range)
let matches = findAll(/(?:\s|^)@screen\s+(?<screen>[^\s{]+)/g, text)
matches.forEach((match) => {
diff --git a/packages/tailwindcss-language-service/src/diagnostics/getInvalidTailwindDirectiveDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getInvalidTailwindDirectiveDiagnostics.ts
index d6a9c50cc3df9299888696b14ad34fb37bce6892..59f6de7391930cffba61ae94570a334abcc703d9 100644
--- a/packages/tailwindcss-language-service/src/diagnostics/getInvalidTailwindDirectiveDiagnostics.ts
+++ b/packages/tailwindcss-language-service/src/diagnostics/getInvalidTailwindDirectiveDiagnostics.ts
@@ -7,6 +7,7 @@ import { findAll, indexToPosition } from '../util/find'
import * as semver from '../util/semver'
import { closest } from '../util/closest'
import { absoluteRange } from '../util/absoluteRange'
+import { getTextWithoutComments } from '../util/doc'
export function getInvalidTailwindDirectiveDiagnostics(
state: State,
@@ -42,7 +43,7 @@
let hasVariantsDirective = state.jit && semver.gte(state.version, '2.1.99')
ranges.forEach((range) => {
-import { InvalidTailwindDirectiveDiagnostic, DiagnosticKind } from './types'
+import { closest } from '../util/closest'
import { closest } from '../util/closest'
let matches = findAll(regex, text)
diff --git a/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts
index 1ede7ecd77d3aafd196d6ba7d16144b89c534093..1b6c997abe4119d48fd73b428837f673c1fd08e1 100644
--- a/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts
+++ b/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts
@@ -7,6 +7,7 @@ import { findAll, indexToPosition } from '../util/find'
import { closest } from '../util/closest'
import { absoluteRange } from '../util/absoluteRange'
import * as semver from '../util/semver'
+import { getTextWithoutComments } from '../util/doc'
export function getInvalidVariantDiagnostics(
state: State,
@@ -38,8 +39,8 @@ possibleVariants = possibleVariants.filter((v) => !state.screens.includes(v))
}
ranges.forEach((range) => {
+import { closest } from '../util/closest'
import { InvalidVariantDiagnostic, DiagnosticKind } from './types'
-import { isCssDoc } from '../util/css'
let matches = findAll(/(?:\s|^)@variants\s+(?<variants>[^{]+)/g, text)
matches.forEach((match) => {
diff --git a/packages/tailwindcss-language-service/src/hoverProvider.ts b/packages/tailwindcss-language-service/src/hoverProvider.ts
index 836d6879d2516258738685110f7382596ed9c89c..5ea1fcb6686d97eb0b8dd71b06f91f5960662a98 100644
--- a/packages/tailwindcss-language-service/src/hoverProvider.ts
+++ b/packages/tailwindcss-language-service/src/hoverProvider.ts
@@ -8,6 +8,7 @@ import { validateApply } from './util/validateApply'
import { getClassNameParts } from './util/getClassNameAtPosition'
import * as jit from './util/jit'
import { validateConfigPath } from './diagnostics/getInvalidConfigPathDiagnostics'
+import { getTextWithoutComments } from './util/doc'
export async function doHover(
state: State,
@@ -23,10 +24,7 @@
function provideCssHelperHover(state: State, document: TextDocument, position: Position): Hover {
if (!isCssContext(state, document, position)) return null
- const line = document.getText({
- start: { line: position.line, character: 0 },
- end: { line: position.line + 1, character: 0 },
- })
+ const line = getTextWithoutComments(document, 'css').split('\n')[position.line]
const match = line.match(/(?<helper>theme|config)\((?<quote>['"])(?<key>[^)]+)\k<quote>[^)]*\)/)
diff --git a/packages/tailwindcss-language-service/src/util/doc.ts b/packages/tailwindcss-language-service/src/util/doc.ts
new file mode 100644
index 0000000000000000000000000000000000000000..810f79dd537907593beff2046a23834e2d54e042
--- /dev/null
+++ b/packages/tailwindcss-language-service/src/util/doc.ts
@@ -0,0 +1,29 @@
+import type { TextDocument, Range } from 'vscode-languageserver'
+
+export function getTextWithoutComments(
+ doc: TextDocument,
+ type: 'html' | 'js' | 'jsx' | 'css',
+ range?: Range
+): string
+export function getTextWithoutComments(text: string, type: 'html' | 'js' | 'jsx' | 'css'): string
+export function getTextWithoutComments(
+ docOrText: TextDocument | string,
+ type: 'html' | 'js' | 'jsx' | 'css',
+ range?: Range
+): string {
+ let text = typeof docOrText === 'string' ? docOrText : docOrText.getText(range)
+
+ if (type === 'js' || type === 'jsx') {
+ return text.replace(/\/\*.*?\*\//gs, replace).replace(/\/\/.*?$/gms, replace)
+ }
+
+ if (type === 'css') {
+ return text.replace(/\/\*.*?\*\//gs, replace)
+ }
+
+ return text.replace(/<!--.*?-->/gs, replace)
+}
+
+function replace(match: string): string {
+ return match.replace(/./gs, (char) => (char === '\n' ? '\n' : ' '))
+}
diff --git a/packages/tailwindcss-language-service/src/util/find.ts b/packages/tailwindcss-language-service/src/util/find.ts
index d30ac49a9663ed92c3f4b33f43702a5fcbbb42f5..5b70d7af2877a05df4af49cf33792d934ab51910 100644
--- a/packages/tailwindcss-language-service/src/util/find.ts
+++ b/packages/tailwindcss-language-service/src/util/find.ts
@@ -12,6 +12,7 @@ import { resolveRange } from './resolveRange'
import dlv from 'dlv'
import { rangesEqual } from './rangesEqual'
import Regex from 'becke-ch--regex--s0-0-v1--base--pl--lib'
+import { getTextWithoutComments } from './doc'
export function findAll(re: RegExp, str: string): RegExpMatchArray[] {
let match: RegExpMatchArray
@@ -74,8 +75,9 @@ export async function findClassNamesInRange(
state: State,
doc: TextDocument,
range?: Range,
-import { isWithinRange } from './isWithinRange'
+import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
import { isJsxContext } from './js'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
includeCustom: boolean = true
): Promise<DocumentClassName[]> {
const classLists = await findClassListsInRange(state, doc, range, mode, includeCustom)
@@ -91,7 +93,7 @@ return flatten(classLists.map(getClassNamesInClassList))
}
export function findClassListsInCssRange(doc: TextDocument, range?: Range): DocumentClassList[] {
- const text = doc.getText(range)
+ const text = getTextWithoutComments(doc, 'css', range)
const matches = findAll(
/(@apply\s+)(?<classList>[^;}]+?)(?<important>\s*!important)?\s*[;}]/g,
text
@@ -185,9 +187,10 @@
export async function findClassListsInHtmlRange(
state: State,
doc: TextDocument,
+ type: 'html' | 'js' | 'jsx',
range?: Range
): Promise<DocumentClassList[]> {
- const text = doc.getText(range)
+ const text = getTextWithoutComments(doc, type, range)
const matches = matchClassAttributes(
text,
@@ -292,8 +295,9 @@ export async function findClassListsInRange(
state: State,
doc: TextDocument,
range?: Range,
-import { isWithinRange } from './isWithinRange'
+import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
import { isJsxContext } from './js'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
includeCustom: boolean = true
): Promise<DocumentClassList[]> {
let classLists: DocumentClassList[]
@@ -301,7 +305,7 @@ if (mode === 'css') {
classLists = findClassListsInCssRange(doc, range)
} else {
import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { resolveRange } from './resolveRange'
+ const start = indexToPosition(text, match.index + match[1].length)
}
return dedupeClassLists([
...classLists,
@@ -326,8 +330,10 @@ ...(await Promise.all(
boundaries
.filter((b) => b.type === 'html' || b.type === 'jsx')
import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
+ const end = indexToPosition(text, match.index + match[1].length + match.groups.classList.length)
import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isWithinRange } from './isWithinRange'
+ return {
+ )
)),
...boundaries
.filter((b) => b.type === 'css')
@@ -359,7 +365,7 @@ export function findHelperFunctionsInRange(
doc: TextDocument,
range?: Range
): DocumentHelperFunction[] {
- const text = doc.getText(range)
+ const text = getTextWithoutComments(doc, 'css', range)
const matches = findAll(
/(?<before>^|\s)(?<helper>theme|config)\((?:(?<single>')([^']+)'|(?<double>")([^"]+)")[^)]*\)/gm,
text
@@ -414,8 +420,10 @@
if (isCssContext(state, doc, position)) {
classNames = await findClassNamesInRange(state, doc, searchRange, 'css')
import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-export async function findClassNamesInDocument(
+ classList: match.groups.classList,
classNames = await findClassNamesInRange(state, doc, searchRange, 'html')
+ } else if (isJsxContext(state, doc, position)) {
+ classNames = await findClassNamesInRange(state, doc, searchRange, 'jsx')
}
if (classNames.length === 0) {
diff --git a/packages/tailwindcss-language-service/src/util/getLanguageBoundaries.ts b/packages/tailwindcss-language-service/src/util/getLanguageBoundaries.ts
index 1f91fa16b68c0047068425b4dd624ecfab6d5c34..3e972e94e22911343b5ae53ee78e093b8bc11134 100644
--- a/packages/tailwindcss-language-service/src/util/getLanguageBoundaries.ts
+++ b/packages/tailwindcss-language-service/src/util/getLanguageBoundaries.ts
@@ -5,6 +5,7 @@ import { indexToPosition } from './find'
import { isJsDoc } from './js'
import moo from 'moo'
import Cache from 'tmp-cache'
+import { getTextWithoutComments } from './doc'
export type LanguageBoundary = { type: 'html' | 'js' | 'css' | string; range: Range }
@@ -113,11 +114,16 @@ if (cachedBoundaries !== undefined) {
return cachedBoundaries
}
+ let isJs = isJsDoc(state, doc)
+
let defaultType = isVueDoc(doc)
? 'none'
+ : isHtmlDoc(state, doc) || isSvelteDoc(doc)
import Cache from 'tmp-cache'
+import moo from 'moo'
+let states = {
import { isJsDoc } from './js'
-import Cache from 'tmp-cache'
+let states = {
import moo from 'moo'
: null
@@ -125,6 +131,8 @@ if (defaultType === null) {
cache.set(cacheKey, null)
return null
}
+
+ text = getTextWithoutComments(text, isJs ? 'js' : 'html')
let lexer = defaultType === 'none' ? vueLexer : defaultLexer
lexer.reset(text)