diff options
| author | davidovski <david@davidovski.xyz> | 2021-10-09 22:20:41 +0100 | 
|---|---|---|
| committer | davidovski <david@davidovski.xyz> | 2021-10-09 22:20:41 +0100 | 
| commit | 01ced0b7ce47d279789efb2dc70d1cd009ac56ad (patch) | |
| tree | 6ece604b8ae3476d2d70c9c9d42f86fe607990da /config/vim/autoload/emmet | |
initial commit
Diffstat (limited to 'config/vim/autoload/emmet')
| -rw-r--r-- | config/vim/autoload/emmet/lang.vim | 52 | ||||
| -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 | ||||
| -rw-r--r-- | config/vim/autoload/emmet/lorem/en.vim | 65 | ||||
| -rw-r--r-- | config/vim/autoload/emmet/lorem/ja.vim | 27 | ||||
| -rw-r--r-- | config/vim/autoload/emmet/util.vim | 410 | 
13 files changed, 3515 insertions, 0 deletions
diff --git a/config/vim/autoload/emmet/lang.vim b/config/vim/autoload/emmet/lang.vim new file mode 100644 index 0000000..37e426b --- /dev/null +++ b/config/vim/autoload/emmet/lang.vim @@ -0,0 +1,52 @@ +let s:exists = {} +function! emmet#lang#exists(type) abort +  if len(a:type) == 0 +    return 0 +  elseif has_key(s:exists, a:type) +    return s:exists[a:type] +  endif +  let s:exists[a:type] = len(globpath(&rtp, 'autoload/emmet/lang/'.a:type.'.vim')) > 0 +  return s:exists[a:type] +endfunction + +function! emmet#lang#type(type) abort +  let type = a:type +  let base = type +  let settings = emmet#getSettings() +  while base != '' +    for b in split(base, '\.') +      if emmet#lang#exists(b) +        return b +      endif +      if has_key(settings, b) && has_key(settings[b], 'extends') +        let base = settings[b].extends +        break +      else +        let base = '' +      endif +    endfor +  endwhile +  return 'html' +endfunction + +" get all extends for a type recursively +function! emmet#lang#getExtends(type) abort +  let settings = emmet#getSettings() + +  if !has_key(settings[a:type], 'extends') +    return [] +  endif + +  let extends = settings[a:type].extends +  if type(extends) ==# 1 +    let tmp = split(extends, '\s*,\s*') +    unlet! extends +    let extends = tmp +  endif + +  for ext in extends +    let extends = extends + emmet#lang#getExtends(ext) +  endfor + +  return extends +endfunction 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 diff --git a/config/vim/autoload/emmet/lorem/en.vim b/config/vim/autoload/emmet/lorem/en.vim new file mode 100644 index 0000000..30713e4 --- /dev/null +++ b/config/vim/autoload/emmet/lorem/en.vim @@ -0,0 +1,65 @@ +function! emmet#lorem#en#expand(command) abort +  let wcount = matchstr(a:command, '\(\d*\)$') +  let wcount = wcount > 0 ? wcount : 30 +   +  let common = ['lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipisicing', 'elit'] +  let words = ['exercitationem', 'perferendis', 'perspiciatis', 'laborum', 'eveniet', +  \            'sunt', 'iure', 'nam', 'nobis', 'eum', 'cum', 'officiis', 'excepturi', +  \            'odio', 'consectetur', 'quasi', 'aut', 'quisquam', 'vel', 'eligendi', +  \            'itaque', 'non', 'odit', 'tempore', 'quaerat', 'dignissimos', +  \            'facilis', 'neque', 'nihil', 'expedita', 'vitae', 'vero', 'ipsum', +  \            'nisi', 'animi', 'cumque', 'pariatur', 'velit', 'modi', 'natus', +  \            'iusto', 'eaque', 'sequi', 'illo', 'sed', 'ex', 'et', 'voluptatibus', +  \            'tempora', 'veritatis', 'ratione', 'assumenda', 'incidunt', 'nostrum', +  \            'placeat', 'aliquid', 'fuga', 'provident', 'praesentium', 'rem', +  \            'necessitatibus', 'suscipit', 'adipisci', 'quidem', 'possimus', +  \            'voluptas', 'debitis', 'sint', 'accusantium', 'unde', 'sapiente', +  \            'voluptate', 'qui', 'aspernatur', 'laudantium', 'soluta', 'amet', +  \            'quo', 'aliquam', 'saepe', 'culpa', 'libero', 'ipsa', 'dicta', +  \            'reiciendis', 'nesciunt', 'doloribus', 'autem', 'impedit', 'minima', +  \            'maiores', 'repudiandae', 'ipsam', 'obcaecati', 'ullam', 'enim', +  \            'totam', 'delectus', 'ducimus', 'quis', 'voluptates', 'dolores', +  \            'molestiae', 'harum', 'dolorem', 'quia', 'voluptatem', 'molestias', +  \            'magni', 'distinctio', 'omnis', 'illum', 'dolorum', 'voluptatum', 'ea', +  \            'quas', 'quam', 'corporis', 'quae', 'blanditiis', 'atque', 'deserunt', +  \            'laboriosam', 'earum', 'consequuntur', 'hic', 'cupiditate', +  \            'quibusdam', 'accusamus', 'ut', 'rerum', 'error', 'minus', 'eius', +  \            'ab', 'ad', 'nemo', 'fugit', 'officia', 'at', 'in', 'id', 'quos', +  \            'reprehenderit', 'numquam', 'iste', 'fugiat', 'sit', 'inventore', +  \            'beatae', 'repellendus', 'magnam', 'recusandae', 'quod', 'explicabo', +  \            'doloremque', 'aperiam', 'consequatur', 'asperiores', 'commodi', +  \            'optio', 'dolor', 'labore', 'temporibus', 'repellat', 'veniam', +  \            'architecto', 'est', 'esse', 'mollitia', 'nulla', 'a', 'similique', +  \            'eos', 'alias', 'dolore', 'tenetur', 'deleniti', 'porro', 'facere', +  \            'maxime', 'corrupti'] +  let ret = [] +  let sentence = 0 +  for i in range(wcount) +    let arr = common +    if sentence > 0 +      let arr += words +    endif +    let r = emmet#util#rand() +    let word = arr[r % len(arr)] +    if sentence == 0 +      let word = substitute(word, '^.', '\U&', '') +    endif +    let sentence += 1 +    call add(ret, word) +    if (sentence > 5 && emmet#util#rand() < 10000) || i == wcount - 1 +      if i == wcount - 1 +        let endc = '?!...'[emmet#util#rand() % 5] +        call add(ret, endc) +      else +        let endc = '?!,...'[emmet#util#rand() % 6] +        call add(ret, endc . ' ') +      endif +      if endc !=# ',' +        let sentence = 0 +      endif +    else +      call add(ret, ' ') +    endif +  endfor +  return join(ret, '') +endfunction diff --git a/config/vim/autoload/emmet/lorem/ja.vim b/config/vim/autoload/emmet/lorem/ja.vim new file mode 100644 index 0000000..f99d8fa --- /dev/null +++ b/config/vim/autoload/emmet/lorem/ja.vim @@ -0,0 +1,27 @@ +scriptencoding utf-8 + +function! emmet#lorem#ja#expand(command) abort +  let wcount = matchstr(a:command, '^\%(lorem\|lipsum\)\(\d*\)}$', '\1', '') +  let wcount = wcount > 0 ? wcount : 30 + +  let url = "http://www.aozora.gr.jp/cards/000081/files/470_15407.html" +  let content = emmet#util#cache(url) +  if len(content) == 0 +    let content = emmet#util#getContentFromURL(url) +    let content = matchstr(content, '<div[^>]*>\zs.\{-}</div>') +    let content = substitute(content, '[ \r]', '', 'g') +    let content = substitute(content, '<br[^>]*>', "\n", 'g') +    let content = substitute(content, '<[^>]\+>', '', 'g') +    let content = join(filter(split(content, "\n"), 'len(v:val)>0'), "\n") +    call emmet#util#cache(url, content) +  endif +   +  let content = substitute(content, "、\n", "、", "g") +  let clines = split(content, '\n') +  let lines = filter(clines, 'len(substitute(v:val,".",".","g"))<=wcount') +  if len(lines) == 0 +    let lines = clines +  endif +  let r = emmet#util#rand() +  return lines[r % len(lines)] +endfunction diff --git a/config/vim/autoload/emmet/util.vim b/config/vim/autoload/emmet/util.vim new file mode 100644 index 0000000..78960c0 --- /dev/null +++ b/config/vim/autoload/emmet/util.vim @@ -0,0 +1,410 @@ +"============================================================================== +" region utils +"============================================================================== +" deleteContent : delete content in region +"   if region make from between '<foo>' and '</foo>' +"   -------------------- +"   begin:<foo> +"   </foo>:end +"   -------------------- +"   this function make the content as following +"   -------------------- +"   begin::end +"   -------------------- +function! emmet#util#deleteContent(region) abort +  let lines = getline(a:region[0][0], a:region[1][0]) +  call setpos('.', [0, a:region[0][0], a:region[0][1], 0]) +  silent! exe 'delete '.(a:region[1][0] - a:region[0][0]) +  call setline(line('.'), lines[0][:a:region[0][1]-2] . lines[-1][a:region[1][1]]) +endfunction + +" change_content : change content in region +"   if region make from between '<foo>' and '</foo>' +"   -------------------- +"   begin:<foo> +"   </foo>:end +"   -------------------- +"   and content is +"   -------------------- +"   foo +"   bar +"   baz +"   -------------------- +"   this function make the content as following +"   -------------------- +"   begin:foo +"   bar +"   baz:end +"   -------------------- +function! emmet#util#setContent(region, content) abort +  let newlines = split(a:content, '\n', 1) +  let oldlines = getline(a:region[0][0], a:region[1][0]) +  call setpos('.', [0, a:region[0][0], a:region[0][1], 0]) +  silent! exe 'delete '.(a:region[1][0] - a:region[0][0]) +  if len(newlines) == 0 +    let tmp = '' +    if a:region[0][1] > 1 +      let tmp = oldlines[0][:a:region[0][1]-2] +    endif +    if a:region[1][1] >= 1 +      let tmp .= oldlines[-1][a:region[1][1]:] +    endif +    call setline(line('.'), tmp) +  elseif len(newlines) == 1 +    if a:region[0][1] > 1 +      let newlines[0] = oldlines[0][:a:region[0][1]-2] . newlines[0] +    endif +    if a:region[1][1] >= 1 +      let newlines[0] .= oldlines[-1][a:region[1][1]:] +    endif +    call setline(line('.'), newlines[0]) +  else +    if a:region[0][1] > 1 +      let newlines[0] = oldlines[0][:a:region[0][1]-2] . newlines[0] +    endif +    if a:region[1][1] >= 1 +      let newlines[-1] .= oldlines[-1][a:region[1][1]:] +    endif +    call setline(line('.'), newlines[0]) +    call append(line('.'), newlines[1:]) +  endif +endfunction + +" select_region : select region +"   this function make a selection of region +function! emmet#util#selectRegion(region) abort +  call setpos('.', [0, a:region[1][0], a:region[1][1], 0]) +  normal! v +  call setpos('.', [0, a:region[0][0], a:region[0][1], 0]) +endfunction + +" point_in_region : check point is in the region +"   this function return 0 or 1 +function! emmet#util#pointInRegion(point, region) abort +  if !emmet#util#regionIsValid(a:region) | return 0 | endif +  if a:region[0][0] > a:point[0] | return 0 | endif +  if a:region[1][0] < a:point[0] | return 0 | endif +  if a:region[0][0] == a:point[0] && a:region[0][1] > a:point[1] | return 0 | endif +  if a:region[1][0] == a:point[0] && a:region[1][1] < a:point[1] | return 0 | endif +  return 1 +endfunction + +" cursor_in_region : check cursor is in the region +"   this function return 0 or 1 +function! emmet#util#cursorInRegion(region) abort +  if !emmet#util#regionIsValid(a:region) | return 0 | endif +  let cur = emmet#util#getcurpos()[1:2] +  return emmet#util#pointInRegion(cur, a:region) +endfunction + +" region_is_valid : check region is valid +"   this function return 0 or 1 +function! emmet#util#regionIsValid(region) abort +  if a:region[0][0] == 0 || a:region[1][0] == 0 | return 0 | endif +  return 1 +endfunction + +" search_region : make region from pattern which is composing start/end +"   this function return array of position +function! emmet#util#searchRegion(start, end) abort +  let b = searchpairpos(a:start, '', a:end, 'bcnW') +  if b == [0, 0] +    return [searchpairpos(a:start, '', a:end, 'bnW'), searchpairpos(a:start, '\%#', a:end, 'nW')] +  else +    return [b, searchpairpos(a:start, '', a:end. '', 'nW')] +  endif +endfunction + +" get_content : get content in region +"   this function return string in region +function! emmet#util#getContent(region) abort +  if !emmet#util#regionIsValid(a:region) +    return '' +  endif +  let lines = getline(a:region[0][0], a:region[1][0]) +  if a:region[0][0] == a:region[1][0] +    let lines[0] = lines[0][a:region[0][1]-1:a:region[1][1]-1] +  else +    let lines[0] = lines[0][a:region[0][1]-1:] +    let lines[-1] = lines[-1][:a:region[1][1]-1] +  endif +  return join(lines, "\n") +endfunction + +" region_in_region : check region is in the region +"   this function return 0 or 1 +function! emmet#util#regionInRegion(outer, inner) abort +  if !emmet#util#regionIsValid(a:inner) || !emmet#util#regionIsValid(a:outer) +    return 0 +  endif +  return emmet#util#pointInRegion(a:inner[0], a:outer) && emmet#util#pointInRegion(a:inner[1], a:outer) +endfunction + +" get_visualblock : get region of visual block +"   this function return region of visual block +function! emmet#util#getVisualBlock() abort +  return [[line("'<"), col("'<")], [line("'>"), col("'>")]] +endfunction + +"============================================================================== +" html utils +"============================================================================== +function! emmet#util#getContentFromURL(url) abort +  let res = system(printf('%s -i %s', g:emmet_curl_command, shellescape(substitute(a:url, '#.*', '', '')))) +  while res =~# '^HTTP/1.\d 3' || res =~# '^HTTP/1\.\d 200 Connection established' || res =~# '^HTTP/1\.\d 100 Continue' +    let pos = stridx(res, "\r\n\r\n") +    if pos != -1 +      let res = strpart(res, pos+4) +    else +      let pos = stridx(res, "\n\n") +      let res = strpart(res, pos+2) +    endif +  endwhile +  let pos = stridx(res, "\r\n\r\n") +  if pos != -1 +    let content = strpart(res, pos+4) +  else +    let pos = stridx(res, "\n\n") +    let content = strpart(res, pos+2) +  endif +  let header = res[:pos-1] +  let charset = matchstr(content, '<meta[^>]\+content=["''][^;"'']\+;\s*charset=\zs[^;"'']\+\ze["''][^>]*>') +  if len(charset) == 0 +    let charset = matchstr(content, '<meta\s\+charset=["'']\?\zs[^"'']\+\ze["'']\?[^>]*>') +  endif +  if len(charset) == 0 +    let charset = matchstr(header, '\nContent-Type:.* charset=[''"]\?\zs[^''";\n]\+\ze') +  endif +  if len(charset) == 0 +    let s1 = len(split(content, '?')) +    let utf8 = iconv(content, 'utf-8', &encoding) +    let s2 = len(split(utf8, '?')) +    return (s2 == s1 || s2 >= s1 * 2) ? utf8 : content +  endif +  return iconv(content, charset, &encoding) +endfunction + +function! emmet#util#getTextFromHTML(buf) abort +  let threshold_len = 100 +  let threshold_per = 0.1 +  let buf = a:buf + +  let buf = strpart(buf, stridx(buf, '</head>')) +  let buf = substitute(buf, '<style[^>]*>.\{-}</style>', '', 'g') +  let buf = substitute(buf, '<script[^>]*>.\{-}</script>', '', 'g') +  let res = '' +  let max = 0 +  let mx = '\(<td[^>]\{-}>\)\|\(<\/td>\)\|\(<div[^>]\{-}>\)\|\(<\/div>\)' +  let m = split(buf, mx) +  for str in m +    let c = split(str, '<[^>]*?>') +    let str = substitute(str, '<[^>]\{-}>', ' ', 'g') +    let str = substitute(str, '>', '>', 'g') +    let str = substitute(str, '<', '<', 'g') +    let str = substitute(str, '"', '"', 'g') +    let str = substitute(str, ''', '''', 'g') +    let str = substitute(str, ' ', ' ', 'g') +    let str = substitute(str, '¥', '\¥', 'g') +    let str = substitute(str, '&', '\&', 'g') +    let str = substitute(str, '^\s*\(.*\)\s*$', '\1', '') +    let str = substitute(str, '\s\+', ' ', 'g') +    let l = len(str) +    if l > threshold_len +      let per = (l+0.0) / len(c) +      if max < l && per > threshold_per +        let max = l +        let res = str +      endif +    endif +  endfor +  let res = substitute(res, '^\s*\(.*\)\s*$', '\1', 'g') +  return res +endfunction + +function! emmet#util#getImageSize(fn) abort +  let fn = a:fn + +  if emmet#util#isImageMagickInstalled() +    return emmet#util#imageSizeWithImageMagick(fn) +  endif + +  if filereadable(fn) +    let hex = substitute(system('xxd -p "'.fn.'"'), '\n', '', 'g') +  else +    if fn !~# '^\w\+://' +      let path = fnamemodify(expand('%'), ':p:gs?\\?/?') +      if has('win32') || has('win64') | +        let path = tolower(path) +      endif +      for k in keys(g:emmet_docroot) +        let root = fnamemodify(k, ':p:gs?\\?/?') +        if has('win32') || has('win64') | +          let root = tolower(root) +        endif +        if stridx(path, root) == 0 +          let v = g:emmet_docroot[k] +          let fn = (len(v) == 0 ? k : v) . fn +          break +        endif +      endfor +    endif +    let hex = substitute(system(g:emmet_curl_command.' "'.fn.'" | xxd -p'), '\n', '', 'g') +  endif + +  let [width, height] = [-1, -1] +  if hex =~# '^89504e470d0a1a0a' +    let width = eval('0x'.hex[32:39]) +    let height = eval('0x'.hex[40:47]) +  endif +  if hex =~# '^ffd8' +    let pos = 4 +    while pos < len(hex) +      let bs = hex[pos+0:pos+3] +      let pos += 4 +      if bs ==# 'ffc0' || bs ==# 'ffc2' +        let pos += 6 +        let height = eval('0x'.hex[pos+0:pos+1])*256 + eval('0x'.hex[pos+2:pos+3]) +        let pos += 4 +        let width = eval('0x'.hex[pos+0:pos+1])*256 + eval('0x'.hex[pos+2:pos+3]) +        break +      elseif bs =~# 'ffd[9a]' +        break +      elseif bs =~# 'ff\(e[0-9a-e]\|fe\|db\|dd\|c4\)' +        let pos += (eval('0x'.hex[pos+0:pos+1])*256 + eval('0x'.hex[pos+2:pos+3])) * 2 +      endif +    endwhile +  endif +  if hex =~# '^47494638' +    let width = eval('0x'.hex[14:15].hex[12:13]) +    let height = eval('0x'.hex[18:19].hex[16:17]) +  endif + +  return [width, height] +endfunction + +function! emmet#util#imageSizeWithImageMagick(fn) abort +  let img_info = system('identify -format "%wx%h" "'.a:fn.'"') +  let img_size = split(substitute(img_info, '\n', '', ''), 'x') +  if len(img_size) != 2 +    return [-1, -1] +  endif +  return img_size +endfunction + +function! emmet#util#isImageMagickInstalled() abort +  if !get(g:, 'emmet_use_identify', 1) +    return 0 +  endif +  return executable('identify') +endfunction + +function! s:b64encode(bytes, table, pad) +  let b64 = [] +  for i in range(0, len(a:bytes) - 1, 3) +    let n = a:bytes[i] * 0x10000 +          \ + get(a:bytes, i + 1, 0) * 0x100 +          \ + get(a:bytes, i + 2, 0) +    call add(b64, a:table[n / 0x40000]) +    call add(b64, a:table[n / 0x1000 % 0x40]) +    call add(b64, a:table[n / 0x40 % 0x40]) +    call add(b64, a:table[n % 0x40]) +  endfor +  if len(a:bytes) % 3 == 2 +    let b64[-1] = a:pad +  elseif len(a:bytes) % 3 == 1 +    let b64[-1] = a:pad +    let b64[-2] = a:pad +  endif +  return b64 +endfunction + +function! emmet#util#imageEncodeDecode(fn, flag) abort +  let fn = a:fn + +  if filereadable(fn) +    let hex = substitute(system('xxd -p "'.fn.'"'), '\n', '', 'g') +  else +    if fn !~# '^\w\+://' +      let path = fnamemodify(expand('%'), ':p:gs?\\?/?') +      if has('win32') || has('win64') | +        let path = tolower(path) +      endif +      for k in keys(g:emmet_docroot) +        let root = fnamemodify(k, ':p:gs?\\?/?') +        if has('win32') || has('win64') | +          let root = tolower(root) +        endif +        if stridx(path, root) == 0 +          let v = g:emmet_docroot[k] +          let fn = (len(v) == 0 ? k : v) . fn +          break +        endif +      endfor +    endif +    let hex = substitute(system(g:emmet_curl_command.' "'.fn.'" | xxd -p'), '\n', '', 'g') +  endif + +  let bin = map(split(hex, '..\zs'), 'eval("0x" . v:val)') +  let table = split('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', '\zs') +  let ret = 'data:image/' +  if hex =~# '^89504e470d0a1a0a' +    let ret .= 'png' +  elseif hex =~# '^ffd8' +    let ret .= 'jpeg' +  elseif hex =~# '^47494638' +    let ret .= 'gif' +  else +    let ret .= 'unknown' +  endif +  return ret . ';base64,' . join(s:b64encode(bin, table, '='), '') +endfunction + +function! emmet#util#unique(arr) abort +  let m = {} +  let r = [] +  for i in a:arr +    if !has_key(m, i) +      let m[i] = 1 +      call add(r, i) +    endif +  endfor +  return r +endfunction + +let s:seed = localtime() +function! emmet#util#srand(seed) abort +  let s:seed = a:seed +endfunction + +function! emmet#util#rand() abort +  let s:seed = s:seed * 214013 + 2531011 +  return (s:seed < 0 ? s:seed - 0x80000000 : s:seed) / 0x10000 % 0x8000 +endfunction + +function! emmet#util#cache(name, ...) abort +  let content = get(a:000, 0, '') +  let dir = expand('~/.emmet/cache') +  if !isdirectory(dir) +    call mkdir(dir, 'p', 0700) +  endif +  let file = dir . '/' . substitute(a:name, '\W', '_', 'g') +  if len(content) == 0 +    if !filereadable(file) +      return '' +    endif +	return join(readfile(file), "\n") +  endif +  call writefile(split(content, "\n"), file) +endfunction + +function! emmet#util#getcurpos() abort +  let pos = getpos('.') +  if mode(0) ==# 'i' && pos[2] > 0 +    let pos[2] -=1 +  endif +  return pos +endfunction + +function! emmet#util#closePopup() abort +  return pumvisible() ? "\<c-e>" : '' +endfunction  | 
