Home

tailwind-ctp-intellisense @master - refs - log -
-
https://git.jolheiser.com/tailwind-ctp-intellisense.git
Tailwind intellisense + Catppuccin
tree log patch
diagnostics
Brad Cornes <brad@parall.ax>
4 years ago
5 changed files, 96 additions(+), 6 deletions(-)
I src/lsp/providers/diagnosticsProvider.ts
diff --git a/src/lsp/providers/diagnosticsProvider.ts b/src/lsp/providers/diagnosticsProvider.ts
new file mode 100644
index 0000000000000000000000000000000000000000..51565e9c5cb5a4d1f3291a37a4c28d99a220d47d
--- /dev/null
+++ b/src/lsp/providers/diagnosticsProvider.ts
@@ -0,0 +1,79 @@
+import {
+  TextDocument,
+  Diagnostic,
+  DiagnosticSeverity,
+} from 'vscode-languageserver'
+import { State } from '../util/state'
+import { isCssDoc } from '../util/css'
+import { findClassNamesInRange } from '../util/find'
+import { getClassNameParts } from '../util/getClassNameAtPosition'
+const dlv = require('dlv')
+
+function provideCssDiagnostics(state: State, document: TextDocument): void {
+  const classNames = findClassNamesInRange(document)
+
+  let diagnostics: Diagnostic[] = classNames
+    .map(({ className, range }) => {
+      const parts = getClassNameParts(state, className)
+      if (!parts) return null
+      const info = dlv(state.classNames.classNames, parts)
+      let message: string
+      if (info.__context && info.__context.length > 0) {
+        if (info.__context.length === 1) {
+          message = `\`@apply\` cannot be used with \`.${className}\` because it is nested inside of an at-rule (${info.__context[0]}).`
+        } else {
+          message = `\`@apply\` cannot be used with \`.${className}\` because it is nested inside of at-rules (${info.__context.join(
+            ', '
+          )}).`
+        }
+      } else if (info.__pseudo && info.__pseudo.length > 0) {
+        if (info.__pseudo.length === 1) {
+          message = `\`@apply\` cannot be used with \`.${className}\` because its definition includes a pseudo-selector (${info.__pseudo[0]})`
+        } else {
+          message = `\`@apply\` cannot be used with \`.${className}\` because its definition includes pseudo-selectors (${info.__pseudo.join(
+            ', '
+          )})`
+        }
+      }
+
+      if (!message) return null
+
+      return {
+        severity: DiagnosticSeverity.Error,
+        range,
+        message,
+        // source: 'ex',
+      }
+    })
+    .filter(Boolean)
+
+  // if (state.editor.capabilities.diagnosticRelatedInformation) {
+  //   diagnostic.relatedInformation = [
+  //     {
+  //       location: {
+  //         uri: document.uri,
+  //         range: Object.assign({}, diagnostic.range),
+  //       },
+  //       message: '',
+  //     },
+  //     {
+  //       location: {
+  //         uri: document.uri,
+  //         range: Object.assign({}, diagnostic.range),
+  //       },
+  //       message: '',
+  //     },
+  //   ]
+  // }
+
+  state.editor.connection.sendDiagnostics({ uri: document.uri, diagnostics })
+}
+
+export async function provideDiagnostics(
+  state: State,
+  document: TextDocument
+): Promise<void> {
+  if (isCssDoc(state, document)) {
+    return provideCssDiagnostics(state, document)
+  }
+}
M src/lsp/server.ts -> src/lsp/server.ts
diff --git a/src/lsp/server.ts b/src/lsp/server.ts
index b28b1bad9d226222f5d9e24472c9d8d698df6187..480aa289e7b5035e907891fd287bf45baeddd159 100644
--- a/src/lsp/server.ts
+++ b/src/lsp/server.ts
@@ -26,6 +26,7 @@ } from './providers/completionProvider'
 import { provideHover } from './providers/hoverProvider'
 import { URI } from 'vscode-uri'
 import { getDocumentSettings } from './util/getDocumentSettings'
