1 Commits

Author SHA1 Message Date
Yasuhiro Matsumoto
84a0388827 [WIP] styled 2019-11-13 16:28:12 +09:00
9 changed files with 34 additions and 231 deletions

View File

@@ -3,7 +3,7 @@
[![Build Status](https://travis-ci.org/mattn/emmet-vim.svg?branch=master)](https://travis-ci.org/mattn/emmet-vim)
[emmet-vim](https://mattn.github.io/emmet-vim/) is a vim plug-in
[emmet-vim](http://mattn.github.com/emmet-vim) is a vim plug-in
which provides support for expanding abbreviations similar to
[emmet](http://emmet.io/).
@@ -13,56 +13,42 @@ which provides support for expanding abbreviations similar to
[Download zip file](http://www.vim.org/scripts/script.php?script_id=2981):
```sh
cd ~/.vim
unzip emmet-vim.zip
```
To install using [pathogen.vim](https://github.com/tpope/vim-pathogen):
```sh
git clone https://github.com/mattn/emmet-vim.git ~/.vim/bundle/emmet-vim
```
To install using [Vundle](https://github.com/gmarik/vundle):
```vim
" add this line to your .vimrc file
Plugin 'mattn/emmet-vim'
```
To install using [Vim-Plug](https://github.com/junegunn/vim-plug):
```vim
" add this line to your .vimrc file
Plug 'mattn/emmet-vim'
```
To checkout the source from repository:
```sh
cd ~/.vim/bundle
git clone https://github.com/mattn/emmet-vim.git
```
or:
```sh
git clone https://github.com/mattn/emmet-vim.git
cd emmet-vim
cp plugin/emmet.vim ~/.vim/plugin/
cp autoload/emmet.vim ~/.vim/autoload/
cp -a autoload/emmet ~/.vim/autoload/
```
## Quick Tutorial
Open or create a New File:
```sh
vim index.html
```
Type ("\_" is the cursor position):
@@ -124,42 +110,10 @@ You can change the **path** to your **snippets_custom.json** according to your p
[Here](http://docs.emmet.io/customization/snippets/) you can find instructions about creating your customized **snippets.json** file.
## Snippet to add meta tag for responsiveness
Update this in your .vimrc file.
let g:user_emmet_settings = {
\ 'variables': {'lang': 'ja'},
\ 'html': {
\ 'default_attributes': {
\ 'option': {'value': v:null},
\ 'textarea': {'id': v:null, 'name': v:null, 'cols': 10, 'rows': 10},
\ },
\ 'snippets': {
\ 'html:5': "<!DOCTYPE html>\n"
\ ."<html lang=\"${lang}\">\n"
\ ."<head>\n"
\ ."\t<meta charset=\"${charset}\">\n"
\ ."\t<title></title>\n"
\ ."\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"
\ ."</head>\n"
\ ."<body>\n\t${child}|\n</body>\n"
\ ."</html>",
\ },
\ },
\}
## Project Authors
[Yasuhiro Matsumoto](http://mattn.kaoriya.net/)
## FAQ
* Pressing ctrl+y+, doesn't work
Probably you set `timeoutlen=0`. Most of Vim plugins which using key-mappings does not work with `timeoutlen=0`.
## Links
### Emmet official site:
@@ -172,7 +126,7 @@ Update this in your .vimrc file.
### emmet.vim:
* <https://mattn.github.io/emmet-vim/>
* <http://mattn.github.com/emmet-vim>
### development repository:

View File

@@ -379,12 +379,8 @@ function! emmet#getFileType(...) abort
endif
endif
if get(g:, 'loaded_nvim_treesitter', 0)
let type = luaeval('require"emmet_utils".get_node_at_cursor()')
else
let pos = emmet#util#getcurpos()
let type = synIDattr(synID(max([pos[1], 1]), max([pos[2], 1]), 1), 'name')
endif
" ignore htmlTagName as it seems to occur too often
if type == 'htmlTagName'
@@ -400,6 +396,8 @@ function! emmet#getFileType(...) abort
let type = 'html'
elseif type =~? '^jsx'
let type = 'jsx'
elseif type =~? '^jsTemplateString'
let type = 'css-block'
elseif (type =~? '^js\w' || type =~? '^javascript') && !(&filetype =~? 'jsx')
let type = 'javascript'
elseif type =~? '^tsx'
@@ -408,8 +406,6 @@ function! emmet#getFileType(...) abort
let type = 'typescript'
elseif type =~? '^xml'
let type = 'xml'
elseif type == 'styledEmmetAbbreviation'
let type = 'styled'
else
let types = split(&filetype, '\.')
for part in types
@@ -789,28 +785,15 @@ function! emmet#updateTag() abort
if empty(current)
return ''
endif
let old_tag_name = current.name
let str = substitute(input('Enter Abbreviation: ', ''), '^\s*\(.*\)\s*$', '\1', 'g')
let tag_changed = str =~# '^\s*\w'
let item = emmet#parseIntoTree(str, type).child[0]
for k in keys(item.attr)
let current.attr[k] = item.attr[k]
endfor
if tag_changed
let current.name = item.name
endif
let html = substitute(emmet#toString(current, 'html', 1), '\n', '', '')
let html = substitute(html, '\${cursor}', '', '')
let html = matchstr(html, '^<[^><]\+>')
if tag_changed
let pos2 = searchpairpos('<' . old_tag_name . '\>[^>]*>', '', '</' . old_tag_name . '>', 'W')
if pos2 != [0, 0]
let html .= emmet#util#getContent([region[1], pos2])[1:-2]
let html .= '</' . current.name . '>'
let region = [region[0], [pos2[0], pos2[1] + len(old_tag_name) + 3]]
endif
endif
call emmet#util#setContent(region, html)
return ''
endfunction
@@ -1699,9 +1682,6 @@ let s:emmet_settings = {
\ 'css.drupal': {
\ 'extends': 'css',
\ },
\ 'styled': {
\ 'extends': 'css',
\ },
\ 'html': {
\ 'snippets': {
\ '!': "html:5",
@@ -1766,31 +1746,17 @@ let s:emmet_settings = {
\ },
\ 'default_attributes': {
\ 'a': [{'href': ''}],
\ 'a:blank': [{'href': 'http://|'},{'target': '_blank'},{'rel': 'noopener noreferrer'}],
\ 'a:link': [{'href': 'http://|'}],
\ 'a:mail': [{'href': 'mailto:|'}],
\ 'a:tel': [{'href': 'tel:+|'}],
\ 'abbr': [{'title': ''}],
\ 'acronym': [{'title': ''}],
\ 'acr': [{'title': ''}],
\ 'base': [{'href': ''}],
\ 'bdo': [{'dir': ''}],
\ 'bdo:r': [{'dir': 'rtl'}],
\ 'bdo:l': [{'dir': 'ltr'}],
\ 'button:disabled': [{'disabled': 'disabled'}],
\ 'button:d': [{'disabled': 'disabled'}],
\ 'btn:d': [{'disabled': 'disabled'}],
\ 'button:submit': [{'type': 'submit'}],
\ 'button:s': [{'type': 'submit'}],
\ 'btn:s': [{'type': 'submit'}],
\ 'button:reset': [{'type': 'reset'}],
\ 'button:r': [{'type': 'reset'}],
\ 'btn:r': [{'type': 'reset'}],
\ 'del': [{'datetime': '${datetime}'}],
\ 'ins': [{'datetime': '${datetime}'}],
\ 'link:css': [{'rel': 'stylesheet'}, g:emmet_html5 ? {} : {'type': 'text/css'}, {'href': '|style.css'}, {'media': 'all'}],
\ 'link:manifest': [{'rel': 'manifest'},{'href': '|manifest.json'}],
\ 'link:mf': [{'rel': 'manifest'},{'href': '|manifest.json'}],
\ 'link:print': [{'rel': 'stylesheet'}, g:emmet_html5 ? {} : {'type': 'text/css'}, {'href': '|print.css'}, {'media': 'print'}],
\ 'link:import': [{'rel': 'import'}, {'href': '|.html'}],
\ 'link:im': [{'rel': 'import'}, {'href': '|.html'}],
@@ -1798,23 +1764,14 @@ let s:emmet_settings = {
\ 'link:touch': [{'rel': 'apple-touch-icon'}, {'href': '|favicon.png'}],
\ 'link:rss': [{'rel': 'alternate'}, {'type': 'application/rss+xml'}, {'title': 'RSS'}, {'href': '|rss.xml'}],
\ 'link:atom': [{'rel': 'alternate'}, {'type': 'application/atom+xml'}, {'title': 'Atom'}, {'href': 'atom.xml'}],
\ 'marquee': [{'behavior': ''},{'direction': ''}],
\ 'meta:utf': [{'http-equiv': 'Content-Type'}, {'content': 'text/html;charset=UTF-8'}],
\ 'meta:vp': [{'name': 'viewport'}, {'content': 'width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0'}],
\ 'meta:win': [{'http-equiv': 'Content-Type'}, {'content': 'text/html;charset=Win-1251'}],
\ 'meta:compat': [{'http-equiv': 'X-UA-Compatible'}, {'content': 'IE=7'}],
\ 'meta:desc': [{'name': 'description'},{'content': ''}],
\ 'meta:edge': [{'http-equiv': 'X-UA-Compatible'}, {'content': 'ie=edge'}],
\ 'meta:kw': [{'name': 'keywords'},{'content': ''}],
\ 'meta:redirect': [{'http-equiv': 'Content-Type'}, {'content': '0; url=http://example.com'}],
\ 'style': g:emmet_html5 ? [] : [{'type': 'text/css'}],
\ 'script': g:emmet_html5 ? [] : [{'type': 'text/javascript'}],
\ 'script:src': (g:emmet_html5 ? [] : [{'type': 'text/javascript'}]) + [{'src': ''}],
\ 'img': [{'src': ''}, {'alt': ''}],
\ 'img:srcset': [{'srcset': ''},{'src': ''}, {'alt': ''}],
\ 'img:s': [{'srcset': ''},{'src': ''}, {'alt': ''}],
\ 'img:sizes': [{'sizes': ''},{'srcset': ''},{'src': ''}, {'alt': ''}],
\ 'img:z': [{'sizes': ''},{'srcset': ''},{'src': ''}, {'alt': ''}],
\ 'iframe': [{'src': ''}, {'frameborder': '0'}],
\ 'embed': [{'src': ''}, {'type': ''}],
\ 'object': [{'data': ''}, {'type': ''}],
@@ -1826,10 +1783,6 @@ let s:emmet_settings = {
\ 'area:r': [{'shape': 'rect'}, {'coords': ''}, {'href': ''}, {'alt': ''}],
\ 'area:p': [{'shape': 'poly'}, {'coords': ''}, {'href': ''}, {'alt': ''}],
\ 'link': [{'rel': 'stylesheet'}, {'href': ''}],
\ 'fieldset:disabled': [{'disabled': 'disabled'}],
\ 'fieldset:d': [{'disabled': 'disabled'}],
\ 'fset:d': [{'disabled': 'disabled'}],
\ 'fst:disabled': [{'disabled': 'disabled'}],
\ 'form': [{'action': ''}],
\ 'form:get': [{'action': ''}, {'method': 'get'}],
\ 'form:post': [{'action': ''}, {'method': 'post'}],
@@ -1842,7 +1795,6 @@ let s:emmet_settings = {
\ 'input:t': [{'type': 'text'}, {'name': ''}, {'id': ''}],
\ 'input:search': [{'type': 'search'}, {'name': ''}, {'id': ''}],
\ 'input:email': [{'type': 'email'}, {'name': ''}, {'id': ''}],
\ 'input:tel': [{'type': 'tel'}, {'name': ''}, {'id': ''}],
\ 'input:url': [{'type': 'url'}, {'name': ''}, {'id': ''}],
\ 'input:password': [{'type': 'password'}, {'name': ''}, {'id': ''}],
\ 'input:p': [{'type': 'password'}, {'name': ''}, {'id': ''}],
@@ -1869,20 +1821,6 @@ let s:emmet_settings = {
\ 'input:button': [{'type': 'button'}, {'value': ''}],
\ 'input:b': [{'type': 'button'}, {'value': ''}],
\ 'select': [{'name': ''}, {'id': ''}],
\ 'select:disabled': [{'name': ''}, {'id': ''}, {'disabled': 'disabled'}],
\ 'source:media': [{'media': '(minwidth: )'},{'srcset': ''}],
\ 'source:m': [{'media': '(minwidth: )'},{'srcset': ''}],
\ 'source:media:type': [{'media': '(minwidth: )'},{'srcset': ''},{'type': 'image/'}],
\ 'source:media:sizes': [{'media': '(minwidth: )'},{'srcset': ''},{'sizes': ''}],
\ 'source:sizes:type': [{'sizes': ''},{'srcset': ''},{'type': 'image/'}],
\ 'source:src': [{'src': ''},{'type': ''}],
\ 'source:sc': [{'src': ''},{'type': ''}],
\ 'source:srcset': [{'srcset': ''}],
\ 'source:s': [{'srcset': ''}],
\ 'source:type': [{'srcset': ''},{'type': 'image/'}],
\ 'source:t': [{'srcset': ''},{'type': 'image/'}],
\ 'source:sizes': [{'sizes': ''},{'srcset': ''}],
\ 'source:z': [{'sizes': ''},{'srcset': ''}],
\ 'option': [{'value': ''}],
\ 'textarea': [{'name': ''}, {'id': ''}, {'cols': '30'}, {'rows': '10'}],
\ 'menu:context': [{'type': 'context'}],
@@ -1904,27 +1842,19 @@ let s:emmet_settings = {
\ 'html:*': 'html',
\ 'a:*': 'a',
\ 'menu:*': 'menu',
\ 'mn': 'main',
\ 'tem': 'template',
\ 'bq': 'blockquote',
\ 'acr': 'acronym',
\ 'fig': 'figure',
\ 'figc': 'figcaption',
\ 'ifr': 'iframe',
\ 'emb': 'embed',
\ 'obj': 'object',
\ 'src:*': 'source',
\ 'src': 'source',
\ 'cap': 'caption',
\ 'colg': 'colgroup',
\ 'fst': 'fieldset',
\ 'fst:disabled': 'fieldset',
\ 'btn': 'button',
\ 'btn:d': 'button',
\ 'btn:r': 'button',
\ 'btn:s': 'button',
\ 'optg': 'optgroup',
\ 'opt': 'option',
\ 'pic': 'picture',
\ 'tarea': 'textarea',
\ 'leg': 'legend',
\ 'sect': 'section',
@@ -1937,14 +1867,12 @@ let s:emmet_settings = {
\ 'sty': 'style',
\ 'prog': 'progress',
\ 'fset': 'fieldset',
\ 'fset:d': 'fieldset',
\ 'datag': 'datagrid',
\ 'datal': 'datalist',
\ 'kg': 'keygen',
\ 'out': 'output',
\ 'det': 'details',
\ 'cmd': 'command',
\ 'sum': 'summary',
\ },
\ 'expandos': {
\ 'ol': 'ol>li',
@@ -1958,14 +1886,6 @@ let s:emmet_settings = {
\ 'select': 'select>option',
\ 'optgroup': 'optgroup>option',
\ 'optg': 'optgroup>option',
\ 'ri:dpr': 'img:s',
\ 'ri:d': 'img:s',
\ 'ri:viewport': 'img:z',
\ 'ri:vp': 'img:z',
\ 'ri:art': 'pic>source:m+img',
\ 'ri:a': 'pic>source:m+img',
\ 'ri:type': 'pic>source:t+img',
\ 'ri:t': 'pic>source:t+img',
\ },
\ 'empty_elements': 'area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,keygen,command',
\ 'block_elements': 'address,applet,blockquote,button,center,dd,del,dir,div,dl,dt,fieldset,form,frameset,hr,iframe,ins,isindex,li,link,map,menu,noframes,noscript,object,ol,p,pre,script,table,tbody,td,tfoot,th,thead,tr,ul,h1,h2,h3,h4,h5,h6',
@@ -2086,19 +2006,9 @@ let s:emmet_settings = {
\ 'attribute_name': {'class': 'className', 'for': 'htmlFor'},
\ 'empty_element_suffix': ' />',
\ },
\ 'javascriptreact': {
\ 'extends': 'html',
\ 'attribute_name': {'class': 'className', 'for': 'htmlFor'},
\ 'empty_element_suffix': ' />',
\ },
\ 'tsx': {
\ 'extends': 'jsx',
\ },
\ 'typescriptreact': {
\ 'extends': 'html',
\ 'attribute_name': {'class': 'className', 'for': 'htmlFor'},
\ 'empty_element_suffix': ' />',
\ },
\ 'xslt': {
\ 'extends': 'xsl',
\ },

View File

@@ -15,6 +15,7 @@ function! emmet#lang#type(type) abort
let settings = emmet#getSettings()
while base != ''
for b in split(base, '\.')
let b = substitute(b, '-.*', '', '')
if emmet#lang#exists(b)
return b
endif

View File

@@ -13,17 +13,18 @@ function! emmet#lang#css#parseIntoTree(abbr, type) abort
let prefix = 0
let value = ''
let indent = emmet#getIndentation(type)
let aliases = emmet#getResource(type, 'aliases', {})
let snippets = emmet#getResource(type, 'snippets', {})
let use_pipe_for_cursor = emmet#getResource(type, 'use_pipe_for_cursor', 1)
let ftype = substitute(type, '-.*', '', '')
let indent = emmet#getIndentation(ftype)
let aliases = emmet#getResource(ftype, 'aliases', {})
let snippets = emmet#getResource(ftype, 'snippets', {})
let use_pipe_for_cursor = emmet#getResource(ftype, 'use_pipe_for_cursor', 1)
let root = emmet#newNode()
" emmet
let tokens = split(abbr, '+\ze[^+)!]')
let block = emmet#util#searchRegion('{', '}')
if abbr !~# '^@' && emmet#getBaseType(type) ==# 'css' && type !=# 'sass' && type !=# 'styled' && block[0] ==# [0,0] && block[1] ==# [0,0]
if abbr !~# '^@' && emmet#getBaseType(type) ==# 'css' && type !=# 'sass' && block[0] ==# [0,0] && block[1] ==# [0,0]
let current = emmet#newNode()
let current.snippet = substitute(abbr, '\s\+$', '', '') . " {\n" . indent . "${cursor}\n}"
let current.name = ''

View File

@@ -232,18 +232,10 @@ function! emmet#lang#html#parseIntoTree(abbr, type) abort
let current.attrs_order += keys(a)
if use_pipe_for_cursor
for k in keys(a)
if type(a[k]) == 7
call remove(current.attr, k)
continue
endif
let current.attr[k] = len(a[k]) ? substitute(a[k], '|', '${cursor}', 'g') : '${cursor}'
endfor
else
for k in keys(a)
if type(a[k]) == 7
call remove(current.attr, k)
continue
endif
let current.attr[k] = a[k]
endfor
endif
@@ -252,18 +244,10 @@ function! emmet#lang#html#parseIntoTree(abbr, type) abort
let current.attrs_order += keys(a)
if use_pipe_for_cursor
for k in keys(a)
if type(a[k]) == 7
call remove(current.attr, k)
continue
endif
let current.attr[k] = len(a[k]) ? substitute(a[k], '|', '${cursor}', 'g') : '${cursor}'
endfor
else
for k in keys(a)
if type(a[k]) == 7
call remove(current.attr, k)
continue
endif
let current.attr[k] = a[k]
endfor
endif
@@ -736,11 +720,11 @@ endfunction
function! emmet#lang#html#parseTag(tag) abort
let current = emmet#newNode()
let mx = '<\([a-zA-Z][a-zA-Z0-9-]*\)\(\%(\s[a-zA-Z][a-zA-Z0-9-]\+=\?\%([^"'' \t]\+\|"[^"]\{-}"\|''[^'']\{-}''\)\s*\)*\)\(/\{0,1}\)>'
let mx = '<\([a-zA-Z][a-zA-Z0-9]*\)\(\%(\s[a-zA-Z][a-zA-Z0-9]\+=\%([^"'' \t]\+\|"[^"]\{-}"\|''[^'']\{-}''\)\s*\)*\)\(/\{0,1}\)>'
let match = matchstr(a:tag, mx)
let current.name = substitute(match, mx, '\1', 'i')
let attrs = substitute(match, mx, '\2', 'i')
let mx = '\([a-zA-Z0-9-]\+\)\(\(=[^"'' \t]\+\)\|="\([^"]\{-}\)"\|=''\([^'']\{-}\)''\)\?'
let mx = '\([a-zA-Z0-9]\+\)=\%(\([^"'' \t]\+\)\|"\([^"]\{-}\)"\|''\([^'']\{-}\)''\)'
while len(attrs) > 0
let match = matchstr(attrs, mx)
if len(match) == 0
@@ -748,12 +732,8 @@ function! emmet#lang#html#parseTag(tag) abort
endif
let attr_match = matchlist(match, mx)
let name = attr_match[1]
if len(attr_match[2])
let Val = len(attr_match[3]) ? attr_match[3] : attr_match[4]
else
let Val = function('emmet#types#true')
endif
let current.attr[name] = Val
let value = len(attr_match[2]) ? attr_match[2] : attr_match[3]
let current.attr[name] = value
let current.attrs_order += [name]
let attrs = attrs[stridx(attrs, match) + len(match):]
endwhile

View File

@@ -353,8 +353,6 @@ function! emmet#util#imageEncodeDecode(fn, flag) abort
let ret .= 'jpeg'
elseif hex =~# '^47494638'
let ret .= 'gif'
elseif hex =~# '^00000020667479706176696600000000'
let ret .= 'avif'
else
let ret .= 'unknown'
endif

View File

@@ -1,25 +0,0 @@
local M = {}
M.get_node_at_cursor = function()
local ts_utils = require("nvim-treesitter.ts_utils")
local node = ts_utils.get_node_at_cursor()
if not node then
return nil
end
while node do
local node_type = node:type()
if node_type == "element" then
return "html"
elseif node_type == "stylesheet" then
return "css"
end
node = node:parent()
end
return ""
end
return M

View File

@@ -23,7 +23,6 @@
" | <head>
" | <title></title>
" | <meta charset="UTF-8">
" | <meta name="viewport" content="width=device-width, initial-scale=1.0">
" | </head>
" | <body>
" | _
@@ -151,7 +150,7 @@ function! s:install_plugin(mode, buffer)
let key = g:user_emmet_leader_key . item.key
endif
if !hasmapto('<plug>(' . item.plug . ')', item.mode) && !len(maparg(key, item.mode))
exe item.mode . 'map ' . buffer . ' <unique> <silent>' . key . ' <plug>(' . item.plug . ')'
exe item.mode . 'map ' . buffer . ' <unique> ' . key . ' <plug>(' . item.plug . ')'
endif
endif
endfor
@@ -175,17 +174,6 @@ if get(g:, 'user_emmet_install_command', 1)
command! -nargs=1 Emmet call emmet#expandAbbr(4, <q-args>)
endif
function! s:setup_styledEmmetAbbreviation() abort
if index(['javascript', 'javascriptreact', 'typescript', 'typescriptreact'], &filetype) != -1
syntax match styledEmmetAbbreviation "[a-z0-9#+!%]\+" containedin=styledDefinition contained
endif
endfunction
augroup ___emmet_setup___
au!
autocmd Syntax * call s:setup_styledEmmetAbbreviation()
augroup END
let &cpoptions = s:save_cpo
unlet s:save_cpo

View File

@@ -681,10 +681,6 @@ finish
'query': "<h$$$$\\<c-y>u.global\\<cr>$$$$3></h3>",
'result': "<h3 class=\"global\"></h3>",
},
{
'query': "<button$$$$\\<c-y>u.btn\\<cr>$$$$ disabled></button>",
'result': "<button class=\"btn\" disabled></button>",
},
],
},
{