diff options
Diffstat (limited to 'config/vim/autoload/emmet/lang')
-rw-r--r-- | config/vim/autoload/emmet/lang/css.vim | 385 | ||||
-rw-r--r-- | config/vim/autoload/emmet/lang/elm.vim | 241 | ||||
-rw-r--r-- | config/vim/autoload/emmet/lang/haml.vim | 337 | ||||
-rw-r--r-- | config/vim/autoload/emmet/lang/html.vim | 1036 | ||||
-rw-r--r-- | config/vim/autoload/emmet/lang/jade.vim | 335 | ||||
-rw-r--r-- | config/vim/autoload/emmet/lang/less.vim | 51 | ||||
-rw-r--r-- | config/vim/autoload/emmet/lang/sass.vim | 163 | ||||
-rw-r--r-- | config/vim/autoload/emmet/lang/scss.vim | 129 | ||||
-rw-r--r-- | config/vim/autoload/emmet/lang/slim.vim | 284 |
9 files changed, 2961 insertions, 0 deletions
diff --git a/config/vim/autoload/emmet/lang/css.vim b/config/vim/autoload/emmet/lang/css.vim new file mode 100644 index 0000000..d26f942 --- /dev/null +++ b/config/vim/autoload/emmet/lang/css.vim @@ -0,0 +1,385 @@ +function! emmet#lang#css#findTokens(str) abort + let tmp = substitute(substitute(a:str, '^.*[;{]\s*', '', ''), '}\s*$', '', '') + if tmp =~ '/' && tmp =~ '^[a-zA-Z0-9/_.]\+$' + " maybe path or something + return '' + endif + return substitute(substitute(a:str, '^.*[;{]\s*', '', ''), '}\s*$', '', '') +endfunction + +function! emmet#lang#css#parseIntoTree(abbr, type) abort + let abbr = a:abbr + let type = a:type + 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 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] + let current = emmet#newNode() + let current.snippet = substitute(abbr, '\s\+$', '', '') . " {\n" . indent . "${cursor}\n}" + let current.name = '' + call add(root.child, deepcopy(current)) + 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.-]\+\%(p\|e\|em\|x\|vh\|vw\|re\|rem\|%\)\{0,}-\{0,1}\|-auto\)*\)$') + if len(prop) + let token = substitute(prop[1], '^(\(.*\))', '\1', '') + if token =~# '^-' + let prefix = 1 + let token = token[1:] + endif + let value = '' + for vt in split(prop[2], '\a\+\zs') + let ut = matchstr(vt, '[a-z]\+$') + if ut == 'auto' + let ut = '' + endif + for v in split(vt, '\d\zs-') + if len(value) > 0 + let value .= ' ' + endif + if v !~ '[a-z]\+$' + let v .= ut + endif + if token =~# '^[z]' + " TODO + let value .= substitute(v, '[^0-9.]*$', '', '') + elseif v =~# 'em$' + let value .= v + elseif v =~# 'ex$' + let value .= v + elseif v =~# 'vh$' + let value .= v + elseif v =~# 'vw$' + let value .= v + elseif v =~# 'rem$' + let value .= v + elseif v ==# 'auto' + let value .= v + elseif v =~# 'p$' + let value .= substitute(v, 'p$', '%', '') + elseif v =~# '%$' + let value .= v + elseif v =~# 'e$' + let value .= substitute(v, 'e$', 'em', '') + elseif v =~# 'x$' + let value .= substitute(v, 'x$', 'ex', '') + elseif v =~# 're$' + let value .= substitute(v, 're$', 'rem', '') + elseif v =~# '\.' + let value .= v . 'em' + elseif v ==# '0' + let value .= '0' + else + let value .= v . 'px' + endif + endfor + endfor + endif + + let tag_name = token + if tag_name =~# '.!$' + let tag_name = tag_name[:-2] + let important = 1 + else + let important = 0 + endif + " make default node + let current = emmet#newNode() + let current.important = important + let current.name = tag_name + + " aliases + if has_key(aliases, tag_name) + let current.name = aliases[tag_name] + endif + + " snippets + if !empty(snippets) + let snippet_name = tag_name + if !has_key(snippets, snippet_name) + let pat = '^' . join(split(tag_name, '\zs'), '\%(\|[^:-]\+-\)') + let vv = filter(sort(keys(snippets)), 'snippets[v:val] =~ pat') + if len(vv) == 0 + let vv = filter(sort(keys(snippets)), 'substitute(v:val, ":", "", "g") == snippet_name') + endif + if len(vv) > 0 + let snippet_name = vv[0] + else + let pat = '^' . join(split(tag_name, '\zs'), '\%(\|[^:-]\+-*\)') + let vv = filter(sort(keys(snippets)), 'snippets[v:val] =~ pat') + if len(vv) == 0 + let pat = '^' . join(split(tag_name, '\zs'), '[^:]\{-}') + let vv = filter(sort(keys(snippets)), 'snippets[v:val] =~ pat') + if len(vv) == 0 + let pat = '^' . join(split(tag_name, '\zs'), '.\{-}') + let vv = filter(sort(keys(snippets)), 'snippets[v:val] =~ pat') + endif + endif + let minl = -1 + for vk in vv + let vvs = snippets[vk] + if minl == -1 || len(vvs) < minl + let snippet_name = vk + let minl = len(vvs) + endif + endfor + endif + endif + if has_key(snippets, snippet_name) + let snippet = snippets[snippet_name] + if use_pipe_for_cursor + let snippet = substitute(snippet, '|', '${cursor}', 'g') + endif + let lines = split(snippet, "\n") + call map(lines, 'substitute(v:val, "\\( \\|\\t\\)", escape(indent, "\\\\"), "g")') + let current.snippet = join(lines, "\n") + let current.name = '' + let current.snippet = substitute(current.snippet, ';', value . ';', '') + if use_pipe_for_cursor && len(value) > 0 + let current.snippet = substitute(current.snippet, '\${cursor}', '', 'g') + endif + if n < len(tokens) - 1 + let current.snippet .= "\n" + endif + endif + endif + + let current.pos = 0 + let lg = matchlist(token, '^\%(linear-gradient\|lg\)(\s*\(\S\+\)\s*,\s*\([^,]\+\)\s*,\s*\([^)]\+\)\s*)$') + if len(lg) == 0 + let lg = matchlist(token, '^\%(linear-gradient\|lg\)(\s*\(\S\+\)\s*,\s*\([^,]\+\)\s*)$') + if len(lg) + let [lg[1], lg[2], lg[3]] = ['linear', lg[1], lg[2]] + endif + endif + if len(lg) + let current.name = '' + let current.snippet = printf("background-image:-webkit-gradient(%s, 0 0, 0 100%, from(%s), to(%s));\n", lg[1], lg[2], lg[3]) + call add(root.child, deepcopy(current)) + let current.snippet = printf("background-image:-webkit-linear-gradient(%s, %s);\n", lg[2], lg[3]) + call add(root.child, deepcopy(current)) + let current.snippet = printf("background-image:-moz-linear-gradient(%s, %s);\n", lg[2], lg[3]) + call add(root.child, deepcopy(current)) + let current.snippet = printf("background-image:-o-linear-gradient(%s, %s);\n", lg[2], lg[3]) + call add(root.child, deepcopy(current)) + let current.snippet = printf("background-image:linear-gradient(%s, %s);\n", lg[2], lg[3]) + call add(root.child, deepcopy(current)) + elseif prefix + let snippet = current.snippet + let current.snippet = '-webkit-' . snippet . "\n" + call add(root.child, deepcopy(current)) + let current.snippet = '-moz-' . snippet . "\n" + call add(root.child, deepcopy(current)) + let current.snippet = '-o-' . snippet . "\n" + call add(root.child, deepcopy(current)) + let current.snippet = '-ms-' . snippet . "\n" + call add(root.child, deepcopy(current)) + let current.snippet = snippet + call add(root.child, current) + elseif token =~# '^c#\([0-9a-fA-F]\{3}\|[0-9a-fA-F]\{6}\)\(\.[0-9]\+\)\?' + let cs = split(token, '\.') + let current.name = '' + let [r,g,b] = [0,0,0] + if len(cs[0]) == 5 + let rgb = matchlist(cs[0], 'c#\(.\)\(.\)\(.\)') + let r = eval('0x'.rgb[1].rgb[1]) + let g = eval('0x'.rgb[2].rgb[2]) + let b = eval('0x'.rgb[3].rgb[3]) + elseif len(cs[0]) == 8 + let rgb = matchlist(cs[0], 'c#\(..\)\(..\)\(..\)') + let r = eval('0x'.rgb[1]) + let g = eval('0x'.rgb[2]) + let b = eval('0x'.rgb[3]) + endif + if len(cs) == 1 + let current.snippet = printf('color:rgb(%d, %d, %d);', r, g, b) + else + let current.snippet = printf('color:rgb(%d, %d, %d, %s);', r, g, b, string(str2float('0.'.cs[1]))) + endif + call add(root.child, current) + elseif token =~# '^c#' + let current.name = '' + let current.snippet = 'color:\${cursor};' + call add(root.child, current) + else + call add(root.child, current) + endif + endfor + endif + return root +endfunction + +function! emmet#lang#css#toString(settings, current, type, inline, filters, itemno, indent) abort + let current = a:current + let value = current.value[1:-2] + let tmp = substitute(value, '\${cursor}', '', 'g') + if tmp !~ '.*{[ \t\r\n]*}$' + if emmet#useFilter(a:filters, 'fc') + let value = substitute(value, '\([^:]\+\):\([^;]*\)', '\1: \2', 'g') + else + let value = substitute(value, '\([^:]\+\):\([^;]*\)', '\1:\2', 'g') + endif + if current.important + let value = substitute(value, ';', ' !important;', '') + endif + endif + return value +endfunction + +function! emmet#lang#css#imageSize() abort + let img_region = emmet#util#searchRegion('{', '}') + if !emmet#util#regionIsValid(img_region) || !emmet#util#cursorInRegion(img_region) + return + endif + let content = emmet#util#getContent(img_region) + let fn = matchstr(content, '\<url(\zs[^)]\+\ze)') + let fn = substitute(fn, '[''" \t]', '', 'g') + if fn =~# '^\s*$' + return + elseif fn !~# '^\(/\|http\)' + let fn = simplify(expand('%:h') . '/' . fn) + endif + let [width, height] = emmet#util#getImageSize(fn) + if width == -1 && height == -1 + return + endif + let indent = emmet#getIndentation('css') + if content =~# '.*\<width\s*:[^;]*;.*' + let content = substitute(content, '\<width\s*:[^;]*;', 'width: ' . width . 'px;', '') + else + let content = substitute(content, '}', indent . 'width: ' . width . "px;\n}", '') + endif + if content =~# '.*\<height\s*:[^;]*;.*' + let content = substitute(content, '\<height\s*:[^;]*;', 'height: ' . height . 'px;', '') + else + let content = substitute(content, '}', indent . 'height: ' . height . "px;\n}", '') + endif + call emmet#util#setContent(img_region, content) +endfunction + +function! emmet#lang#css#imageEncode() abort + let img_region = emmet#util#searchRegion('url(', ')') + if !emmet#util#regionIsValid(img_region) || !emmet#util#cursorInRegion(img_region) + return + endif + let content = emmet#util#getContent(img_region) + let fn = matchstr(content, '\<url(\zs[^)]\+\ze)') + let fn = substitute(fn, '[''" \t]', '', 'g') + if fn =~# '^\s*$' + return + elseif fn !~# '^\(/\|http\)' + let fn = simplify(expand('%:h') . '/' . fn) + endif + let encoded = emmet#util#imageEncodeDecode(fn, 0) + call emmet#util#setContent(img_region, 'url(' . encoded . ')') +endfunction + +function! emmet#lang#css#parseTag(tag) abort + return {} +endfunction + +function! emmet#lang#css#toggleComment() abort + let line = getline('.') + let mx = '^\(\s*\)/\*\s*\(.*\)\s*\*/\s*$' + if line =~# '{\s*$' + let block = emmet#util#searchRegion('/\*', '\*/\zs') + if emmet#util#regionIsValid(block) + let content = emmet#util#getContent(block) + let content = substitute(content, '/\*\s\(.*\)\s\*/', '\1', '') + call emmet#util#setContent(block, content) + else + let node = expand('<cword>') + if len(node) + exe "normal ciw\<c-r>='/* '.node.' */'\<cr>" + endif + endif + else + if line =~# mx + let space = substitute(matchstr(line, mx), mx, '\1', '') + let line = substitute(matchstr(line, mx), mx, '\2', '') + let line = space . substitute(line, '^\s*\|\s*$', '\1', 'g') + else + let mx = '^\(\s*\)\(''[^'']*''\|[^'']*\|;\)\s*$' + " TODO multi-property + "let mx = '^\(\s*\)\(\%(''[^'']*''\|[^'';]\+\)*;\{0,1}\)' + let line = substitute(line, mx, '\1/* \2 */', '') + endif + call setline('.', line) + endif +endfunction + +function! emmet#lang#css#balanceTag(flag) range abort + if a:flag == -2 || a:flag == 2 + let curpos = [0, line("'<"), col("'<"), 0] + else + let curpos = emmet#util#getcurpos() + endif + let block = emmet#util#getVisualBlock() + if !emmet#util#regionIsValid(block) + if a:flag > 0 + let block = emmet#util#searchRegion('^', ';') + if emmet#util#regionIsValid(block) + call emmet#util#selectRegion(block) + return + endif + endif + else + if a:flag > 0 + let content = emmet#util#getContent(block) + if content !~# '^{.*}$' + let block = emmet#util#searchRegion('{', '}') + if emmet#util#regionIsValid(block) + call emmet#util#selectRegion(block) + return + endif + endif + else + let pos = searchpos('.*;', 'nW') + if pos[0] != 0 + call setpos('.', [0, pos[0], pos[1], 0]) + let block = emmet#util#searchRegion('^', ';') + if emmet#util#regionIsValid(block) + call emmet#util#selectRegion(block) + return + endif + endif + endif + endif + if a:flag == -2 || a:flag == 2 + silent! exe 'normal! gv' + else + call setpos('.', curpos) + endif +endfunction + +function! emmet#lang#css#moveNextPrevItem(flag) abort + return emmet#lang#css#moveNextPrev(a:flag) +endfunction + +function! emmet#lang#css#moveNextPrev(flag) abort + call search('""\|()\|\(:\s*\zs;\{1,0}$\)', a:flag ? 'Wbp' : 'Wp') + return '' +endfunction + +function! emmet#lang#css#splitJoinTag() abort + " nothing to do +endfunction + +function! emmet#lang#css#removeTag() abort + " nothing to do +endfunction + +function! emmet#lang#css#mergeLines() abort + " nothing to do +endfunction diff --git a/config/vim/autoload/emmet/lang/elm.vim b/config/vim/autoload/emmet/lang/elm.vim new file mode 100644 index 0000000..ce663bd --- /dev/null +++ b/config/vim/autoload/emmet/lang/elm.vim @@ -0,0 +1,241 @@ +function! emmet#lang#elm#findTokens(str) abort + return emmet#lang#html#findTokens(a:str) +endfunction + +function! emmet#lang#elm#parseIntoTree(abbr, type) abort + let tree = emmet#lang#html#parseIntoTree(a:abbr, a:type) + if len(tree.child) < 2 | return tree | endif + + " Add ',' nodes between root elements. + let new_children = [] + for child in tree.child[0:-2] + let comma = emmet#newNode() + let comma.name = ',' + call add(new_children, child) + call add(new_children, comma) + endfor + call add(new_children, tree.child[-1]) + let tree.child = new_children + return tree +endfunction + +function! emmet#lang#elm#renderNode(node) + let elm_nodes = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6' + \, 'div', 'p', 'hr', 'pre', 'blockquote' + \, 'span', 'a', 'code', 'em', 'strong', 'i', 'b', 'u', 'sub', 'sup', 'br' + \, 'ol', 'ul', 'li', 'dl', 'dt', 'dd' + \, 'img', 'iframe', 'canvas', 'math' + \, 'form', 'input', 'textarea', 'button', 'select', 'option' + \, 'section', 'nav', 'article', 'aside', 'header', 'footer', 'address', 'main_', 'body' + \, 'figure', 'figcaption' + \, 'table', 'caption', 'colgroup', 'col', 'tbody', 'thead', 'tfoot', 'tr', 'td', 'th' + \, 'fieldset', 'legend', 'label', 'datalist', 'optgroup', 'keygen', 'output', 'progress', 'meter' + \, 'audio', 'video', 'source', 'track' + \, 'embed', 'object', 'param' + \, 'ins', 'del' + \, 'small', 'cite', 'dfn', 'abbr', 'time', 'var', 'samp', 'kbd', 's', 'q' + \, 'mark', 'ruby', 'rt', 'rp', 'bdi', 'bdo', 'wbr' + \, 'details', 'summary', 'menuitem', 'menu'] + + if index(elm_nodes, a:node) >= 0 + return a:node + endif + return 'node "' . a:node . '"' +endfunction + +function! emmet#lang#elm#renderParam(param) + let elm_events = ["onClick", "onDoubleClick" + \, "onMouseDown", "onMouseUp" + \, "onMouseEnter", "onMouseLeave" + \, "onMouseOver", "onMouseOut" + \, "onInput", "onCheck", "onSubmit" + \, "onBlur", "onFocus" + \, "on", "onWithOptions", "Options", "defaultOptions" + \, "targetValue", "targetChecked", "keyCode"] + if index(elm_events, a:param) >= 0 + return a:param + endif + let elm_attributes = ["style", "map" , "class", "id", "title", "hidden" + \, "type", "type_", "value", "defaultValue", "checked", "placeholder", "selected" + \, "accept", "acceptCharset", "action", "autocomplete", "autofocus" + \, "disabled", "enctype", "formaction", "list", "maxlength", "minlength", "method", "multiple" + \, "name", "novalidate", "pattern", "readonly", "required", "size", "for", "form" + \, "max", "min", "step" + \, "cols", "rows", "wrap" + \, "href", "target", "download", "downloadAs", "hreflang", "media", "ping", "rel" + \, "ismap", "usemap", "shape", "coords" + \, "src", "height", "width", "alt" + \, "autoplay", "controls", "loop", "preload", "poster", "default", "kind", "srclang" + \, "sandbox", "seamless", "srcdoc" + \, "reversed", "start" + \, "align", "colspan", "rowspan", "headers", "scope" + \, "async", "charset", "content", "defer", "httpEquiv", "language", "scoped" + \, "accesskey", "contenteditable", "contextmenu", "dir", "draggable", "dropzone" + \, "itemprop", "lang", "spellcheck", "tabindex" + \, "challenge", "keytype" + \, "cite", "datetime", "pubdate", "manifest"] + + if index(elm_attributes, a:param) >= 0 + if a:param == 'type' + return 'type_' + endif + return a:param + endif + return 'attribute "' . a:param . '"' +endfunction + +function! emmet#lang#elm#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 str = '' + + " comma between items with *, eg. li*3 + if itemno > 0 + let str = ", " + endif + + let current_name = current.name + if dollar_expr + let current_name = substitute(current.name, '\$$', itemno+1, '') + endif + + if len(current.name) > 0 + " inserted root comma nodes + if current_name == ',' + return "\n, " + endif + let str .= emmet#lang#elm#renderNode(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] + + let attr = emmet#lang#elm#renderParam(attr) + + if type(Val) == 2 && Val == function('emmet#types#true') + let tmp .= ', ' . attr . ' True' + 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 tmp .=', id "' . Val . '"' + elseif attr ==# 'class' && len(valtmp) > 0 + let tmp .= ', class "' . substitute(Val, '\.', ' ', 'g') . '"' + else + let tmp .= ', ' . attr . ' "' . Val . '"' + endif + endif + endfor + + if ! len(tmp) + let str .= ' []' + else + let tmp = strpart(tmp, 2) + let str .= ' [ ' . tmp . ' ]' + endif + + " No children quit early + if len(current.child) == 0 && len(current.value) == 0 + "Place cursor in node with no value or children + let str .= ' [${cursor}]' + return str + endif + + let inner = '' + + " Parent contex text + if len(current.value) > 0 + let text = current.value[1:-2] + if dollar_expr + let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + let text = substitute(text, '\${nr}', "\n", 'g') + let text = substitute(text, '\\\$', '$', 'g') + " let str = substitute(str, '\$#', text, 'g') + let inner .= ', text "' . text . '"' + endif + endif + + + " Has children + for child in current.child + if len(child.name) == 0 && len(child.value) > 0 + " Text node + let text = child.value[1:-2] + if dollar_expr + let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + let text = substitute(text, '\${nr}', "\n", 'g') + let text = substitute(text, '\\\$', '$', 'g') + endif + let inner .= ', text "' . text . '"' + else + " Other nodes + let inner .= ', ' . emmet#toString(child, type, inline, filters, 0, indent) + endif + endfor + + let inner = substitute(inner, "\n", "\n" . escape(indent, '\'), 'g') + let inner = substitute(inner, "\n" . escape(indent, '\') . '$', '', 'g') + let inner = strpart(inner, 2) + + let inner = substitute(inner, ' ', '', 'g') + + if ! len(inner) + let str .= ' []' + else + let str .= ' [ ' . inner . ' ]' + endif + + else + let str = current.value[1:-2] + if dollar_expr + let str = substitute(str, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + let str = substitute(str, '\${nr}', "\n", 'g') + let str = substitute(str, '\\\$', '$', 'g') + endif + endif + + let str .= "\n" + return str +endfunction + +function! emmet#lang#elm#imageEncode() abort +endfunction + +function! emmet#lang#elm#parseTag(tag) abort + return {} +endfunction + +function! emmet#lang#elm#toggleComment() abort +endfunction + +function! emmet#lang#elm#balanceTag(flag) range abort +endfunction + +function! emmet#lang#elm#moveNextPrevItem(flag) abort + return emmet#lang#elm#moveNextPrev(a:flag) +endfunction + +function! emmet#lang#elm#moveNextPrev(flag) abort +endfunction + +function! emmet#lang#elm#splitJoinTag() abort +endfunction + +function! emmet#lang#elm#removeTag() abort +endfunction + +function! emmet#lang#elm#mergeLines() abort +endfunction diff --git a/config/vim/autoload/emmet/lang/haml.vim b/config/vim/autoload/emmet/lang/haml.vim new file mode 100644 index 0000000..7ea97d1 --- /dev/null +++ b/config/vim/autoload/emmet/lang/haml.vim @@ -0,0 +1,337 @@ +function! emmet#lang#haml#findTokens(str) abort + return emmet#lang#html#findTokens(a:str) +endfunction + +function! emmet#lang#haml#parseIntoTree(abbr, type) abort + return emmet#lang#html#parseIntoTree(a:abbr, a:type) +endfunction + +function! emmet#lang#haml#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('haml', '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 + 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 + if stridx(','.settings.html.empty_elements.',', ','.current_name.',') != -1 && len(current.value) == 0 + let str .= '/' + endif + + let inner = '' + if len(current.value) > 0 + let text = current.value[1:-2] + if dollar_expr + let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + let text = substitute(text, '\${nr}', "\n", 'g') + let text = substitute(text, '\\\$', '$', 'g') + let str = substitute(str, '\$#', text, 'g') + endif + let lines = split(text, "\n") + if len(lines) == 1 + let str .= ' ' . text + else + for line in lines + let str .= "\n" . indent . line . ' |' + endfor + endif + elseif len(current.child) == 0 + let str .= '${cursor}' + endif + if len(current.child) == 1 && len(current.child[0].name) == 0 + let text = current.child[0].value[1:-2] + if dollar_expr + let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + let text = substitute(text, '\${nr}', "\n", 'g') + let text = substitute(text, '\\\$', '$', 'g') + endif + let lines = split(text, "\n") + if len(lines) == 1 + let str .= ' ' . text + else + for line in lines + let str .= "\n" . indent . line . ' |' + endfor + endif + elseif len(current.child) > 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, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + let str = substitute(str, '\${nr}', "\n", 'g') + let str = substitute(str, '\\\$', '$', 'g') + endif + endif + let str .= "\n" + return str +endfunction + +function! emmet#lang#haml#imageSize() abort + let line = getline('.') + let current = emmet#lang#haml#parseTag(line) + if empty(current) || !has_key(current.attr, 'src') + return + endif + let fn = current.attr.src + if fn =~# '^\s*$' + return + elseif fn !~# '^\(/\|http\)' + let fn = simplify(expand('%:h') . '/' . fn) + endif + + let [width, height] = emmet#util#getImageSize(fn) + if width == -1 && height == -1 + return + endif + let current.attr.width = width + let current.attr.height = height + let current.attrs_order += ['width', 'height'] + let haml = emmet#toString(current, 'haml', 1) + let haml = substitute(haml, '\${cursor}', '', '') + call setline('.', substitute(matchstr(line, '^\s*') . haml, "\n", '', 'g')) +endfunction + +function! emmet#lang#haml#imageEncode() abort +endfunction + +function! emmet#lang#haml#parseTag(tag) abort + let current = emmet#newNode() + let mx = '%\([a-zA-Z][a-zA-Z0-9]*\)\s*\%({\(.*\)}\)' + let match = matchstr(a:tag, mx) + let current.name = substitute(match, mx, '\1', '') + let attrs = substitute(match, mx, '\2', '') + let mx = '\([a-zA-Z0-9]\+\)\s*=>\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#haml#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#haml#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#haml#moveNextPrevItem(flag) abort + return emmet#lang#haml#moveNextPrev(a:flag) +endfunction + +function! emmet#lang#haml#moveNextPrev(flag) abort + let pos = search('""', a:flag ? 'Wb' : 'W') + if pos != 0 + silent! normal! l + startinsert + endif +endfunction + +function! emmet#lang#haml#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#haml#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 + +function! emmet#lang#haml#mergeLines() abort +endfunction diff --git a/config/vim/autoload/emmet/lang/html.vim b/config/vim/autoload/emmet/lang/html.vim new file mode 100644 index 0000000..fad887a --- /dev/null +++ b/config/vim/autoload/emmet/lang/html.vim @@ -0,0 +1,1036 @@ +let s:bx = '{\%("[^"]*"\|''[^'']*''\|\$#\|\${\w\+}\|\$\+\|{[^{]\+\|[^{}]\)\{-}}' +let s:mx = '\([+>]\|[<^]\+\)\{-}' +\ .'\((*\)\{-}' +\ .'\([@#.]\{-}[a-zA-Z_\!][a-zA-Z0-9:_\!\-$]*\|' . s:bx . '\|\[[^\]]\+\]\)' +\ .'\(' +\ .'\%(' +\ .'\%(#{[{}a-zA-Z0-9_\-\$]\+\|#[a-zA-Z0-9_\-\$]\+\)' +\ .'\|\%(\[\%(\[[^\]]*\]\|"[^"]*"\|[^"\[\]]*\)\+\]\)' +\ .'\|\%(\.{[{}a-zA-Z0-9_\-\$\.]\+\|\.[a-zA-Z0-9_\-\$]\+\)' +\ .'\)*' +\ .'\)' +\ .'\%(\(' . s:bx . '\+\)\)\{0,1}' +\ .'\%(\(@-\{0,1}[0-9]*\)\{0,1}\*\([0-9]\+\)\)\{0,1}' +\ .'\(\%()\%(\(@-\{0,1}[0-9]*\)\{0,1}\*[0-9]\+\)\{0,1}\)*\)' + +function! emmet#lang#html#findTokens(str) abort + let str = a:str + let [pos, last_pos] = [0, 0] + while 1 + let tag = matchstr(str, '<[a-zA-Z].\{-}>', pos) + if len(tag) == 0 + break + endif + let pos = stridx(str, tag, pos) + len(tag) + endwhile + while 1 + let tag = matchstr(str, '{%[^%]\{-}%}', pos) + if len(tag) == 0 + break + endif + let pos = stridx(str, tag, pos) + len(tag) + endwhile + let last_pos = pos + while len(str) > 0 + let white = matchstr(str, '^\s\+', pos) + if white != '' + let last_pos = pos + len(white) + let pos = last_pos + endif + let token = matchstr(str, s:mx, pos) + if token ==# '' + break + endif + let pos = stridx(str, token, pos) + len(token) + endwhile + let str = a:str[last_pos :-1] + if str =~# '^\w\+="[^"]*$' + return '' + endif + return str +endfunction + +function! emmet#lang#html#parseIntoTree(abbr, type) abort + let abbr = a:abbr + let type = a:type + + let settings = emmet#getSettings() + if !has_key(settings, type) + let type = 'html' + endif + if len(type) == 0 | let type = 'html' | endif + + let indent = emmet#getIndentation(type) + let pmap = { + \'p': 'span', + \'ul': 'li', + \'ol': 'li', + \'table': 'tr', + \'tr': 'td', + \'tbody': 'tr', + \'thead': 'tr', + \'tfoot': 'tr', + \'colgroup': 'col', + \'select': 'option', + \'optgroup': 'option', + \'audio': 'source', + \'video': 'source', + \'object': 'param', + \'map': 'area' + \} + + let inlineLevel = split('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var',',') + + let custom_expands = emmet#getResource(type, 'custom_expands', {}) + if empty(custom_expands) && has_key(settings, 'custom_expands') + let custom_expands = settings['custom_expands'] + endif + + " try 'foo' to (foo-x) + let rabbr = emmet#getExpandos(type, abbr) + if rabbr == abbr + " try 'foo+(' to (foo-x) + let rabbr = substitute(abbr, '\%(+\|^\)\([a-zA-Z][a-zA-Z0-9+]\+\)+\([(){}>]\|$\)', '\="(".emmet#getExpandos(type, submatch(1)).")".submatch(2)', 'i') + endif + let abbr = rabbr + + let root = emmet#newNode() + let root['variables'] = {} + let parent = root + let last = root + let pos = [] + while len(abbr) + " parse line + let match = matchstr(abbr, s:mx) + let str = substitute(match, s:mx, '\0', 'ig') + let operator = substitute(match, s:mx, '\1', 'ig') + let block_start = substitute(match, s:mx, '\2', 'ig') + let tag_name = substitute(match, s:mx, '\3', 'ig') + let attributes = substitute(match, s:mx, '\4', 'ig') + let value = substitute(match, s:mx, '\5', 'ig') + let basevalue = substitute(match, s:mx, '\6', 'ig') + let multiplier = 0 + substitute(match, s:mx, '\7', 'ig') + let block_end = substitute(match, s:mx, '\8', 'ig') + let custom = '' + let important = 0 + if len(str) == 0 + break + endif + if tag_name =~# '^#' + let attributes = tag_name . attributes + let tag_name = '' + endif + if tag_name =~# '[^!]!$' + let tag_name = tag_name[:-2] + let important = 1 + endif + if tag_name =~# '^\.' + let attributes = tag_name . attributes + let tag_name = '' + endif + if tag_name =~# '^\[.*\]$' + let attributes = tag_name . attributes + let tag_name = '' + endif + + for k in keys(custom_expands) + if tag_name =~ k + let custom = tag_name + let tag_name = '' + break + endif + endfor + + if empty(tag_name) + let pname = len(parent.child) > 0 ? parent.child[0].name : '' + if !empty(pname) && has_key(pmap, pname) && custom == '' + let tag_name = pmap[pname] + elseif !empty(pname) && index(inlineLevel, pname) > -1 + let tag_name = 'span' + elseif len(custom) == 0 + let tag_name = 'div' + elseif len(custom) != 0 && multiplier > 1 + let tag_name = 'div' + else + let tag_name = custom + endif + endif + + let basedirect = basevalue[1] ==# '-' ? -1 : 1 + if basevalue != '' + let basevalue = 0 + abs(basevalue[1:]) + else + let basevalue = 1 + endif + if multiplier <= 0 | let multiplier = 1 | endif + + " make default node + let current = emmet#newNode() + + let current.name = tag_name + let current.important = important + + " aliases + let aliases = emmet#getResource(type, 'aliases', {}) + if has_key(aliases, tag_name) + let current.name = aliases[tag_name] + endif + + let use_pipe_for_cursor = emmet#getResource(type, 'use_pipe_for_cursor', 1) + + " snippets + let snippets = emmet#getResource(type, 'snippets', {}) + if !empty(snippets) + let snippet_name = tag_name + if has_key(snippets, snippet_name) + let snippet = snippet_name + while has_key(snippets, snippet) + let snippet = snippets[snippet] + endwhile + if use_pipe_for_cursor + let snippet = substitute(snippet, '|', '${cursor}', 'g') + endif + " just redirect to expanding + if type == 'html' && snippet !~ '^\s*[{\[<]' + return emmet#lang#html#parseIntoTree(snippet, a:type) + endif + let lines = split(snippet, "\n", 1) + call map(lines, 'substitute(v:val, "\\( \\|\\t\\)", escape(indent, "\\\\"), "g")') + let current.snippet = join(lines, "\n") + let current.name = '' + endif + endif + + for k in keys(custom_expands) + if tag_name =~# k + let snippet = '${' . (empty(custom) ? tag_name : custom) . '}' + let current.name = '' + let current.snippet = snippet + break + elseif custom =~# k + let snippet = '${' . custom . '}' + let current.snippet = '${' . custom . '}' + if current.name != '' + let snode = emmet#newNode() + let snode.snippet = snippet + let snode.parent = current + call add(current.child, snode) + else + let current.snippet = snippet + endif + break + endif + endfor + + " default_attributes + let default_attributes = emmet#getResource(type, 'default_attributes', {}) + if !empty(default_attributes) + for pat in [current.name, tag_name] + if has_key(default_attributes, pat) + if type(default_attributes[pat]) == 4 + let a = default_attributes[pat] + 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 + else + for a in default_attributes[pat] + 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 + endfor + endif + if has_key(settings.html.default_attributes, current.name) + let current.name = substitute(current.name, ':.*$', '', '') + endif + break + endif + endfor + endif + + " parse attributes + if len(attributes) + let attr = attributes + while len(attr) + let item = matchstr(attr, '\(\%(\%(#[{}a-zA-Z0-9_\-\$]\+\)\|\%(\[\%(\[[^\]]*\]\|"[^"]*"\|[^"\[\]]*\)\+\]\)\|\%(\.[{}a-zA-Z0-9_\-\$]\+\)*\)\)') + if g:emmet_debug > 1 + echomsg 'attr=' . item + endif + if len(item) == 0 + break + endif + if item[0] ==# '#' + let current.attr.id = item[1:] + let root['variables']['id'] = current.attr.id + endif + if item[0] ==# '.' + let current.attr.class = substitute(item[1:], '\.', ' ', 'g') + let root['variables']['class'] = current.attr.class + endif + if item[0] ==# '[' + let atts = item[1:-2] + if matchstr(atts, '^\s*\zs[0-9a-zA-Z_\-:]\+\(="[^"]*"\|=''[^'']*''\|=[^ ''"]\+\)') ==# '' + let ks = [] + if has_key(default_attributes, current.name) + let dfa = default_attributes[current.name] + let ks = type(dfa) == 3 ? len(dfa) > 0 ? keys(dfa[0]) : [] : keys(dfa) + endif + if len(ks) == 0 && has_key(default_attributes, current.name . ':src') + let dfa = default_attributes[current.name . ':src'] + let ks = type(dfa) == 3 ? len(dfa) > 0 ? keys(dfa[0]) : [] : keys(dfa) + endif + if len(ks) > 0 + let current.attr[ks[0]] = atts + elseif atts =~# '\.$' + let current.attr[atts[:-2]] = function('emmet#types#true') + else + let current.attr[atts] = '' + endif + else + while len(atts) + let amat = matchstr(atts, '^\s*\zs\([0-9a-zA-Z-:]\+\%(={{.\{-}}}\|="[^"]*"\|=''[^'']*''\|=[^ ''"]\+\|[^ ''"\]]*\)\{0,1}\)') + if len(amat) == 0 + break + endif + let key = split(amat, '=')[0] + let Val = amat[len(key)+1:] + if key =~# '\.$' && Val ==# '' + let key = key[:-2] + unlet Val + let Val = function('emmet#types#true') + elseif Val =~# '^["'']' + let Val = Val[1:-2] + endif + let current.attr[key] = Val + if index(current.attrs_order, key) == -1 + let current.attrs_order += [key] + endif + let atts = atts[stridx(atts, amat) + len(amat):] + unlet Val + endwhile + endif + endif + let attr = substitute(strpart(attr, len(item)), '^\s*', '', '') + endwhile + endif + + " parse text + if tag_name =~# '^{.*}$' + let current.name = '' + let current.value = tag_name + else + let current.value = value + endif + let current.basedirect = basedirect + let current.basevalue = basevalue + let current.multiplier = multiplier + + " parse step inside/outside + if !empty(last) + if operator =~# '>' + unlet! parent + let parent = last + let current.parent = last + let current.pos = last.pos + 1 + else + let current.parent = parent + let current.pos = last.pos + endif + else + let current.parent = parent + let current.pos = 1 + endif + if operator =~# '[<^]' + for c in range(len(operator)) + let tmp = parent.parent + if empty(tmp) + break + endif + let parent = tmp + let current.parent = tmp + endfor + endif + + call add(parent.child, current) + let last = current + + " parse block + if block_start =~# '(' + if operator =~# '>' + let last.pos += 1 + endif + let last.block = 1 + for n in range(len(block_start)) + let pos += [last.pos] + endfor + endif + if block_end =~# ')' + for n in split(substitute(substitute(block_end, ' ', '', 'g'), ')', ',),', 'g'), ',') + if n ==# ')' + if len(pos) > 0 && last.pos >= pos[-1] + for c in range(last.pos - pos[-1]) + let tmp = parent.parent + if !has_key(tmp, 'parent') + break + endif + let parent = tmp + endfor + if len(pos) > 0 + call remove(pos, -1) + endif + let last = parent + let last.pos += 1 + endif + elseif len(n) + let st = 0 + for nc in range(len(last.child)) + if last.child[nc].block + let st = nc + break + endif + endfor + let cl = last.child[st :] + let cls = [] + for c in range(n[1:]) + for cc in cl + if cc.multiplier > 1 + let cc.basedirect = c + 1 + else + let cc.basevalue = c + 1 + endif + endfor + let cls += deepcopy(cl) + endfor + if st > 0 + let last.child = last.child[:st-1] + cls + else + let last.child = cls + endif + endif + endfor + endif + let abbr = abbr[stridx(abbr, match) + len(match):] + if abbr == '/' + let current.empty = 1 + endif + + if g:emmet_debug > 1 + echomsg 'str='.str + echomsg 'block_start='.block_start + echomsg 'tag_name='.tag_name + echomsg 'operator='.operator + echomsg 'attributes='.attributes + echomsg 'value='.value + echomsg 'basevalue='.basevalue + echomsg 'multiplier='.multiplier + echomsg 'block_end='.block_end + echomsg 'abbr='.abbr + echomsg 'pos='.string(pos) + echomsg '---' + endif + endwhile + return root +endfunction + +function! s:dollar_add(base,no) abort + if a:base > 0 + return a:base + a:no - 1 + elseif a:base < 0 + return a:base - a:no + 1 + else + return a:no + endif +endfunction + +function! emmet#lang#html#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 = a:indent + let dollar_expr = emmet#getResource(type, 'dollar_expr', 1) + let q = emmet#getResource(type, 'quote_char', '"') + let ct = emmet#getResource(type, 'comment_type', 'both') + let an = emmet#getResource(type, 'attribute_name', {}) + let empty_elements = emmet#getResource(type, 'empty_elements', settings.html.empty_elements) + let empty_element_suffix = emmet#getResource(type, 'empty_element_suffix', settings.html.empty_element_suffix) + + if emmet#useFilter(filters, 'haml') + return emmet#lang#haml#toString(settings, current, type, inline, filters, itemno, indent) + endif + if emmet#useFilter(filters, 'slim') + return emmet#lang#slim#toString(settings, current, type, inline, filters, itemno, indent) + endif + + let comment = '' + let current_name = current.name + if dollar_expr + let current_name = substitute(current_name, '\$$', itemno+1, '') + endif + + let str = '' + if len(current_name) == 0 + let text = current.value[1:-2] + if dollar_expr + " TODO: regexp engine specified + let nr = itemno + 1 + if exists('®expengine') + let text = substitute(text, '\%#=1\%(\\\)\@\<!\(\$\+\)\(@-\?[0-9]\+\)\{0,1}\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d",s:dollar_add(submatch(2)[1:],nr)).submatch(3)', 'g') + else + let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\(@-\?[0-9]\+\)\{0,1}\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d",s:dollar_add(submatch(2)[1:],nr).submatch(3)', 'g') + endif + let text = substitute(text, '\${nr}', "\n", 'g') + let text = substitute(text, '\\\$', '$', 'g') + endif + return text + endif + if len(current_name) > 0 + let str .= '<' . current_name + endif + 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') + unlet Val + let Val = 'true' + if g:emmet_html5 + let str .= ' ' . attr + else + let str .= ' ' . attr . '=' . q . attr . q + endif + if emmet#useFilter(filters, 'c') + if attr ==# 'id' | let comment .= '#' . Val | endif + if attr ==# 'class' | let comment .= '.' . Val | endif + endif + else + if dollar_expr + while Val =~# '\$\([^#{]\|$\)' + " TODO: regexp engine specified + if exists('®expengine') + let Val = substitute(Val, '\%#=1\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + else + let Val = substitute(Val, '\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + endif + endwhile + let attr = substitute(attr, '\$$', itemno+1, '') + endif + if attr ==# 'class' && emmet#useFilter(filters, 'bem') + let vals = split(Val, '\s\+') + let Val = '' + let lead = '' + for _val in vals + if len(Val) > 0 + let Val .= ' ' + endif + if _val =~# '^_' + if has_key(current.parent.attr, 'class') + let lead = current.parent.attr["class"] + if _val =~# '^__' + let Val .= lead . _val + else + let Val .= lead . ' ' . lead . _val + endif + else + let lead = split(vals[0], '_')[0] + let Val .= lead . _val + endif + elseif _val =~# '^-' + for l in split(_val, '_') + if len(Val) > 0 + let Val .= ' ' + endif + let l = substitute(l, '^-', '__', '') + if len(lead) == 0 + let pattr = current.parent.attr + if has_key(pattr, 'class') + let lead = split(pattr['class'], '\s\+')[0] + endif + endif + let Val .= lead . l + let lead .= l . '_' + endfor + else + let Val .= _val + endif + endfor + endif + if has_key(an, attr) + let attr = an[attr] + endif + if emmet#isExtends(type, 'jsx') && Val =~ '^{.*}$' + let str .= ' ' . attr . '=' . Val + else + let str .= ' ' . attr . '=' . q . Val . q + endif + if emmet#useFilter(filters, 'c') + if attr ==# 'id' | let comment .= '#' . Val | endif + if attr ==# 'class' | let comment .= '.' . Val | endif + endif + endif + unlet Val + endfor + if len(comment) > 0 && ct ==# 'both' + let str = '<!-- ' . comment . " -->\n" . str + endif + if current.empty + let str .= ' />' + elseif stridx(','.empty_elements.',', ','.current_name.',') != -1 + let str .= empty_element_suffix + else + let str .= '>' + let text = current.value[1:-2] + if dollar_expr + " TODO: regexp engine specified + let nr = itemno + 1 + if exists('®expengine') + let text = substitute(text, '\%#=1\%(\\\)\@\<!\(\$\+\)\(@-\?[0-9]\+\)\{0,1}\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d",s:dollar_add(submatch(2)[1:],nr)).submatch(3)', 'g') + else + let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\(@-\?[0-9]\+\)\{0,1}\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d",s:dollar_add(submatch(2)[1:],nr)).submatch(3)', 'g') + endif + let text = substitute(text, '\${nr}', "\n", 'g') + let text = substitute(text, '\\\$', '$', 'g') + if text != '' + let str = substitute(str, '\("\zs$#\ze"\|\s\zs\$#"\|"\$#\ze\s\)', text, 'g') + endif + endif + let str .= text + let nc = len(current.child) + let dr = 0 + if nc > 0 + for n in range(nc) + let child = current.child[n] + if child.multiplier > 1 || (child.multiplier == 1 && len(child.child) > 0 && stridx(','.settings.html.inline_elements.',', ','.current_name.',') == -1) || settings.html.block_all_childless + let str .= "\n" . indent + let dr = 1 + elseif len(current_name) > 0 && stridx(','.settings.html.inline_elements.',', ','.current_name.',') == -1 + if nc > 1 || (len(child.name) > 0 && stridx(','.settings.html.inline_elements.',', ','.child.name.',') == -1) + let str .= "\n" . indent + let dr = 1 + elseif current.multiplier == 1 && nc == 1 && len(child.name) == 0 + let str .= "\n" . indent + let dr = 1 + endif + endif + let inner = emmet#toString(child, type, 0, filters, itemno, indent) + let inner = substitute(inner, "^\n", '', 'g') + let inner = substitute(inner, "\n", "\n" . escape(indent, '\'), 'g') + let inner = substitute(inner, "\n" . escape(indent, '\') . '$', '', 'g') + let str .= inner + endfor + else + if settings.html.indent_blockelement && len(current_name) > 0 && stridx(','.settings.html.inline_elements.',', ','.current_name.',') == -1 || settings.html.block_all_childless + let str .= "\n" . indent . '${cursor}' . "\n" + else + let str .= '${cursor}' + endif + endif + if dr + let str .= "\n" + endif + let str .= '</' . current_name . '>' + endif + if len(comment) > 0 + if ct ==# 'lastonly' + let str .= '<!-- ' . comment . ' -->' + else + let str .= "\n<!-- /" . comment . ' -->' + endif + endif + if len(current_name) > 0 && current.multiplier > 0 || stridx(','.settings.html.block_elements.',', ','.current_name.',') != -1 + let str .= "\n" + endif + return str +endfunction + +function! emmet#lang#html#imageSize() abort + let img_region = emmet#util#searchRegion('<img\s', '>') + if !emmet#util#regionIsValid(img_region) || !emmet#util#cursorInRegion(img_region) + return + endif + let content = emmet#util#getContent(img_region) + if content !~# '^<img[^><]\+>$' + return + endif + let current = emmet#lang#html#parseTag(content) + if empty(current) || !has_key(current.attr, 'src') + return + endif + let fn = current.attr.src + if fn =~# '^\s*$' + return + elseif fn !~# '^\(/\|http\)' + let fn = simplify(expand('%:h') . '/' . fn) + endif + + let [width, height] = emmet#util#getImageSize(fn) + if width == -1 && height == -1 + return + endif + let current.attr.width = width + let current.attr.height = height + let current.attrs_order += ['width', 'height'] + let html = substitute(emmet#toString(current, 'html', 1), '\n', '', '') + let html = substitute(html, '\${cursor}', '', '') + call emmet#util#setContent(img_region, html) +endfunction + +function! emmet#lang#html#imageEncode() abort + let img_region = emmet#util#searchRegion('<img\s', '>') + if !emmet#util#regionIsValid(img_region) || !emmet#util#cursorInRegion(img_region) + return + endif + let content = emmet#util#getContent(img_region) + if content !~# '^<img[^><]\+>$' + return + endif + let current = emmet#lang#html#parseTag(content) + if empty(current) || !has_key(current.attr, 'src') + return + endif + let fn = current.attr.src + if fn =~# '^\s*$' + return + elseif fn !~# '^\(/\|http\)' + let fn = simplify(expand('%:h') . '/' . fn) + endif + + let encoded = emmet#util#imageEncodeDecode(fn, 0) + let current.attr.src = encoded + let content = substitute(emmet#toString(current, 'html', 1), '\n', '', '') + let content = substitute(content, '\${cursor}', '', '') + call emmet#util#setContent(img_region, content) +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 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]\+\)\|="\([^"]\{-}\)"\|=''\([^'']\{-}\)''\)\?' + 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] + 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 current.attrs_order += [name] + let attrs = attrs[stridx(attrs, match) + len(match):] + endwhile + return current +endfunction + +function! emmet#lang#html#toggleComment() abort + let orgpos = getpos('.') + let curpos = getpos('.') + let mx = '<\%#[^>]*>' + while 1 + let block = emmet#util#searchRegion('<!--', '-->') + if emmet#util#regionIsValid(block) + let block[1][1] += 2 + let content = emmet#util#getContent(block) + let content = substitute(content, '^<!--\s\(.*\)\s-->$', '\1', '') + call emmet#util#setContent(block, content) + silent! call setpos('.', orgpos) + return + endif + let block = emmet#util#searchRegion('<[^>]', '>') + if !emmet#util#regionIsValid(block) + let pos1 = searchpos('<', 'bcW') + if pos1[0] == 0 && pos1[1] == 0 + return + endif + let curpos = getpos('.') + continue + endif + let pos1 = block[0] + let pos2 = block[1] + let content = emmet#util#getContent(block) + let tag_name = matchstr(content, '^<\zs/\{0,1}[^ \r\n>]\+') + if tag_name[0] ==# '/' + call setpos('.', [0, pos1[0], pos1[1], 0]) + let pos2 = searchpairpos('<'. tag_name[1:] . '\>[^/>]*>', '', '</' . tag_name[1:] . '>', 'bnW') + let pos1 = searchpos('>', 'cneW') + let block = [pos2, pos1] + elseif tag_name =~# '/$' + if !emmet#util#pointInRegion(orgpos[1:2], block) + " it's broken tree + call setpos('.', orgpos) + let block = emmet#util#searchRegion('>', '<') + let content = '><!-- ' . emmet#util#getContent(block)[1:-2] . ' --><' + call emmet#util#setContent(block, content) + silent! call setpos('.', orgpos) + return + endif + else + call setpos('.', [0, pos2[0], pos2[1], 0]) + let pos3 = searchpairpos('<'. tag_name . '\>[^/>]*>', '', '</' . tag_name . '>', 'nW') + if pos3 == [0, 0] + let block = [pos1, pos2] + else + call setpos('.', [0, pos3[0], pos3[1], 0]) + let pos2 = searchpos('>', 'neW') + let block = [pos1, pos2] + endif + endif + if !emmet#util#regionIsValid(block) + silent! call setpos('.', orgpos) + return + endif + if emmet#util#pointInRegion(curpos[1:2], block) + let content = '<!-- ' . emmet#util#getContent(block) . ' -->' + call emmet#util#setContent(block, content) + silent! call setpos('.', orgpos) + return + endif + endwhile +endfunction + +function! emmet#lang#html#balanceTag(flag) range abort + let vblock = emmet#util#getVisualBlock() + let curpos = emmet#util#getcurpos() + let settings = emmet#getSettings() + + if a:flag > 0 + let mx = '<\([a-zA-Z][a-zA-Z0-9:_\-]*\)[^>]*' + let last = curpos[1:2] + while 1 + let pos1 = searchpos(mx, 'bW') + let content = matchstr(getline(pos1[0])[pos1[1]-1:], mx) + let tag_name = matchstr(content, '^<\zs[a-zA-Z0-9:_\-]*\ze') + if stridx(','.settings.html.empty_elements.',', ','.tag_name.',') != -1 + let pos2 = searchpos('>', 'nW') + else + let pos2 = searchpairpos('<' . tag_name . '[^>]*>', '', '</'. tag_name . '\zs>', 'nW') + endif + let block = [pos1, pos2] + if pos1 == [0, 0] + break + endif + if emmet#util#pointInRegion(last, block) && emmet#util#regionIsValid(block) + call emmet#util#selectRegion(block) + return + endif + if pos1 == last + break + endif + let last = pos1 + endwhile + else + let mx = '<\([a-zA-Z][a-zA-Z0-9:_\-]*\)[^>]*>' + while 1 + let pos1 = searchpos(mx, 'W') + if pos1 == [0, 0] || pos1 == curpos[1:2] + let pos1 = searchpos('>\zs', 'W') + let pos2 = searchpos('.\ze<', 'W') + let block = [pos1, pos2] + if emmet#util#regionIsValid(block) + call emmet#util#selectRegion(block) + return + endif + endif + let content = matchstr(getline(pos1[0])[pos1[1]-1:], mx) + let tag_name = matchstr(content, '^<\zs[a-zA-Z0-9:_\-]*\ze') + if stridx(','.settings.html.empty_elements.',', ','.tag_name.',') != -1 + let pos2 = searchpos('>', 'nW') + else + let pos2 = searchpairpos('<' . tag_name . '[^>]*>', '', '</'. tag_name . '\zs>', 'nW') + endif + let block = [pos1, pos2] + if pos1 == [0, 0] + break + endif + if emmet#util#regionIsValid(block) + call emmet#util#selectRegion(block) + return + endif + endwhile + endif + call setpos('.', curpos) +endfunction + +function! emmet#lang#html#moveNextPrevItem(flag) abort + silent! exe "normal \<esc>" + let mx = '\%([0-9a-zA-Z-:]\+\%(="[^"]*"\|=''[^'']*''\|[^ ''">\]]*\)\{0,1}\)' + let pos = searchpos('\s'.mx.'\zs', '') + if pos != [0,0] + call feedkeys('v?\s\zs'.mx."\<cr>", '') + endif + return '' +endfunction + +function! emmet#lang#html#moveNextPrev(flag) abort + let pos = search('\%(</\w\+\)\@<!\zs><\/\|\(""\)\|^\(\s*\)$', a:flag ? 'Wpb' : 'Wp') + if pos == 3 + startinsert! + elseif pos != 0 + silent! normal! l + startinsert + endif + return '' +endfunction + +function! emmet#lang#html#splitJoinTag() abort + let curpos = emmet#util#getcurpos() + let mx = '<\(/\{0,1}[a-zA-Z][-a-zA-Z0-9:_\-]*\)\%(\%(\s[a-zA-Z][a-zA-Z0-9]\+=\%([^"'' \t]\+\|"[^"]\{-}"\|''[^'']\{-}''\)\s*\)*\)\s*\%(/\{0,1}\)>' + while 1 + let old = getpos('.')[1:2] + let pos1 = searchpos(mx, 'bcnW') + let content = matchstr(getline(pos1[0])[pos1[1]-1:], mx) + let tag_name = substitute(content, '^<\(/\{0,1}[a-zA-Z][a-zA-Z0-9:_\-]*\).*$', '\1', '') + let block = [pos1, [pos1[0], pos1[1] + len(content) - 1]] + if content[-2:] ==# '/>' && emmet#util#cursorInRegion(block) + let content = substitute(content[:-3], '\s*$', '', '') . '></' . tag_name . '>' + call emmet#util#setContent(block, content) + call setpos('.', [0, block[0][0], block[0][1], 0]) + return + endif + if tag_name[0] ==# '/' + let pos1 = searchpos('<' . tag_name[1:] . '[^a-zA-Z0-9]', 'bcnW') + call setpos('.', [0, pos1[0], pos1[1], 0]) + let pos2 = searchpairpos('<'. tag_name[1:] . '\>[^/>]*>', '', '</' . tag_name[1:] . '>', 'W') + else + let pos2 = searchpairpos('<'. tag_name . '[^/>]*>', '', '</' . tag_name . '>', 'W') + endif + if pos2 == [0, 0] + return + endif + let pos2 = searchpos('>', 'neW') + let block = [pos1, pos2] + if emmet#util#pointInRegion(curpos[1:2], block) + let content = matchstr(content, mx)[:-2] . ' />' + call emmet#util#setContent(block, content) + call setpos('.', [0, block[0][0], block[0][1], 0]) + return + endif + if block[0][0] > 0 + call setpos('.', [0, block[0][0]-1, block[0][1], 0]) + else + call setpos('.', curpos) + return + endif + if pos1 == old + call setpos('.', curpos) + return + endif + endwhile +endfunction + +function! emmet#lang#html#removeTag() abort + let curpos = emmet#util#getcurpos() + let mx = '<\(/\{0,1}[a-zA-Z][-a-zA-Z0-9:_\-]*\)\%(\%(\s[a-zA-Z][a-zA-Z0-9]\+=\%([^"'' \t]\+\|"[^"]\{-}"\|''[^'']\{-}''\)\s*\)*\)\s*\%(/\{0,1}\)>' + + let pos1 = searchpos(mx, 'bcnW') + let content = matchstr(getline(pos1[0])[pos1[1]-1:], mx) + let tag_name = substitute(content, '^<\(/\{0,1}[a-zA-Z][a-zA-Z0-9:_\-]*\).*$', '\1', '') + let block = [pos1, [pos1[0], pos1[1] + len(content) - 1]] + if content[-2:] ==# '/>' && emmet#util#cursorInRegion(block) + call emmet#util#setContent(block, '') + call setpos('.', [0, block[0][0], block[0][1], 0]) + return + endif + if tag_name[0] ==# '/' + let pos1 = searchpos('<' . tag_name[1:] . '[^a-zA-Z0-9]', 'bcnW') + call setpos('.', [0, pos1[0], pos1[1], 0]) + let pos2 = searchpairpos('<'. tag_name[1:] . '\>[^/>]*>', '', '</' . tag_name[1:] . '>', 'W') + else + let pos2 = searchpairpos('<'. tag_name . '[^/>]*>', '', '</' . tag_name . '>', 'W') + endif + if pos2 == [0, 0] + return + endif + let pos2 = searchpos('>', 'neW') + let block = [pos1, pos2] + if emmet#util#pointInRegion(curpos[1:2], block) + call emmet#util#setContent(block, '') + call setpos('.', [0, block[0][0], block[0][1], 0]) + return + endif + if block[0][0] > 0 + call setpos('.', [0, block[0][0]-1, block[0][1], 0]) + else + call setpos('.', curpos) + endif +endfunction + +function! emmet#lang#html#mergeLines() abort + let curpos = emmet#util#getcurpos() + let settings = emmet#getSettings() + + let mx = '<\([a-zA-Z][a-zA-Z0-9:_\-]*\)[^>]*>' + let last = curpos[1:2] + while 1 + let pos1 = searchpos(mx, 'bcW') + let content = matchstr(getline(pos1[0])[pos1[1]-1:], mx) + echomsg string(content) + let tag_name = matchstr(content, '^<\zs[a-zA-Z0-9:_\-]*\ze') + if stridx(','.settings.html.empty_elements.',', ','.tag_name.',') != -1 + let pos2 = searchpos('>', 'nW') + else + let pos2 = searchpairpos('<' . tag_name . '[^>]*>', '', '</'. tag_name . '\zs>', 'nW') + endif + if pos1 == [0, 0] || pos2 == [0, 0] + call setpos('.', curpos) + return + endif + let block = [pos1, pos2] + if emmet#util#pointInRegion(last, block) && emmet#util#regionIsValid(block) + break + endif + if pos1 == last + call setpos('.', curpos) + return + endif + let last = pos1 + endwhile + + let content = emmet#util#getContent(block) + let mx = '<\(/\{0,1}[a-zA-Z][-a-zA-Z0-9:_\-]*\)\%(\%(\s[a-zA-Z][a-zA-Z0-9]\+=\%([^"'' \t]\+\|"[^"]\{-}"\|''[^'']\{-}''\)\s*\)*\)\s*\%(/\{0,1}\)>' + let content = join(map(split(content, mx . '\zs\s*'), 'trim(v:val)'), '') + call emmet#util#setContent(block, content) + if block[0][0] > 0 + call setpos('.', [0, block[0][0], block[0][1], 0]) + else + call setpos('.', curpos) + endif +endfunction diff --git a/config/vim/autoload/emmet/lang/jade.vim b/config/vim/autoload/emmet/lang/jade.vim new file mode 100644 index 0000000..f59f22d --- /dev/null +++ b/config/vim/autoload/emmet/lang/jade.vim @@ -0,0 +1,335 @@ +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 + 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, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + let text = substitute(text, '\${nr}', "\n", 'g') + let text = substitute(text, '\\\$', '$', 'g') + let str = substitute(str, '\$#', text, 'g') + endif + let lines = split(text, "\n") + if len(lines) == 1 + let str .= ' ' . text + else + for line in lines + let str .= "\n" . indent . line . ' |' + endfor + endif + elseif len(current.child) == 0 + let str .= '${cursor}' + endif + if len(current.child) == 1 && len(current.child[0].name) == 0 + let text = current.child[0].value[1:-2] + if dollar_expr + let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + let text = substitute(text, '\${nr}', "\n", 'g') + let text = substitute(text, '\\\$', '$', 'g') + endif + let lines = split(text, "\n") + if len(lines) == 1 + let str .= ' ' . text + else + for line in lines + let str .= "\n" . indent . line . ' |' + endfor + endif + elseif len(current.child) > 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, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + let str = substitute(str, '\${nr}', "\n", 'g') + let str = substitute(str, '\\\$', '$', 'g') + endif + endif + let str .= "\n" + return str +endfunction + +function! emmet#lang#jade#imageSize() abort + let line = getline('.') + let current = emmet#lang#jade#parseTag(line) + if empty(current) || !has_key(current.attr, 'src') + return + endif + let fn = current.attr.src + if fn =~# '^\s*$' + return + elseif fn !~# '^\(/\|http\)' + let fn = simplify(expand('%:h') . '/' . fn) + endif + + let [width, height] = emmet#util#getImageSize(fn) + if width == -1 && height == -1 + return + endif + let current.attr.width = width + let current.attr.height = height + let current.attrs_order += ['width', 'height'] + let jade = emmet#toString(current, 'jade', 1) + let jade = substitute(jade, '\${cursor}', '', '') + call setline('.', substitute(matchstr(line, '^\s*') . jade, "\n", '', 'g')) +endfunction + +function! emmet#lang#jade#imageEncode() abort +endfunction + +function! emmet#lang#jade#parseTag(tag) abort + let current = emmet#newNode() + let mx = '%\([a-zA-Z][a-zA-Z0-9]*\)\s*\%({\(.*\)}\)' + let match = matchstr(a:tag, mx) + let current.name = substitute(match, mx, '\1', '') + let attrs = substitute(match, mx, '\2', '') + let mx = '\([a-zA-Z0-9]\+\)\s*=>\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 + +function! emmet#lang#jade#mergeLines() abort + " nothing to do +endfunction diff --git a/config/vim/autoload/emmet/lang/less.vim b/config/vim/autoload/emmet/lang/less.vim new file mode 100644 index 0000000..ae956c4 --- /dev/null +++ b/config/vim/autoload/emmet/lang/less.vim @@ -0,0 +1,51 @@ +function! emmet#lang#less#findTokens(str) abort + return emmet#lang#html#findTokens(a:str) +endfunction + +function! emmet#lang#less#parseIntoTree(abbr, type) abort + return emmet#lang#scss#parseIntoTree(a:abbr, a:type) +endfunction + +function! emmet#lang#less#toString(settings, current, type, inline, filters, itemno, indent) abort + return emmet#lang#scss#toString(a:settings, a:current, a:type, a:inline, a:filters, a:itemno, a:indent) +endfunction + +function! emmet#lang#less#imageSize() abort + call emmet#lang#css#imageSize() +endfunction + +function! emmet#lang#less#imageEncode() abort + return emmet#lang#css#imageEncode() +endfunction + +function! emmet#lang#less#parseTag(tag) abort + return emmet#lang#css#parseTag(a:tag) +endfunction + +function! emmet#lang#less#toggleComment() abort + call emmet#lang#css#toggleComment() +endfunction + +function! emmet#lang#less#balanceTag(flag) range abort + call emmet#lang#scss#balanceTag(a:flag) +endfunction + +function! emmet#lang#less#moveNextPrevItem(flag) abort + return emmet#lang#less#moveNextPrev(a:flag) +endfunction + +function! emmet#lang#less#moveNextPrev(flag) abort + call emmet#lang#scss#moveNextPrev(a:flag) +endfunction + +function! emmet#lang#less#splitJoinTag() abort + call emmet#lang#css#splitJoinTag() +endfunction + +function! emmet#lang#less#removeTag() abort + call emmet#lang#css#removeTag() +endfunction + +function! emmet#lang#less#mergeLines() abort + call emmet#lang#css#mergeLines() +endfunction diff --git a/config/vim/autoload/emmet/lang/sass.vim b/config/vim/autoload/emmet/lang/sass.vim new file mode 100644 index 0000000..3d3fd58 --- /dev/null +++ b/config/vim/autoload/emmet/lang/sass.vim @@ -0,0 +1,163 @@ +function! emmet#lang#sass#findTokens(str) abort + return emmet#lang#css#findTokens(a:str) +endfunction + +function! emmet#lang#sass#parseIntoTree(abbr, type) abort + return emmet#lang#css#parseIntoTree(a:abbr, a:type) +endfunction + +function! emmet#lang#sass#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 = a:indent + let str = '' + + let current_name = current.name + let current_name = substitute(current.name, '\$$', itemno+1, '') + if len(current.name) > 0 + let str .= current_name + let tmp = '' + for attr in keys(current.attr) + let val = current.attr[attr] + while val =~# '\$\([^#{]\|$\)' + let val = substitute(val, '\(\$\+\)\([^{]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + endwhile + let attr = substitute(attr, '\$$', itemno+1, '') + if attr ==# 'id' + let str .= '#' . val + elseif attr ==# 'class' + let str .= '.' . val + else + let tmp .= attr . ': ' . val + endif + endfor + if len(tmp) > 0 + let str .= "\n" + for line in split(tmp, "\n") + let str .= indent . line . "\n" + endfor + else + let str .= "\n" + endif + + let inner = '' + for child in current.child + let tmp = emmet#toString(child, type, inline, filters, itemno, indent) + let tmp = substitute(tmp, "\n", "\n" . escape(indent, '\'), 'g') + let tmp = substitute(tmp, "\n" . escape(indent, '\') . '$', '${cursor}\n', 'g') + let inner .= tmp + endfor + if len(inner) > 0 + let str .= indent . inner + endif + else + let text = emmet#lang#css#toString(settings, current, type, inline, filters, itemno, indent) + let text = substitute(text, '\s*;\ze\(\${[^}]\+}\)\?\(\n\|$\)', '', 'g') + return text + endif + return str +endfunction + +function! emmet#lang#sass#imageSize() abort +endfunction + +function! emmet#lang#sass#imageEncode() abort +endfunction + +function! emmet#lang#sass#parseTag(tag) abort +endfunction + +function! emmet#lang#sass#toggleComment() abort +endfunction + +function! emmet#lang#sass#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#sass#moveNextPrevItem(flag) abort + return emmet#lang#sass#moveNextPrev(a:flag) +endfunction + +function! emmet#lang#sass#moveNextPrev(flag) abort + let pos = search('""\|\(^\s*|\s*\zs\)', a:flag ? 'Wpb' : 'Wp') + if pos == 2 + startinsert! + elseif pos != 0 + silent! normal! l + startinsert + endif +endfunction + +function! emmet#lang#sass#splitJoinTag() abort +endfunction + +function! emmet#lang#sass#removeTag() abort +endfunction + +function! emmet#lang#sass#mergeLines() abort +endfunction diff --git a/config/vim/autoload/emmet/lang/scss.vim b/config/vim/autoload/emmet/lang/scss.vim new file mode 100644 index 0000000..ae35469 --- /dev/null +++ b/config/vim/autoload/emmet/lang/scss.vim @@ -0,0 +1,129 @@ +function! emmet#lang#scss#findTokens(str) abort + return emmet#lang#css#findTokens(a:str) +endfunction + +function! emmet#lang#scss#parseIntoTree(abbr, type) abort + if a:abbr =~# '>' + return emmet#lang#html#parseIntoTree(a:abbr, a:type) + else + return emmet#lang#css#parseIntoTree(a:abbr, a:type) + endif +endfunction + +function! emmet#lang#scss#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 = a:indent + let str = '' + + let current_name = substitute(current.name, '\$$', itemno+1, '') + if len(current.name) > 0 + let str .= current_name + let tmp = '' + for attr in keys(current.attr) + let val = current.attr[attr] + while val =~# '\$\([^#{]\|$\)' + let val = substitute(val, '\(\$\+\)\([^{]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + endwhile + let attr = substitute(attr, '\$$', itemno+1, '') + if attr ==# 'id' + let str .= '#' . val + elseif attr ==# 'class' + let str .= '.' . val + else + let tmp .= attr . ': ' . val . ';' + endif + endfor + if len(tmp) > 0 + let str .= " {\n" + for line in split(tmp, "\n") + let str .= indent . line . "\n" + endfor + else + let str .= " {\n" + endif + + let inner = '' + for child in current.child + let inner .= emmet#toString(child, type, inline, filters, itemno) + endfor + let inner = substitute(inner, "\n", "\n" . escape(indent, '\'), 'g') + let inner = substitute(inner, "\n" . escape(indent, '\') . '$', '', 'g') + let str .= indent . inner . "${cursor}\n}\n" + else + return emmet#lang#css#toString(settings, current, type, inline, filters, itemno, indent) + endif + return str +endfunction + +function! emmet#lang#scss#imageSize() abort + call emmet#lang#css#imageSize() +endfunction + +function! emmet#lang#scss#imageEncode() abort + return emmet#lang#css#imageEncode() +endfunction + +function! emmet#lang#scss#parseTag(tag) abort + return emmet#lang#css#parseTag(a:tag) +endfunction + +function! emmet#lang#scss#toggleComment() abort + call emmet#lang#css#toggleComment() +endfunction + +function! emmet#lang#scss#balanceTag(flag) range abort + if a:flag == -2 || a:flag == 2 + let curpos = [0, line("'<"), col("'<"), 0] + call setpos('.', curpos) + else + let curpos = emmet#util#getcurpos() + endif + if a:flag < 0 + let ret = searchpair('}', '', '.\zs{') + else + let ret = searchpair('{', '', '}', 'bW') + endif + if ret > 0 + let pos1 = emmet#util#getcurpos()[1:2] + if a:flag < 0 + let pos2 = searchpairpos('{', '', '}') + else + let pos2 = searchpairpos('{', '', '}') + endif + let block = [pos1, pos2] + if emmet#util#regionIsValid(block) + call emmet#util#selectRegion(block) + return + endif + endif + if a:flag == -2 || a:flag == 2 + silent! exe 'normal! gv' + else + call setpos('.', curpos) + endif +endfunction + +function! emmet#lang#scss#moveNextPrevItem(flag) abort + return emmet#lang#scss#moveNextPrev(a:flag) +endfunction + +function! emmet#lang#scss#moveNextPrev(flag) abort + call emmet#lang#css#moveNextPrev(a:flag) +endfunction + +function! emmet#lang#scss#splitJoinTag() abort + call emmet#lang#css#splitJoinTag() +endfunction + +function! emmet#lang#scss#removeTag() abort + call emmet#lang#css#removeTag() +endfunction + +function! emmet#lang#scss#mergeLines() abort + call emmet#lang#css#mergeLines() +endfunction diff --git a/config/vim/autoload/emmet/lang/slim.vim b/config/vim/autoload/emmet/lang/slim.vim new file mode 100644 index 0000000..c583c1c --- /dev/null +++ b/config/vim/autoload/emmet/lang/slim.vim @@ -0,0 +1,284 @@ +function! emmet#lang#slim#findTokens(str) abort + return emmet#lang#html#findTokens(a:str) +endfunction + +function! emmet#lang#slim#parseIntoTree(abbr, type) abort + return emmet#lang#html#parseIntoTree(a:abbr, a:type) +endfunction + +function! emmet#lang#slim#toString(settings, current, type, inline, filters, itemno, indent) abort + 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 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 + 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') + let str .= ' ' . attr . '=true' + else + if dollar_expr + while Val =~# '\$\([^#{]\|$\)' + let Val = substitute(Val, '\(\$\+\)\([^{]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + endwhile + endif + let attr = substitute(attr, '\$$', itemno+1, '') + let str .= ' ' . attr . '="' . Val . '"' + endif + endfor + + let inner = '' + if len(current.value) > 0 + let str .= "\n" + let text = current.value[1:-2] + if dollar_expr + let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + let text = substitute(text, '\${nr}', "\n", 'g') + let text = substitute(text, '\\\$', '$', 'g') + let str = substitute(str, '\$#', text, 'g') + endif + for line in split(text, "\n") + let str .= indent . '| ' . line . "\n" + endfor + elseif len(current.child) == 0 + let str .= '${cursor}' + endif + if len(current.child) == 1 && len(current.child[0].name) == 0 + let str .= "\n" + let text = current.child[0].value[1:-2] + if dollar_expr + let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + let text = substitute(text, '\${nr}', "\n", 'g') + let text = substitute(text, '\\\$', '$', 'g') + endif + for line in split(text, "\n") + let str .= indent . '| ' . line . "\n" + endfor + elseif len(current.child) > 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, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + let str = substitute(str, '\${nr}', "\n", 'g') + let str = substitute(str, '\\\$', '$', 'g') + endif + endif + if str !~# "\n$" + let str .= "\n" + endif + return str +endfunction + +function! emmet#lang#slim#imageSize() abort + let line = getline('.') + let current = emmet#lang#slim#parseTag(line) + if empty(current) || !has_key(current.attr, 'src') + return + endif + let fn = current.attr.src + if fn =~# '^\s*$' + return + elseif fn !~# '^\(/\|http\)' + let fn = simplify(expand('%:h') . '/' . fn) + endif + + let [width, height] = emmet#util#getImageSize(fn) + if width == -1 && height == -1 + return + endif + let current.attr.width = width + let current.attr.height = height + let current.attrs_order += ['width', 'height'] + let slim = emmet#toString(current, 'slim', 1) + let slim = substitute(slim, '\${cursor}', '', '') + call setline('.', substitute(matchstr(line, '^\s*') . slim, "\n", '', 'g')) +endfunction + +function! emmet#lang#slim#imageEncode() abort +endfunction + +function! emmet#lang#slim#parseTag(tag) abort + let current = emmet#newNode() + let mx = '\([a-zA-Z][a-zA-Z0-9]*\)\s\+\(.*\)' + let match = matchstr(a:tag, mx) + let current.name = substitute(match, mx, '\1', '') + let attrs = substitute(match, mx, '\2', '') + let mx = '\([a-zA-Z0-9]\+\)=\%(\([^"'' \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#slim#toggleComment() abort + let line = getline('.') + let space = matchstr(line, '^\s*') + if line =~# '^\s*/' + call setline('.', space . line[len(space)+1:]) + elseif line =~# '^\s*[a-z]' + call setline('.', space . '/' . line[len(space):]) + endif +endfunction + +function! emmet#lang#slim#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#slim#moveNextPrevItem(flag) abort + return emmet#lang#slim#moveNextPrev(a:flag) +endfunction + +function! emmet#lang#slim#moveNextPrev(flag) abort + let pos = search('""\|\(^\s*|\s*\zs\)', a:flag ? 'Wpb' : 'Wp') + if pos == 2 + startinsert! + elseif pos != 0 + silent! normal! l + startinsert + endif +endfunction + +function! emmet#lang#slim#splitJoinTag() abort + let n = line('.') + while n > 0 + if getline(n) =~# '^\s*\ze[a-z]' + let sn = n + let n += 1 + if getline(n) =~# '^\s*|' + while n <= line('$') + if getline(n) !~# '^\s*|' + break + endif + exe n 'delete' + endwhile + call setpos('.', [0, sn, 1, 0]) + else + let spaces = matchstr(getline(sn), '^\s*') + call append(sn, spaces . ' | ') + call setpos('.', [0, sn+1, 1, 0]) + startinsert! + endif + break + endif + let n -= 1 + endwhile +endfunction + +function! emmet#lang#slim#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 + +function! emmet#lang#slim#mergeLines() abort +endfunction |