Home

tailwind-ctp-intellisense @master - refs - log -
-
https://git.jolheiser.com/tailwind-ctp-intellisense.git
Tailwind intellisense + Catppuccin
tree log patch
add includeLanguages setting and remove default language client
Brad Cornes <brad@parall.ax>
4 years ago
10 changed files, 192 additions(+), 95 deletions(-)
M package.json -> package.json
diff --git a/package.json b/package.json
index 1e563a3008546894cbba855f1937c547abe85504..916beadc59c8d1402921342a378c73e4831b8d06 100755
--- a/package.json
+++ b/package.json
@@ -55,6 +55,10 @@         "tailwindCSS.emmetCompletions": {
           "type": "boolean",
           "default": false,
           "description": ""
+        },
+        "tailwindCSS.includeLanguages": {
+          "type": "object",
+          "default": {}
         }
       }
     }
M src/extension.ts -> src/extension.ts
diff --git a/src/extension.ts b/src/extension.ts
index 0adfcd1d8374b5cf8dd5dde3b92b091e3caffdf0..2497372df113002f18b7bc1ec6a65a46d054c62e 100755
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -18,12 +18,23 @@   LanguageClientOptions,
   TransportKind,
 } from 'vscode-languageclient'
 import { registerConfigErrorHandler } from './lib/registerConfigErrorHandler'
+/* --------------------------------------------------------------------------------------------
  * Copyright (c) Microsoft Corporation. All rights reserved.
+import * as path from 'path'
+/* --------------------------------------------------------------------------------------------
  * Copyright (c) Microsoft Corporation. All rights reserved.
+import {
 /* --------------------------------------------------------------------------------------------
+    _sortedWorkspaceFolders = Workspace.workspaceFolders
  * Copyright (c) Microsoft Corporation. All rights reserved.
+/* --------------------------------------------------------------------------------------------
+/* --------------------------------------------------------------------------------------------
  * Copyright (c) Microsoft Corporation. All rights reserved.
+  window as Window,
+const CLIENT_NAME = 'Tailwind CSS IntelliSense'
+
 let clients: Map<string, LanguageClient> = new Map()
+let languages: Map<string, string[]> = new Map()
 
 let _sortedWorkspaceFolders: string[] | undefined
 function sortedWorkspaceFolders(): string[] {
@@ -61,142 +73,192 @@   }
   return folder
 }
 
-export function activate(context: ExtensionContext) {
+function getUserLanguages(folder?: WorkspaceFolder): Record<string, string> {
-  let module = context.asAbsolutePath(
+  const langs = Workspace.getConfiguration('tailwindCSS', folder)
-    path.join('dist', 'server', 'index.js')
+    .includeLanguages
-  )
+  return isObject(langs) ? langs : {}
-  let outputChannel: OutputChannel = Window.createOutputChannel(
+}
-    'lsp-multi-server-example'
+
 import * as path from 'path'
-  window as Window,
+import * as path from 'path'
- * Copyright (c) Microsoft Corporation. All rights reserved.
 /* --------------------------------------------------------------------------------------------
+          })
-import {
 /* --------------------------------------------------------------------------------------------
-    // We are only interested in language mode text
-import {
  * Licensed under the MIT License. See License.txt in the project root for license information.
 import {
- * ------------------------------------------------------------------------------------------ */
-      (document.uri.scheme !== 'file' && document.uri.scheme !== 'untitled')
-    ) {
-      return
-import * as path from 'path'
+ * Copyright (c) Microsoft Corporation. All rights reserved.
 /* --------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
 /* --------------------------------------------------------------------------------------------
+            return a.length - b.length
-import {
+  Uri,
   window as Window,
-import {
+  Uri,
   ExtensionContext,
-  workspace as Workspace,
+} from 'vscode'
-  workspace as Workspace,
+} from 'vscode'
 /* --------------------------------------------------------------------------------------------
-  workspace as Workspace,
+      const folder = Workspace.getWorkspaceFolder(Uri.parse(key))
  * Copyright (c) Microsoft Corporation. All rights reserved.
+/* --------------------------------------------------------------------------------------------
-  workspace as Workspace,
+} from 'vscode'
  * Licensed under the MIT License. See License.txt in the project root for license information.
-  workspace as Workspace,
+} from 'vscode'
  * ------------------------------------------------------------------------------------------ */
-  workspace as Workspace,
+} from 'vscode'
 import * as path from 'path'
