diff --git a/src/extension.ts b/src/extension.ts index c4598ae87dd8ca51c151bfc2d884b4b6a6913040..371c76f62394a33b3048c83dd47afe1913b2ef6d 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,8 +1,7 @@ 'use strict' import * as vscode from 'vscode' -import { dirname } from 'path' -const htmlElements = require('./htmlElements.js') +import { join, dirname } from 'path' const tailwindClassNames = require('tailwind-class-names') const dlv = require('dlv') const Color = require('color') @@ -22,7 +21,9 @@ 'erb', 'handlebars', 'ejs', 'nunjucks', - 'haml' + 'haml', + // for jsx + ...JS_TYPES ] const CSS_TYPES = ['css', 'sass', 'scss', 'less', 'postcss', 'stylus'] @@ -146,17 +147,7 @@ } else if (emmet) { // match emmet style syntax // e.g. .flex.items-center let currentLine = lines[lines.length - 1] - 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( - '|' - )}).*?\\.([^.()#>*^ \\[\\]=$@{}]*)$` - ) - ) - } + matches = currentLine.match(/\.([^()#>*^ \[\]=$@{}]*)$/i) let parts = matches[matches.length - 1].split('.') str = parts[parts.length - 1] } @@ -431,78 +422,32 @@ this._providers.push( createCompletionItemProvider({ items: this._items, languages: HTML_TYPES, - regex: /\bclass=["']([^"']*)$/, // /\bclass(Name)?=(["'])(?!.*?\2)/ + regex: /\bclass(Name)?=["']([^"']*)$/, // /\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=["']([^"']*)$/, + regex: /\bclass(Name)?=["']([^"']*)$/, enable: text => { if ( - text.indexOf('') === -1 + (text.indexOf('') === -1) || + (text.indexOf('') === -1) ) { return true } return false }, - triggerCharacters: ["'", '"', ' ', separator] - .concat([ - Object.keys( - vscode.workspace.getConfiguration('emmet.includeLanguages') - ).indexOf('vue-html') !== -1 && '.' - ]) - .filter(Boolean), + triggerCharacters: ["'", '"', ' ', '.', separator], config: tailwind.config, - 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('') === -1 - ) { - return true - } - return false - }, - triggerCharacters: ["'", '"', ' ', separator], - config: tailwind.config + emmet: true }) ) this._providers.push( @@ -548,89 +493,86 @@ }) ) this._providers.push( - 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) + 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 + if (!/\bclass(Name)?=['"][^'"]*$/.test(text1)) return - 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) + 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) - let str = text1 + text2.substr(text1.length).match(/^([^"' ]*)/)[0] - let matches = str.match(/\bclass(Name)?=["']([^"']*)$/) + let str = text1 + text2.substr(text1.length).match(/^([^"' ]*)/)[0] + let matches = str.match(/\bclass(Name)?=["']([^"']*)$/) - if (matches && matches[2]) { - let className = matches[2].split(' ').pop() - let parts = className.split(':') + if (matches && matches[2]) { + let className = matches[2].split(' ').pop() + let parts = className.split(':') - if (typeof dlv(this._tailwind.classNames, parts) === 'string') { - let base = parts.pop() - let selector = `.${escapeClassName(className)}` + if (typeof dlv(this._tailwind.classNames, parts) === 'string') { + let base = parts.pop() + let selector = `.${escapeClassName(className)}` - 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 (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}` + } - 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() + 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', {}) + + Object.keys(screens).some(screen => { + if (parts.indexOf(screen) !== -1) { + code = `@media (min-width: ${ + screens[screen] + }) {\n${code.replace(/^/gm, ' ')}\n}` + return true } - css = css.replace(/([;{]) /g, '$1\n').replace(/^/gm, ' ') - let code = `${selector} {\n${css}\n}` - let screens = dlv(this._tailwind.config, 'screens', {}) + return false + }) + hoverStr.appendCodeblock(code, 'css') - 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) diff --git a/src/htmlElements.ts b/src/htmlElements.ts deleted file mode 100644 index 4bb7b1c1220b17799c08d5b923dd5e8ac0e4f280..0000000000000000000000000000000000000000 --- a/src/htmlElements.ts +++ /dev/null @@ -1,142 +0,0 @@ -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' -]