+import { provideDiagnostics } from './providers/diagnosticsProvider'
 
 let state: State = { enabled: false }
 let connection = createConnection(ProposedFeatures.all)
@@ -45,6 +46,9 @@ })
 documents.onDidClose((event) => {
   documentSettings.delete(event.document.uri)
 })
+documents.onDidChangeContent((change) => {
+  provideDiagnostics(state, change.document)
+})
 documents.listen(connection)
 
 connection.onInitialize(
@@ -64,6 +68,10 @@           : {},
       capabilities: {
         configuration:
           capabilities.workspace && !!capabilities.workspace.configuration,
+        diagnosticRelatedInformation:
+          capabilities.textDocument &&
+          capabilities.textDocument.publishDiagnostics &&
+          capabilities.textDocument.publishDiagnostics.relatedInformation,
       },
     }
 
M src/lsp/util/css.ts -> src/lsp/util/css.ts
diff --git a/src/lsp/util/css.ts b/src/lsp/util/css.ts
index 84b788889c876707b4201ba3d2093b8bb472dd2f..d1acbea2b4e6e166e57d7d604ac2e615d1e94a0b 100644
--- a/src/lsp/util/css.ts
+++ b/src/lsp/util/css.ts
@@ -11,8 +11,8 @@   'scss',
   'stylus',
 ]
 
-import { TextDocument, Position } from 'vscode-languageserver'
 import { State } from './state'
+
   const userCssLanguages = Object.keys(
     state.editor.userLanguages
   ).filter((lang) => CSS_LANGUAGES.includes(state.editor.userLanguages[lang]))
M src/lsp/util/find.ts -> src/lsp/util/find.ts
diff --git a/src/lsp/util/find.ts b/src/lsp/util/find.ts
index 3fb04517624e5208d2b2c4f2152e3285e1bb9d8a..17b6a127654ae8b748941e828167512078286361 100644
--- a/src/lsp/util/find.ts
+++ b/src/lsp/util/find.ts
@@ -72,7 +72,7 @@ }
 
 export function findClassNamesInRange(
   doc: TextDocument,
-  range: Range
+  range?: Range
 ): DocumentClassName[] {
   const classLists = findClassListsInRange(doc, range)
   return [].concat.apply(
@@ -111,10 +111,11 @@ }
 
 export function findClassListsInRange(
   doc: TextDocument,
-  range: Range
+  range?: Range
 ): DocumentClassList[] {
   const text = doc.getText(range)
   const matches = findAll(/(@apply\s+)(?<classList>[^;}]+)[;}]/g, text)
+  const globalStart: Position = range ? range.start : { line: 0, character: 0 }
 
   return matches.map((match) => {
     const start = indexToPosition(text, match.index + match[1].length)
@@ -127,15 +128,16 @@       classList: match.groups.classList,
       range: {
         start: {
 import { TextDocument, Range, Position } from 'vscode-languageserver'
-  let match: RegExpMatchArray
+  for (let i = arr.length - 1; i >= 0; --i) {
 import { TextDocument, Range, Position } from 'vscode-languageserver'
+import { DocumentClassName, DocumentClassList } from './state'
-  let matches: RegExpMatchArray[] = []
         },
         end: {
 import { TextDocument, Range, Position } from 'vscode-languageserver'
+import { DocumentClassName, DocumentClassList } from './state'
 import { TextDocument, Range, Position } from 'vscode-languageserver'
 import { TextDocument, Range, Position } from 'vscode-languageserver'
-  return matches
+      return x
         },
       },
     }
M src/lsp/util/state.ts -> src/lsp/util/state.ts
diff --git a/src/lsp/util/state.ts b/src/lsp/util/state.ts
index daaa0501c05f20e0e88dc85c4357533d26e4a74d..fc474eb4e418d6628542a8d78c69e54d6d9288b6 100644
--- a/src/lsp/util/state.ts
+++ b/src/lsp/util/state.ts
@@ -21,6 +21,7 @@   globalSettings: Settings
   userLanguages: Record<string, string>
   capabilities: {
     configuration: boolean
+    diagnosticRelatedInformation: boolean
   }
 }