Home

tailwind-ctp-intellisense @master - refs - log -
-
https://git.jolheiser.com/tailwind-ctp-intellisense.git
Tailwind intellisense + Catppuccin
tree log patch
prevent crash on config error
Brad Cornes <brad@parall.ax>
5 years ago
3 changed files, 96 additions(+), 54 deletions(-)
packages/tailwindcss-class-names/src/index.jspackages/tailwindcss-language-server/src/server.tspackages/tailwindcss-language-server/src/util/state.ts
M packages/tailwindcss-class-names/src/index.jspackages/tailwindcss-class-names/src/index.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
 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
diff --git a/packages/tailwindcss-class-names/src/index.js b/packages/tailwindcss-class-names/src/index.js
index f9f39c4c9e30d741c28f7e84e2e10fc642f46f89..1835e66efab64cbc1e93c7335b0d9cadb7a836b1 100644
--- a/packages/tailwindcss-class-names/src/index.js
+++ b/packages/tailwindcss-class-names/src/index.js
@@ -17,7 +17,7 @@   return new Promise((resolve, reject) => {
     let g = new nodeGlob.Glob(pattern, options)
     let matches = []
     let max = dlv(options, 'max', Infinity)
-    g.on('match', match => {
+    g.on('match', (match) => {
       matches.push(path.resolve(options.cwd || process.cwd(), match))
       if (matches.length === max) {
         g.abort()
@@ -38,39 +38,35 @@     JSON.stringify(arr2.concat([]).sort())
   )
 }
 
+const CONFIG_GLOB =
+  '**/{tailwind,tailwind.config,tailwind-config,.tailwindrc}.js'
+
 export default async function getClassNames(
   cwd = process.cwd(),
   { onChange = () => {} } = {}
 ) {
-  let configPath
-  let postcss
-  let tailwindcss
-  let version
+  async function run() {
+    let configPath
+    let postcss
+    let tailwindcss
+    let version
 
-  try {
-    configPath = await glob(
-      '**/{tailwind,tailwind.config,tailwind-config,.tailwindrc}.js',
-      {
-        cwd,
-        ignore: '**/node_modules/**',
-        max: 1
-      }
-    )
+    configPath = await glob(CONFIG_GLOB, {
+      cwd,
+      ignore: '**/node_modules/**',
+      max: 1,
+    })
     invariant(configPath.length === 1, 'No Tailwind CSS config found.')
     configPath = configPath[0]
     postcss = importFrom(cwd, 'postcss')
     tailwindcss = importFrom(cwd, 'tailwindcss')
     version = importFrom(cwd, 'tailwindcss/package.json').version
-  } catch (_) {
-    return null
-  }
 
-  async function run() {
     const sepLocation = semver.gte(version, '0.99.0')
       ? ['separator']
       : ['options', 'separator']
     let userSeperator
-    let hook = Hook(configPath, exports => {
+    let hook = Hook(configPath, (exports) => {
       userSeperator = dlv(exports, sepLocation)
       dset(exports, sepLocation, '__TAILWIND_SEPARATOR__')
       return exports
@@ -97,35 +93,48 @@       delete config[sepLocation]
     }
 
     return {
+      configPath,
       config: resolveConfig({ cwd, config }),
       separator: typeof userSeperator === 'undefined' ? ':' : userSeperator,
       classNames: await extractClassNames(ast),
-      dependencies: [configPath, ...hook.deps],
+      dependencies: hook.deps,
       plugins: getPlugins(config),
-      variants: getVariants({ config, version, postcss })
+      variants: getVariants({ config, version, postcss }),
     }
   }
 
   let watcher
-  function watch(files) {
+  function watch(files = []) {
     if (watcher) watcher.close()
     watcher = chokidar
-      .watch(files)
+      .watch([CONFIG_GLOB, ...files])
       .on('change', handleChange)
       .on('unlink', handleChange)
   }
-
-  let result = await run()
-  watch(result.dependencies)
 
   async function handleChange() {
-    const prevDeps = result.dependencies
-    result = await run()
+    const prevDeps = result ? result.dependencies : []
+    try {
+      result = await run()
+    } catch (_) {
+      onChange(null)
+      return
+    }
     if (!arraysEqual(prevDeps, result.dependencies)) {
       watch(result.dependencies)
     }
     onChange(result)
   }
+
+  let result
+  try {
+    result = await run()
+  } catch (_) {
+    watch()
+    return null
+  }
+
+  watch(result.dependencies)
 
   return result
 }
M packages/tailwindcss-language-server/src/server.tspackages/tailwindcss-language-server/src/server.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
diff --git a/packages/tailwindcss-language-server/src/server.ts b/packages/tailwindcss-language-server/src/server.ts
index 58fada32d5f70b0653c5bb9228fcd71053621143..729d1f0c30862343cf77f8ab1c278230155392d7 100644
--- a/packages/tailwindcss-language-server/src/server.ts
+++ b/packages/tailwindcss-language-server/src/server.ts
@@ -18,7 +18,7 @@   TextDocumentPositionParams,
   DidChangeConfigurationNotification,
 } from 'vscode-languageserver'
 import getTailwindState from 'tailwindcss-class-names'
-import { State, Settings } from './util/state'
+import { State, Settings, EditorState } from './util/state'
 import {
   provideCompletions,
   resolveCompletionItem,
@@ -27,7 +27,7 @@ import { provideHover } from './providers/hoverProvider'
 import { URI } from 'vscode-uri'
 import { getDocumentSettings } from './util/getDocumentSettings'
 
-let state: State = null
+let state: State = { enabled: false }
 let connection = createConnection(ProposedFeatures.all)
 let documents = new TextDocuments()
 let workspaceFolder: string | null
@@ -46,28 +46,43 @@ documents.listen(connection)
 
 connection.onInitialize(
   async (params: InitializeParams): Promise<InitializeResult> => {
-    state = await getTailwindState(
+    const capabilities = params.capabilities
+
+    const editorState: EditorState = {
+      connection,
+      documents,
+      documentSettings,
+      globalSettings,
+      capabilities: {
+        configuration:
+          capabilities.workspace && !!capabilities.workspace.configuration,
+      },
+    }
+
+    const tailwindState = await getTailwindState(
       params.rootPath || URI.parse(params.rootUri).path,
       {
         onChange: (newState: State): void => {
-          state = { ...newState, editor: state.editor }
-          connection.sendNotification('tailwindcss/configUpdated', [
-            state.dependencies[0],
-            state.config,
-            state.plugins,
-          ])
+          if (newState) {
+            state = { ...newState, enabled: true, editor: editorState }
+            connection.sendNotification('tailwindcss/configUpdated', [
+              state.configPath,
+              state.config,
+              state.plugins,
+            ])
+          } else {
+            state = { enabled: false, editor: editorState }
+            // TODO
+            // connection.sendNotification('tailwindcss/configUpdated', [null])
+          }
         },
       }
     )
 
-    const capabilities = params.capabilities
-
-    state.editor = {
-      connection,
-      documents,
-      documentSettings,
-      globalSettings,
-      capabilities: { configuration: capabilities.workspace && !!capabilities.workspace.configuration },
+    if (tailwindState) {
+      state = { enabled: true, editor: editorState, ...tailwindState }
+    } else {
+      state = { enabled: false, editor: editorState }
     }
 
     return {
@@ -79,7 +94,20 @@         // },
         textDocumentSync: documents.syncKind,
         completionProvider: {
           resolveProvider: true,
-          triggerCharacters: ['"', "'", '`', ' ', '.', '[', state.separator],
+          triggerCharacters: [
+            // class attributes
+            '"',
+            "'",
+            '`',
+            // between class names
+            ' ',
+            // @apply and emmet-style
+            '.',
+            // config/theme helper
+            '[',
+            // TODO: restart server if separater changes?
+            typeof state.separator === 'undefined' ? ':' : state.separator,
+          ],
         },
         hoverProvider: true,
       },
@@ -97,7 +125,7 @@       )
     }
 
     connection.sendNotification('tailwindcss/configUpdated', [
-      state.dependencies[0],
+      state.configPath,
       state.config,
       state.plugins,
     ])
@@ -120,18 +148,21 @@ })
 
 connection.onCompletion(
   (params: CompletionParams): Promise<CompletionList> => {
+    if (!state.enabled) return null
     return provideCompletions(state, params)
   }
 )
 
 connection.onCompletionResolve(
   (item: CompletionItem): CompletionItem => {
+    if (!state.enabled) return null
     return resolveCompletionItem(state, item)
   }
 )
 
 connection.onHover(
   (params: TextDocumentPositionParams): Hover => {
+    if (!state.enabled) return null
     return provideHover(state, params)
   }
 )
M packages/tailwindcss-language-server/src/util/state.tspackages/tailwindcss-language-server/src/util/state.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
diff --git a/packages/tailwindcss-language-server/src/util/state.ts b/packages/tailwindcss-language-server/src/util/state.ts
index 4b258320520a2dc616f627a4d1e5f73ad3742383..175dade6ed563cc36605c1fc3c55f5b56e900573 100644
--- a/packages/tailwindcss-language-server/src/util/state.ts
+++ b/packages/tailwindcss-language-server/src/util/state.ts
@@ -28,13 +28,15 @@   emmetCompletions: boolean
 }
 
 export type State = null | {
-  config: any
-  separator: string
-  plugins: any[]
-  variants: string[]
-  classNames: ClassNames
-  dependencies: string[]
-  editor: EditorState
+  enabled: boolean
+  configPath?: string
+  config?: any
+  separator?: string
+  plugins?: any[]
+  variants?: string[]
+  classNames?: ClassNames
+  dependencies?: string[]
+  editor?: EditorState
 }
 
 export type DocumentClassList = {