Home

tailwind-ctp-intellisense @master - refs - log -
-
https://git.jolheiser.com/tailwind-ctp-intellisense.git
Tailwind intellisense + Catppuccin
tree log patch
add initial quick fix for utility conflict diagnostic
Brad Cornes <bradlc41@gmail.com>
4 years ago
2 changed files, 125 additions(+), 55 deletions(-)
M src/lsp/providers/codeActionProvider/index.ts -> src/lsp/providers/codeActionProvider/index.ts
diff --git a/src/lsp/providers/codeActionProvider/index.ts b/src/lsp/providers/codeActionProvider/index.ts
index 28b51444d56fb61000f2e34b32affdfdd19e4f01..959411af30b8194c3b3cf7531771774e91424ead 100644
--- a/src/lsp/providers/codeActionProvider/index.ts
+++ b/src/lsp/providers/codeActionProvider/index.ts
@@ -22,7 +22,10 @@   DiagnosticKind,
   isInvalidApplyDiagnostic,
   AugmentedDiagnostic,
   InvalidApplyDiagnostic,
+  isUtilityConflictsDiagnostic,
+  UtilityConflictsDiagnostic,
 } from '../diagnostics/types'
+import { flatten, dedupeBy } from '../../../util/array'
 
 async function getDiagnosticsFromCodeActionParams(
   state: State,
@@ -35,7 +38,11 @@
   return params.context.diagnostics
     .map((diagnostic) => {
       return diagnostics.find((d) => {
-        return rangesEqual(d.range, diagnostic.range)
+        return (
+          d.code === diagnostic.code &&
+          d.message === diagnostic.message &&
+          rangesEqual(d.range, diagnostic.range)
+        )
       })
     })
     .filter(Boolean)
@@ -55,40 +62,46 @@     params,
     codes
   )
 
-  return Promise.all(
-    diagnostics
-      .map((diagnostic) => {
-        if (isInvalidApplyDiagnostic(diagnostic)) {
-          return provideInvalidApplyCodeAction(state, params, diagnostic)
-        }
+  let actions = diagnostics.map((diagnostic) => {
+    if (isInvalidApplyDiagnostic(diagnostic)) {
+      return provideInvalidApplyCodeActions(state, params, diagnostic)
+    }
+
+    if (isUtilityConflictsDiagnostic(diagnostic)) {
+      return provideUtilityConflictsCodeActions(state, params, diagnostic)
+    }
 
-        let match = findLast(
-          / Did you mean (?:something like )?'(?<replacement>[^']+)'\?$/g,
-          diagnostic.message
-        )
+    let match = findLast(
+      / Did you mean (?:something like )?'(?<replacement>[^']+)'\?$/g,
+      diagnostic.message
+    )
 
-        if (!match) {
-          return null
-        }
+    if (!match) {
+      return []
+    }
 
-        return {
-          title: `Replace with '${match.groups.replacement}'`,
-          kind: CodeActionKind.QuickFix,
-          diagnostics: [diagnostic],
-          edit: {
-            changes: {
-              [params.textDocument.uri]: [
-                {
-                  range: diagnostic.range,
-                  newText: match.groups.replacement,
-                },
-              ],
-            },
+    return [
+      {
+        title: `Replace with '${match.groups.replacement}'`,
+        kind: CodeActionKind.QuickFix,
+        diagnostics: [diagnostic],
+        edit: {
+          changes: {
+            [params.textDocument.uri]: [
+              {
+                range: diagnostic.range,
+                newText: match.groups.replacement,
+              },
+            ],
           },
-        }
-      })
-      .filter(Boolean)
-  )
+        },
+      },
+    ]
+  })
+
+  return Promise.all(actions)
+    .then(flatten)
+    .then((x) => dedupeBy(x, (item) => JSON.stringify(item.edit)))
 }
 
 function classNameToAst(
@@ -154,11 +167,56 @@
   return cssObjToAst(obj, state.modules.postcss)
 }
 
