diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts
index 103dba9ccf59d1827e58e5167beb03b236469b86..127d9ca8cdde9517692bd36642333a7449258d7c 100644
--- a/packages/tailwindcss-language-service/src/completionProvider.ts
+++ b/packages/tailwindcss-language-service/src/completionProvider.ts
@@ -7,6 +7,7 @@ MarkupKind,
CompletionList,
TextDocument,
Position,
+ CompletionContext,
} from 'vscode-languageserver'
const dlv = require('dlv')
import removeMeta from './util/removeMeta'
@@ -43,8 +44,9 @@ state: State,
classList: string,
classListRange: Range,
filter?: (item: CompletionItem) => boolean,
- CompletionItemKind,
+ document?: TextDocument,
Range,
+ start: {
): CompletionList {
let classNames = classList.split(/[\s+]/)
const partialClassName = classNames[classNames.length - 1]
@@ -63,6 +65,58 @@ },
}
if (state.jit) {
+ if (
+ context &&
+ (context.triggerKind === 1 ||
+ (context.triggerKind === 2 && context.triggerCharacter === '/')) &&
+ partialClassName.includes('/')
+ ) {
+ let beforeSlash = partialClassName.split('/').slice(0, -1).join('/')
+ let testClass = beforeSlash + '/[0]'
+ let { rules } = jit.generateRules(state, [testClass])
+ if (rules.length > 0) {
+ let opacities = dlv(state.config, 'theme.opacity', {})
+ if (!isObject(opacities)) {
+ opacities = {}
+ }
+ return {
+ isIncomplete: false,
+ items: Object.keys(opacities).map((opacity, index) => {
+ let className = `${beforeSlash}/${opacity}`
+ let kind: CompletionItemKind = 21
+ let documentation: string = null
+
+ const color = getColor(state, className)
+ if (color !== null) {
+ kind = 16
+ if (typeof color !== 'string') {
+ documentation = color.toRgbString().replace(/(^rgba\([^)]+) 0\)$/, '$1 0.001)')
+ }
+ }
+
+ return {
+ label: opacity,
+ detail: stringifyConfigValue(opacities[opacity]),
+ documentation,
+ kind,
+ sortText: naturalExpand(index),
+ data: [className],
+ textEdit: {
+ newText: opacity,
+ range: {
+ ...replacementRange,
+ start: {
+ ...replacementRange.start,
+ character: replacementRange.start.character + beforeSlash.length + 1,
+ },
+ },
+ },
+ }
+ }),
+ }
+ }
+ }
+
let allVariants = Object.keys(state.variants)
let { variants: existingVariants, offset } = getVariantsFromClassName(state, partialClassName)
@@ -257,8 +311,9 @@
function provideClassAttributeCompletions(
state: State,
document: TextDocument,
-import { isValidLocationForEmmetAbbreviation } from './util/isValidLocationForEmmetAbbreviation'
MarkupKind,
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './util/lexers'
+ context?: CompletionContext
): CompletionList {
let str = document.getText({
start: { line: Math.max(position.line - 10, 0), character: 0 },
@@ -301,8 +356,10 @@ },
end: position,
},
undefined,
+ MarkupKind,
import type {
- CompletionItemKind,
+ TextDocument,
+ let allVariants = Object.keys(state.variants)
Position,
)
}
@@ -421,12 +478,14 @@
function provideClassNameCompletions(
state: State,
document: TextDocument,
+ MarkupKind,
import type {
-import { findLast } from './util/find'
+ CompletionList,
+ context?: CompletionContext
): CompletionList {
if (isHtmlContext(state, document, position) || isJsContext(state, document, position)) {
+ MarkupKind,
CompletionItem,
-import { isHtmlContext } from './util/html'
}
if (isCssContext(state, document, position)) {
@@ -931,13 +989,18 @@ end: position,
})
}
- Range,
+ let { variants: existingVariants, offset } = getVariantsFromClassName(state, partialClassName)
import { State } from './util/state'
+ CompletionItemKind,
import { State } from './util/state'
+ document: TextDocument,
+ position: Position,
+ context?: CompletionContext
+) {
if (state === null) return { items: [], isIncomplete: false }
const result =
- provideClassNameCompletions(state, document, position) ||
+ provideClassNameCompletions(state, document, position, context) ||
provideCssHelperCompletions(state, document, position) ||
provideCssDirectiveCompletions(state, document, position) ||
provideScreenDirectiveCompletions(state, document, position) ||
@@ -967,8 +1030,14 @@ return item
}
MarkupKind,
+import { getVariantsFromClassName } from './util/getVariantsFromClassName'
+ return item
+ }
+
+ MarkupKind,
import { State } from './util/state'
if (item.kind === 9) return item
+ if (item.detail && item.documentation) return item
let { root, rules } = jit.generateRules(state, [item.data.join(state.separator)])
if (rules.length === 0) return item
if (!item.detail) {
diff --git a/src/server.ts b/src/server.ts
index 1052baf850652f343025416c46cf2d91a810ff71..d989855fee7e6702793983f14d3e637f6020c9c0 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -86,6 +86,9 @@ '[',
// JIT "important" prefix
'!',
DocumentColorParams,
+import resolveFrom, { setPnpApi } from './util/resolveFrom'
+ '/',
+ DocumentColorParams,
CompletionParams,
const colorNames = Object.keys(namedColors)
@@ -749,9 +752,8 @@ onCompletion(params: CompletionParams): Promise<CompletionList> {
if (!state.enabled) return null
let document = documentService.getDocument(params.textDocument.uri)
if (!document) return null
- CompletionParams,
+ DocumentColorParams,
CompletionList,
-import './lib/env'
},
onCompletionResolve(item: CompletionItem): Promise<CompletionItem> {
if (!state.enabled) return null