diff --git a/autoload/emmet.vim b/autoload/emmet.vim index 4e70773..e6f9c7c 100644 --- a/autoload/emmet.vim +++ b/autoload/emmet.vim @@ -237,7 +237,11 @@ function! emmet#toString(...) abort let snippet_node = emmet#newNode() let snippet_node.value = '{'.tmp.'}' let snippet_node.important = current.important - let str = emmet#lang#{rtype}#toString(s:emmet_settings, snippet_node, type, inline, filters, s:itemno(group_itemno, current), indent) + let snippet_node.multiplier = current.multiplier + let str .= emmet#lang#{rtype}#toString(s:emmet_settings, snippet_node, type, inline, filters, s:itemno(group_itemno, current), indent) + if current.multiplier > 1 + let str .= "\n" + endif else if len(current.name) let str .= current.name @@ -646,7 +650,7 @@ function! emmet#expandAbbr(mode, abbr) range abort endif let expand = substitute(expand, '[\r\n]\s*$', '', 'g') if emmet#useFilter(filters, 's') - let epart = substitute(expand, '[\r\n]\s\*', '', 'g') + let epart = substitute(expand, '[\r\n]\s*', '', 'g') else let epart = substitute(expand, '[\r\n]', "\n" . indent, 'g') endif diff --git a/autoload/emmet/lang/css.vim b/autoload/emmet/lang/css.vim index 361d89d..48bc3c2 100644 --- a/autoload/emmet/lang/css.vim +++ b/autoload/emmet/lang/css.vim @@ -31,7 +31,7 @@ function! emmet#lang#css#parseIntoTree(abbr, type) abort else for n in range(len(tokens)) let token = tokens[n] - let prop = matchlist(token, '^\(-\{0,1}[a-zA-Z]\+\|[a-zA-Z0-9]\++\{0,1}\|([a-zA-Z0-9]\++\{0,1})\)\(\%([0-9.-]\+[pe]\{0,1}-\{0,1}\|-auto\)*\)$') + let prop = matchlist(token, '^\(-\{0,1}[a-zA-Z]\+\|[a-zA-Z0-9]\++\{0,1}\|([a-zA-Z0-9]\++\{0,1})\)\(\%([0-9.-]\+\%(p\|e\|em\|re\|rem\|%\)\{0,1}-\{0,1}\|-auto\)*\)$') if len(prop) let token = substitute(prop[1], '^(\(.*\))', '\1', '') if token =~# '^-' @@ -48,8 +48,16 @@ function! emmet#lang#css#parseIntoTree(abbr, type) abort let value .= substitute(v, '[^0-9.]*$', '', '') elseif v =~# 'p$' let value .= substitute(v, 'p$', '%', '') + elseif v =~# '%$' + let value .= v elseif v =~# 'e$' let value .= substitute(v, 'e$', 'em', '') + elseif v =~# 'em$' + let value .= v + elseif v =~# 're$' + let value .= substitute(v, 're$', 'rem', '') + elseif v =~# 'rem$' + let value .= v elseif v =~# '\.' let value .= v . 'em' elseif v ==# 'auto' diff --git a/autoload/emmet/lang/jade.vim b/autoload/emmet/lang/jade.vim new file mode 100644 index 0000000..8b0596a --- /dev/null +++ b/autoload/emmet/lang/jade.vim @@ -0,0 +1,332 @@ +function! emmet#lang#jade#findTokens(str) abort + return emmet#lang#html#findTokens(a:str) +endfunction + +function! emmet#lang#jade#parseIntoTree(abbr, type) abort + return emmet#lang#html#parseIntoTree(a:abbr, a:type) +endfunction + +function! emmet#lang#jade#toString(settings, current, type, inline, filters, itemno, indent) abort + let settings = a:settings + let current = a:current + let type = a:type + let inline = a:inline + let filters = a:filters + let itemno = a:itemno + let indent = emmet#getIndentation(type) + let dollar_expr = emmet#getResource(type, 'dollar_expr', 1) + let attribute_style = emmet#getResource('jade', 'attribute_style', 'hash') + let str = '' + + let current_name = current.name + if dollar_expr + let current_name = substitute(current.name, '\$$', itemno+1, '') + endif + if len(current.name) > 0 + let str .= '' . current_name + let tmp = '' + for attr in emmet#util#unique(current.attrs_order + keys(current.attr)) + if !has_key(current.attr, attr) + continue + endif + let Val = current.attr[attr] + if type(Val) == 2 && Val == function('emmet#types#true') + if attribute_style ==# 'hash' + let tmp .= ' ' . attr . ' = true' + elseif attribute_style ==# 'html' + let tmp .= attr . '=true' + end + else + if dollar_expr + while Val =~# '\$\([^#{]\|$\)' + let Val = substitute(Val, '\(\$\+\)\([^{]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + endwhile + let attr = substitute(attr, '\$$', itemno+1, '') + endif + let valtmp = substitute(Val, '\${cursor}', '', '') + if attr ==# 'id' && len(valtmp) > 0 + let str .= '#' . Val + elseif attr ==# 'class' && len(valtmp) > 0 + let str .= '.' . substitute(Val, ' ', '.', 'g') + else + if len(tmp) > 0 + if attribute_style ==# 'hash' + let tmp .= ', ' + elseif attribute_style ==# 'html' + let tmp .= ' ' + endif + endif + let Val = substitute(Val, '\${cursor}', '', '') + if attribute_style ==# 'hash' + let tmp .= '' . attr . '="' . Val . '"' + elseif attribute_style ==# 'html' + let tmp .= attr . '="' . Val . '"' + end + endif + endif + endfor + if len(tmp) + if attribute_style ==# 'hash' + let str .= '(' . tmp . ')' + elseif attribute_style ==# 'html' + let str .= '(' . tmp . ')' + end + endif + + let inner = '' + if len(current.value) > 0 + let text = current.value[1:-2] + if dollar_expr + let text = substitute(text, '\%(\\\)\@\ 0 + for child in current.child + let inner .= emmet#toString(child, type, inline, filters, itemno, indent) + endfor + let inner = substitute(inner, "\n", "\n" . escape(indent, '\'), 'g') + let inner = substitute(inner, "\n" . escape(indent, '\') . '$', '', 'g') + let str .= "\n" . indent . inner + endif + else + let str = current.value[1:-2] + if dollar_expr + let str = substitute(str, '\%(\\\)\@\\s*\%(\([^"'' \t]\+\)\|"\([^"]\{-}\)"\|''\([^'']\{-}\)''\)' + while len(attrs) > 0 + let match = matchstr(attrs, mx) + if len(match) ==# 0 + break + endif + let attr_match = matchlist(match, mx) + let name = attr_match[1] + 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 + return current +endfunction + +function! emmet#lang#jade#toggleComment() abort + let line = getline('.') + let space = matchstr(line, '^\s*') + if line =~# '^\s*-#' + call setline('.', space . matchstr(line[len(space)+2:], '^\s*\zs.*')) + elseif line =~# '^\s*%[a-z]' + call setline('.', space . '-# ' . line[len(space):]) + endif +endfunction + +function! emmet#lang#jade#balanceTag(flag) range abort + let block = emmet#util#getVisualBlock() + if a:flag == -2 || a:flag == 2 + let curpos = [0, line("'<"), col("'<"), 0] + else + let curpos = emmet#util#getcurpos() + endif + let n = curpos[1] + let ml = len(matchstr(getline(n), '^\s*')) + + if a:flag > 0 + if a:flag == 1 || !emmet#util#regionIsValid(block) + let n = line('.') + else + while n > 0 + let l = len(matchstr(getline(n), '^\s*\ze%[a-z]')) + if l > 0 && l < ml + let ml = l + break + endif + let n -= 1 + endwhile + endif + let sn = n + if n == 0 + let ml = 0 + endif + while n < line('$') + let l = len(matchstr(getline(n), '^\s*%[a-z]')) + if l > 0 && l <= ml + let n -= 1 + break + endif + let n += 1 + endwhile + call setpos('.', [0, n, 1, 0]) + normal! V + call setpos('.', [0, sn, 1, 0]) + else + while n > 0 + let l = len(matchstr(getline(n), '^\s*\ze[a-z]')) + if l > 0 && l > ml + let ml = l + break + endif + let n += 1 + endwhile + let sn = n + if n == 0 + let ml = 0 + endif + while n < line('$') + let l = len(matchstr(getline(n), '^\s*%[a-z]')) + if l > 0 && l <= ml + let n -= 1 + break + endif + let n += 1 + endwhile + call setpos('.', [0, n, 1, 0]) + normal! V + call setpos('.', [0, sn, 1, 0]) + endif +endfunction + +function! emmet#lang#jade#moveNextPrevItem(flag) abort + return emmet#lang#jade#moveNextPrev(a:flag) +endfunction + +function! emmet#lang#jade#moveNextPrev(flag) abort + let pos = search('""', a:flag ? 'Wb' : 'W') + if pos != 0 + silent! normal! l + startinsert + endif +endfunction + +function! emmet#lang#jade#splitJoinTag() abort + let n = line('.') + let sml = len(matchstr(getline(n), '^\s*%[a-z]')) + while n > 0 + if getline(n) =~# '^\s*\ze%[a-z]' + if len(matchstr(getline(n), '^\s*%[a-z]')) < sml + break + endif + let line = getline(n) + call setline(n, substitute(line, '^\s*%\w\+\%(\s*{[^}]*}\|\s\)\zs.*', '', '')) + let sn = n + let n += 1 + let ml = len(matchstr(getline(n), '^\s*%[a-z]')) + if len(matchstr(getline(n), '^\s*')) > ml + while n <= line('$') + let l = len(matchstr(getline(n), '^\s*')) + if l <= ml + break + endif + exe n 'delete' + endwhile + call setpos('.', [0, sn, 1, 0]) + else + let tag = matchstr(getline(sn), '^\s*%\zs\(\w\+\)') + let spaces = matchstr(getline(sn), '^\s*') + let settings = emmet#getSettings() + if stridx(','.settings.html.inline_elements.',', ','.tag.',') == -1 + call append(sn, spaces . ' ') + call setpos('.', [0, sn+1, 1, 0]) + else + call setpos('.', [0, sn, 1, 0]) + endif + startinsert! + endif + break + endif + let n -= 1 + endwhile +endfunction + +function! emmet#lang#jade#removeTag() abort + let n = line('.') + let ml = 0 + while n > 0 + if getline(n) =~# '^\s*\ze[a-z]' + let ml = len(matchstr(getline(n), '^\s*%[a-z]')) + break + endif + let n -= 1 + endwhile + let sn = n + while n < line('$') + let l = len(matchstr(getline(n), '^\s*%[a-z]')) + if l > 0 && l <= ml + let n -= 1 + break + endif + let n += 1 + endwhile + if sn == n + exe 'delete' + else + exe sn ',' (n-1) 'delete' + endif +endfunction diff --git a/doc/emmet.txt b/doc/emmet.txt index e6d3a5e..dcaf776 100644 --- a/doc/emmet.txt +++ b/doc/emmet.txt @@ -906,7 +906,7 @@ inside generated tree and elements' attributes. < Other examples: > - .wrapper ->
+ .wrapper -> #popup -> < When you expand abbreviation, Emmet tries to grab parent context, diff --git a/plugin/emmet.vim b/plugin/emmet.vim index ae18852..67c04e3 100644 --- a/plugin/emmet.vim +++ b/plugin/emmet.vim @@ -114,6 +114,10 @@ function! s:install_plugin(mode, buffer) \ {'mode': 'n', 'var': 'user_emmet_next_key', 'key': 'n', 'plug': 'emmet-move-next', 'func': ':call emmet#moveNextPrev(0)