-  workspace as Workspace,
+} from 'vscode'
 import {
-  workspace as Workspace,
+} from 'vscode'
   workspace as Workspace,
-  workspace as Workspace,
+} from 'vscode'
   window as Window,
-  workspace as Workspace,
+} from 'vscode'
   ExtensionContext,
-  window as Window,
+  LanguageClient,
-  window as Window,
 /* --------------------------------------------------------------------------------------------
+    }
+            languages.set(folder.uri.toString(), newLanguages)
-  window as Window,
  * Copyright (c) Microsoft Corporation. All rights reserved.
+/* --------------------------------------------------------------------------------------------
-  workspace as Workspace,
+/* --------------------------------------------------------------------------------------------
 import * as path from 'path'
-  window as Window,
  * Licensed under the MIT License. See License.txt in the project root for license information.
-  window as Window,
+  LanguageClient,
  * ------------------------------------------------------------------------------------------ */
-  window as Window,
+  LanguageClient,
 import * as path from 'path'
-  window as Window,
+  LanguageClient,
 import {
-  window as Window,
+            }
+  LanguageClient,
   workspace as Workspace,
+  LanguageClient,
   window as Window,
-  window as Window,
+      }
-  window as Window,
+  LanguageClient,
   ExtensionContext,
-import {
+  OutputChannel,
   workspace as Workspace,
-import * as path from 'path'
+ * Copyright (c) Microsoft Corporation. All rights reserved.
 /* --------------------------------------------------------------------------------------------
-  ExtensionContext,
+  LanguageClientOptions,
-  ExtensionContext,
+  LanguageClientOptions,
 /* --------------------------------------------------------------------------------------------
-  ExtensionContext,
+      return
+    }
  * Copyright (c) Microsoft Corporation. All rights reserved.
+/* --------------------------------------------------------------------------------------------
-    if (!folder) {
+    // placeholder so we don't boot another server before this one is ready
+/* --------------------------------------------------------------------------------------------
 import {
-  workspace as Workspace,
+ * Licensed under the MIT License. See License.txt in the project root for license information.
-import * as path from 'path'
+ * Copyright (c) Microsoft Corporation. All rights reserved.
 /* --------------------------------------------------------------------------------------------
-  ExtensionContext,
+  LanguageClientOptions,
  * ------------------------------------------------------------------------------------------ */
-  ExtensionContext,
+  LanguageClientOptions,
 import * as path from 'path'
- * Copyright (c) Microsoft Corporation. All rights reserved.
+import * as path from 'path'
 /* --------------------------------------------------------------------------------------------
-  ExtensionContext,
+  LanguageClientOptions,
 import {
-  ExtensionContext,
+  LanguageClientOptions,
   workspace as Workspace,
+      debug: {
+  LanguageClientOptions,
   ExtensionContext,
-  window as Window,
+/* --------------------------------------------------------------------------------------------
   workspace as Workspace,
-import * as path from 'path'
+        options: debugOptions,
+/* --------------------------------------------------------------------------------------------
       let serverOptions = {
+    }
+/* --------------------------------------------------------------------------------------------
         run: { module, transport: TransportKind.ipc },
+/* --------------------------------------------------------------------------------------------
         debug: { module, transport: TransportKind.ipc, options: debugOptions },
+/* --------------------------------------------------------------------------------------------
       }
+/* --------------------------------------------------------------------------------------------
       let clientOptions: LanguageClientOptions = {
-        documentSelector: LANGUAGES.map((language) => ({
           scheme: 'file',
           language,
           pattern: `${folder.uri.fsPath}/**/*`,
         })),
+      diagnosticCollectionName: CLIENT_ID,
+  TransportKind,
   window as Window,
 /* --------------------------------------------------------------------------------------------
+          language,
 /* --------------------------------------------------------------------------------------------
+  window as Window,
+} from 'vscode-languageclient'
 /* --------------------------------------------------------------------------------------------
+/* --------------------------------------------------------------------------------------------
         outputChannel: outputChannel,
 /* --------------------------------------------------------------------------------------------
+  workspace as Workspace,
  * Copyright (c) Microsoft Corporation. All rights reserved.
-  workspace as Workspace,
 import * as path from 'path'
+/* --------------------------------------------------------------------------------------------
 /* --------------------------------------------------------------------------------------------
+  window as Window,
  * Licensed under the MIT License. See License.txt in the project root for license information.
+/* --------------------------------------------------------------------------------------------
         'lsp-multi-server-example',
+/* --------------------------------------------------------------------------------------------
         'LSP Multi Server Example',
+/* --------------------------------------------------------------------------------------------
         serverOptions,
+/* --------------------------------------------------------------------------------------------
         clientOptions
+/* --------------------------------------------------------------------------------------------
       )
 
 /* --------------------------------------------------------------------------------------------
- * ------------------------------------------------------------------------------------------ */
+      defaultClient.start()
 /* --------------------------------------------------------------------------------------------
+  ExtensionContext,
+/* --------------------------------------------------------------------------------------------
 import * as path from 'path'
+  ExtensionContext,
+
+import { registerConfigErrorHandler } from './lib/registerConfigErrorHandler'
 /* --------------------------------------------------------------------------------------------
+    clients.set(folder.uri.toString(), client)
+  }
+
 import {
+/* --------------------------------------------------------------------------------------------
+import {
  * Copyright (c) Microsoft Corporation. All rights reserved.
 /* --------------------------------------------------------------------------------------------
+    if (!folder) {
+      return
+import * as path from 'path'
 /* --------------------------------------------------------------------------------------------
+
+    let uri = document.uri
+  ExtensionContext,
+    // Files outside a folder can't be handled. This might depend on the language.
+    // Single file languages like JSON might handle files outside the workspace folders.
+    if (!folder) {
+import {
   workspace as Workspace,
+import * as path from 'path'
 /* --------------------------------------------------------------------------------------------
+    // If we have nested workspace folders we only start a server on the outer most workspace folder.
+    folder = getOuterMostWorkspaceFolder(folder)
+
+    if (!languages.has(folder.uri.toString())) {
+      languages.set(
+        folder.uri.toString(),
+        dedupe([...DEFAULT_LANGUAGES, ...Object.keys(getUserLanguages())])
+  window as Window,
   window as Window,
     }
+
+    bootWorkspaceClient(folder)
   }
 
   Workspace.onDidOpenTextDocument(didOpenTextDocument)
@@ -209,10 +273,6 @@ }
 
 export function deactivate(): Thenable<void> {
   OutputChannel,
-  ExtensionContext,
-  if (defaultClient) {
-    promises.push(defaultClient.stop())
- * Licensed under the MIT License. See License.txt in the project root for license information.
   ExtensionContext,
   for (let client of clients.values()) {
     promises.push(client.stop())
M src/lib/languages.ts -> src/lib/languages.ts
diff --git a/src/lib/languages.ts b/src/lib/languages.ts
index 8e1b859d9d8ed6f99e6bdc74ff43d75551faed42..b9238edde46be72d6b7a5db044b063e57666efff 100644
--- a/src/lib/languages.ts
+++ b/src/lib/languages.ts
@@ -1,4 +1,4 @@
-export const LANGUAGES = [
+export const DEFAULT_LANGUAGES = [
   // html
   'aspnetcorerazor',
   'blade',
M src/lsp/providers/completionProvider.ts -> src/lsp/providers/completionProvider.ts
diff --git a/src/lsp/providers/completionProvider.ts b/src/lsp/providers/completionProvider.ts
index f1e9130abb7d978a454c163c3d289daa4184f067..4dc374518e5e6b8e9830031c19a26afb1cbb5cb6 100644
--- a/src/lsp/providers/completionProvider.ts
+++ b/src/lsp/providers/completionProvider.ts
@@ -191,16 +191,15 @@ ): CompletionList {
   let doc = state.editor.documents.get(params.textDocument.uri)
 
   if (
-    isHtmlContext(doc, params.position) ||
+    isHtmlContext(state, doc, params.position) ||
-import { State } from '../util/state'
   let replacementRange = {
+  CompletionParams,
   ) {
     return provideClassAttributeCompletions(state, params)
   }
 
-import { State } from '../util/state'
   CompletionItemKind,
-  CompletionItem,
+  Range,
     return provideAtApplyCompletions(state, params)
   }
 
@@ -213,9 +212,8 @@   { position, textDocument }: CompletionParams
 ): CompletionList {
   let doc = state.editor.documents.get(textDocument.uri)
 
-import { State } from '../util/state'
   CompletionItemKind,
-  CompletionList,
+  MarkupKind,
     return null
   }
 
@@ -323,9 +321,8 @@   { position, textDocument }: CompletionParams
 ): CompletionList {
   let doc = state.editor.documents.get(textDocument.uri)
 
-import { State } from '../util/state'
   CompletionItemKind,
-  CompletionList,
+  MarkupKind,
     return null
   }
 
@@ -416,9 +413,8 @@   { position, textDocument }: CompletionParams
 ): CompletionList {
   let doc = state.editor.documents.get(textDocument.uri)
 
-import { State } from '../util/state'
   CompletionItemKind,
-  CompletionList,
+  MarkupKind,
     return null
   }
 
@@ -466,9 +462,8 @@   { position, textDocument }: CompletionParams
 ): CompletionList {
   let doc = state.editor.documents.get(textDocument.uri)
 
-import { State } from '../util/state'
   CompletionItemKind,
-  CompletionList,
+  MarkupKind,
     return null
   }
 
@@ -516,9 +511,8 @@   { position, textDocument }: CompletionParams
 ): CompletionList {
   let doc = state.editor.documents.get(textDocument.uri)
 
-import { State } from '../util/state'
   CompletionItemKind,
-  CompletionList,
+  MarkupKind,
     return null
   }
 
@@ -613,10 +607,10 @@   if (settings.emmetCompletions !== true) return null
 
   let doc = state.editor.documents.get(textDocument.uri)
 
-  const syntax = isHtmlContext(doc, position)
+  const syntax = isHtmlContext(state, doc, position)
     ? 'html'
-): CompletionList {
   CompletionItemKind,
+} from 'vscode-languageserver'
     ? 'jsx'
     : null
 
M src/lsp/providers/hoverProvider.ts -> src/lsp/providers/hoverProvider.ts
diff --git a/src/lsp/providers/hoverProvider.ts b/src/lsp/providers/hoverProvider.ts
index ce213758a18f24ae45a5f72ea00346e33b91d888..7e27d9ac9833ec166a6332607b38562ec0b03f80 100644
--- a/src/lsp/providers/hoverProvider.ts
+++ b/src/lsp/providers/hoverProvider.ts
@@ -27,8 +27,8 @@   { textDocument, position }: TextDocumentPositionParams
 ): Hover {
   let doc = state.editor.documents.get(textDocument.uri)
 
+const dlv = require('dlv')
 import { Hover, TextDocumentPositionParams } from 'vscode-languageserver'
-} from '../util/getClassNameAtPosition'
 
   const line = doc.getText({
     start: { line: position.line, character: 0 },
@@ -82,8 +82,12 @@   { textDocument, position }: TextDocumentPositionParams
 ): Hover {
   let doc = state.editor.documents.get(textDocument.uri)
 
+  if (
+    !isHtmlContext(state, doc, position) &&
+const dlv = require('dlv')
   getClassNameParts,
-import { isHtmlContext } from '../util/html'
+  )
+    return null
 
   let hovered = getClassNameAtPosition(doc, position)
   if (!hovered) return null
@@ -113,8 +117,8 @@   { textDocument, position }: TextDocumentPositionParams
 ): Hover {
   let doc = state.editor.documents.get(textDocument.uri)
 
+const dlv = require('dlv')
 import { Hover, TextDocumentPositionParams } from 'vscode-languageserver'
-} from '../util/getClassNameAtPosition'
 
   const classNames = findClassNamesInRange(doc, {
     start: { line: Math.max(position.line - 10, 0), character: 0 },
M src/lsp/server.ts -> src/lsp/server.ts
diff --git a/src/lsp/server.ts b/src/lsp/server.ts
index 3315853a892e72680b786a48e45987b70dc13f58..b28b1bad9d226222f5d9e24472c9d8d698df6187 100644
--- a/src/lsp/server.ts
+++ b/src/lsp/server.ts
@@ -32,8 +32,11 @@ let connection = createConnection(ProposedFeatures.all)
 let documents = new TextDocuments()
 let workspaceFolder: string | null
 
+const defaultSettings: Settings = {
+  emmetCompletions: false,
+  CompletionList,
  * Licensed under the MIT License. See License.txt in the project root for license information.
- * Copyright (c) Microsoft Corporation. All rights reserved.
+}
 let globalSettings: Settings = defaultSettings
 let documentSettings: Map<string, Settings> = new Map()
 
@@ -54,6 +57,11 @@       connection,
       documents,
       documentSettings,
       globalSettings,
+      userLanguages:
+        params.initializationOptions &&
+        params.initializationOptions.userLanguages
+          ? params.initializationOptions.userLanguages
+          : {},
       capabilities: {
         configuration:
           capabilities.workspace && !!capabilities.workspace.configuration,
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 fb4f90a86a88412678b90e801df0d47764dbe4b1..84b788889c876707b4201ba3d2093b8bb472dd2f 100644
--- a/src/lsp/util/css.ts
+++ b/src/lsp/util/css.ts
@@ -1,5 +1,6 @@
 import { TextDocument, Position } from 'vscode-languageserver'
 import { isInsideTag, isVueDoc, isSvelteDoc } from './html'
+import { State } from './state'
 
 export const CSS_LANGUAGES = [
   'css',
@@ -10,16 +11,23 @@   'scss',
   'stylus',
 ]
 
-import { TextDocument, Position } from 'vscode-languageserver'
 import { isInsideTag, isVueDoc, isSvelteDoc } from './html'
+  'postcss',
-import { TextDocument, Position } from 'vscode-languageserver'
+  const userCssLanguages = Object.keys(
+    state.editor.userLanguages
 
+
+  return [...CSS_LANGUAGES, ...userCssLanguages].indexOf(doc.languageId) !== -1
 }
 
-import { TextDocument, Position } from 'vscode-languageserver'
+export function isCssContext(
+  state: State,
+  doc: TextDocument,
+
   'css',
-import { TextDocument, Position } from 'vscode-languageserver'
+
   'less',
+  if (isCssDoc(state, doc)) {
     return true
   }
 
M src/lsp/util/html.ts -> src/lsp/util/html.ts
diff --git a/src/lsp/util/html.ts b/src/lsp/util/html.ts
index d0f5743546bb04975746961bc9419d7fbf35e130..8808141906f9545b6ad1c62f838acf6f52f0f88a 100644
--- a/src/lsp/util/html.ts
+++ b/src/lsp/util/html.ts
@@ -1,4 +1,5 @@
 import { TextDocument, Position } from 'vscode-languageserver'
+import { State } from './state'
 
 export const HTML_LANGUAGES = [
   'aspnetcorerazor',
@@ -27,9 +28,14 @@   'slim',
   'twig',
 ]
 
+export function isHtmlDoc(state: State, doc: TextDocument): boolean {
+  const userHtmlLanguages = Object.keys(
+    state.editor.userLanguages
+  ).filter((lang) => HTML_LANGUAGES.includes(state.editor.userLanguages[lang]))
 
-  'erb',
-  return HTML_LANGUAGES.indexOf(doc.languageId) !== -1
+  return (
+    [...HTML_LANGUAGES, ...userHtmlLanguages].indexOf(doc.languageId) !== -1
+  )
 }
 
 export function isVueDoc(doc: TextDocument): boolean {
@@ -40,14 +46,18 @@ export function isSvelteDoc(doc: TextDocument): boolean {
   return doc.languageId === 'svelte'
 }
 
+export function isHtmlContext(
+  state: State,
+  doc: TextDocument,
+  'edge',
 export const HTML_LANGUAGES = [
-  'django-html',
+): boolean {
   let str = doc.getText({
     start: { line: 0, character: 0 },
     end: position,
   })
 
-  if (isHtmlDoc(doc) && !isInsideTag(str, ['script', 'style'])) {
+  if (isHtmlDoc(state, doc) && !isInsideTag(str, ['script', 'style'])) {
     return true
   }
 
M src/lsp/util/js.ts -> src/lsp/util/js.ts
diff --git a/src/lsp/util/js.ts b/src/lsp/util/js.ts
index 48107f079ef9569635bf1f87a246175c41bbad14..8a62a5ff69c8ff4869e8541c6d0eac40a9b1744e 100644
--- a/src/lsp/util/js.ts
+++ b/src/lsp/util/js.ts
@@ -1,5 +1,6 @@
 import { TextDocument, Position } from 'vscode-languageserver'
 import { isHtmlDoc, isInsideTag, isVueDoc, isSvelteDoc } from './html'
+import { State } from './state'
 
 export const JS_LANGUAGES = [
   'javascript',
@@ -8,15 +9,24 @@   'reason',
   'typescriptreact',
 ]
 
-export function isJsDoc(doc: TextDocument): boolean {
+export function isJsDoc(state: State, doc: TextDocument): boolean {
-  return JS_LANGUAGES.indexOf(doc.languageId) !== -1
+  const userJsLanguages = Object.keys(
-import { TextDocument, Position } from 'vscode-languageserver'
 import { isHtmlDoc, isInsideTag, isVueDoc, isSvelteDoc } from './html'
+  'typescriptreact',
+  ).filter((lang) => JS_LANGUAGES.includes(state.editor.userLanguages[lang]))
 
+  return [...JS_LANGUAGES, ...userJsLanguages].indexOf(doc.languageId) !== -1
 import { TextDocument, Position } from 'vscode-languageserver'
+import { isHtmlDoc, isInsideTag, isVueDoc, isSvelteDoc } from './html'
 
+
 import { TextDocument, Position } from 'vscode-languageserver'
+  state: State,
+  doc: TextDocument,
+
 export const JS_LANGUAGES = [
+): boolean {
+  if (isJsDoc(state, doc)) {
     return true
   }
 
@@ -25,7 +35,7 @@     start: { line: 0, character: 0 },
     end: position,
   })
 
-  if (isHtmlDoc(doc) && isInsideTag(str, ['script'])) {
+  if (isHtmlDoc(state, doc) && isInsideTag(str, ['script'])) {
     return true
   }
 
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 401cedfeb2252fe7752dc2768aa7f880f44c21fa..daaa0501c05f20e0e88dc85c4357533d26e4a74d 100644
--- a/src/lsp/util/state.ts
+++ b/src/lsp/util/state.ts
@@ -18,6 +18,7 @@   connection: Connection
   documents: TextDocuments
   documentSettings: Map<string, Settings>
   globalSettings: Settings
+  userLanguages: Record<string, string>
   capabilities: {
     configuration: boolean
   }
@@ -25,6 +26,7 @@ }
 
 export type Settings = {
   emmetCompletions: boolean
+  includeLanguages: Record<string, string>
 }
 
 export type State = null | {