Home

tailwind-ctp-intellisense @master - refs - log -
-
https://git.jolheiser.com/tailwind-ctp-intellisense.git
Tailwind intellisense + Catppuccin
tree log patch
Remove duplicate `variant` + `value` pairs from completions (#874) * Refactor * Support using multiple fixtures in a single test file * Add test * Remove duplicate `variant` + `value` pairs from completions * Update changelog
Signature
-----BEGIN PGP SIGNATURE----- wsBcBAABCAAQBQJlO/bkCRBK7hj4Ov3rIwAA2roIAKryzkWS94Uf75mjpid7nOwq jicSqaOCymoYyb77bTgjPMpV1jZtuUAa0PQB14tTBAp2yRedDbJUUoNZbTm7Tt3u ARjMliJMpHWpW9MZuMd3Wmkr0MvPUMMKG+P/DKOBXt9/P7HAtwNKApLgHDdBMFpc LQyKrSZqxEtGPHs9t89U8fvwy0Pchg51c5ZNi0dn13OBqRFfHe17DOFlvInG1y53 RMieqzA4z0YZ3cBOzb+p//PUM7xxaAi6tJRLm26PQYO3BLWa+OpejO8q5KB1VMJv c5Z/gz6Bl3o64LYesV7iGvTGStsZjy9sJ+dV7wkNzfNCJj0DjrbPkhEWolQiOgI= =AqiD -----END PGP SIGNATURE-----
Jordan Pittman <jordan@cryptica.me>
2 years ago
5 changed files, 133 additions(+), 99 deletions(-)
packages/tailwindcss-language-server/tests/common.jspackages/tailwindcss-language-server/tests/completions/completions.test.jspackages/tailwindcss-language-server/tests/fixtures/overrides-variants/tailwind.config.jspackages/tailwindcss-language-service/src/completionProvider.tspackages/vscode-tailwindcss/CHANGELOG.md
M packages/tailwindcss-language-server/tests/common.jspackages/tailwindcss-language-server/tests/common.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
diff --git a/packages/tailwindcss-language-server/tests/common.js b/packages/tailwindcss-language-server/tests/common.js
index 7202e736a7d31cb032fa0295db23003b992b7b38..abdc8cca62304bd6df48451b22ec95bec81f4ae9 100644
--- a/packages/tailwindcss-language-server/tests/common.js
+++ b/packages/tailwindcss-language-server/tests/common.js
@@ -3,13 +3,11 @@ import * as cp from 'node:child_process'
 import * as rpc from 'vscode-jsonrpc'
 import { beforeAll } from 'vitest'
 
-let settings = {}
-let initPromise
-let childProcess
-let docSettings = new Map()
-
 async function init(fixture) {
-  childProcess = cp.fork('./bin/tailwindcss-language-server', { silent: true })
+  let settings = {}
+  let docSettings = new Map()
+
+  let childProcess = cp.fork('./bin/tailwindcss-language-server', { silent: true })
 
   const capabilities = {
     textDocument: {
@@ -116,7 +114,7 @@       return settings[item.section] ?? {}
     })
   })
 
-  initPromise = new Promise((resolve) => {
+  let initPromise = new Promise((resolve) => {
     connection.onRequest(new rpc.RequestType('client/registerCapability'), ({ registrations }) => {
       if (registrations.findIndex((r) => r.method === 'textDocument/completion') > -1) {
         resolve()
@@ -177,33 +175,18 @@   }
 }
 
 export function withFixture(fixture, callback) {
-  let c
+  let c = {}
 
   beforeAll(async () => {
-    c = await init(fixture)
+    // Using the connection object as the prototype lets us access the connection
+    // without defining getters for all the methods and also lets us add helpers
+    // to the connection object without having to resort to using a Proxy
+    Object.setPrototypeOf(c, await init(fixture))
+
     return () => c.connection.end()
   })
 
-  callback({
-    get connection() {
-      return c.connection
-    },
-    get sendRequest() {
-      return c.sendRequest
-    },
-    get onNotification() {
-      return c.onNotification
-    },
-    get openDocument() {
-      return c.openDocument
-    },
-    get updateSettings() {
-      return c.updateSettings
-    },
-    get updateFile() {
-      return c.updateFile
-    },
-  })
+  callback(c)
 }
 
 // let counter = 0
M packages/tailwindcss-language-server/tests/completions/completions.test.jspackages/tailwindcss-language-server/tests/completions/completions.test.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
diff --git a/packages/tailwindcss-language-server/tests/completions/completions.test.js b/packages/tailwindcss-language-server/tests/completions/completions.test.js
index df64d38d3d4285aa53282b62302226b8406d93ca..996518a9c2f6227648ed6c606914ec84e2e1fbf8 100644
--- a/packages/tailwindcss-language-server/tests/completions/completions.test.js
+++ b/packages/tailwindcss-language-server/tests/completions/completions.test.js
@@ -119,3 +119,35 @@       },
     })
   })
 })