-async function provideInvalidApplyCodeAction(
+async function provideUtilityConflictsCodeActions(
+  state: State,
+  params: CodeActionParams,
+  diagnostic: UtilityConflictsDiagnostic
+): Promise<CodeAction[]> {
+  return [
+    {
+      title: `Delete '${diagnostic.className.className}'`,
+      kind: CodeActionKind.QuickFix,
+      diagnostics: [diagnostic],
+      edit: {
+        changes: {
+          [params.textDocument.uri]: [
+            {
+              range: diagnostic.className.classList.range,
+              newText: removeRangeFromString(
+                diagnostic.className.classList.classList,
+                diagnostic.className.relativeRange
+              ),
+            },
+          ],
+        },
+      },
+    },
+    {
+      title: `Delete '${diagnostic.otherClassName.className}'`,
+      kind: CodeActionKind.QuickFix,
+      diagnostics: [diagnostic],
+      edit: {
+        changes: {
+          [params.textDocument.uri]: [
+            {
+              range: diagnostic.className.classList.range,
+              newText: removeRangeFromString(
+                diagnostic.className.classList.classList,
+                diagnostic.otherClassName.relativeRange
+              ),
+            },
+          ],
+        },
+      },
+    },
+  ]
+}
+
+async function provideInvalidApplyCodeActions(
   state: State,
   params: CodeActionParams,
   diagnostic: InvalidApplyDiagnostic
-): Promise<CodeAction> {
+): Promise<CodeAction[]> {
   let document = state.editor.documents.get(params.textDocument.uri)
   let documentText = document.getText()
   const { postcss } = state.modules
@@ -250,30 +308,32 @@     }),
   ]).process(documentText, { from: undefined })
 
   if (!change) {
-    return null
+    return []
   }
 
-  return {
-    title: 'Extract to new rule.',
-    kind: CodeActionKind.QuickFix,
-    diagnostics: [diagnostic],
-    edit: {
-      changes: {
-        [params.textDocument.uri]: [
-          ...(totalClassNamesInClassList > 1
-            ? [
-                {
-                  range: diagnostic.className.classList.range,
-                  newText: removeRangeFromString(
-                    diagnostic.className.classList.classList,
-                    diagnostic.className.relativeRange
-                  ),
-                },
-              ]
-            : []),
-          change,
-        ],
+  return [
+    {
+      title: 'Extract to new rule',
+      kind: CodeActionKind.QuickFix,
+      diagnostics: [diagnostic],
+      edit: {
+        changes: {
+          [params.textDocument.uri]: [
+            ...(totalClassNamesInClassList > 1
+              ? [
+                  {
+                    range: diagnostic.className.classList.range,
+                    newText: removeRangeFromString(
+                      diagnostic.className.classList.classList,
+                      diagnostic.className.relativeRange
+                    ),
+                  },
+                ]
+              : []),
+            change,
+          ],
+        },
       },
     },
-  }
+  ]
 }
M src/util/array.ts -> src/util/array.ts
diff --git a/src/util/array.ts b/src/util/array.ts
index b40dd245fe57a3f1e1ddeb24fc75343041b530db..869eb9f6cd346528cd554b115bfb374952032e48 100644
--- a/src/util/array.ts
+++ b/src/util/array.ts
@@ -2,6 +2,16 @@ export function dedupe<T>(arr: Array<T>): Array<T> {
   return arr.filter((value, index, self) => self.indexOf(value) === index)
 }
 
+export function dedupeBy<T>(
+  arr: Array<T>,
+  transform: (item: T) => any
+): Array<T> {
+  return arr.filter(
+    (value, index, self) =>
+      self.map(transform).indexOf(transform(value)) === index
+  )
+}
+
 export function ensureArray<T>(value: T | T[]): T[] {
   return Array.isArray(value) ? value : [value]
 }