improve emmet syntax handling (#3)

master
Brad Cornes 2018-08-25 11:57:21 +01:00
parent 3ed7a35646
commit cc42400081
2 changed files with 279 additions and 79 deletions

View File

@ -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 @@ const HTML_TYPES = [
'handlebars',
'ejs',
'nunjucks',
'haml',
// for jsx
...JS_TYPES
'haml'
]
const CSS_TYPES = ['css', 'sass', 'scss', 'less', 'postcss', 'stylus']
@ -147,7 +146,17 @@ function createCompletionItemProvider({
// 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 @@ class TailwindIntellisense {
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,7 +548,9 @@ class TailwindIntellisense {
)
this._providers.push(
vscode.languages.registerHoverProvider(HTML_TYPES, {
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),
@ -572,7 +629,8 @@ class TailwindIntellisense {
return null
}
})
}
)
)
this._disposable = vscode.Disposable.from(...this._providers)

142
src/htmlElements.ts 100644
View File

@ -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'
]