+
+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: '<div class="custom-hover"></div>',
+        position: { line: 0, character: 23 },
+      })
+
+      expect(result.items.filter((item) => item.label.endsWith('custom-hover:')).length).toBe(1)
+    }
+  )
+})
I packages/tailwindcss-language-server/tests/fixtures/overrides-variants/tailwind.config.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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
new file mode 100644
index 0000000000000000000000000000000000000000..22e28cd6d6ec281c98876ae7988dbc2e4f7b20a2
--- /dev/null
+++ b/packages/tailwindcss-language-server/tests/fixtures/overrides-variants/tailwind.config.js
@@ -0,0 +1,8 @@
+module.exports = {
+  plugins: [
+    function ({ addVariant, matchVariant }) {
+      matchVariant('custom', (value) => `.custom:${value} &`, { values: { hover: 'hover' } })
+      addVariant('custom-hover', `.custom:hover &:hover`)
+    },
+  ],
+}
M packages/tailwindcss-language-service/src/completionProvider.tspackages/tailwindcss-language-service/src/completionProvider.ts
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts
index 62ab9e5abe501090663fe01f3aaf7b7fc9745f45..6468b93aa518ae13921f02cd032c5bc4127e1f75 100644
--- a/packages/tailwindcss-language-service/src/completionProvider.ts
+++ b/packages/tailwindcss-language-service/src/completionProvider.ts
@@ -138,6 +138,7 @@       replacementRange.start.character += 1
     }
 
     let items: CompletionItem[] = []
+    let seenVariants = new Set<string>()
 
     if (!important) {
       let variantOrder = 0
@@ -163,85 +164,94 @@           ...item,
         }
       }
 
