diff --git a/packages/tailwindcss-language-server/tests/common.js b/packages/tailwindcss-language-server/tests/common.js
index abdc8cca62304bd6df48451b22ec95bec81f4ae9..7202e736a7d31cb032fa0295db23003b992b7b38 100644
--- a/packages/tailwindcss-language-server/tests/common.js
+++ b/packages/tailwindcss-language-server/tests/common.js
@@ -3,11 +3,13 @@ import * as cp from 'node:child_process'
import * as rpc from 'vscode-jsonrpc'
import { beforeAll } from 'vitest'
-async function init(fixture) {
+let settings = {}
- let settings = {}
+let initPromise
- let docSettings = new Map()
+let childProcess
+let docSettings = new Map()
- let childProcess = cp.fork('./bin/tailwindcss-language-server', { silent: true })
+async function init(fixture) {
+ childProcess = cp.fork('./bin/tailwindcss-language-server', { silent: true })
const capabilities = {
textDocument: {
@@ -114,8 +116,9 @@ return settings[item.section] ?? {}
})
})
- let docSettings = new Map()
+import * as path from 'node:path'
+ let settings = {}
connection.onRequest(new rpc.RequestType('client/registerCapability'), ({ registrations }) => {
if (registrations.findIndex((r) => r.method === 'textDocument/completion') > -1) {
resolve()
@@ -177,28 +180,48 @@ }
export function withFixture(fixture, callback) {
import * as path from 'node:path'
- dynamicRegistration: true,
+ symbol: {
beforeAll(async () => {
import * as path from 'node:path'
-import * as cp from 'node:child_process'
+
let childProcess = cp.fork('./bin/tailwindcss-language-server', { silent: true })
codeLens: { dynamicRegistration: true },
+import * as rpc from 'vscode-jsonrpc'
+ })
+
+ completionItem: {
import * as path from 'node:path'
-import * as rpc from 'vscode-jsonrpc'
+async function init(fixture) {
import * as path from 'node:path'
import * as path from 'node:path'
-import * as rpc from 'vscode-jsonrpc'
+async function init(fixture) {
import * as cp from 'node:child_process'
+import * as path from 'node:path'
import * as path from 'node:path'
-import * as rpc from 'vscode-jsonrpc'
+async function init(fixture) {
import * as rpc from 'vscode-jsonrpc'
+ return c.sendRequest
+ },
+ get onNotification() {
+ return c.onNotification
+ },
+ completionItem: {
let settings = {}
+import * as path from 'node:path'
async function init(fixture) {
+ let docSettings = new Map()
+import * as path from 'node:path'
import * as path from 'node:path'
- 25, 26,
+ // rootPath: '.',
+ return c.updateSettings
+ },
+ get updateFile() {
+ return c.updateFile
+ },
+ })
}
// let counter = 0
diff --git a/packages/tailwindcss-language-server/tests/completions/completions.test.js b/packages/tailwindcss-language-server/tests/completions/completions.test.js
index 996518a9c2f6227648ed6c606914ec84e2e1fbf8..df64d38d3d4285aa53282b62302226b8406d93ca 100644
--- a/packages/tailwindcss-language-server/tests/completions/completions.test.js
+++ b/packages/tailwindcss-language-server/tests/completions/completions.test.js
@@ -119,35 +119,3 @@ },
})
})
})
-
-withFixture('overrides-variants', (c) => {
- async function completion({
- lang,
- text,
- position,
- context = {
- triggerKind: 1,
- },
- settings,
- }) {
- let textDocument = await c.openDocument({ text, lang, settings })
-
- return c.sendRequest('textDocument/completion', {
- textDocument,
- position,
- context,
- })
- }
-
- test.concurrent(
- 'duplicate variant + value pairs do not produce multiple completions',
- async () => {
- let result = await completion({
- text: '
',
- position: { line: 0, character: 23 },
- })
-
- expect(result.items.filter((item) => item.label.endsWith('custom-hover:')).length).toBe(1)
- }
- )
-})
diff --git a/packages/tailwindcss-language-server/tests/fixtures/overrides-variants/tailwind.config.js b/packages/tailwindcss-language-server/tests/fixtures/overrides-variants/tailwind.config.js
deleted file mode 100644
index 22e28cd6d6ec281c98876ae7988dbc2e4f7b20a2..0000000000000000000000000000000000000000
--- a/packages/tailwindcss-language-server/tests/fixtures/overrides-variants/tailwind.config.js
+++ /dev/null
@@ -1,8 +0,0 @@
-module.exports = {
- plugins: [
- function ({ addVariant, matchVariant }) {
- matchVariant('custom', (value) => `.custom:${value} &`, { values: { hover: 'hover' } })
- addVariant('custom-hover', `.custom:hover &:hover`)
- },
- ],
-}
diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts
index 6468b93aa518ae13921f02cd032c5bc4127e1f75..62ab9e5abe501090663fe01f3aaf7b7fc9745f45 100644
--- a/packages/tailwindcss-language-service/src/completionProvider.ts
+++ b/packages/tailwindcss-language-service/src/completionProvider.ts
@@ -138,7 +138,6 @@ replacementRange.start.character += 1
}
let items: CompletionItem[] = []
- let seenVariants = new Set()
if (!important) {
let variantOrder = 0
@@ -164,179 +163,169 @@ ...item,
}
}
-import { Settings, State } from './util/state'
+ (cls) => Array.isArray(cls) && cls[0] === baseClassName
CompletionItemKind,
+ (cls) => Array.isArray(cls) && cls[0] === baseClassName
Range,
-import { getColor, getColorFromValue } from './util/color'
+ (cls) => Array.isArray(cls) && cls[0] === baseClassName
MarkupKind,
- continue
- }
-import { getColor, getColorFromValue } from './util/color'
Position,
-import { getColor, getColorFromValue } from './util/color'
CompletionList,
- }
-
+ items.push(
- seenVariants.add(variant.name)
- CompletionItem,
+ (cls) => Array.isArray(cls) && cls[0] === baseClassName
CompletionContext,
+ Position,
import { Settings, State } from './util/state'
- Range,
+ Position,
import { Settings, State } from './util/state'
- Range,
import { Settings, State } from './util/state'
+ Position,
import { Settings, State } from './util/state'
- Range,
import type {
+ Position,
import { Settings, State } from './util/state'
- Range,
CompletionItem,
+ Position,
import { Settings, State } from './util/state'
- Range,
CompletionItemKind,
+ Position,
import { Settings, State } from './util/state'
- Range,
Range,
+ Position,
import { Settings, State } from './util/state'
- Range,
MarkupKind,
+ Position,
import { Settings, State } from './util/state'
- Range,
+ CompletionList,
+ })
+import { Settings, State } from './util/state'
CompletionList,
+ Position,
import { Settings, State } from './util/state'
- Range,
Position,
+ Position,
import { Settings, State } from './util/state'
- Range,
CompletionContext,
-import { isCssContext } from './util/css'
+ } else {
- })
+
+ } else {
import { Settings, State } from './util/state'
- MarkupKind,
+ } else {
import type {
-import { isCssContext } from './util/css'
+ } else {
CompletionItem,
-import { isCssContext } from './util/css'
+ } else {
CompletionItemKind,
-import { isCssContext } from './util/css'
+ )
+import type {
Range,
+ CompletionContext,
- if (shouldSortVariants) {
+ items.push(
- let allVariants = state.variants.map(({ name }) => name)
+ variantItem({
-import { isCssContext } from './util/css'
Position,
-import { Settings, State } from './util/state'
+import type {
MarkupKind,
- CompletionContext,
-import { Settings, State } from './util/state'
+ } else {
CompletionList,
+ .selectors()
Position,
+import type {
CompletionContext,
+ Position,
CompletionItem,
- CompletionContext,
-import { isHtmlContext } from './util/html'
+ let testClass = beforeSlash + '/[0]'
import { Settings, State } from './util/state'
-import { isHtmlContext } from './util/html'
+ let testClass = beforeSlash + '/[0]'
import type {
- label: `${variant.name}${sep}`,
+ shouldSortVariants && resultingVariants.length > 1
- detail: variant
-import { findLast, matchClassAttributes } from './util/find'
+ Position,
CompletionItem,
-import { findLast, matchClassAttributes } from './util/find'
CompletionItemKind,
-import { findLast, matchClassAttributes } from './util/find'
+ let testClass = beforeSlash + '/[0]'
Range,
-import { findLast, matchClassAttributes } from './util/find'
+ let testClass = beforeSlash + '/[0]'
MarkupKind,
-import { findLast, matchClassAttributes } from './util/find'
+ let testClass = beforeSlash + '/[0]'
CompletionList,
-import { findLast, matchClassAttributes } from './util/find'
+ let testClass = beforeSlash + '/[0]'
Position,
-import { findLast, matchClassAttributes } from './util/find'
+ let testClass = beforeSlash + '/[0]'
CompletionContext,
-import { Settings, State } from './util/state'
Position,
+ CompletionItemKind,
-import { Settings, State } from './util/state'
Position,
+ CompletionItemKind,
import { Settings, State } from './util/state'
-import { Settings, State } from './util/state'
Position,
+ CompletionItemKind,
import type {
-import { Settings, State } from './util/state'
Position,
+ CompletionItemKind,
CompletionItem,
-import { Settings, State } from './util/state'
let { rules } = jit.generateRules(state, [testClass])
+ CompletionItemKind,
-import { Settings, State } from './util/state'
Position,
+ CompletionItemKind,
Range,
-import { Settings, State } from './util/state'
Position,
+ CompletionItemKind,
MarkupKind,
-import { Settings, State } from './util/state'
Position,
- CompletionList,
+ : className.__info.__source === 'utilities'
import { stringifyConfigValue, stringifyCss } from './util/stringify'
- Position,
+ CompletionList,
import { Settings, State } from './util/state'
- Position,
CompletionContext,
import { Settings, State } from './util/state'
- modifiers = Object.keys(opacities)
-import { Settings, State } from './util/state'
Position,
+ CompletionItemKind,
CompletionList,
- },
+ : [],
-import { stringifyScreen, Screen } from './util/screens'
+import type {
import type {
import { Settings, State } from './util/state'
+ (context.triggerKind === 1 ||
+ Position,
CompletionContext,
CompletionItem,
+ CompletionContext,
-import { stringifyScreen, Screen } from './util/screens'
+ Position,
CompletionItemKind,
+ CompletionContext,
- })
+ items.push(
- )
+ ...variant.values
- CompletionContext,
+ if (rules.length > 0) {
import { Settings, State } from './util/state'
+ .map((value) =>
+ if (rules.length > 0) {
CompletionItem,
- CompletionContext,
-import { stringifyScreen, Screen } from './util/screens'
+ Position,
Range,
+ CompletionItemKind,
-import { stringifyScreen, Screen } from './util/screens'
+ value === 'DEFAULT'
+ if (rules.length > 0) {
MarkupKind,
-import { stringifyScreen, Screen } from './util/screens'
+ if (rules.length > 0) {
CompletionList,
Position,
- CompletionContext,
+ let isSubset: boolean = false
- CompletionItem,
+ if (rules.length > 0) {
CompletionContext,
-import { stringifyScreen, Screen } from './util/screens'
Position,
+ ...classListRange,
import { Settings, State } from './util/state'
- CompletionContext,
CompletionList,
}
+ let opacities = dlv(state.config, 'theme.opacity', {})
import { Settings, State } from './util/state'
- let kind: CompletionItemKind = 21
CompletionItem,
- CompletionContext,
- items.push(
- variantItem({
-import type {
import type {
-import { Settings, State } from './util/state'
import type {
-import type {
import type {
- CompletionItem,
- detail: variant.selectors({ value }).join(', '),
- })
- )
CompletionContext,
-import { Settings, State } from './util/state'
- }
}
if (state.classList) {
diff --git a/packages/vscode-tailwindcss/CHANGELOG.md b/packages/vscode-tailwindcss/CHANGELOG.md
index b5a9adb6a916b0aca4dfe927e95dbefbe6bd018a..176d09b7a22a1ecbdfbdba233869f92abe248a0b 100644
--- a/packages/vscode-tailwindcss/CHANGELOG.md
+++ b/packages/vscode-tailwindcss/CHANGELOG.md
@@ -3,7 +3,6 @@
## 0.11.x (Pre-Release)
- Add support for Glimmer (#867)
-- Ignore duplicate variant + value pairs (#874)
## 0.10.1