Home

tailwind-ctp-intellisense @master - refs - log -
-
https://git.jolheiser.com/tailwind-ctp-intellisense.git
Tailwind intellisense + Catppuccin
tree log patch
improve emmet syntax handling (#3)
Brad Cornes <bradlc41@gmail.com>
6 years ago
2 changed files, 278 additions(+), 78 deletions(-)
M src/extension.ts -> src/extension.ts
diff --git a/src/extension.ts b/src/extension.ts
index 371c76f62394a33b3048c83dd47afe1913b2ef6d..c4598ae87dd8ca51c151bfc2d884b4b6a6913040 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -1,7 +1,8 @@
 'use strict'
 
 import * as vscode from 'vscode'
-import { join, dirname } from 'path'
+import { dirname } from 'path'
+const htmlElements = require('./htmlElements.js')
 const tailwindClassNames = require('tailwind-class-names')
 const dlv = require('dlv')
 const Color = require('color')
@@ -21,9 +22,7 @@   'erb',
   'handlebars',
   'ejs',
   'nunjucks',
-  'haml',
-  // for jsx
-  ...JS_TYPES
+  'haml'
 ]
 const CSS_TYPES = ['css', 'sass', 'scss', 'less', 'postcss', 'stylus']
 
@@ -147,7 +146,17 @@         } else if (emmet) {
           // match emmet style syntax
           // e.g. .flex.items-center
           let currentLine = lines[lines.length - 1]
-          matches = currentLine.match(/\.([^()#>*^ \[\]=$@{}]*)$/i)
+          let currentWord = currentLine.split(' ').pop()
+          matches = currentWord.match(/^\.([^.()#>*^ \[\]=$@{}]*)$/)
+          if (!matches) {
+            matches = currentWord.match(
+              new RegExp(
+                `^([A-Z][a-zA-Z0-9]*|[a-z][a-z0-9]*-[a-z0-9-]+|${htmlElements.join(
+                  '|'
+                )}).*?\\.([^.()#>*^ \\[\\]=$@{}]*)$`
+              )
+            )
+          }
           let parts = matches[matches.length - 1].split('.')
           str = parts[parts.length - 1]
         }
@@ -422,32 +431,78 @@     this._providers.push(
       createCompletionItemProvider({
         items: this._items,
         languages: HTML_TYPES,
-        regex: /\bclass(Name)?=["']([^"']*)$/, // /\bclass(Name)?=(["'])(?!.*?\2)/
+        regex: /\bclass=["']([^"']*)$/, // /\bclass(Name)?=(["'])(?!.*?\2)/
         triggerCharacters: ["'", '"', ' ', '.', separator],
         config: tailwind.config,
         emmet: true
       })
     )
 
+    this._providers.push(
+      createCompletionItemProvider({
+        items: this._items,
+        languages: JS_TYPES,
+        regex: /\bclass(Name)?=["']([^"']*)$/, // /\bclass(Name)?=(["'])(?!.*?\2)/
+        triggerCharacters: ["'", '"', ' ', separator]
+          .concat([
+            Object.keys(
+              vscode.workspace.getConfiguration('emmet.includeLanguages')
+            ).indexOf('javascript') !== -1 && '.'
+          ])
+          .filter(Boolean),
+        config: tailwind.config,
+        emmet:
+          Object.keys(
+            vscode.workspace.getConfiguration('emmet.includeLanguages')
+          ).indexOf('javascript') !== -1
+      })
+    )
+
     // Vue.js
     this._providers.push(
       createCompletionItemProvider({
         items: this._items,
         languages: ['vue'],
-        regex: /\bclass(Name)?=["']([^"']*)$/,
+        regex: /\bclass=["']([^"']*)$/,
         enable: text => {
           if (
-            (text.indexOf('<template') !== -1 &&
-              text.indexOf('</template>') === -1) ||
-            (text.indexOf('<script') !== -1 && text.indexOf('</script>') === -1)
+            text.indexOf('<template') !== -1 &&
+            text.indexOf('</template>') === -1
           ) {
             return true
           }
           return false
         },
-        triggerCharacters: ["'", '"', ' ', '.', separator],
+        triggerCharacters: ["'", '"', ' ', separator]
+          .concat([
+            Object.keys(
+              vscode.workspace.getConfiguration('emmet.includeLanguages')
+            ).indexOf('vue-html') !== -1 && '.'
+          ])
+          .filter(Boolean),
         config: tailwind.config,
-        emmet: true
+        emmet:
+          Object.keys(
+            vscode.workspace.getConfiguration('emmet.includeLanguages')
+          ).indexOf('vue-html') !== -1
+      })
+    )
+    this._providers.push(
+      createCompletionItemProvider({
+        items: this._items,
+        languages: ['vue'],
+        regex: /\bclass=["']([^"']*)$/,
+        enable: text => {
+          if (
+            text.indexOf('<script') !== -1 &&
+            text.indexOf('</script>') === -1
+          ) {
+            return true
+          }
+          return false
+        },
+        triggerCharacters: ["'", '"', ' ', separator],
+        config: tailwind.config
       })
     )
     this._providers.push(
@@ -493,86 +548,89 @@       })
     )
 
     this._providers.push(
-      vscode.languages.registerHoverProvider(HTML_TYPES, {
-        provideHover: (document, position, token) => {
-          const range1: vscode.Range = new vscode.Range(
-            new vscode.Position(Math.max(position.line - 5, 0), 0),
-            position
-          )
-          const text1: string = document.getText(range1)
-
-          if (!/\bclass(Name)?=['"][^'"]*$/.test(text1)) return
+      vscode.languages.registerHoverProvider(
+        [...HTML_TYPES, ...JS_TYPES, 'vue'],
+        {
+          provideHover: (document, position, token) => {
+            const range1: vscode.Range = new vscode.Range(
+              new vscode.Position(Math.max(position.line - 5, 0), 0),
+              position
+            )
+            const text1: string = document.getText(range1)
 
-          const range2: vscode.Range = new vscode.Range(
-            new vscode.Position(Math.max(position.line - 5, 0), 0),
-            position.with({ line: position.line + 1 })
-          )
-          const text2: string = document.getText(range2)
+            if (!/\bclass(Name)?=['"][^'"]*$/.test(text1)) return
 
-          let str = text1 + text2.substr(text1.length).match(/^([^"' ]*)/)[0]
-          let matches = str.match(/\bclass(Name)?=["']([^"']*)$/)
+            const range2: vscode.Range = new vscode.Range(
+              new vscode.Position(Math.max(position.line - 5, 0), 0),
+              position.with({ line: position.line + 1 })
+            )
+            const text2: string = document.getText(range2)
 
-          if (matches && matches[2]) {
-            let className = matches[2].split(' ').pop()
-            let parts = className.split(':')
+            let str = text1 + text2.substr(text1.length).match(/^([^"' ]*)/)[0]
+            let matches = str.match(/\bclass(Name)?=["']([^"']*)$/)
 
-            if (typeof dlv(this._tailwind.classNames, parts) === 'string') {
-              let base = parts.pop()
-              let selector = `.${escapeClassName(className)}`
+            if (matches && matches[2]) {
+              let className = matches[2].split(' ').pop()
+              let parts = className.split(':')
 
-              if (parts.indexOf('hover') !== -1) {
-                selector += ':hover'
-              } else if (parts.indexOf('focus') !== -1) {
-                selector += ':focus'
-              } else if (parts.indexOf('active') !== -1) {
-                selector += ':active'
-              } else if (parts.indexOf('group-hover') !== -1) {
-                selector = `.group:hover ${selector}`
-              }
+              if (typeof dlv(this._tailwind.classNames, parts) === 'string') {
+                let base = parts.pop()
+                let selector = `.${escapeClassName(className)}`
 
-              let hoverStr = new vscode.MarkdownString()
-              let css = this._tailwind.classNames[base]
-              let m = css.match(/^(::?[a-z-]+) {(.*?)}/)
-              if (m) {
-                selector += m[1]
-                css = m[2].trim()
-              }
-              css = css.replace(/([;{]) /g, '$1\n').replace(/^/gm, '  ')
-              let code = `${selector} {\n${css}\n}`
-              let screens = dlv(this._tailwind.config, 'screens', {})
+                if (parts.indexOf('hover') !== -1) {
+                  selector += ':hover'
+                } else if (parts.indexOf('focus') !== -1) {
+                  selector += ':focus'
+                } else if (parts.indexOf('active') !== -1) {
+                  selector += ':active'
+                } else if (parts.indexOf('group-hover') !== -1) {
+                  selector = `.group:hover ${selector}`
+                }
 
-              Object.keys(screens).some(screen => {
-                if (parts.indexOf(screen) !== -1) {
-                  code = `@media (min-width: ${
-                    screens[screen]
-                  }) {\n${code.replace(/^/gm, '  ')}\n}`
-                  return true
+                let hoverStr = new vscode.MarkdownString()
+                let css = this._tailwind.classNames[base]
+                let m = css.match(/^(::?[a-z-]+) {(.*?)}/)
+                if (m) {
+                  selector += m[1]
+                  css = m[2].trim()
                 }
-                return false
-              })
-              hoverStr.appendCodeblock(code, 'css')
+                css = css.replace(/([;{]) /g, '$1\n').replace(/^/gm, '  ')
+                let code = `${selector} {\n${css}\n}`
+                let screens = dlv(this._tailwind.config, 'screens', {})
+
+                Object.keys(screens).some(screen => {
+                  if (parts.indexOf(screen) !== -1) {
+                    code = `@media (min-width: ${
+                      screens[screen]
+                    }) {\n${code.replace(/^/gm, '  ')}\n}`
+                    return true
+                  }
+                  return false
+                })
+                hoverStr.appendCodeblock(code, 'css')
 
-              let hoverRange = new vscode.Range(
-                new vscode.Position(
-                  position.line,
-                  position.character +
-                    str.length -
-                    text1.length -
-                    className.length
-                ),
-                new vscode.Position(
-                  position.line,
-                  position.character + str.length - text1.length
+                let hoverRange = new vscode.Range(
+                  new vscode.Position(
+                    position.line,
+                    position.character +
+                      str.length -
+                      text1.length -
+                      className.length
+                  ),
+                  new vscode.Position(
+                    position.line,
+                    position.character + str.length - text1.length
+                  )
                 )
-              )
 
-              return new vscode.Hover(hoverStr, hoverRange)
+                return new vscode.Hover(hoverStr, hoverRange)
+              }
             }
-          }
 
-          return null
+            return null
+          }
         }
-      })
+      )
     )
 
     this._disposable = vscode.Disposable.from(...this._providers)
I src/htmlElements.ts
diff --git a/src/htmlElements.ts b/src/htmlElements.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4bb7b1c1220b17799c08d5b923dd5e8ac0e4f280
--- /dev/null
+++ b/src/htmlElements.ts
@@ -0,0 +1,142 @@
+module.exports = [
+  'a',
+  'abbr',
+  'acronym',
+  'address',
+  'applet',
+  'area',
+  'article',
+  'aside',
+  'audio',
+  'b',
+  'base',
+  'basefont',
+  'bdi',
+  'bdo',
+  'bgsound',
+  'big',
+  'blink',
+  'blockquote',
+  'body',
+  'br',
+  'button',
+  'canvas',
+  'caption',
+  'center',
+  'cite',
+  'code',
+  'col',
+  'colgroup',
+  'command',
+  'content',
+  'data',
+  'datalist',
+  'dd',
+  'del',
+  'details',
+  'dfn',
+  'dialog',
+  'dir',
+  'div',
+  'dl',
+  'dt',
+  'element',
+  'em',
+  'embed',
+  'fieldset',
+  'figcaption',
+  'figure',
+  'font',
+  'footer',
+  'form',
+  'frame',
+  'frameset',
+  'h1',
+  'head',
+  'header',
+  'hgroup',
+  'hr',
+  'html',
+  'i',
+  'iframe',
+  'image',
+  'img',
+  'input',
+  'ins',
+  'isindex',
+  'kbd',
+  'keygen',
+  'label',
+  'legend',
+  'li',
+  'link',
+  'listing',
+  'main',
+  'map',
+  'mark',
+  'marquee',
+  'menu',
+  'menuitem',
+  'meta',
+  'meter',
+  'multicol',
+  'nav',
+  'nextid',
+  'nobr',
+  'noembed',
+  'noframes',
+  'noscript',
+  'object',
+  'ol',
+  'optgroup',
+  'option',
+  'output',
+  'p',
+  'param',
+  'picture',
+  'plaintext',
+  'pre',
+  'progress',
+  'q',
+  'rb',
+  'rp',
+  'rt',
+  'rtc',
+  'ruby',
+  's',
+  'samp',
+  'script',
+  'section',
+  'select',
+  'shadow',
+  'slot',
+  'small',
+  'source',
+  'spacer',
+  'span',
+  'strike',
+  'strong',
+  'style',
+  'sub',
+  'summary',
+  'sup',
+  'table',
+  'tbody',
+  'td',
+  'template',
+  'textarea',
+  'tfoot',
+  'th',
+  'thead',
+  'time',
+  'title',
+  'tr',
+  'track',
+  'tt',
+  'u',
+  'ul',
+  'var',
+  'video',
+  'wbr',
+  'xmp'
+]