-      items.push(
-        ...state.variants.flatMap((variant) => {
-          let items: CompletionItem[] = []
+      for (let variant of state.variants) {
+        if (existingVariants.includes(variant.name)) {
+          continue
+        }
+
+        if (seenVariants.has(variant.name)) {
+          continue
+        }
 
-          if (variant.isArbitrary) {
-            items.push(
-              variantItem({
-                label: `${variant.name}${variant.hasDash ? '-' : ''}[]${sep}`,
-                insertTextFormat: 2,
-                textEditText: `${variant.name}${variant.hasDash ? '-' : ''}[\${1}]${sep}\${0}`,
-                // command: {
-                //   title: '',
-                //   command: 'tailwindCSS.onInsertArbitraryVariantSnippet',
-                //   arguments: [variant.name, replacementRange],
-                // },
-              })
-            )
-          } else if (!existingVariants.includes(variant.name)) {
-            let shouldSortVariants = !semver.gte(state.version, '2.99.0')
-            let resultingVariants = [...existingVariants, variant.name]
+        seenVariants.add(variant.name)
 
-            if (shouldSortVariants) {
-              let allVariants = state.variants.map(({ name }) => name)
-              resultingVariants = resultingVariants.sort(
-                (a, b) => allVariants.indexOf(b) - allVariants.indexOf(a)
-              )
-            }
+        if (variant.isArbitrary) {
+          items.push(
+            variantItem({
+              label: `${variant.name}${variant.hasDash ? '-' : ''}[]${sep}`,
+              insertTextFormat: 2,
+              textEditText: `${variant.name}${variant.hasDash ? '-' : ''}[\${1}]${sep}\${0}`,
+              // command: {
+              //   title: '',
+              //   command: 'tailwindCSS.onInsertArbitraryVariantSnippet',
+              //   arguments: [variant.name, replacementRange],
+              // },
+            })
+          )
+        } else {
+          let shouldSortVariants = !semver.gte(state.version, '2.99.0')
+          let resultingVariants = [...existingVariants, variant.name]
 
-            items.push(
-              variantItem({
-                label: `${variant.name}${sep}`,
-                detail: variant
-                  .selectors()
-                  .map((selector) => addPixelEquivalentsToMediaQuery(selector, rootFontSize))
-                  .join(', '),
-                textEditText: resultingVariants[resultingVariants.length - 1] + sep,
-                additionalTextEdits:
-                  shouldSortVariants && resultingVariants.length > 1
-                    ? [
-                        {
-                          newText:
-                            resultingVariants.slice(0, resultingVariants.length - 1).join(sep) +
-                            sep,
-                          range: {
-                            start: {
-                              ...classListRange.start,
-                              character: classListRange.end.character - partialClassName.length,
-                            },
-                            end: {
-                              ...replacementRange.start,
-                              character: replacementRange.start.character,
-                            },
+          if (shouldSortVariants) {
+            let allVariants = state.variants.map(({ name }) => name)
+            resultingVariants = resultingVariants.sort(
+              (a, b) => allVariants.indexOf(b) - allVariants.indexOf(a)
+            )
+          }
+
+          items.push(
+            variantItem({
+              label: `${variant.name}${sep}`,
+              detail: variant
+                .selectors()
+                .map((selector) => addPixelEquivalentsToMediaQuery(selector, rootFontSize))
+                .join(', '),
+              textEditText: resultingVariants[resultingVariants.length - 1] + sep,
+              additionalTextEdits:
+                shouldSortVariants && resultingVariants.length > 1
+                  ? [
+                      {
+                        newText:
+                          resultingVariants.slice(0, resultingVariants.length - 1).join(sep) + sep,
+                        range: {
+                          start: {
+                            ...classListRange.start,
+                            character: classListRange.end.character - partialClassName.length,
+                          },
+                          end: {
+                            ...replacementRange.start,
+                            character: replacementRange.start.character,
                           },
                         },
-                      ]
-                    : [],
-              })
-            )
+                      },
+                    ]
+                  : [],
+            })
+          )
+        }
+
+        for (let value of variant.values ?? []) {
+          if (existingVariants.includes(`${variant.name}-${value}`)) {
+            continue
           }
 
-          if (variant.values.length) {
-            items.push(
-              ...variant.values
-                .filter((value) => !existingVariants.includes(`${variant.name}-${value}`))
-                .map((value) =>
-                  variantItem({
-                    label:
-                      value === 'DEFAULT'
-                        ? `${variant.name}${sep}`
-                        : `${variant.name}${variant.hasDash ? '-' : ''}${value}${sep}`,
-                    detail: variant.selectors({ value }).join(', '),
-                  })
-                )
-            )
+          if (seenVariants.has(`${variant.name}-${value}`)) {
+            continue
           }
 
-          return items
-        })
-      )
+          seenVariants.add(`${variant.name}-${value}`)
+
+          items.push(
+            variantItem({
+              label:
+                value === 'DEFAULT'
+                  ? `${variant.name}${sep}`
+                  : `${variant.name}${variant.hasDash ? '-' : ''}${value}${sep}`,
+              detail: variant.selectors({ value }).join(', '),
+            })
+          )
+        }
+      }
     }
 
     if (state.classList) {
M packages/vscode-tailwindcss/CHANGELOG.mdpackages/vscode-tailwindcss/CHANGELOG.md
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
diff --git a/packages/vscode-tailwindcss/CHANGELOG.md b/packages/vscode-tailwindcss/CHANGELOG.md
index 176d09b7a22a1ecbdfbdba233869f92abe248a0b..b5a9adb6a916b0aca4dfe927e95dbefbe6bd018a 100644
--- a/packages/vscode-tailwindcss/CHANGELOG.md
+++ b/packages/vscode-tailwindcss/CHANGELOG.md
@@ -3,6 +3,7 @@
 ## 0.11.x (Pre-Release)
 
 - Add support for Glimmer (#867)
+- Ignore duplicate variant + value pairs (#874)
 
 ## 0.10.1