From 8e6f41fa0f57f4ac31e3037c24fc8741df9bbf6b Mon Sep 17 00:00:00 2001 From: Rick Date: Tue, 7 Jul 2020 11:28:09 +0200 Subject: [PATCH] Patch soucis fichiers --- README.md | 1 + autoload | 1 - autoload/airline/themes/codedark.vim | 120 + autoload/codedark | 1 + autoload/emmet.vim | 1886 ++++++++++++ autoload/emmet/lang.vim | 11 + autoload/emmet/lang/css.vim | 346 +++ autoload/emmet/lang/haml.vim | 335 +++ autoload/emmet/lang/html.vim | 857 ++++++ autoload/emmet/lang/jade.vim | 332 +++ autoload/emmet/lang/less.vim | 47 + autoload/emmet/lang/sass.vim | 160 ++ autoload/emmet/lang/scss.vim | 125 + autoload/emmet/lang/slim.vim | 281 ++ autoload/emmet/lorem/en.vim | 65 + autoload/emmet/lorem/ja.vim | 27 + autoload/emmet/util.vim | 349 +++ autoload/pathogen.vim | 264 ++ autoload/plug.vim | 2538 +++++++++++++++++ autoload/rainbow.vim | 128 + autoload/rainbow_main.vim | 132 + base16 | 1 - base16/schemes/codedark/codedark.yaml | 18 + .../templates/putty/putty/base16-codedark.reg | 72 + .../shell/scripts/base16-codedark.sh | 123 + bundle | 1 - bundle/vim-doge | 1 + colors | 1 - colors/codedark.vim | 358 +++ doc | 1 - doc/emmet.txt | 1745 ++++++++++++ macros | 1 - plugin | 1 - plugin/auto-pairs.vim | 673 +++++ plugin/emmet.vim | 177 ++ plugin/endwise.vim | 212 ++ plugin/ragtag.vim | 571 ++++ plugin/rainbow.vim | 163 ++ plugin/rainbow_main.vim | 12 + vimrc.bepo | 82 +- 40 files changed, 12211 insertions(+), 8 deletions(-) delete mode 120000 autoload create mode 100644 autoload/airline/themes/codedark.vim create mode 160000 autoload/codedark create mode 100644 autoload/emmet.vim create mode 100644 autoload/emmet/lang.vim create mode 100644 autoload/emmet/lang/css.vim create mode 100644 autoload/emmet/lang/haml.vim create mode 100644 autoload/emmet/lang/html.vim create mode 100644 autoload/emmet/lang/jade.vim create mode 100644 autoload/emmet/lang/less.vim create mode 100644 autoload/emmet/lang/sass.vim create mode 100644 autoload/emmet/lang/scss.vim create mode 100644 autoload/emmet/lang/slim.vim create mode 100644 autoload/emmet/lorem/en.vim create mode 100644 autoload/emmet/lorem/ja.vim create mode 100644 autoload/emmet/util.vim create mode 100644 autoload/pathogen.vim create mode 100644 autoload/plug.vim create mode 100644 autoload/rainbow.vim create mode 100644 autoload/rainbow_main.vim delete mode 120000 base16 create mode 100644 base16/schemes/codedark/codedark.yaml create mode 100644 base16/templates/putty/putty/base16-codedark.reg create mode 100644 base16/templates/shell/scripts/base16-codedark.sh delete mode 120000 bundle create mode 160000 bundle/vim-doge delete mode 120000 colors create mode 100644 colors/codedark.vim delete mode 120000 doc create mode 100644 doc/emmet.txt delete mode 120000 macros delete mode 120000 plugin create mode 100644 plugin/auto-pairs.vim create mode 100644 plugin/emmet.vim create mode 100644 plugin/endwise.vim create mode 100644 plugin/ragtag.vim create mode 100644 plugin/rainbow.vim create mode 100644 plugin/rainbow_main.vim mode change 120000 => 100644 vimrc.bepo diff --git a/README.md b/README.md index f3cbd38..6ac5d53 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,4 @@ Le fichier vimrc.bepo est une configuration spéciale pour les claviers bépo. V * Thème de couleurs : [vim-code-dark](https://github.com/tomasiser/vim-code-dark) * [Pathogen](https://github.com/tpope/vim-pathogen) * [Vim Doge](https://github.com/kkoomen/vim-doge) +* [Rainbow](https://github.com/luochen1990/rainbow) diff --git a/autoload b/autoload deleted file mode 120000 index 50f6d82..0000000 --- a/autoload +++ /dev/null @@ -1 +0,0 @@ -/home/rick/.vim/autoload \ No newline at end of file diff --git a/autoload/airline/themes/codedark.vim b/autoload/airline/themes/codedark.vim new file mode 100644 index 0000000..ec393d8 --- /dev/null +++ b/autoload/airline/themes/codedark.vim @@ -0,0 +1,120 @@ +" Vim Code Dark (airline theme) +" https://github.com/tomasiser/vim-code-dark + +scriptencoding utf-8 + +let g:airline#themes#codedark#palette = {} + +" Terminal colors (base16): +let s:cterm00 = "00" +let s:cterm03 = "08" +let s:cterm05 = "07" +let s:cterm07 = "15" +let s:cterm08 = "01" +let s:cterm0A = "03" +let s:cterm0B = "02" +let s:cterm0C = "06" +let s:cterm0D = "04" +let s:cterm0E = "05" +if exists('base16colorspace') && base16colorspace == "256" + let s:cterm01 = "18" + let s:cterm02 = "19" + let s:cterm04 = "20" + let s:cterm06 = "21" + let s:cterm09 = "16" + let s:cterm0F = "17" +else + let s:cterm01 = "00" + let s:cterm02 = "08" + let s:cterm04 = "07" + let s:cterm06 = "07" + let s:cterm09 = "06" + let s:cterm0F = "03" +endif + +if &t_Co >= 256 + let g:codedark_term256=1 +elseif !exists("g:codedark_term256") + let g:codedark_term256=0 +endif + +let s:cdFront = {'gui': '#FFFFFF', 'cterm': (g:codedark_term256 ? '15' : s:cterm07)} +let s:cdFrontGray = {'gui': '#D4D4D4', 'cterm': (g:codedark_term256 ? '188' : s:cterm05)} +let s:cdBack = {'gui': '#1E1E1E', 'cterm': (g:codedark_term256 ? '234' : s:cterm00)} +let s:cdSelection = {'gui': '#264F78', 'cterm': (g:codedark_term256 ? '24' : s:cterm01)} + +let s:cdBlue = {'gui': '#0A7ACA', 'cterm': (g:codedark_term256 ? '32' : s:cterm0D)} +let s:cdLightBlue = {'gui': '#5CB6F8', 'cterm': (g:codedark_term256 ? '75' : s:cterm0C)} +let s:cdYellow = {'gui': '#FFAF00', 'cterm': (g:codedark_term256 ? '214' : s:cterm0A)} +let s:cdRed = {'gui': '#F44747', 'cterm': (g:codedark_term256 ? '203' : s:cterm08)} + +let s:cdDarkDarkDark = {'gui': '#262626', 'cterm': (g:codedark_term256 ? '235' : s:cterm01)} +let s:cdDarkDark = {'gui': '#303030', 'cterm': (g:codedark_term256 ? '236' : s:cterm02)} +let s:cdDark = {'gui': '#3C3C3C', 'cterm': (g:codedark_term256 ? '237' : s:cterm03)} + +let s:Warning = [ s:cdRed.gui, s:cdDarkDark.gui, s:cdRed.cterm, s:cdDarkDark.cterm, 'none'] + +" Normal: + +let s:N1 = [ s:cdFront.gui, s:cdBlue.gui, s:cdFront.cterm, s:cdBlue.cterm, 'none' ] +let s:N2 = [ s:cdFront.gui, s:cdDarkDark.gui, s:cdFront.cterm, s:cdDarkDark.cterm, 'none' ] +let s:N3 = [ s:cdFront.gui, s:cdDarkDarkDark.gui, s:cdFront.cterm, s:cdDarkDarkDark.cterm, 'none' ] +let s:NM = [ s:cdFront.gui, s:cdDarkDarkDark.gui, s:cdFront.cterm, s:cdDarkDarkDark.cterm, 'none'] + +let g:airline#themes#codedark#palette.normal = airline#themes#generate_color_map(s:N1, s:N2, s:N3) +let g:airline#themes#codedark#palette.normal_modified = { 'airline_c': s:NM } +let g:airline#themes#codedark#palette.normal.airline_warning = s:Warning +let g:airline#themes#codedark#palette.normal_modified.airline_warning = s:Warning + +" Insert: + +let s:I1 = [ s:cdBack.gui, s:cdYellow.gui, s:cdBack.cterm, s:cdYellow.cterm, 'none' ] +let s:I2 = [ s:cdFront.gui, s:cdDarkDark.gui, s:cdFront.cterm, s:cdDarkDark.cterm, 'none' ] +let s:I3 = [ s:cdFront.gui, s:cdDarkDarkDark.gui, s:cdFront.cterm, s:cdDarkDarkDark.cterm, 'none' ] +let s:IM = [ s:cdFront.gui, s:cdDarkDarkDark.gui, s:cdFront.cterm, s:cdDarkDarkDark.cterm, 'none'] + +let g:airline#themes#codedark#palette.insert = airline#themes#generate_color_map(s:I1, s:I2, s:I3) +let g:airline#themes#codedark#palette.insert_modified = { 'airline_c': s:IM } +let g:airline#themes#codedark#palette.insert.airline_warning = s:Warning +let g:airline#themes#codedark#palette.insert_modified.airline_warning = s:Warning + +" Replace: + +let s:R1 = [ s:cdBack.gui, s:cdYellow.gui, s:cdBack.cterm, s:cdYellow.cterm, 'none' ] +let s:R2 = [ s:cdFront.gui, s:cdDarkDark.gui, s:cdFront.cterm, s:cdDarkDark.cterm, 'none' ] +let s:R3 = [ s:cdFront.gui, s:cdDarkDarkDark.gui, s:cdFront.cterm, s:cdDarkDarkDark.cterm, 'none' ] +let s:RM = [ s:cdFront.gui, s:cdDarkDarkDark.gui, s:cdFront.cterm, s:cdDarkDarkDark.cterm, 'none'] + +let g:airline#themes#codedark#palette.replace = airline#themes#generate_color_map(s:R1, s:R2, s:R3) +let g:airline#themes#codedark#palette.replace_modified = { 'airline_c': s:RM } +let g:airline#themes#codedark#palette.replace.airline_warning = s:Warning +let g:airline#themes#codedark#palette.replace_modified.airline_warning = s:Warning + +" Visual: + +let s:V1 = [ s:cdLightBlue.gui, s:cdDark.gui, s:cdLightBlue.cterm, s:cdDark.cterm, 'none' ] +let s:V2 = [ s:cdFront.gui, s:cdDarkDark.gui, s:cdFront.cterm, s:cdDarkDark.cterm, 'none' ] +let s:V3 = [ s:cdFront.gui, s:cdDarkDarkDark.gui, s:cdFront.cterm, s:cdDarkDarkDark.cterm, 'none' ] +let s:VM = [ s:cdFront.gui, s:cdDarkDarkDark.gui, s:cdFront.cterm, s:cdDarkDarkDark.cterm, 'none'] + +let g:airline#themes#codedark#palette.visual = airline#themes#generate_color_map(s:V1, s:V2, s:V3) +let g:airline#themes#codedark#palette.visual_modified = { 'airline_c': s:VM } +let g:airline#themes#codedark#palette.visual.airline_warning = s:Warning +let g:airline#themes#codedark#palette.visual_modified.airline_warning = s:Warning + +" Inactive: + +let s:IA1 = [ s:cdFrontGray.gui, s:cdDark.gui, s:cdFrontGray.cterm, s:cdDark.cterm, 'none' ] +let s:IA2 = [ s:cdFrontGray.gui, s:cdDarkDark.gui, s:cdFrontGray.cterm, s:cdDarkDark.cterm, 'none' ] +let s:IA3 = [ s:cdFrontGray.gui, s:cdDarkDarkDark.gui, s:cdFrontGray.cterm, s:cdDarkDarkDark.cterm, 'none' ] +let s:IAM = [ s:cdFrontGray.gui, s:cdDarkDarkDark.gui, s:cdFrontGray.cterm, s:cdDarkDarkDark.cterm, 'none' ] + +let g:airline#themes#codedark#palette.inactive = airline#themes#generate_color_map(s:IA1, s:IA2, s:IA3) +let g:airline#themes#codedark#palette.inactive_modified = { 'airline_c': s:IAM } + +" Red accent for readonly: + +let g:airline#themes#codedark#palette.accents = { + \ 'red': [ s:cdRed.gui, '', s:cdRed.cterm, '' ] + \ } + diff --git a/autoload/codedark b/autoload/codedark new file mode 160000 index 0000000..811fcff --- /dev/null +++ b/autoload/codedark @@ -0,0 +1 @@ +Subproject commit 811fcff1526f330e87f3d7663fe60588b22e5dd8 diff --git a/autoload/emmet.vim b/autoload/emmet.vim new file mode 100644 index 0000000..5723801 --- /dev/null +++ b/autoload/emmet.vim @@ -0,0 +1,1886 @@ +"============================================================================= +" emmet.vim +" Author: Yasuhiro Matsumoto +" Last Change: 26-Jul-2015. + +let s:save_cpo = &cpoptions +set cpoptions&vim + +let s:filtermx = '|\(\%(bem\|html\|haml\|slim\|e\|c\|s\|fc\|xsl\|t\|\/[^ ]\+\)\s*,\{0,1}\s*\)*$' + +function! emmet#getExpandos(type, key) abort + let expandos = emmet#getResource(a:type, 'expandos', {}) + if has_key(expandos, a:key) + return expandos[a:key] + endif + return a:key +endfunction + +function! emmet#splitFilterArg(filters) abort + for f in a:filters + if f =~# '^/' + return f[1:] + endif + endfor + return '' +endfunction + +function! emmet#useFilter(filters, filter) abort + for f in a:filters + if a:filter ==# '/' && f =~# '^/' + return 1 + elseif f ==# a:filter + return 1 + endif + endfor + return 0 +endfunction + +function! emmet#getIndentation(...) abort + if a:0 > 0 + let type = a:1 + else + let type = emmet#getFileType() + endif + if has_key(s:emmet_settings, type) && has_key(s:emmet_settings[type], 'indentation') + let indent = s:emmet_settings[type].indentation + elseif has_key(s:emmet_settings, 'indentation') + let indent = s:emmet_settings.indentation + elseif has_key(s:emmet_settings.variables, 'indentation') + let indent = s:emmet_settings.variables.indentation + else + let indent = (&l:expandtab || &l:tabstop !=# &l:shiftwidth) ? repeat(' ', &l:shiftwidth) : "\t" + endif + return indent +endfunction + +function! emmet#getBaseType(type) abort + if !has_key(s:emmet_settings, a:type) + return '' + endif + if !has_key(s:emmet_settings[a:type], 'extends') + return a:type + endif + let extends = s:emmet_settings[a:type].extends + if type(extends) ==# 1 + let tmp = split(extends, '\s*,\s*') + let ext = tmp[0] + else + let ext = extends[0] + endif + if a:type !=# ext + return emmet#getBaseType(ext) + endif + return '' +endfunction + +function! emmet#isExtends(type, extend) abort + if a:type ==# a:extend + return 1 + endif + if !has_key(s:emmet_settings, a:type) + return 0 + endif + if !has_key(s:emmet_settings[a:type], 'extends') + return 0 + endif + let extends = s:emmet_settings[a:type].extends + if type(extends) ==# 1 + let tmp = split(extends, '\s*,\s*') + unlet! extends + let extends = tmp + endif + for ext in extends + if a:extend ==# ext + return 1 + endif + endfor + return 0 +endfunction + +function! emmet#parseIntoTree(abbr, type) abort + let abbr = a:abbr + let type = a:type + let rtype = emmet#lang#exists(type) ? type : 'html' + return emmet#lang#{rtype}#parseIntoTree(abbr, type) +endfunction + +function! emmet#expandAbbrIntelligent(feedkey) abort + if !emmet#isExpandable() + return a:feedkey + endif + return "\(emmet-expand-abbr)" +endfunction + +function! emmet#isExpandable() abort + let line = getline('.') + if col('.') < len(line) + let line = matchstr(line, '^\(.*\%'.col('.').'c\)') + endif + let part = matchstr(line, '\(\S.*\)$') + let type = emmet#getFileType() + let ftype = emmet#lang#exists(type) ? type : 'html' + let part = emmet#lang#{ftype}#findTokens(part) + return len(part) > 0 +endfunction + +function! emmet#mergeConfig(lhs, rhs) abort + let [lhs, rhs] = [a:lhs, a:rhs] + if type(lhs) ==# 3 && type(rhs) ==# 3 + let lhs += rhs + if len(lhs) + call remove(lhs, 0, len(lhs)-1) + endif + for rhi in rhs + call add(lhs, rhs[rhi]) + endfor + elseif type(lhs) ==# 4 && type(rhs) ==# 4 + for key in keys(rhs) + if type(rhs[key]) ==# 3 + if !has_key(lhs, key) + let lhs[key] = [] + endif + let lhs[key] += rhs[key] + elseif type(rhs[key]) ==# 4 + if has_key(lhs, key) + call emmet#mergeConfig(lhs[key], rhs[key]) + else + let lhs[key] = rhs[key] + endif + else + let lhs[key] = rhs[key] + endif + endfor + endif +endfunction + +function! emmet#newNode() abort + return { 'name': '', 'attr': {}, 'child': [], 'snippet': '', 'basevalue': 0, 'basedirect': 1, 'multiplier': 1, 'parent': {}, 'value': '', 'pos': 0, 'important': 0, 'attrs_order': ['id', 'class'] } +endfunction + +function! s:itemno(itemno, current) abort + let current = a:current + if current.basedirect > 0 + if current.basevalue ==# 0 + return a:itemno + else + return current.basevalue - 1 + a:itemno + endif + else + if current.basevalue ==# 0 + return current.multiplier - 1 - a:itemno + else + return current.multiplier + current.basevalue - 2 - a:itemno + endif + endif +endfunction + +function! emmet#toString(...) abort + let current = a:1 + if a:0 > 1 + let type = a:2 + else + let type = &filetype + endif + if len(type) ==# 0 | let type = 'html' | endif + if a:0 > 2 + let inline = a:3 + else + let inline = 0 + endif + if a:0 > 3 + if type(a:4) ==# 1 + let filters = split(a:4, '\s*,\s*') + else + let filters = a:4 + endif + else + let filters = ['html'] + endif + if a:0 > 4 + let group_itemno = a:5 + else + let group_itemno = 0 + endif + if a:0 > 5 + let indent = a:6 + else + let indent = '' + endif + + let dollar_expr = emmet#getResource(type, 'dollar_expr', 1) + let itemno = 0 + let str = '' + let rtype = emmet#lang#exists(type) ? type : 'html' + while itemno < current.multiplier + if len(current.name) + if current.multiplier ==# 1 + let inner = emmet#lang#{rtype}#toString(s:emmet_settings, current, type, inline, filters, s:itemno(group_itemno, current), indent) + else + let inner = emmet#lang#{rtype}#toString(s:emmet_settings, current, type, inline, filters, s:itemno(itemno, current), indent) + endif + if current.multiplier > 1 + let inner = substitute(inner, '\$#', '$line'.(itemno+1).'$', 'g') + endif + let str .= inner + else + let snippet = current.snippet + if len(snippet) ==# 0 + let snippets = emmet#getResource(type, 'snippets', {}) + if !empty(snippets) && has_key(snippets, 'emmet_snippet') + let snippet = snippets['emmet_snippet'] + endif + endif + if len(snippet) > 0 + let tmp = snippet + let tmp = substitute(tmp, '\${emmet_name}', current.name, 'g') + let snippet_node = emmet#newNode() + let snippet_node.value = '{'.tmp.'}' + let snippet_node.important = current.important + let snippet_node.multiplier = current.multiplier + let str .= emmet#lang#{rtype}#toString(s:emmet_settings, snippet_node, type, inline, filters, s:itemno(group_itemno, current), indent) + if current.multiplier > 1 + let str .= "\n" + endif + else + if len(current.name) + let str .= current.name + endif + if len(current.value) + let text = current.value[1:-2] + if dollar_expr + " TODO: regexp engine specified + if exists('®expengine') + let text = substitute(text, '\%#=1\%(\\\)\@\ 0 + let key = get(matcharr, 1) + if key !~# '^\d\+:' + let key = substitute(key, '\\{', '{', 'g') + let key = substitute(key, '\\}', '}', 'g') + let value = emmet#getDollarValueByKey(key) + if type(value) ==# type('') + let expr = get(matcharr, 0) + call add(dollar_list, {'expr': expr, 'value': value}) + endif + endif + else + break + endif + let expand = substitute(expand, dollar_reg, '', '') + endwhile + return dollar_list +endfunction + +function! emmet#getDollarValueByKey(key) abort + let ret = 0 + let key = a:key + let ftsetting = get(s:emmet_settings, emmet#getFileType()) + if type(ftsetting) ==# 4 && has_key(ftsetting, key) + let V = get(ftsetting, key) + if type(V) ==# 1 | return V | endif + endif + if type(ret) !=# 1 && has_key(s:emmet_settings.variables, key) + let V = get(s:emmet_settings.variables, key) + if type(V) ==# 1 | return V | endif + endif + if has_key(s:emmet_settings, 'custom_expands') && type(s:emmet_settings['custom_expands']) ==# 4 + for k in keys(s:emmet_settings['custom_expands']) + if key =~# k + let V = get(s:emmet_settings['custom_expands'], k) + if type(V) ==# 1 | return V | endif + if type(V) ==# 2 | return V(key) | endif + endif + endfor + endif + return ret +endfunction + +function! emmet#reExpandDollarExpr(expand, times) abort + let expand = a:expand + let dollar_exprs = emmet#getDollarExprs(expand) + if len(dollar_exprs) > 0 + if a:times < 9 + for n in range(len(dollar_exprs)) + let pair = get(dollar_exprs, n) + let pat = get(pair, 'expr') + let sub = get(pair, 'value') + let expand = substitute(expand, pat, sub, '') + endfor + return emmet#reExpandDollarExpr(expand, a:times + 1) + endif + endif + return expand +endfunction + +function! emmet#expandDollarExpr(expand) abort + return emmet#reExpandDollarExpr(a:expand, 0) +endfunction + +function! emmet#expandCursorExpr(expand, mode) abort + let expand = a:expand + if expand !~# '\${cursor}' + if a:mode ==# 2 + let expand = '${cursor}' . expand + else + let expand .= '${cursor}' + endif + endif + let expand = substitute(expand, '\${\d\+:\?\([^}]\+\)}', '$select$$cursor$\1$select$', 'g') + let expand = substitute(expand, '\${\d\+}', '$select$$cursor$$select$', 'g') + let expand = substitute(expand, '\${cursor}', '$cursor$', '') + let expand = substitute(expand, '\${cursor}', '', 'g') + let expand = substitute(expand, '\${cursor}', '', 'g') + return expand +endfunction + +function! emmet#unescapeDollarExpr(expand) abort + return substitute(a:expand, '\\\$', '$', 'g') +endfunction + +function! emmet#expandAbbr(mode, abbr) range abort + let type = emmet#getFileType() + let rtype = emmet#getFileType(1) + let indent = emmet#getIndentation(type) + let expand = '' + let line = '' + let part = '' + let rest = '' + + let filters = emmet#getFilters(type) + if len(filters) ==# 0 + let filters = ['html'] + endif + + if a:mode ==# 2 + let leader = substitute(input('Tag: ', ''), '^\s*\(.*\)\s*$', '\1', 'g') + if len(leader) ==# 0 + return '' + endif + if leader =~# s:filtermx + let filters = map(split(matchstr(leader, s:filtermx)[1:], '\s*[^\\]\zs,\s*'), 'substitute(v:val, "\\\\\\\\zs.\\\\ze", "&", "g")') + let leader = substitute(leader, s:filtermx, '', '') + endif + if leader =~# '\*' + let query = substitute(leader, '*', '*' . (a:lastline - a:firstline + 1), '') + if query !~# '}\s*$' && query !~# '\$#' + let query .= '>{$#}' + endif + if emmet#useFilter(filters, '/') + let spl = emmet#splitFilterArg(filters) + let fline = getline(a:firstline) + let query = substitute(query, '>\{0,1}{\$#}\s*$', '{\\$column\\$}*' . len(split(fline, spl)), '') + else + let spl = '' + endif + let items = emmet#parseIntoTree(query, type).child + for item in items + let expand .= emmet#toString(item, rtype, 0, filters, 0, indent) + endfor + if emmet#useFilter(filters, 'e') + let expand = substitute(expand, '&', '\&', 'g') + let expand = substitute(expand, '<', '\<', 'g') + let expand = substitute(expand, '>', '\>', 'g') + endif + let line = getline(a:firstline) + let part = substitute(line, '^\s*', '', '') + for n in range(a:firstline, a:lastline) + let lline = getline(n) + let lpart = substitute(lline, '^\s\+', '', '') + if emmet#useFilter(filters, 't') + let lpart = substitute(lpart, '^[0-9.-]\+\s\+', '', '') + let lpart = substitute(lpart, '\s\+$', '', '') + endif + if emmet#useFilter(filters, '/') + for column in split(lpart, spl) + let expand = substitute(expand, '\$column\$', '\=column', '') + endfor + else + let expand = substitute(expand, '\$line'.(n-a:firstline+1).'\$', '\=lpart', 'g') + endif + endfor + let expand = substitute(expand, '\$line\d*\$', '', 'g') + let expand = substitute(expand, '\$column\$', '', 'g') + let content = join(getline(a:firstline, a:lastline), "\n") + if stridx(expand, '$#') < len(expand)-2 + let expand = substitute(expand, '^\(.*\)\$#\s*$', '\1', '') + endif + let expand = substitute(expand, '\$#', '\=content', 'g') + else + let str = '' + if visualmode() ==# 'V' + let line = getline(a:firstline) + let lspaces = matchstr(line, '^\s*', '', '') + let part = substitute(line, '^\s*', '', '') + for n in range(a:firstline, a:lastline) + if len(leader) > 0 + let line = getline(a:firstline) + let spaces = matchstr(line, '^\s*', '', '') + if len(spaces) >= len(lspaces) + let str .= indent . getline(n)[len(lspaces):] . "\n" + else + let str .= getline(n) . "\n" + endif + else + let lpart = substitute(getline(n), '^\s*', '', '') + let str .= lpart . "\n" + endif + endfor + if stridx(leader, '{$#}') ==# -1 + let leader .= '{$#}' + endif + let items = emmet#parseIntoTree(leader, type).child + else + let save_regcont = @" + let save_regtype = getregtype('"') + silent! normal! gvygv + let str = @" + call setreg('"', save_regcont, save_regtype) + if stridx(leader, '{$#}') ==# -1 + let leader .= '{$#}' + endif + let items = emmet#parseIntoTree(leader, type).child + endif + for item in items + let expand .= emmet#toString(item, rtype, 0, filters, 0, '') + endfor + if emmet#useFilter(filters, 'e') + let expand = substitute(expand, '&', '\&', 'g') + let expand = substitute(expand, '<', '\<', 'g') + let expand = substitute(expand, '>', '\>', 'g') + endif + if stridx(leader, '{$#}') !=# -1 + let expand = substitute(expand, '\$#', '\="\n" . str', 'g') + endif + endif + elseif a:mode ==# 4 + let line = getline('.') + let spaces = matchstr(line, '^\s*') + if line !~# '^\s*$' + put =spaces.a:abbr + else + call setline('.', spaces.a:abbr) + endif + normal! $ + call emmet#expandAbbr(0, '') + return '' + else + let line = getline('.') + if col('.') < len(line) + let line = matchstr(line, '^\(.*\%'.col('.').'c\)') + endif + if a:mode ==# 1 + let part = matchstr(line, '\([a-zA-Z0-9:_\-\@|]\+\)$') + else + let part = matchstr(line, '\(\S.*\)$') + let ftype = emmet#lang#exists(type) ? type : 'html' + let part = emmet#lang#{ftype}#findTokens(part) + let line = line[0: strridx(line, part) + len(part) - 1] + endif + if col('.') ==# col('$') + let rest = '' + else + let rest = getline('.')[len(line):] + endif + let str = part + if str =~# s:filtermx + let filters = split(matchstr(str, s:filtermx)[1:], '\s*,\s*') + let str = substitute(str, s:filtermx, '', '') + endif + let items = emmet#parseIntoTree(str, rtype).child + for item in items + let expand .= emmet#toString(item, rtype, 0, filters, 0, indent) + endfor + if emmet#useFilter(filters, 'e') + let expand = substitute(expand, '&', '\&', 'g') + let expand = substitute(expand, '<', '\<', 'g') + let expand = substitute(expand, '>', '\>', 'g') + endif + let expand = substitute(expand, '\$line\([0-9]\+\)\$', '\=submatch(1)', 'g') + endif + let expand = emmet#expandDollarExpr(expand) + let expand = emmet#expandCursorExpr(expand, a:mode) + if len(expand) + if has_key(s:emmet_settings, 'timezone') && len(s:emmet_settings.timezone) + let expand = substitute(expand, '${datetime}', strftime('%Y-%m-%dT%H:%M:%S') . s:emmet_settings.timezone, 'g') + else + " TODO: on windows, %z/%Z is 'Tokyo(Standard)' + let expand = substitute(expand, '${datetime}', strftime('%Y-%m-%dT%H:%M:%S %z'), 'g') + endif + let expand = emmet#unescapeDollarExpr(expand) + if a:mode ==# 2 && visualmode() ==# 'v' + if a:firstline ==# a:lastline + let expand = substitute(expand, '[\r\n]\s*', '', 'g') + else + let expand = substitute(expand, '[\n]$', '', 'g') + endif + silent! normal! gv + let col = col('''<') + silent! normal! c + let line = getline('.') + let lhs = matchstr(line, '.*\%<'.col.'c.') + let rhs = matchstr(line, '\%>'.(col-1).'c.*') + let expand = lhs.expand.rhs + let lines = split(expand, '\n') + call setline(line('.'), lines[0]) + if len(lines) > 1 + call append(line('.'), lines[1:]) + endif + else + if line[:-len(part)-1] =~# '^\s\+$' + let indent = line[:-len(part)-1] + else + let indent = '' + endif + let expand = substitute(expand, '[\r\n]\s*$', '', 'g') + if emmet#useFilter(filters, 's') + let epart = substitute(expand, '[\r\n]\s*', '', 'g') + else + let epart = substitute(expand, '[\r\n]', "\n" . indent, 'g') + endif + let expand = line[:-len(part)-1] . epart . rest + let lines = split(expand, '[\r\n]', 1) + if a:mode ==# 2 + silent! exe 'normal! gvc' + endif + call setline('.', lines[0]) + if len(lines) > 1 + call append('.', lines[1:]) + endif + endif + endif + if g:emmet_debug > 1 + call getchar() + endif + if search('\ze\$\(cursor\|select\)\$') + let oldselection = &selection + let &selection = 'inclusive' + if foldclosed(line('.')) !=# -1 + silent! foldopen + endif + let pos = emmet#util#getcurpos() + let use_selection = emmet#getResource(type, 'use_selection', 0) + if use_selection && getline('.')[col('.')-1:] =~# '^\$select' + let pos[2] += 1 + silent! s/\$select\$// + let next = searchpos('.\ze\$select\$', 'nW') + silent! %s/\$\(cursor\|select\)\$//g + call emmet#util#selectRegion([pos[1:2], next]) + return "\gv" + else + silent! %s/\$\(cursor\|select\)\$//g + silent! call setpos('.', pos) + if col('.') < col('$') + return "\" + endif + endif + let &selection = oldselection + endif + return '' +endfunction + +function! emmet#updateTag() abort + let type = emmet#getFileType() + let region = emmet#util#searchRegion('<\S', '>') + if !emmet#util#regionIsValid(region) || !emmet#util#cursorInRegion(region) + return '' + endif + let content = emmet#util#getContent(region) + let content = matchstr(content, '^<[^><]\+>') + if content !~# '^<[^><]\+>$' + return '' + endif + let current = emmet#lang#html#parseTag(content) + if empty(current) + return '' + endif + + let str = substitute(input('Enter Abbreviation: ', ''), '^\s*\(.*\)\s*$', '\1', 'g') + let item = emmet#parseIntoTree(str, type).child[0] + for k in keys(item.attr) + let current.attr[k] = item.attr[k] + endfor + let html = substitute(emmet#toString(current, 'html', 1), '\n', '', '') + let html = substitute(html, '\${cursor}', '', '') + let html = matchstr(html, '^<[^><]\+>') + call emmet#util#setContent(region, html) + return '' +endfunction + +function! emmet#moveNextPrevItem(flag) abort + let type = emmet#getFileType() + let rtype = emmet#lang#exists(type) ? type : 'html' + return emmet#lang#{rtype}#moveNextPrevItem(a:flag) +endfunction + +function! emmet#moveNextPrev(flag) abort + let type = emmet#getFileType() + let rtype = emmet#lang#exists(type) ? type : 'html' + return emmet#lang#{rtype}#moveNextPrev(a:flag) +endfunction + +function! emmet#imageSize() abort + let orgpos = emmet#util#getcurpos() + let type = emmet#getFileType() + let rtype = emmet#lang#exists(type) ? type : 'html' + call emmet#lang#{rtype}#imageSize() + silent! call setpos('.', orgpos) + return '' +endfunction + +function! emmet#encodeImage() abort + let type = emmet#getFileType() + let rtype = emmet#lang#exists(type) ? type : 'html' + return emmet#lang#{rtype}#encodeImage() +endfunction + +function! emmet#toggleComment() abort + let type = emmet#getFileType() + let rtype = emmet#lang#exists(type) ? type : 'html' + call emmet#lang#{rtype}#toggleComment() + return '' +endfunction + +function! emmet#balanceTag(flag) range abort + let type = emmet#getFileType() + let rtype = emmet#lang#exists(type) ? type : 'html' + return emmet#lang#{rtype}#balanceTag(a:flag) +endfunction + +function! emmet#splitJoinTag() abort + let type = emmet#getFileType() + let rtype = emmet#lang#exists(type) ? type : 'html' + return emmet#lang#{rtype}#splitJoinTag() +endfunction + +function! emmet#mergeLines() range abort + let lines = join(map(getline(a:firstline, a:lastline), 'matchstr(v:val, "^\\s*\\zs.*\\ze\\s*$")'), '') + let indent = substitute(getline('.'), '^\(\s*\).*', '\1', '') + silent! exe 'normal! gvc' + call setline('.', indent . lines) +endfunction + +function! emmet#removeTag() abort + let type = emmet#getFileType() + let rtype = emmet#lang#exists(type) ? type : 'html' + call emmet#lang#{rtype}#removeTag() + return '' +endfunction + +function! emmet#anchorizeURL(flag) abort + let mx = 'https\=:\/\/[-!#$%&*+,./:;=?@0-9a-zA-Z_~]\+' + let pos1 = searchpos(mx, 'bcnW') + let url = matchstr(getline(pos1[0])[pos1[1]-1:], mx) + let block = [pos1, [pos1[0], pos1[1] + len(url) - 1]] + if !emmet#util#cursorInRegion(block) + return '' + endif + + let mx = '.*]*>\s*\zs\([^<]\+\)\ze\s*<\/title[^>]*>.*' + let content = emmet#util#getContentFromURL(url) + let content = substitute(content, '\r', '', 'g') + let content = substitute(content, '[ \n]\+', ' ', 'g') + let content = substitute(content, '', '', 'g') + let title = matchstr(content, mx) + + let type = emmet#getFileType() + let rtype = emmet#lang#exists(type) ? type : 'html' + if &filetype ==# 'markdown' + let expand = printf('[%s](%s)', substitute(title, '[\[\]]', '\\&', 'g'), url) + elseif a:flag ==# 0 + let a = emmet#lang#html#parseTag('') + let a.attr.href = url + let a.value = '{' . title . '}' + let expand = emmet#toString(a, rtype, 0, []) + let expand = substitute(expand, '\${cursor}', '', 'g') + else + let body = emmet#util#getTextFromHTML(content) + let body = '{' . substitute(body, '^\(.\{0,100}\).*', '\1', '') . '...}' + + let blockquote = emmet#lang#html#parseTag('
') + let a = emmet#lang#html#parseTag('') + let a.attr.href = url + let a.value = '{' . title . '}' + call add(blockquote.child, a) + call add(blockquote.child, emmet#lang#html#parseTag('
')) + let p = emmet#lang#html#parseTag('

') + let p.value = body + call add(blockquote.child, p) + let cite = emmet#lang#html#parseTag('') + let cite.value = '{' . url . '}' + call add(blockquote.child, cite) + let expand = emmet#toString(blockquote, rtype, 0, []) + let expand = substitute(expand, '\${cursor}', '', 'g') + endif + let indent = substitute(getline('.'), '^\(\s*\).*', '\1', '') + let expand = substitute(expand, "\n", "\n" . indent, 'g') + call emmet#util#setContent(block, expand) + return '' +endfunction + +function! emmet#codePretty() range abort + let type = input('FileType: ', &filetype, 'filetype') + if len(type) ==# 0 + return + endif + let block = emmet#util#getVisualBlock() + let content = emmet#util#getContent(block) + silent! 1new + let &l:filetype = type + call setline(1, split(content, "\n")) + let old_lazyredraw = &lazyredraw + set lazyredraw + silent! TOhtml + let &lazyredraw = old_lazyredraw + let content = join(getline(1, '$'), "\n") + silent! bw! + silent! bw! + let content = matchstr(content, ']*>[\s\n]*\zs.*\ze') + call emmet#util#setContent(block, content) +endfunction + +function! emmet#expandWord(abbr, type, orig) abort + let str = a:abbr + let type = a:type + let indent = emmet#getIndentation(type) + + if len(type) ==# 0 | let type = 'html' | endif + if str =~# s:filtermx + let filters = split(matchstr(str, s:filtermx)[1:], '\s*,\s*') + let str = substitute(str, s:filtermx, '', '') + else + let filters = emmet#getFilters(a:type) + if len(filters) ==# 0 + let filters = ['html'] + endif + endif + let str = substitute(str, '|', '${cursor}', 'g') + let items = emmet#parseIntoTree(str, a:type).child + let expand = '' + for item in items + let expand .= emmet#toString(item, a:type, 0, filters, 0, indent) + endfor + if emmet#useFilter(filters, 'e') + let expand = substitute(expand, '&', '\&', 'g') + let expand = substitute(expand, '<', '\<', 'g') + let expand = substitute(expand, '>', '\>', 'g') + endif + if emmet#useFilter(filters, 's') + let expand = substitute(expand, "\n\s\*", '', 'g') + endif + if a:orig ==# 0 + let expand = emmet#expandDollarExpr(expand) + let expand = substitute(expand, '\${cursor}', '', 'g') + endif + return expand +endfunction + +function! emmet#getSnippets(type) abort + let type = a:type + if len(type) ==# 0 || !has_key(s:emmet_settings, type) + let type = 'html' + endif + return emmet#getResource(type, 'snippets', {}) +endfunction + +function! emmet#completeTag(findstart, base) abort + if a:findstart + let line = getline('.') + let start = col('.') - 1 + while start > 0 && line[start - 1] =~# '[a-zA-Z0-9:_\@\-]' + let start -= 1 + endwhile + return start + else + let type = emmet#getFileType() + let res = [] + + let snippets = emmet#getResource(type, 'snippets', {}) + for item in keys(snippets) + if stridx(item, a:base) !=# -1 + call add(res, substitute(item, '\${cursor}\||', '', 'g')) + endif + endfor + let aliases = emmet#getResource(type, 'aliases', {}) + for item in values(aliases) + if stridx(item, a:base) !=# -1 + call add(res, substitute(item, '\${cursor}\||', '', 'g')) + endif + endfor + return res + endif +endfunction + +unlet! s:emmet_settings +let s:emmet_settings = { +\ 'variables': { +\ 'lang': "en", +\ 'locale': "en-US", +\ 'charset': "UTF-8", +\ 'newline': "\n", +\ 'use_selection': 0, +\ }, +\ 'custom_expands' : { +\ '^\%(lorem\|lipsum\)\(\d*\)$' : function('emmet#lorem#en#expand'), +\ }, +\ 'css': { +\ 'snippets': { +\ "@i": "@import url(|);", +\ "@import": "@import url(|);", +\ "@m": "@media ${1:screen} {\n\t|\n}", +\ "@media": "@media ${1:screen} {\n\t|\n}", +\ "@f": "@font-face {\n\tfont-family:|;\n\tsrc:url(|);\n}", +\ "@f+": "@font-face {\n\tfont-family: '${1:FontName}';\n\tsrc: url('${2:FileName}.eot');\n\tsrc: url('${2:FileName}.eot?#iefix') format('embedded-opentype'),\n\t\t url('${2:FileName}.woff') format('woff'),\n\t\t url('${2:FileName}.ttf') format('truetype'),\n\t\t url('${2:FileName}.svg#${1:FontName}') format('svg');\n\tfont-style: ${3:normal};\n\tfont-weight: ${4:normal};\n}", +\ "@kf": "@-webkit-keyframes ${1:identifier} {\n\t${2:from} { ${3} }${6}\n\t${4:to} { ${5} }\n}\n@-o-keyframes ${1:identifier} {\n\t${2:from} { ${3} }${6}\n\t${4:to} { ${5} }\n}\n@-moz-keyframes ${1:identifier} {\n\t${2:from} { ${3} }${6}\n\t${4:to} { ${5} }\n}\n@keyframes ${1:identifier} {\n\t${2:from} { ${3} }${6}\n\t${4:to} { ${5} }\n}", +\ "anim": "animation:|;", +\ "anim-": "animation:${1:name} ${2:duration} ${3:timing-function} ${4:delay} ${5:iteration-count} ${6:direction} ${7:fill-mode};", +\ "animdel": "animation-delay:${1:time};", +\ "animdir": "animation-direction:${1:normal};", +\ "animdir:n": "animation-direction:normal;", +\ "animdir:r": "animation-direction:reverse;", +\ "animdir:a": "animation-direction:alternate;", +\ "animdir:ar": "animation-direction:alternate-reverse;", +\ "animdur": "animation-duration:${1:0}s;", +\ "animfm": "animation-fill-mode:${1:both};", +\ "animfm:f": "animation-fill-mode:forwards;", +\ "animfm:b": "animation-fill-mode:backwards;", +\ "animfm:bt": "animation-fill-mode:both;", +\ "animfm:bh": "animation-fill-mode:both;", +\ "animic": "animation-iteration-count:${1:1};", +\ "animic:i": "animation-iteration-count:infinite;", +\ "animn": "animation-name:${1:none};", +\ "animps": "animation-play-state:${1:running};", +\ "animps:p": "animation-play-state:paused;", +\ "animps:r": "animation-play-state:running;", +\ "animtf": "animation-timing-function:${1:linear};", +\ "animtf:e": "animation-timing-function:ease;", +\ "animtf:ei": "animation-timing-function:ease-in;", +\ "animtf:eo": "animation-timing-function:ease-out;", +\ "animtf:eio": "animation-timing-function:ease-in-out;", +\ "animtf:l": "animation-timing-function:linear;", +\ "animtf:cb": "animation-timing-function:cubic-bezier(${1:0.1}, ${2:0.7}, ${3:1.0}, ${3:0.1});", +\ "ap": "appearance:${none};", +\ "!": "!important", +\ "pos": "position:${1:relative};", +\ "pos:s": "position:static;", +\ "pos:a": "position:absolute;", +\ "pos:r": "position:relative;", +\ "pos:f": "position:fixed;", +\ "t": "top:|;", +\ "t:a": "top:auto;", +\ "r": "right:|;", +\ "r:a": "right:auto;", +\ "b": "bottom:|;", +\ "b:a": "bottom:auto;", +\ "l": "left:|;", +\ "l:a": "left:auto;", +\ "z": "z-index:|;", +\ "z:a": "z-index:auto;", +\ "fl": "float:${1:left};", +\ "fl:n": "float:none;", +\ "fl:l": "float:left;", +\ "fl:r": "float:right;", +\ "cl": "clear:${1:both};", +\ "cl:n": "clear:none;", +\ "cl:l": "clear:left;", +\ "cl:r": "clear:right;", +\ "cl:b": "clear:both;", +\ "colm": "columns:|;", +\ "colmc": "column-count:|;", +\ "colmf": "column-fill:|;", +\ "colmg": "column-gap:|;", +\ "colmr": "column-rule:|;", +\ "colmrc": "column-rule-color:|;", +\ "colmrs": "column-rule-style:|;", +\ "colmrw": "column-rule-width:|;", +\ "colms": "column-span:|;", +\ "colmw": "column-width:|;", +\ "d": "display:${1:block};", +\ "d:n": "display:none;", +\ "d:b": "display:block;", +\ "d:f": "display:flex;", +\ "d:i": "display:inline;", +\ "d:ib": "display:inline-block;", +\ "d:ib+": "display: inline-block;\n*display: inline;\n*zoom: 1;", +\ "d:li": "display:list-item;", +\ "d:ri": "display:run-in;", +\ "d:cp": "display:compact;", +\ "d:tb": "display:table;", +\ "d:itb": "display:inline-table;", +\ "d:tbcp": "display:table-caption;", +\ "d:tbcl": "display:table-column;", +\ "d:tbclg": "display:table-column-group;", +\ "d:tbhg": "display:table-header-group;", +\ "d:tbfg": "display:table-footer-group;", +\ "d:tbr": "display:table-row;", +\ "d:tbrg": "display:table-row-group;", +\ "d:tbc": "display:table-cell;", +\ "d:rb": "display:ruby;", +\ "d:rbb": "display:ruby-base;", +\ "d:rbbg": "display:ruby-base-group;", +\ "d:rbt": "display:ruby-text;", +\ "d:rbtg": "display:ruby-text-group;", +\ "v": "visibility:${1:hidden};", +\ "v:v": "visibility:visible;", +\ "v:h": "visibility:hidden;", +\ "v:c": "visibility:collapse;", +\ "ov": "overflow:${1:hidden};", +\ "ov:v": "overflow:visible;", +\ "ov:h": "overflow:hidden;", +\ "ov:s": "overflow:scroll;", +\ "ov:a": "overflow:auto;", +\ "ovx": "overflow-x:${1:hidden};", +\ "ovx:v": "overflow-x:visible;", +\ "ovx:h": "overflow-x:hidden;", +\ "ovx:s": "overflow-x:scroll;", +\ "ovx:a": "overflow-x:auto;", +\ "ovy": "overflow-y:${1:hidden};", +\ "ovy:v": "overflow-y:visible;", +\ "ovy:h": "overflow-y:hidden;", +\ "ovy:s": "overflow-y:scroll;", +\ "ovy:a": "overflow-y:auto;", +\ "ovs": "overflow-style:${1:scrollbar};", +\ "ovs:a": "overflow-style:auto;", +\ "ovs:s": "overflow-style:scrollbar;", +\ "ovs:p": "overflow-style:panner;", +\ "ovs:m": "overflow-style:move;", +\ "ovs:mq": "overflow-style:marquee;", +\ "zoo": "zoom:1;", +\ "zm": "zoom:1;", +\ "cp": "clip:|;", +\ "cp:a": "clip:auto;", +\ "cp:r": "clip:rect(${1:top} ${2:right} ${3:bottom} ${4:left});", +\ "bxz": "box-sizing:${1:border-box};", +\ "bxz:cb": "box-sizing:content-box;", +\ "bxz:bb": "box-sizing:border-box;", +\ "bxsh": "box-shadow:${1:inset }${2:hoff} ${3:voff} ${4:blur} ${5:color};", +\ "bxsh:r": "box-shadow:${1:inset }${2:hoff} ${3:voff} ${4:blur} ${5:spread }rgb(${6:0}, ${7:0}, ${8:0});", +\ "bxsh:ra": "box-shadow:${1:inset }${2:h} ${3:v} ${4:blur} ${5:spread }rgba(${6:0}, ${7:0}, ${8:0}, .${9:5});", +\ "bxsh:n": "box-shadow:none;", +\ "m": "margin:|;", +\ "m:a": "margin:auto;", +\ "mt": "margin-top:|;", +\ "mt:a": "margin-top:auto;", +\ "mr": "margin-right:|;", +\ "mr:a": "margin-right:auto;", +\ "mb": "margin-bottom:|;", +\ "mb:a": "margin-bottom:auto;", +\ "ml": "margin-left:|;", +\ "ml:a": "margin-left:auto;", +\ "p": "padding:|;", +\ "pt": "padding-top:|;", +\ "pr": "padding-right:|;", +\ "pb": "padding-bottom:|;", +\ "pl": "padding-left:|;", +\ "w": "width:|;", +\ "w:a": "width:auto;", +\ "h": "height:|;", +\ "h:a": "height:auto;", +\ "maw": "max-width:|;", +\ "maw:n": "max-width:none;", +\ "mah": "max-height:|;", +\ "mah:n": "max-height:none;", +\ "miw": "min-width:|;", +\ "mih": "min-height:|;", +\ "mar": "max-resolution:${1:res};", +\ "mir": "min-resolution:${1:res};", +\ "ori": "orientation:|;", +\ "ori:l": "orientation:landscape;", +\ "ori:p": "orientation:portrait;", +\ "ol": "outline:|;", +\ "ol:n": "outline:none;", +\ "olo": "outline-offset:|;", +\ "olw": "outline-width:|;", +\ "olw:tn": "outline-width:thin;", +\ "olw:m": "outline-width:medium;", +\ "olw:tc": "outline-width:thick;", +\ "ols": "outline-style:|;", +\ "ols:n": "outline-style:none;", +\ "ols:dt": "outline-style:dotted;", +\ "ols:ds": "outline-style:dashed;", +\ "ols:s": "outline-style:solid;", +\ "ols:db": "outline-style:double;", +\ "ols:g": "outline-style:groove;", +\ "ols:r": "outline-style:ridge;", +\ "ols:i": "outline-style:inset;", +\ "ols:o": "outline-style:outset;", +\ "olc": "outline-color:#${1:000};", +\ "olc:i": "outline-color:invert;", +\ "bfv": "backface-visibility:|;", +\ "bfv:h": "backface-visibility:hidden;", +\ "bfv:v": "backface-visibility:visible;", +\ "bd": "border:|;", +\ "bd+": "border:${1:1px} ${2:solid} ${3:#000};", +\ "bd:n": "border:none;", +\ "bdbk": "border-break:${1:close};", +\ "bdbk:c": "border-break:close;", +\ "bdcl": "border-collapse:|;", +\ "bdcl:c": "border-collapse:collapse;", +\ "bdcl:s": "border-collapse:separate;", +\ "bdc": "border-color:#${1:000};", +\ "bdc:t": "border-color:transparent;", +\ "bdi": "border-image:url(|);", +\ "bdi:n": "border-image:none;", +\ "bdti": "border-top-image:url(|);", +\ "bdti:n": "border-top-image:none;", +\ "bdri": "border-right-image:url(|);", +\ "bdri:n": "border-right-image:none;", +\ "bdbi": "border-bottom-image:url(|);", +\ "bdbi:n": "border-bottom-image:none;", +\ "bdli": "border-left-image:url(|);", +\ "bdli:n": "border-left-image:none;", +\ "bdci": "border-corner-image:url(|);", +\ "bdci:n": "border-corner-image:none;", +\ "bdci:c": "border-corner-image:continue;", +\ "bdtli": "border-top-left-image:url(|);", +\ "bdtli:n": "border-top-left-image:none;", +\ "bdtli:c": "border-top-left-image:continue;", +\ "bdtri": "border-top-right-image:url(|);", +\ "bdtri:n": "border-top-right-image:none;", +\ "bdtri:c": "border-top-right-image:continue;", +\ "bdbri": "border-bottom-right-image:url(|);", +\ "bdbri:n": "border-bottom-right-image:none;", +\ "bdbri:c": "border-bottom-right-image:continue;", +\ "bdbli": "border-bottom-left-image:url(|);", +\ "bdbli:n": "border-bottom-left-image:none;", +\ "bdbli:c": "border-bottom-left-image:continue;", +\ "bdf": "border-fit:${1:repeat};", +\ "bdf:c": "border-fit:clip;", +\ "bdf:r": "border-fit:repeat;", +\ "bdf:sc": "border-fit:scale;", +\ "bdf:st": "border-fit:stretch;", +\ "bdf:ow": "border-fit:overwrite;", +\ "bdf:of": "border-fit:overflow;", +\ "bdf:sp": "border-fit:space;", +\ "bdlen": "border-length:|;", +\ "bdlen:a": "border-length:auto;", +\ "bdsp": "border-spacing:|;", +\ "bds": "border-style:|;", +\ "bds:n": "border-style:none;", +\ "bds:h": "border-style:hidden;", +\ "bds:dt": "border-style:dotted;", +\ "bds:ds": "border-style:dashed;", +\ "bds:s": "border-style:solid;", +\ "bds:db": "border-style:double;", +\ "bds:dtds": "border-style:dot-dash;", +\ "bds:dtdtds": "border-style:dot-dot-dash;", +\ "bds:w": "border-style:wave;", +\ "bds:g": "border-style:groove;", +\ "bds:r": "border-style:ridge;", +\ "bds:i": "border-style:inset;", +\ "bds:o": "border-style:outset;", +\ "bdw": "border-width:|;", +\ "bdtw": "border-top-width:|;", +\ "bdrw": "border-right-width:|;", +\ "bdbw": "border-bottom-width:|;", +\ "bdlw": "border-left-width:|;", +\ "bdt": "border-top:|;", +\ "bt": "border-top:|;", +\ "bdt+": "border-top:${1:1px} ${2:solid} ${3:#000};", +\ "bdt:n": "border-top:none;", +\ "bdts": "border-top-style:|;", +\ "bdts:n": "border-top-style:none;", +\ "bdtc": "border-top-color:#${1:000};", +\ "bdtc:t": "border-top-color:transparent;", +\ "bdr": "border-right:|;", +\ "br": "border-right:|;", +\ "bdr+": "border-right:${1:1px} ${2:solid} ${3:#000};", +\ "bdr:n": "border-right:none;", +\ "bdrst": "border-right-style:|;", +\ "bdrst:n": "border-right-style:none;", +\ "bdrc": "border-right-color:#${1:000};", +\ "bdrc:t": "border-right-color:transparent;", +\ "bdb": "border-bottom:|;", +\ "bb": "border-bottom:|;", +\ "bdb+": "border-bottom:${1:1px} ${2:solid} ${3:#000};", +\ "bdb:n": "border-bottom:none;", +\ "bdbs": "border-bottom-style:|;", +\ "bdbs:n": "border-bottom-style:none;", +\ "bdbc": "border-bottom-color:#${1:000};", +\ "bdbc:t": "border-bottom-color:transparent;", +\ "bdl": "border-left:|;", +\ "bl": "border-left:|;", +\ "bdl+": "border-left:${1:1px} ${2:solid} ${3:#000};", +\ "bdl:n": "border-left:none;", +\ "bdls": "border-left-style:|;", +\ "bdls:n": "border-left-style:none;", +\ "bdlc": "border-left-color:#${1:000};", +\ "bdlc:t": "border-left-color:transparent;", +\ "bdrs": "border-radius:|;", +\ "bdtrrs": "border-top-right-radius:|;", +\ "bdtlrs": "border-top-left-radius:|;", +\ "bdbrrs": "border-bottom-right-radius:|;", +\ "bdblrs": "border-bottom-left-radius:|;", +\ "bg": "background:#${1:000};", +\ "bg+": "background:${1:#fff} url(${2}) ${3:0} ${4:0} ${5:no-repeat};", +\ "bg:n": "background:none;", +\ "bg:ie": "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='${1:x}.png',sizingMethod='${2:crop}');", +\ "bgc": "background-color:#${1:fff};", +\ "bgc:t": "background-color:transparent;", +\ "bgi": "background-image:url(|);", +\ "bgi:n": "background-image:none;", +\ "bgr": "background-repeat:|;", +\ "bgr:n": "background-repeat:no-repeat;", +\ "bgr:x": "background-repeat:repeat-x;", +\ "bgr:y": "background-repeat:repeat-y;", +\ "bgr:sp": "background-repeat:space;", +\ "bgr:rd": "background-repeat:round;", +\ "bga": "background-attachment:|;", +\ "bga:f": "background-attachment:fixed;", +\ "bga:s": "background-attachment:scroll;", +\ "bgp": "background-position:${1:0} ${2:0};", +\ "bgpx": "background-position-x:|;", +\ "bgpy": "background-position-y:|;", +\ "bgbk": "background-break:|;", +\ "bgbk:bb": "background-break:bounding-box;", +\ "bgbk:eb": "background-break:each-box;", +\ "bgbk:c": "background-break:continuous;", +\ "bgcp": "background-clip:${1:padding-box};", +\ "bgcp:bb": "background-clip:border-box;", +\ "bgcp:pb": "background-clip:padding-box;", +\ "bgcp:cb": "background-clip:content-box;", +\ "bgcp:nc": "background-clip:no-clip;", +\ "bgo": "background-origin:|;", +\ "bgo:pb": "background-origin:padding-box;", +\ "bgo:bb": "background-origin:border-box;", +\ "bgo:cb": "background-origin:content-box;", +\ "bgsz": "background-size:|;", +\ "bgsz:a": "background-size:auto;", +\ "bgsz:ct": "background-size:contain;", +\ "bgsz:cv": "background-size:cover;", +\ "c": "color:#${1:000};", +\ "c:r": "color:rgb(${1:0}, ${2:0}, ${3:0});", +\ "c:ra": "color:rgba(${1:0}, ${2:0}, ${3:0}, .${4:5});", +\ "cm": "/* |${child} */", +\ "cnt": "content:'|';", +\ "cnt:n": "content:normal;", +\ "cnt:oq": "content:open-quote;", +\ "cnt:noq": "content:no-open-quote;", +\ "cnt:cq": "content:close-quote;", +\ "cnt:ncq": "content:no-close-quote;", +\ "cnt:a": "content:attr(|);", +\ "cnt:c": "content:counter(|);", +\ "cnt:cs": "content:counters(|);", +\ "tbl": "table-layout:|;", +\ "tbl:a": "table-layout:auto;", +\ "tbl:f": "table-layout:fixed;", +\ "cps": "caption-side:|;", +\ "cps:t": "caption-side:top;", +\ "cps:b": "caption-side:bottom;", +\ "ec": "empty-cells:|;", +\ "ec:s": "empty-cells:show;", +\ "ec:h": "empty-cells:hide;", +\ "lis": "list-style:|;", +\ "lis:n": "list-style:none;", +\ "lisp": "list-style-position:|;", +\ "lisp:i": "list-style-position:inside;", +\ "lisp:o": "list-style-position:outside;", +\ "list": "list-style-type:|;", +\ "list:n": "list-style-type:none;", +\ "list:d": "list-style-type:disc;", +\ "list:c": "list-style-type:circle;", +\ "list:s": "list-style-type:square;", +\ "list:dc": "list-style-type:decimal;", +\ "list:dclz": "list-style-type:decimal-leading-zero;", +\ "list:lr": "list-style-type:lower-roman;", +\ "list:ur": "list-style-type:upper-roman;", +\ "lisi": "list-style-image:|;", +\ "lisi:n": "list-style-image:none;", +\ "q": "quotes:|;", +\ "q:n": "quotes:none;", +\ "q:ru": "quotes:'\\00AB' '\\00BB' '\\201E' '\\201C';", +\ "q:en": "quotes:'\\201C' '\\201D' '\\2018' '\\2019';", +\ "ct": "content:|;", +\ "ct:n": "content:normal;", +\ "ct:oq": "content:open-quote;", +\ "ct:noq": "content:no-open-quote;", +\ "ct:cq": "content:close-quote;", +\ "ct:ncq": "content:no-close-quote;", +\ "ct:a": "content:attr(|);", +\ "ct:c": "content:counter(|);", +\ "ct:cs": "content:counters(|);", +\ "coi": "counter-increment:|;", +\ "cor": "counter-reset:|;", +\ "va": "vertical-align:${1:top};", +\ "va:sup": "vertical-align:super;", +\ "va:t": "vertical-align:top;", +\ "va:tt": "vertical-align:text-top;", +\ "va:m": "vertical-align:middle;", +\ "va:bl": "vertical-align:baseline;", +\ "va:b": "vertical-align:bottom;", +\ "va:tb": "vertical-align:text-bottom;", +\ "va:sub": "vertical-align:sub;", +\ "ta": "text-align:${1:left};", +\ "ta:l": "text-align:left;", +\ "ta:c": "text-align:center;", +\ "ta:r": "text-align:right;", +\ "ta:j": "text-align:justify;", +\ "ta-lst": "text-align-last:|;", +\ "tal:a": "text-align-last:auto;", +\ "tal:l": "text-align-last:left;", +\ "tal:c": "text-align-last:center;", +\ "tal:r": "text-align-last:right;", +\ "td": "text-decoration:${1:none};", +\ "td:n": "text-decoration:none;", +\ "td:u": "text-decoration:underline;", +\ "td:o": "text-decoration:overline;", +\ "td:l": "text-decoration:line-through;", +\ "te": "text-emphasis:|;", +\ "te:n": "text-emphasis:none;", +\ "te:ac": "text-emphasis:accent;", +\ "te:dt": "text-emphasis:dot;", +\ "te:c": "text-emphasis:circle;", +\ "te:ds": "text-emphasis:disc;", +\ "te:b": "text-emphasis:before;", +\ "te:a": "text-emphasis:after;", +\ "th": "text-height:|;", +\ "th:a": "text-height:auto;", +\ "th:f": "text-height:font-size;", +\ "th:t": "text-height:text-size;", +\ "th:m": "text-height:max-size;", +\ "ti": "text-indent:|;", +\ "ti:-": "text-indent:-9999px;", +\ "tj": "text-justify:|;", +\ "tj:a": "text-justify:auto;", +\ "tj:iw": "text-justify:inter-word;", +\ "tj:ii": "text-justify:inter-ideograph;", +\ "tj:ic": "text-justify:inter-cluster;", +\ "tj:d": "text-justify:distribute;", +\ "tj:k": "text-justify:kashida;", +\ "tj:t": "text-justify:tibetan;", +\ "tov": "text-overflow:${ellipsis};", +\ "tov:e": "text-overflow:ellipsis;", +\ "tov:c": "text-overflow:clip;", +\ "to": "text-outline:|;", +\ "to+": "text-outline:${1:0} ${2:0} ${3:#000};", +\ "to:n": "text-outline:none;", +\ "tr": "text-replace:|;", +\ "tr:n": "text-replace:none;", +\ "tt": "text-transform:${1:uppercase};", +\ "tt:n": "text-transform:none;", +\ "tt:c": "text-transform:capitalize;", +\ "tt:u": "text-transform:uppercase;", +\ "tt:l": "text-transform:lowercase;", +\ "tw": "text-wrap:|;", +\ "tw:n": "text-wrap:normal;", +\ "tw:no": "text-wrap:none;", +\ "tw:u": "text-wrap:unrestricted;", +\ "tw:s": "text-wrap:suppress;", +\ "tsh": "text-shadow:${1:hoff} ${2:voff} ${3:blur} ${4:#000};", +\ "tsh:r": "text-shadow:${1:h} ${2:v} ${3:blur} rgb(${4:0}, ${5:0}, ${6:0});", +\ "tsh:ra": "text-shadow:${1:h} ${2:v} ${3:blur} rgba(${4:0}, ${5:0}, ${6:0}, .${7:5});", +\ "tsh+": "text-shadow:${1:0} ${2:0} ${3:0} ${4:#000};", +\ "tsh:n": "text-shadow:none;", +\ "trf": "transform:|;", +\ "trf:skx": "transform: skewX(${1:angle});", +\ "trf:sky": "transform: skewY(${1:angle});", +\ "trf:sc": "transform: scale(${1:x}, ${2:y});", +\ "trf:scx": "transform: scaleX(${1:x});", +\ "trf:scy": "transform: scaleY(${1:y});", +\ "trf:scz": "transform: scaleZ(${1:z});", +\ "trf:sc3": "transform: scale3d(${1:x}, ${2:y}, ${3:z});", +\ "trf:r": "transform: rotate(${1:angle});", +\ "trf:rx": "transform: rotateX(${1:angle});", +\ "trf:ry": "transform: rotateY(${1:angle});", +\ "trf:rz": "transform: rotateZ(${1:angle});", +\ "trf:t": "transform: translate(${1:x}, ${2:y});", +\ "trf:tx": "transform: translateX(${1:x});", +\ "trf:ty": "transform: translateY(${1:y});", +\ "trf:tz": "transform: translateZ(${1:z});", +\ "trf:t3": "transform: translate3d(${1:tx}, ${2:ty}, ${3:tz});", +\ "trfo": "transform-origin:|;", +\ "trfs": "transform-style:${1:preserve-3d};", +\ "trs": "transition:${1:prop} ${2:time};", +\ "trsde": "transition-delay:${1:time};", +\ "trsdu": "transition-duration:${1:time};", +\ "trsp": "transition-property:${1:prop};", +\ "trstf": "transition-timing-function:${1:tfunc};", +\ "lh": "line-height:|;", +\ "whs": "white-space:|;", +\ "whs:n": "white-space:normal;", +\ "whs:p": "white-space:pre;", +\ "whs:nw": "white-space:nowrap;", +\ "whs:pw": "white-space:pre-wrap;", +\ "whs:pl": "white-space:pre-line;", +\ "whsc": "white-space-collapse:|;", +\ "whsc:n": "white-space-collapse:normal;", +\ "whsc:k": "white-space-collapse:keep-all;", +\ "whsc:l": "white-space-collapse:loose;", +\ "whsc:bs": "white-space-collapse:break-strict;", +\ "whsc:ba": "white-space-collapse:break-all;", +\ "wob": "word-break:|;", +\ "wob:n": "word-break:normal;", +\ "wob:k": "word-break:keep-all;", +\ "wob:ba": "word-break:break-all;", +\ "wos": "word-spacing:|;", +\ "wow": "word-wrap:|;", +\ "wow:nm": "word-wrap:normal;", +\ "wow:n": "word-wrap:none;", +\ "wow:u": "word-wrap:unrestricted;", +\ "wow:s": "word-wrap:suppress;", +\ "wow:b": "word-wrap:break-word;", +\ "wm": "writing-mode:${1:lr-tb};", +\ "wm:lrt": "writing-mode:lr-tb;", +\ "wm:lrb": "writing-mode:lr-bt;", +\ "wm:rlt": "writing-mode:rl-tb;", +\ "wm:rlb": "writing-mode:rl-bt;", +\ "wm:tbr": "writing-mode:tb-rl;", +\ "wm:tbl": "writing-mode:tb-lr;", +\ "wm:btl": "writing-mode:bt-lr;", +\ "wm:btr": "writing-mode:bt-rl;", +\ "lts": "letter-spacing:|;", +\ "lts-n": "letter-spacing:normal;", +\ "f": "font:|;", +\ "f+": "font:${1:1em} ${2:Arial,sans-serif};", +\ "fw": "font-weight:|;", +\ "fw:n": "font-weight:normal;", +\ "fw:b": "font-weight:bold;", +\ "fw:br": "font-weight:bolder;", +\ "fw:lr": "font-weight:lighter;", +\ "fs": "font-style:${italic};", +\ "fs:n": "font-style:normal;", +\ "fs:i": "font-style:italic;", +\ "fs:o": "font-style:oblique;", +\ "fv": "font-variant:|;", +\ "fv:n": "font-variant:normal;", +\ "fv:sc": "font-variant:small-caps;", +\ "fz": "font-size:|;", +\ "fza": "font-size-adjust:|;", +\ "fza:n": "font-size-adjust:none;", +\ "ff": "font-family:|;", +\ "ff:s": "font-family:serif;", +\ "ff:ss": "font-family:sans-serif;", +\ "ff:c": "font-family:cursive;", +\ "ff:f": "font-family:fantasy;", +\ "ff:m": "font-family:monospace;", +\ "ff:a": "font-family: Arial, \"Helvetica Neue\", Helvetica, sans-serif;", +\ "ff:t": "font-family: \"Times New Roman\", Times, Baskerville, Georgia, serif;", +\ "ff:v": "font-family: Verdana, Geneva, sans-serif;", +\ "fef": "font-effect:|;", +\ "fef:n": "font-effect:none;", +\ "fef:eg": "font-effect:engrave;", +\ "fef:eb": "font-effect:emboss;", +\ "fef:o": "font-effect:outline;", +\ "fem": "font-emphasize:|;", +\ "femp": "font-emphasize-position:|;", +\ "femp:b": "font-emphasize-position:before;", +\ "femp:a": "font-emphasize-position:after;", +\ "fems": "font-emphasize-style:|;", +\ "fems:n": "font-emphasize-style:none;", +\ "fems:ac": "font-emphasize-style:accent;", +\ "fems:dt": "font-emphasize-style:dot;", +\ "fems:c": "font-emphasize-style:circle;", +\ "fems:ds": "font-emphasize-style:disc;", +\ "fsm": "font-smooth:|;", +\ "fsm:a": "font-smooth:auto;", +\ "fsm:n": "font-smooth:never;", +\ "fsm:aw": "font-smooth:always;", +\ "fst": "font-stretch:|;", +\ "fst:n": "font-stretch:normal;", +\ "fst:uc": "font-stretch:ultra-condensed;", +\ "fst:ec": "font-stretch:extra-condensed;", +\ "fst:c": "font-stretch:condensed;", +\ "fst:sc": "font-stretch:semi-condensed;", +\ "fst:se": "font-stretch:semi-expanded;", +\ "fst:e": "font-stretch:expanded;", +\ "fst:ee": "font-stretch:extra-expanded;", +\ "fst:ue": "font-stretch:ultra-expanded;", +\ "op": "opacity:|;", +\ "op+": "opacity: $1;\nfilter: alpha(opacity=$2);", +\ "op:ie": "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);", +\ "op:ms": "-ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=100)';", +\ "rsz": "resize:|;", +\ "rsz:n": "resize:none;", +\ "rsz:b": "resize:both;", +\ "rsz:h": "resize:horizontal;", +\ "rsz:v": "resize:vertical;", +\ "cur": "cursor:${pointer};", +\ "cur:a": "cursor:auto;", +\ "cur:d": "cursor:default;", +\ "cur:c": "cursor:crosshair;", +\ "cur:ha": "cursor:hand;", +\ "cur:he": "cursor:help;", +\ "cur:m": "cursor:move;", +\ "cur:p": "cursor:pointer;", +\ "cur:t": "cursor:text;", +\ "pgbb": "page-break-before:|;", +\ "pgbb:au": "page-break-before:auto;", +\ "pgbb:al": "page-break-before:always;", +\ "pgbb:l": "page-break-before:left;", +\ "pgbb:r": "page-break-before:right;", +\ "pgbi": "page-break-inside:|;", +\ "pgbi:au": "page-break-inside:auto;", +\ "pgbi:av": "page-break-inside:avoid;", +\ "pgba": "page-break-after:|;", +\ "pgba:au": "page-break-after:auto;", +\ "pgba:al": "page-break-after:always;", +\ "pgba:l": "page-break-after:left;", +\ "pgba:r": "page-break-after:right;", +\ "orp": "orphans:|;", +\ "us": "user-select:${none};", +\ "wid": "widows:|;", +\ "wfsm": "-webkit-font-smoothing:${antialiased};", +\ "wfsm:a": "-webkit-font-smoothing:antialiased;", +\ "wfsm:s": "-webkit-font-smoothing:subpixel-antialiased;", +\ "wfsm:sa": "-webkit-font-smoothing:subpixel-antialiased;", +\ "wfsm:n": "-webkit-font-smoothing:none;" +\ }, +\ 'filters': 'fc', +\ }, +\ 'sass': { +\ 'extends': 'css', +\ 'snippets': { +\ '@if': "@if {\n\t|\n}", +\ '@e': "@else {\n\t|\n}", +\ '@in': "@include |", +\ '@ex': "@extend |", +\ '@mx': "@mixin {\n\t|\n}", +\ '@fn': "@function {\n\t|\n}", +\ '@r': "@return |", +\ }, +\ }, +\ 'scss': { +\ 'extends': 'css', +\ }, +\ 'less': { +\ 'extends': 'css', +\ }, +\ 'css.drupal': { +\ 'extends': 'css', +\ }, +\ 'html': { +\ 'snippets': { +\ '!': "html:5", +\ '!!!': "\n", +\ '!!!4t': "\n", +\ '!!!4s': "\n", +\ '!!!xt': "\n", +\ '!!!xs': "\n", +\ '!!!xxs': "\n", +\ 'c': "", +\ 'cc:ie6': "", +\ 'cc:ie': "", +\ 'cc:noie': "\n\t${child}|\n", +\ 'html:4t': "\n" +\ ."\n" +\ ."\n" +\ ."\t\n" +\ ."\t\n" +\ ."\n" +\ ."\n\t${child}|\n\n" +\ ."", +\ 'html:4s': "\n" +\ ."\n" +\ ."\n" +\ ."\t\n" +\ ."\t\n" +\ ."\n" +\ ."\n\t${child}|\n\n" +\ ."", +\ 'html:xt': "\n" +\ ."\n" +\ ."\n" +\ ."\t\n" +\ ."\t\n" +\ ."\n" +\ ."\n\t${child}|\n\n" +\ ."", +\ 'html:xs': "\n" +\ ."\n" +\ ."\n" +\ ."\t\n" +\ ."\t\n" +\ ."\n" +\ ."\n\t${child}|\n\n" +\ ."", +\ 'html:xxs': "\n" +\ ."\n" +\ ."\n" +\ ."\t\n" +\ ."\t\n" +\ ."\n" +\ ."\n\t${child}|\n\n" +\ ."", +\ 'html:5': "\n" +\ ."\n" +\ ."\n" +\ ."\t\n" +\ ."\t\n" +\ ."\n" +\ ."\n\t${child}|\n\n" +\ ."", +\ }, +\ 'default_attributes': { +\ 'a': {'href': ''}, +\ 'a:link': {'href': 'http://|'}, +\ 'a:mail': {'href': 'mailto:|'}, +\ 'abbr': {'title': ''}, +\ 'acronym': {'title': ''}, +\ 'base': {'href': ''}, +\ 'bdo': {'dir': ''}, +\ 'bdo:r': {'dir': 'rtl'}, +\ 'bdo:l': {'dir': 'ltr'}, +\ 'del': {'datetime': '${datetime}'}, +\ 'ins': {'datetime': '${datetime}'}, +\ 'link:css': [{'rel': 'stylesheet'}, g:emmet_html5 ? {} : {'type': 'text/css'}, {'href': '|style.css'}, {'media': 'all'}], +\ 'link:print': [{'rel': 'stylesheet'}, g:emmet_html5 ? {} : {'type': 'text/css'}, {'href': '|print.css'}, {'media': 'print'}], +\ 'link:import': [{'rel': 'import'}, {'href': '|.html'}], +\ 'link:im': [{'rel': 'import'}, {'href': '|.html'}], +\ 'link:favicon': [{'rel': 'shortcut icon'}, {'type': 'image/x-icon'}, {'href': '|favicon.ico'}], +\ 'link:touch': [{'rel': 'apple-touch-icon'}, {'href': '|favicon.png'}], +\ 'link:rss': [{'rel': 'alternate'}, {'type': 'application/rss+xml'}, {'title': 'RSS'}, {'href': '|rss.xml'}], +\ 'link:atom': [{'rel': 'alternate'}, {'type': 'application/atom+xml'}, {'title': 'Atom'}, {'href': 'atom.xml'}], +\ 'meta:utf': [{'http-equiv': 'Content-Type'}, {'content': 'text/html;charset=UTF-8'}], +\ 'meta:vp': [{'name': 'viewport'}, {'content': 'width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0'}], +\ 'meta:win': [{'http-equiv': 'Content-Type'}, {'content': 'text/html;charset=Win-1251'}], +\ 'meta:compat': [{'http-equiv': 'X-UA-Compatible'}, {'content': 'IE=7'}], +\ 'style': g:emmet_html5 ? {} : {'type': 'text/css'}, +\ 'script': g:emmet_html5 ? {} : {'type': 'text/javascript'}, +\ 'script:src': g:emmet_html5 ? {'src': ''} : [{'type': 'text/javascript'}, {'src': ''}], +\ 'img': [{'src': ''}, {'alt': ''}], +\ 'iframe': [{'src': ''}, {'frameborder': '0'}], +\ 'embed': [{'src': ''}, {'type': ''}], +\ 'object': [{'data': ''}, {'type': ''}], +\ 'param': [{'name': ''}, {'value': ''}], +\ 'map': {'name': ''}, +\ 'area': [{'shape': ''}, {'coords': ''}, {'href': ''}, {'alt': ''}], +\ 'area:d': [{'shape': 'default'}, {'href': ''}, {'alt': ''}], +\ 'area:c': [{'shape': 'circle'}, {'coords': ''}, {'href': ''}, {'alt': ''}], +\ 'area:r': [{'shape': 'rect'}, {'coords': ''}, {'href': ''}, {'alt': ''}], +\ 'area:p': [{'shape': 'poly'}, {'coords': ''}, {'href': ''}, {'alt': ''}], +\ 'link': [{'rel': 'stylesheet'}, {'href': ''}], +\ 'form': {'action': ''}, +\ 'form:get': {'action': '', 'method': 'get'}, +\ 'form:post': {'action': '', 'method': 'post'}, +\ 'form:upload': {'action': '', 'method': 'post', 'enctype': 'multipart/form-data'}, +\ 'label': {'for': ''}, +\ 'input': {'type': ''}, +\ 'input:hidden': [{'type': 'hidden'}, {'name': ''}], +\ 'input:h': [{'type': 'hidden'}, {'name': ''}], +\ 'input:text': [{'type': 'text'}, {'name': ''}, {'id': ''}], +\ 'input:t': [{'type': 'text'}, {'name': ''}, {'id': ''}], +\ 'input:search': [{'type': 'search'}, {'name': ''}, {'id': ''}], +\ 'input:email': [{'type': 'email'}, {'name': ''}, {'id': ''}], +\ 'input:url': [{'type': 'url'}, {'name': ''}, {'id': ''}], +\ 'input:password': [{'type': 'password'}, {'name': ''}, {'id': ''}], +\ 'input:p': [{'type': 'password'}, {'name': ''}, {'id': ''}], +\ 'input:datetime': [{'type': 'datetime'}, {'name': ''}, {'id': ''}], +\ 'input:date': [{'type': 'date'}, {'name': ''}, {'id': ''}], +\ 'input:datetime-local': [{'type': 'datetime-local'}, {'name': ''}, {'id': ''}], +\ 'input:month': [{'type': 'month'}, {'name': ''}, {'id': ''}], +\ 'input:week': [{'type': 'week'}, {'name': ''}, {'id': ''}], +\ 'input:time': [{'type': 'time'}, {'name': ''}, {'id': ''}], +\ 'input:number': [{'type': 'number'}, {'name': ''}, {'id': ''}], +\ 'input:color': [{'type': 'color'}, {'name': ''}, {'id': ''}], +\ 'input:checkbox': [{'type': 'checkbox'}, {'name': ''}, {'id': ''}], +\ 'input:c': [{'type': 'checkbox'}, {'name': ''}, {'id': ''}], +\ 'input:radio': [{'type': 'radio'}, {'name': ''}, {'id': ''}], +\ 'input:r': [{'type': 'radio'}, {'name': ''}, {'id': ''}], +\ 'input:range': [{'type': 'range'}, {'name': ''}, {'id': ''}], +\ 'input:file': [{'type': 'file'}, {'name': ''}, {'id': ''}], +\ 'input:f': [{'type': 'file'}, {'name': ''}, {'id': ''}], +\ 'input:submit': [{'type': 'submit'}, {'value': ''}], +\ 'input:s': [{'type': 'submit'}, {'value': ''}], +\ 'input:image': [{'type': 'image'}, {'src': ''}, {'alt': ''}], +\ 'input:i': [{'type': 'image'}, {'src': ''}, {'alt': ''}], +\ 'input:reset': [{'type': 'reset'}, {'value': ''}], +\ 'input:button': [{'type': 'button'}, {'value': ''}], +\ 'input:b': [{'type': 'button'}, {'value': ''}], +\ 'select': [{'name': ''}, {'id': ''}], +\ 'option': {'value': ''}, +\ 'textarea': [{'name': ''}, {'id': ''}, {'cols': '30'}, {'rows': '10'}], +\ 'menu:context': {'type': 'context'}, +\ 'menu:c': {'type': 'context'}, +\ 'menu:toolbar': {'type': 'toolbar'}, +\ 'menu:t': {'type': 'toolbar'}, +\ 'video': {'src': ''}, +\ 'audio': {'src': ''}, +\ 'html:xml': [{'xmlns': 'http://www.w3.org/1999/xhtml'}, {'xml:lang': '${lang}'}], +\ }, +\ 'aliases': { +\ 'link:*': 'link', +\ 'meta:*': 'meta', +\ 'area:*': 'area', +\ 'bdo:*': 'bdo', +\ 'form:*': 'form', +\ 'input:*': 'input', +\ 'script:*': 'script', +\ 'html:*': 'html', +\ 'a:*': 'a', +\ 'menu:*': 'menu', +\ 'bq': 'blockquote', +\ 'acr': 'acronym', +\ 'fig': 'figure', +\ 'ifr': 'iframe', +\ 'emb': 'embed', +\ 'obj': 'object', +\ 'src': 'source', +\ 'cap': 'caption', +\ 'colg': 'colgroup', +\ 'fst': 'fieldset', +\ 'btn': 'button', +\ 'optg': 'optgroup', +\ 'opt': 'option', +\ 'tarea': 'textarea', +\ 'leg': 'legend', +\ 'sect': 'section', +\ 'art': 'article', +\ 'hdr': 'header', +\ 'ftr': 'footer', +\ 'adr': 'address', +\ 'dlg': 'dialog', +\ 'str': 'strong', +\ 'sty': 'style', +\ 'prog': 'progress', +\ 'fset': 'fieldset', +\ 'datag': 'datagrid', +\ 'datal': 'datalist', +\ 'kg': 'keygen', +\ 'out': 'output', +\ 'det': 'details', +\ 'cmd': 'command', +\ }, +\ 'expandos': { +\ 'ol': 'ol>li', +\ 'ul': 'ul>li', +\ 'dl': 'dl>dt+dd', +\ 'map': 'map>area', +\ 'table': 'table>tr>td', +\ 'colgroup': 'colgroup>col', +\ 'colg': 'colgroup>col', +\ 'tr': 'tr>td', +\ 'select': 'select>option', +\ 'optgroup': 'optgroup>option', +\ 'optg': 'optgroup>option', +\ }, +\ 'empty_elements': 'area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,keygen,command', +\ 'block_elements': 'address,applet,blockquote,button,center,dd,del,dir,div,dl,dt,fieldset,form,frameset,hr,iframe,ins,isindex,li,link,map,menu,noframes,noscript,object,ol,p,pre,script,table,tbody,td,tfoot,th,thead,tr,ul,h1,h2,h3,h4,h5,h6', +\ 'inline_elements': '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,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var', +\ 'empty_element_suffix': g:emmet_html5 ? '>' : ' />', +\ 'indent_blockelement': 0, +\ }, +\ 'htmldjango': { +\ 'extends': 'html', +\ }, +\ 'html.django_template': { +\ 'extends': 'html', +\ }, +\ 'xsl': { +\ 'extends': 'html', +\ 'default_attributes': { +\ 'tmatch': [{'match': ''}, {'mode': ''}], +\ 'tname': [{'name': ''}], +\ 'xsl:when': {'test': ''}, +\ 'var': [{'name': ''}, {'select': ''}], +\ 'vari': {'name': ''}, +\ 'if': {'test': ''}, +\ 'call': {'name': ''}, +\ 'attr': {'name': ''}, +\ 'wp': [{'name': ''}, {'select': ''}], +\ 'par': [{'name': ''}, {'select': ''}], +\ 'val': {'select': ''}, +\ 'co': {'select': ''}, +\ 'each': {'select': ''}, +\ 'ap': [{'select': ''}, {'mode': ''}] +\ }, +\ 'aliases': { +\ 'tmatch': 'xsl:template', +\ 'tname': 'xsl:template', +\ 'var': 'xsl:variable', +\ 'vari': 'xsl:variable', +\ 'if': 'xsl:if', +\ 'choose': 'xsl:choose', +\ 'call': 'xsl:call-template', +\ 'wp': 'xsl:with-param', +\ 'par': 'xsl:param', +\ 'val': 'xsl:value-of', +\ 'attr': 'xsl:attribute', +\ 'co' : 'xsl:copy-of', +\ 'each' : 'xsl:for-each', +\ 'ap' : 'xsl:apply-templates', +\ }, +\ 'expandos': { +\ 'choose': 'xsl:choose>xsl:when+xsl:otherwise', +\ } +\ }, +\ 'jsx': { +\ 'extends': 'html', +\ 'attribute_name': {'class': 'className'}, +\ }, +\ 'xslt': { +\ 'extends': 'xsl', +\ }, +\ 'haml': { +\ 'indentation': ' ', +\ 'extends': 'html', +\ 'snippets': { +\ 'html:5': "!!! 5\n" +\ ."%html{:lang => \"${lang}\"}\n" +\ ."\t%head\n" +\ ."\t\t%meta{:charset => \"${charset}\"}\n" +\ ."\t\t%title\n" +\ ."\t%body\n" +\ ."\t\t${child}|\n", +\ }, +\ 'attribute_style': 'hash', +\ }, +\ 'slim': { +\ 'indentation': ' ', +\ 'extends': 'html', +\ 'snippets': { +\ 'html:5': "doctype 5\n" +\ ."html lang=\"${lang}\"\n" +\ ."\thead\n" +\ ."\t\tmeta charset=\"${charset}\"\n" +\ ."\t\ttitle\n" +\ ."\tbody\n" +\ ."\t\t${child}|\n", +\ }, +\ }, +\ 'xhtml': { +\ 'extends': 'html' +\ }, +\ 'mustache': { +\ 'extends': 'html' +\ }, +\ 'xsd': { +\ 'extends': 'html', +\ 'snippets': { +\ 'xsd:w3c': "\n" +\ ."\n" +\ ."\t\n" +\ ."\n" +\ } +\ } +\} + +if exists('g:user_emmet_settings') + call emmet#mergeConfig(s:emmet_settings, g:user_emmet_settings) +endif + +let &cpoptions = s:save_cpo +unlet s:save_cpo + +" vim:set et: diff --git a/autoload/emmet/lang.vim b/autoload/emmet/lang.vim new file mode 100644 index 0000000..c839fea --- /dev/null +++ b/autoload/emmet/lang.vim @@ -0,0 +1,11 @@ +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 + diff --git a/autoload/emmet/lang/css.vim b/autoload/emmet/lang/css.vim new file mode 100644 index 0000000..48bc3c2 --- /dev/null +++ b/autoload/emmet/lang/css.vim @@ -0,0 +1,346 @@ +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' && 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\|re\|rem\|%\)\{0,1}-\{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 v in split(prop[2], '\d\zs-') + if len(value) > 0 + let value .= ' ' + endif + if token =~# '^[z]' + " TODO + let value .= substitute(v, '[^0-9.]*$', '', '') + elseif v =~# 'p$' + let value .= substitute(v, 'p$', '%', '') + elseif v =~# '%$' + let value .= v + elseif v =~# 'e$' + let value .= substitute(v, 'e$', 'em', '') + elseif v =~# 'em$' + let value .= v + elseif v =~# 're$' + let value .= substitute(v, 're$', 'rem', '') + elseif v =~# 'rem$' + let value .= v + elseif v =~# '\.' + let value .= v . 'em' + elseif v ==# 'auto' + let value .= v + elseif v ==# '0' + let value .= '0' + else + let value .= v . 'px' + endif + 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 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 = 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, '\') + if len(node) + exe "normal ciw\='/* '.node.' */'\" + 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*$' + 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 + let pos = search('""\|()\|\(:\s*\zs$\)', a:flag ? 'Wbp' : 'Wp') + if pos == 2 + startinsert! + else + silent! normal! l + startinsert + endif +endfunction + +function! emmet#lang#css#splitJoinTag() abort + " nothing to do +endfunction + +function! emmet#lang#css#removeTag() abort + " nothing to do +endfunction diff --git a/autoload/emmet/lang/haml.vim b/autoload/emmet/lang/haml.vim new file mode 100644 index 0000000..bd8d247 --- /dev/null +++ b/autoload/emmet/lang/haml.vim @@ -0,0 +1,335 @@ +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 + let Val = substitute(Val, '\${cursor}', '', '') + if attribute_style ==# 'hash' + let tmp .= ' :' . attr . ' => "' . Val . '"' + elseif attribute_style ==# 'html' + let tmp .= attr . '="' . Val . '"' + end + endif + endif + endfor + if len(tmp) + if attribute_style ==# 'hash' + let str .= '{' . tmp . ' }' + elseif attribute_style ==# 'html' + let str .= '(' . tmp . ')' + end + endif + 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, '\%(\\\)\@\ 0 + for child in current.child + let inner .= emmet#toString(child, type, inline, filters, itemno, indent) + endfor + let inner = substitute(inner, "\n", "\n" . escape(indent, '\'), 'g') + let inner = substitute(inner, "\n" . escape(indent, '\') . '$', '', 'g') + let str .= "\n" . indent . inner + endif + else + let str = current.value[1:-2] + if dollar_expr + let str = substitute(str, '\%(\\\)\@\\s*\%(\([^"'' \t]\+\)\|"\([^"]\{-}\)"\|''\([^'']\{-}\)''\)' + while len(attrs) > 0 + let match = matchstr(attrs, mx) + if len(match) ==# 0 + break + endif + let attr_match = matchlist(match, mx) + let name = attr_match[1] + let value = len(attr_match[2]) ? attr_match[2] : attr_match[3] + let current.attr[name] = value + let current.attrs_order += [name] + let attrs = attrs[stridx(attrs, match) + len(match):] + endwhile + return current +endfunction + +function! emmet#lang#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 diff --git a/autoload/emmet/lang/html.vim b/autoload/emmet/lang/html.vim new file mode 100644 index 0000000..41558d2 --- /dev/null +++ b/autoload/emmet/lang/html.vim @@ -0,0 +1,857 @@ +let s:mx = '\([+>]\|[<^]\+\)\{-}\s*' +\ .'\((*\)\{-}\s*' +\ .'\([@#.]\{-}[a-zA-Z_\!][a-zA-Z0-9:_\!\-$]*\|{\%([^$}]\+\|\$#\|\${\w\+}\|\$\+\)*}*[ \t\r\n}]*\|\[[^\]]\+\]\)' +\ .'\(' +\ .'\%(' +\ .'\%(#{[{}a-zA-Z0-9_\-\$]\+\|#[a-zA-Z0-9_\-\$]\+\)' +\ .'\|\%(\[\%("[^"]*"\|[^"\]]*\)\+\]\)' +\ .'\|\%(\.{[{}a-zA-Z0-9_\-\$]\+\|\.[a-zA-Z0-9_\-\$]\+\)' +\ .'\)*' +\ .'\)' +\ .'\%(\({\%([^$}]\+\|\$#\|\${\w\+}\|\$\+\)*}\+\)\)\{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 + let last_pos = pos + while len(str) > 0 + let token = matchstr(str, s:mx, pos) + if token ==# '' + break + endif + if token =~# '^\s' + let token = matchstr(token, '^\s*\zs.*') + let last_pos = stridx(str, token, pos) + 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 settings = emmet#getSettings() + let indent = emmet#getIndentation(type) + + " 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 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 important = 0 + if len(str) == 0 + break + endif + if tag_name =~# '^#' + let attributes = tag_name . attributes + let tag_name = 'div' + 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 = 'div' + endif + if tag_name =~# '^\[.*\]$' + let attributes = tag_name . attributes + let tag_name = 'div' + endif + let basedirect = basevalue[1] ==# '-' ? -1 : 1 + let basevalue = 0 + abs(basevalue[1:]) + 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 + 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 + + let custom_expands = emmet#getResource(type, 'custom_expands', {}) + if empty(custom_expands) && has_key(settings, 'custom_expands') + let custom_expands = settings['custom_expands'] + endif + for k in keys(custom_expands) + if tag_name =~# k + let current.snippet = '${' . tag_name . '}' + let current.name = '' + 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) + let current.attr[k] = len(a[k]) ? substitute(a[k], '|', '${cursor}', 'g') : '${cursor}' + endfor + else + for k in keys(a) + 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) + let current.attr[k] = len(a[k]) ? substitute(a[k], '|', '${cursor}', 'g') : '${cursor}' + endfor + else + for k in keys(a) + 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:] + endif + if item[0] ==# '.' + let current.attr.class = substitute(item[1:], '\.', ' ', 'g') + 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 ? keys(dfa[0]) : keys(dfa) + endif + if len(ks) == 0 && has_key(default_attributes, current.name . ':src') + let ks = keys(default_attributes[current.name . ':src']) + endif + if len(ks) > 0 + let current.attr[ks[0]] = atts + 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 + 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 cl = last.child + 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 + let last.child = cls + endif + endfor + endif + let abbr = abbr[stridx(abbr, match) + len(match):] + + 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', {}) + + 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 + 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 =~# '^\a_' + let lead = _val[0] + let Val .= lead . ' ' . _val + elseif _val =~# '^_' + if len(lead) == 0 + let pattr = current.parent.attr + if has_key(pattr, 'class') + let lead = pattr['class'] + endif + endif + let Val .= lead . ' ' . lead . _val + else + let Val .= _val + endif + endfor + endif + if has_key(an, attr) + let attr = an[attr] + endif + let str .= ' ' . attr . '=' . q . Val . q + 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 = '\n" . str + endif + if stridx(','.settings.html.empty_elements.',', ','.current_name.',') != -1 + let str .= settings.html.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 + for n in range(nc) + let child = current.child[n] + if child.multiplier > 1 + 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 + let str .= "\n" . indent . '${cursor}' . "\n" + else + let str .= '${cursor}' + endif + endif + if dr + let str .= "\n" + endif + let str .= '' + endif + if len(comment) > 0 + if ct ==# 'lastonly' + let str .= '' + else + let str .= "\n' + 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('') + if !emmet#util#regionIsValid(img_region) || !emmet#util#cursorInRegion(img_region) + return + endif + let content = emmet#util#getContent(img_region) + if content !~# '^<]\+>$' + 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#encodeImage() 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) + if content !~# '^<]\+>$' + 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 !~# '^\(/\|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 html = emmet#toString(current, 'html', 1) + call emmet#util#setContent(img_region, html) +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] + 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#html#toggleComment() abort + let orgpos = emmet#util#getcurpos() + let curpos = emmet#util#getcurpos() + 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, '^$', '\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 = emmet#util#getcurpos() + 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:] . '\>[^>]*>', '', '', '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 = '><' + 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 . '\>[^>]*>', '', '', '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 = '' + 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() + if a:flag == -2 || a:flag == 2 + let curpos = [0, line("'<"), col("'<"), 0] + else + let curpos = emmet#util#getcurpos() + endif + 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 . '[^>]*>', '', '', 'nW') + endif + let block = [pos1, pos2] + if pos1[0] == 0 && pos1[1] == 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 == curpos[1:2] + let pos1 = searchpos(mx . '\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 . '[^>]*>', '', '', 'nW') + endif + let block = [pos1, pos2] + if pos1[0] == 0 && pos1[1] == 0 + break + endif + if emmet#util#regionIsValid(block) + call emmet#util#selectRegion(block) + return + endif + endwhile + endif + if a:flag == -2 || a:flag == 2 + silent! exe 'normal! gv' + else + call setpos('.', curpos) + endif +endfunction + +function! emmet#lang#html#moveNextPrevItem(flag) abort + silent! exe "normal \" + let mx = '\%([0-9a-zA-Z-:]\+\%(="[^"]*"\|=''[^'']*''\|[^ ''">\]]*\)\{0,1}\)' + let pos = searchpos('\s'.mx.'\zs', '') + if pos != [0,0] + call feedkeys('v?\s\zs'.mx."\", '') + endif +endfunction + +function! emmet#lang#html#moveNextPrev(flag) abort + let pos = search('\%(<\/\|\(""\)\|^\(\s*\)$', a:flag ? 'Wpb' : 'Wp') + if pos == 3 + startinsert! + elseif pos != 0 + silent! normal! l + startinsert + endif +endfunction + +function! emmet#lang#html#splitJoinTag() abort + let curpos = emmet#util#getcurpos() + while 1 + let mx = '<\(/\{0,1}[a-zA-Z][a-zA-Z0-9:_\-]*\)[^>]*>' + 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 = content[:-3] . '>' + call emmet#util#setContent(block, content) + call setpos('.', [0, block[0][0], block[0][1], 0]) + return + else + 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 = searchpos('', 'cneW') + else + let pos2 = searchpos('', 'cneW') + endif + let block = [pos1, pos2] + let content = emmet#util#getContent(block) + if emmet#util#pointInRegion(curpos[1:2], block) && content[1:] !~# '<' . tag_name . '[^a-zA-Z0-9]*[^>]*>' + let content = matchstr(content, mx)[:-2] . '/>' + call emmet#util#setContent(block, content) + call setpos('.', [0, block[0][0], block[0][1], 0]) + return + else + if block[0][0] > 0 + call setpos('.', [0, block[0][0]-1, block[0][1], 0]) + else + call setpos('.', curpos) + return + endif + endif + endif + endwhile +endfunction + +function! emmet#lang#html#removeTag() abort + let curpos = emmet#util#getcurpos() + while 1 + let mx = '<\(/\{0,1}[a-zA-Z][a-zA-Z0-9:_\-]*\)[^>]*' + let pos1 = searchpos(mx, 'bcnW') + let content = matchstr(getline(pos1[0])[pos1[1]-1:], mx) + let tag_name = matchstr(content, '^<\zs/\{0,1}[a-zA-Z0-9:_\-]*') + 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 + else + 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 = searchpos('', 'cneW') + else + let pos2 = searchpos('', 'cneW') + endif + let block = [pos1, pos2] + let content = emmet#util#getContent(block) + if emmet#util#pointInRegion(curpos[1:2], block) && content[1:] !~# '^<' . tag_name . '[^a-zA-Z0-9]' + call emmet#util#setContent(block, '') + call setpos('.', [0, block[0][0], block[0][1], 0]) + return + else + if block[0][0] > 0 + call setpos('.', [0, block[0][0]-1, block[0][1], 0]) + else + call setpos('.', curpos) + return + endif + endif + endif + endwhile +endfunction diff --git a/autoload/emmet/lang/jade.vim b/autoload/emmet/lang/jade.vim new file mode 100644 index 0000000..8b0596a --- /dev/null +++ b/autoload/emmet/lang/jade.vim @@ -0,0 +1,332 @@ +function! emmet#lang#jade#findTokens(str) abort + return emmet#lang#html#findTokens(a:str) +endfunction + +function! emmet#lang#jade#parseIntoTree(abbr, type) abort + return emmet#lang#html#parseIntoTree(a:abbr, a:type) +endfunction + +function! emmet#lang#jade#toString(settings, current, type, inline, filters, itemno, indent) abort + let settings = a:settings + let current = a:current + let type = a:type + let inline = a:inline + let filters = a:filters + let itemno = a:itemno + let indent = emmet#getIndentation(type) + let dollar_expr = emmet#getResource(type, 'dollar_expr', 1) + let attribute_style = emmet#getResource('jade', 'attribute_style', 'hash') + let str = '' + + let current_name = current.name + if dollar_expr + let current_name = substitute(current.name, '\$$', itemno+1, '') + endif + if len(current.name) > 0 + let str .= '' . current_name + let tmp = '' + for attr in emmet#util#unique(current.attrs_order + keys(current.attr)) + if !has_key(current.attr, attr) + continue + endif + let Val = current.attr[attr] + if type(Val) == 2 && Val == function('emmet#types#true') + if attribute_style ==# 'hash' + let tmp .= ' ' . attr . ' = true' + elseif attribute_style ==# 'html' + let tmp .= attr . '=true' + end + else + if dollar_expr + while Val =~# '\$\([^#{]\|$\)' + let Val = substitute(Val, '\(\$\+\)\([^{]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g') + endwhile + let attr = substitute(attr, '\$$', itemno+1, '') + endif + let valtmp = substitute(Val, '\${cursor}', '', '') + if attr ==# 'id' && len(valtmp) > 0 + let str .= '#' . Val + elseif attr ==# 'class' && len(valtmp) > 0 + let str .= '.' . substitute(Val, ' ', '.', 'g') + else + if len(tmp) > 0 + if attribute_style ==# 'hash' + let tmp .= ', ' + elseif attribute_style ==# 'html' + let tmp .= ' ' + endif + endif + let Val = substitute(Val, '\${cursor}', '', '') + if attribute_style ==# 'hash' + let tmp .= '' . attr . '="' . Val . '"' + elseif attribute_style ==# 'html' + let tmp .= attr . '="' . Val . '"' + end + endif + endif + endfor + if len(tmp) + if attribute_style ==# 'hash' + let str .= '(' . tmp . ')' + elseif attribute_style ==# 'html' + let str .= '(' . tmp . ')' + end + endif + + let inner = '' + if len(current.value) > 0 + let text = current.value[1:-2] + if dollar_expr + let text = substitute(text, '\%(\\\)\@\ 0 + for child in current.child + let inner .= emmet#toString(child, type, inline, filters, itemno, indent) + endfor + let inner = substitute(inner, "\n", "\n" . escape(indent, '\'), 'g') + let inner = substitute(inner, "\n" . escape(indent, '\') . '$', '', 'g') + let str .= "\n" . indent . inner + endif + else + let str = current.value[1:-2] + if dollar_expr + let str = substitute(str, '\%(\\\)\@\\s*\%(\([^"'' \t]\+\)\|"\([^"]\{-}\)"\|''\([^'']\{-}\)''\)' + while len(attrs) > 0 + let match = matchstr(attrs, mx) + if len(match) ==# 0 + break + endif + let attr_match = matchlist(match, mx) + let name = attr_match[1] + let value = len(attr_match[2]) ? attr_match[2] : attr_match[3] + let current.attr[name] = value + let current.attrs_order += [name] + let attrs = attrs[stridx(attrs, match) + len(match):] + endwhile + return current +endfunction + +function! emmet#lang#jade#toggleComment() abort + let line = getline('.') + let space = matchstr(line, '^\s*') + if line =~# '^\s*-#' + call setline('.', space . matchstr(line[len(space)+2:], '^\s*\zs.*')) + elseif line =~# '^\s*%[a-z]' + call setline('.', space . '-# ' . line[len(space):]) + endif +endfunction + +function! emmet#lang#jade#balanceTag(flag) range abort + let block = emmet#util#getVisualBlock() + if a:flag == -2 || a:flag == 2 + let curpos = [0, line("'<"), col("'<"), 0] + else + let curpos = emmet#util#getcurpos() + endif + let n = curpos[1] + let ml = len(matchstr(getline(n), '^\s*')) + + if a:flag > 0 + if a:flag == 1 || !emmet#util#regionIsValid(block) + let n = line('.') + else + while n > 0 + let l = len(matchstr(getline(n), '^\s*\ze%[a-z]')) + if l > 0 && l < ml + let ml = l + break + endif + let n -= 1 + endwhile + endif + let sn = n + if n == 0 + let ml = 0 + endif + while n < line('$') + let l = len(matchstr(getline(n), '^\s*%[a-z]')) + if l > 0 && l <= ml + let n -= 1 + break + endif + let n += 1 + endwhile + call setpos('.', [0, n, 1, 0]) + normal! V + call setpos('.', [0, sn, 1, 0]) + else + while n > 0 + let l = len(matchstr(getline(n), '^\s*\ze[a-z]')) + if l > 0 && l > ml + let ml = l + break + endif + let n += 1 + endwhile + let sn = n + if n == 0 + let ml = 0 + endif + while n < line('$') + let l = len(matchstr(getline(n), '^\s*%[a-z]')) + if l > 0 && l <= ml + let n -= 1 + break + endif + let n += 1 + endwhile + call setpos('.', [0, n, 1, 0]) + normal! V + call setpos('.', [0, sn, 1, 0]) + endif +endfunction + +function! emmet#lang#jade#moveNextPrevItem(flag) abort + return emmet#lang#jade#moveNextPrev(a:flag) +endfunction + +function! emmet#lang#jade#moveNextPrev(flag) abort + let pos = search('""', a:flag ? 'Wb' : 'W') + if pos != 0 + silent! normal! l + startinsert + endif +endfunction + +function! emmet#lang#jade#splitJoinTag() abort + let n = line('.') + let sml = len(matchstr(getline(n), '^\s*%[a-z]')) + while n > 0 + if getline(n) =~# '^\s*\ze%[a-z]' + if len(matchstr(getline(n), '^\s*%[a-z]')) < sml + break + endif + let line = getline(n) + call setline(n, substitute(line, '^\s*%\w\+\%(\s*{[^}]*}\|\s\)\zs.*', '', '')) + let sn = n + let n += 1 + let ml = len(matchstr(getline(n), '^\s*%[a-z]')) + if len(matchstr(getline(n), '^\s*')) > ml + while n <= line('$') + let l = len(matchstr(getline(n), '^\s*')) + if l <= ml + break + endif + exe n 'delete' + endwhile + call setpos('.', [0, sn, 1, 0]) + else + let tag = matchstr(getline(sn), '^\s*%\zs\(\w\+\)') + let spaces = matchstr(getline(sn), '^\s*') + let settings = emmet#getSettings() + if stridx(','.settings.html.inline_elements.',', ','.tag.',') == -1 + call append(sn, spaces . ' ') + call setpos('.', [0, sn+1, 1, 0]) + else + call setpos('.', [0, sn, 1, 0]) + endif + startinsert! + endif + break + endif + let n -= 1 + endwhile +endfunction + +function! emmet#lang#jade#removeTag() abort + let n = line('.') + let ml = 0 + while n > 0 + if getline(n) =~# '^\s*\ze[a-z]' + let ml = len(matchstr(getline(n), '^\s*%[a-z]')) + break + endif + let n -= 1 + endwhile + let sn = n + while n < line('$') + let l = len(matchstr(getline(n), '^\s*%[a-z]')) + if l > 0 && l <= ml + let n -= 1 + break + endif + let n += 1 + endwhile + if sn == n + exe 'delete' + else + exe sn ',' (n-1) 'delete' + endif +endfunction diff --git a/autoload/emmet/lang/less.vim b/autoload/emmet/lang/less.vim new file mode 100644 index 0000000..25308a0 --- /dev/null +++ b/autoload/emmet/lang/less.vim @@ -0,0 +1,47 @@ +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#encodeImage() abort + return emmet#lang#css#encodeImage() +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 diff --git a/autoload/emmet/lang/sass.vim b/autoload/emmet/lang/sass.vim new file mode 100644 index 0000000..10531d1 --- /dev/null +++ b/autoload/emmet/lang/sass.vim @@ -0,0 +1,160 @@ +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#html#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#encodeImage() 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 diff --git a/autoload/emmet/lang/scss.vim b/autoload/emmet/lang/scss.vim new file mode 100644 index 0000000..f06ac77 --- /dev/null +++ b/autoload/emmet/lang/scss.vim @@ -0,0 +1,125 @@ +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 . "\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#encodeImage() abort + return emmet#lang#css#encodeImage() +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 diff --git a/autoload/emmet/lang/slim.vim b/autoload/emmet/lang/slim.vim new file mode 100644 index 0000000..d57bf1f --- /dev/null +++ b/autoload/emmet/lang/slim.vim @@ -0,0 +1,281 @@ +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, '\%(\\\)\@\ 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, '\%(\\\)\@\ 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 diff --git a/autoload/emmet/lorem/en.vim b/autoload/emmet/lorem/en.vim new file mode 100644 index 0000000..30713e4 --- /dev/null +++ b/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/autoload/emmet/lorem/ja.vim b/autoload/emmet/lorem/ja.vim new file mode 100644 index 0000000..f99d8fa --- /dev/null +++ b/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, ']*>\zs.\{-}') + let content = substitute(content, '[ \r]', '', 'g') + let content = substitute(content, ']*>', "\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/autoload/emmet/util.vim b/autoload/emmet/util.vim new file mode 100644 index 0000000..9da8f96 --- /dev/null +++ b/autoload/emmet/util.vim @@ -0,0 +1,349 @@ +"============================================================================== +" region utils +"============================================================================== +" deleteContent : delete content in region +" if region make from between '' and '' +" -------------------- +" begin: +" :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 '' and '' +" -------------------- +" begin: +" :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, ']\+content=["''][^;"'']\+;\s*charset=\zs[^;"'']\+\ze["''][^>]*>') + if len(charset) == 0 + let charset = matchstr(content, ']*>') + 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, '')) + let buf = substitute(buf, ']*>.\{-}', '', 'g') + let buf = substitute(buf, ']*>.\{-}', '', 'g') + let res = '' + let max = 0 + let mx = '\(]\{-}>\)\|\(<\/td>\)\|\(]\{-}>\)\|\(<\/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(s:, 'emmet_use_identify', 1) + return 0 + endif + return executable('identify') +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() ? "\" : '' +endfunction diff --git a/autoload/pathogen.vim b/autoload/pathogen.vim new file mode 100644 index 0000000..3582fbf --- /dev/null +++ b/autoload/pathogen.vim @@ -0,0 +1,264 @@ +" pathogen.vim - path option manipulation +" Maintainer: Tim Pope +" Version: 2.4 + +" Install in ~/.vim/autoload (or ~\vimfiles\autoload). +" +" For management of individually installed plugins in ~/.vim/bundle (or +" ~\vimfiles\bundle), adding `execute pathogen#infect()` to the top of your +" .vimrc is the only other setup necessary. +" +" The API is documented inline below. + +if exists("g:loaded_pathogen") || &cp + finish +endif +let g:loaded_pathogen = 1 + +" Point of entry for basic default usage. Give a relative path to invoke +" pathogen#interpose() or an absolute path to invoke pathogen#surround(). +" Curly braces are expanded with pathogen#expand(): "bundle/{}" finds all +" subdirectories inside "bundle" inside all directories in the runtime path. +" If no arguments are given, defaults "bundle/{}", and also "pack/{}/start/{}" +" on versions of Vim without native package support. +function! pathogen#infect(...) abort + if a:0 + let paths = filter(reverse(copy(a:000)), 'type(v:val) == type("")') + else + let paths = ['bundle/{}', 'pack/{}/start/{}'] + endif + if has('packages') + call filter(paths, 'v:val !~# "^pack/[^/]*/start/[^/]*$"') + endif + let static = '^\%([$~\\/]\|\w:[\\/]\)[^{}*]*$' + for path in filter(copy(paths), 'v:val =~# static') + call pathogen#surround(path) + endfor + for path in filter(copy(paths), 'v:val !~# static') + if path =~# '^\%([$~\\/]\|\w:[\\/]\)' + call pathogen#surround(path) + else + call pathogen#interpose(path) + endif + endfor + call pathogen#cycle_filetype() + if pathogen#is_disabled($MYVIMRC) + return 'finish' + endif + return '' +endfunction + +" Split a path into a list. +function! pathogen#split(path) abort + if type(a:path) == type([]) | return a:path | endif + if empty(a:path) | return [] | endif + let split = split(a:path,'\\\@]','\\&','') + endif +endfunction + +" Like findfile(), but hardcoded to use the runtimepath. +function! pathogen#runtime_findfile(file,count) abort + let rtp = pathogen#join(1,pathogen#split(&rtp)) + let file = findfile(a:file,rtp,a:count) + if file ==# '' + return '' + else + return fnamemodify(file,':p') + endif +endfunction + +" vim:set et sw=2 foldmethod=expr foldexpr=getline(v\:lnum)=~'^\"\ Section\:'?'>1'\:getline(v\:lnum)=~#'^fu'?'a1'\:getline(v\:lnum)=~#'^endf'?'s1'\:'=': diff --git a/autoload/plug.vim b/autoload/plug.vim new file mode 100644 index 0000000..ab0e082 --- /dev/null +++ b/autoload/plug.vim @@ -0,0 +1,2538 @@ +" vim-plug: Vim plugin manager +" ============================ +" +" Download plug.vim and put it in ~/.vim/autoload +" +" curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ +" https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim +" +" Edit your .vimrc +" +" call plug#begin('~/.vim/plugged') +" +" " Make sure you use single quotes +" +" " Shorthand notation; fetches https://github.com/junegunn/vim-easy-align +" Plug 'junegunn/vim-easy-align' +" +" " Any valid git URL is allowed +" Plug 'https://github.com/junegunn/vim-github-dashboard.git' +" +" " Multiple Plug commands can be written in a single line using | separators +" Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets' +" +" " On-demand loading +" Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } +" Plug 'tpope/vim-fireplace', { 'for': 'clojure' } +" +" " Using a non-master branch +" Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' } +" +" " Using a tagged release; wildcard allowed (requires git 1.9.2 or above) +" Plug 'fatih/vim-go', { 'tag': '*' } +" +" " Plugin options +" Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' } +" +" " Plugin outside ~/.vim/plugged with post-update hook +" Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } +" +" " Unmanaged plugin (manually installed and updated) +" Plug '~/my-prototype-plugin' +" +" " Initialize plugin system +" call plug#end() +" +" Then reload .vimrc and :PlugInstall to install plugins. +" +" Plug options: +" +"| Option | Description | +"| ----------------------- | ------------------------------------------------ | +"| `branch`/`tag`/`commit` | Branch/tag/commit of the repository to use | +"| `rtp` | Subdirectory that contains Vim plugin | +"| `dir` | Custom directory for the plugin | +"| `as` | Use different name for the plugin | +"| `do` | Post-update hook (string or funcref) | +"| `on` | On-demand loading: Commands or ``-mappings | +"| `for` | On-demand loading: File types | +"| `frozen` | Do not update unless explicitly specified | +" +" More information: https://github.com/junegunn/vim-plug +" +" +" Copyright (c) 2017 Junegunn Choi +" +" MIT License +" +" Permission is hereby granted, free of charge, to any person obtaining +" a copy of this software and associated documentation files (the +" "Software"), to deal in the Software without restriction, including +" without limitation the rights to use, copy, modify, merge, publish, +" distribute, sublicense, and/or sell copies of the Software, and to +" permit persons to whom the Software is furnished to do so, subject to +" the following conditions: +" +" The above copyright notice and this permission notice shall be +" included in all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +if exists('g:loaded_plug') + finish +endif +let g:loaded_plug = 1 + +let s:cpo_save = &cpo +set cpo&vim + +let s:plug_src = 'https://github.com/junegunn/vim-plug.git' +let s:plug_tab = get(s:, 'plug_tab', -1) +let s:plug_buf = get(s:, 'plug_buf', -1) +let s:mac_gui = has('gui_macvim') && has('gui_running') +let s:is_win = has('win32') +let s:nvim = has('nvim-0.2') || (has('nvim') && exists('*jobwait') && !s:is_win) +let s:vim8 = has('patch-8.0.0039') && exists('*job_start') +let s:me = resolve(expand(':p')) +let s:base_spec = { 'branch': 'master', 'frozen': 0 } +let s:TYPE = { +\ 'string': type(''), +\ 'list': type([]), +\ 'dict': type({}), +\ 'funcref': type(function('call')) +\ } +let s:loaded = get(s:, 'loaded', {}) +let s:triggers = get(s:, 'triggers', {}) + +function! plug#begin(...) + if a:0 > 0 + let s:plug_home_org = a:1 + let home = s:path(fnamemodify(expand(a:1), ':p')) + elseif exists('g:plug_home') + let home = s:path(g:plug_home) + elseif !empty(&rtp) + let home = s:path(split(&rtp, ',')[0]) . '/plugged' + else + return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.') + endif + if fnamemodify(home, ':t') ==# 'plugin' && fnamemodify(home, ':h') ==# s:first_rtp + return s:err('Invalid plug home. '.home.' is a standard Vim runtime path and is not allowed.') + endif + + let g:plug_home = home + let g:plugs = {} + let g:plugs_order = [] + let s:triggers = {} + + call s:define_commands() + return 1 +endfunction + +function! s:define_commands() + command! -nargs=+ -bar Plug call plug#() + if !executable('git') + return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.') + endif + command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install(0, []) + command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update(0, []) + command! -nargs=0 -bar -bang PlugClean call s:clean(0) + command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:esc(s:me) | endif + command! -nargs=0 -bar PlugStatus call s:status() + command! -nargs=0 -bar PlugDiff call s:diff() + command! -nargs=? -bar -bang -complete=file PlugSnapshot call s:snapshot(0, ) +endfunction + +function! s:to_a(v) + return type(a:v) == s:TYPE.list ? a:v : [a:v] +endfunction + +function! s:to_s(v) + return type(a:v) == s:TYPE.string ? a:v : join(a:v, "\n") . "\n" +endfunction + +function! s:glob(from, pattern) + return s:lines(globpath(a:from, a:pattern)) +endfunction + +function! s:source(from, ...) + let found = 0 + for pattern in a:000 + for vim in s:glob(a:from, pattern) + execute 'source' s:esc(vim) + let found = 1 + endfor + endfor + return found +endfunction + +function! s:assoc(dict, key, val) + let a:dict[a:key] = add(get(a:dict, a:key, []), a:val) +endfunction + +function! s:ask(message, ...) + call inputsave() + echohl WarningMsg + let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) ')) + echohl None + call inputrestore() + echo "\r" + return (a:0 && answer =~? '^a') ? 2 : (answer =~? '^y') ? 1 : 0 +endfunction + +function! s:ask_no_interrupt(...) + try + return call('s:ask', a:000) + catch + return 0 + endtry +endfunction + +function! s:lazy(plug, opt) + return has_key(a:plug, a:opt) && + \ (empty(s:to_a(a:plug[a:opt])) || + \ !isdirectory(a:plug.dir) || + \ len(s:glob(s:rtp(a:plug), 'plugin')) || + \ len(s:glob(s:rtp(a:plug), 'after/plugin'))) +endfunction + +function! plug#end() + if !exists('g:plugs') + return s:err('Call plug#begin() first') + endif + + if exists('#PlugLOD') + augroup PlugLOD + autocmd! + augroup END + augroup! PlugLOD + endif + let lod = { 'ft': {}, 'map': {}, 'cmd': {} } + + if exists('g:did_load_filetypes') + filetype off + endif + for name in g:plugs_order + if !has_key(g:plugs, name) + continue + endif + let plug = g:plugs[name] + if get(s:loaded, name, 0) || !s:lazy(plug, 'on') && !s:lazy(plug, 'for') + let s:loaded[name] = 1 + continue + endif + + if has_key(plug, 'on') + let s:triggers[name] = { 'map': [], 'cmd': [] } + for cmd in s:to_a(plug.on) + if cmd =~? '^.\+' + if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i')) + call s:assoc(lod.map, cmd, name) + endif + call add(s:triggers[name].map, cmd) + elseif cmd =~# '^[A-Z]' + let cmd = substitute(cmd, '!*$', '', '') + if exists(':'.cmd) != 2 + call s:assoc(lod.cmd, cmd, name) + endif + call add(s:triggers[name].cmd, cmd) + else + call s:err('Invalid `on` option: '.cmd. + \ '. Should start with an uppercase letter or ``.') + endif + endfor + endif + + if has_key(plug, 'for') + let types = s:to_a(plug.for) + if !empty(types) + augroup filetypedetect + call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') + augroup END + endif + for type in types + call s:assoc(lod.ft, type, name) + endfor + endif + endfor + + for [cmd, names] in items(lod.cmd) + execute printf( + \ 'command! -nargs=* -range -bang -complete=file %s call s:lod_cmd(%s, "", , , , %s)', + \ cmd, string(cmd), string(names)) + endfor + + for [map, names] in items(lod.map) + for [mode, map_prefix, key_prefix] in + \ [['i', '', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']] + execute printf( + \ '%snoremap %s %s:call lod_map(%s, %s, %s, "%s")', + \ mode, map, map_prefix, string(map), string(names), mode != 'i', key_prefix) + endfor + endfor + + for [ft, names] in items(lod.ft) + augroup PlugLOD + execute printf('autocmd FileType %s call lod_ft(%s, %s)', + \ ft, string(ft), string(names)) + augroup END + endfor + + call s:reorg_rtp() + filetype plugin indent on + if has('vim_starting') + if has('syntax') && !exists('g:syntax_on') + syntax enable + end + else + call s:reload_plugins() + endif +endfunction + +function! s:loaded_names() + return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)') +endfunction + +function! s:load_plugin(spec) + call s:source(s:rtp(a:spec), 'plugin/**/*.vim', 'after/plugin/**/*.vim') +endfunction + +function! s:reload_plugins() + for name in s:loaded_names() + call s:load_plugin(g:plugs[name]) + endfor +endfunction + +function! s:trim(str) + return substitute(a:str, '[\/]\+$', '', '') +endfunction + +function! s:version_requirement(val, min) + for idx in range(0, len(a:min) - 1) + let v = get(a:val, idx, 0) + if v < a:min[idx] | return 0 + elseif v > a:min[idx] | return 1 + endif + endfor + return 1 +endfunction + +function! s:git_version_requirement(...) + if !exists('s:git_version') + let s:git_version = map(split(split(s:system('git --version'))[2], '\.'), 'str2nr(v:val)') + endif + return s:version_requirement(s:git_version, a:000) +endfunction + +function! s:progress_opt(base) + return a:base && !s:is_win && + \ s:git_version_requirement(1, 7, 1) ? '--progress' : '' +endfunction + +function! s:rtp(spec) + return s:path(a:spec.dir . get(a:spec, 'rtp', '')) +endfunction + +if s:is_win + function! s:path(path) + return s:trim(substitute(a:path, '/', '\', 'g')) + endfunction + + function! s:dirpath(path) + return s:path(a:path) . '\' + endfunction + + function! s:is_local_plug(repo) + return a:repo =~? '^[a-z]:\|^[%~]' + endfunction + + " Copied from fzf + function! s:wrap_cmds(cmds) + let use_chcp = executable('sed') + return map([ + \ '@echo off', + \ 'setlocal enabledelayedexpansion'] + \ + (use_chcp ? [ + \ 'for /f "usebackq" %%a in (`chcp ^| sed "s/[^0-9]//gp"`) do set origchcp=%%a', + \ 'chcp 65001 > nul'] : []) + \ + (type(a:cmds) == type([]) ? a:cmds : [a:cmds]) + \ + (use_chcp ? ['chcp !origchcp! > nul'] : []) + \ + ['endlocal'], + \ 'v:val."\r"') + endfunction + + function! s:batchfile(cmd) + let batchfile = tempname().'.bat' + call writefile(s:wrap_cmds(a:cmd), batchfile) + let cmd = plug#shellescape(batchfile, {'shell': &shell, 'script': 1}) + if &shell =~# 'powershell\.exe$' + let cmd = '& ' . cmd + endif + return [batchfile, cmd] + endfunction +else + function! s:path(path) + return s:trim(a:path) + endfunction + + function! s:dirpath(path) + return substitute(a:path, '[/\\]*$', '/', '') + endfunction + + function! s:is_local_plug(repo) + return a:repo[0] =~ '[/$~]' + endfunction +endif + +function! s:err(msg) + echohl ErrorMsg + echom '[vim-plug] '.a:msg + echohl None +endfunction + +function! s:warn(cmd, msg) + echohl WarningMsg + execute a:cmd 'a:msg' + echohl None +endfunction + +function! s:esc(path) + return escape(a:path, ' ') +endfunction + +function! s:escrtp(path) + return escape(a:path, ' ,') +endfunction + +function! s:remove_rtp() + for name in s:loaded_names() + let rtp = s:rtp(g:plugs[name]) + execute 'set rtp-='.s:escrtp(rtp) + let after = globpath(rtp, 'after') + if isdirectory(after) + execute 'set rtp-='.s:escrtp(after) + endif + endfor +endfunction + +function! s:reorg_rtp() + if !empty(s:first_rtp) + execute 'set rtp-='.s:first_rtp + execute 'set rtp-='.s:last_rtp + endif + + " &rtp is modified from outside + if exists('s:prtp') && s:prtp !=# &rtp + call s:remove_rtp() + unlet! s:middle + endif + + let s:middle = get(s:, 'middle', &rtp) + let rtps = map(s:loaded_names(), 's:rtp(g:plugs[v:val])') + let afters = filter(map(copy(rtps), 'globpath(v:val, "after")'), '!empty(v:val)') + let rtp = join(map(rtps, 'escape(v:val, ",")'), ',') + \ . ','.s:middle.',' + \ . join(map(afters, 'escape(v:val, ",")'), ',') + let &rtp = substitute(substitute(rtp, ',,*', ',', 'g'), '^,\|,$', '', 'g') + let s:prtp = &rtp + + if !empty(s:first_rtp) + execute 'set rtp^='.s:first_rtp + execute 'set rtp+='.s:last_rtp + endif +endfunction + +function! s:doautocmd(...) + if exists('#'.join(a:000, '#')) + execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '' : '') join(a:000) + endif +endfunction + +function! s:dobufread(names) + for name in a:names + let path = s:rtp(g:plugs[name]) + for dir in ['ftdetect', 'ftplugin', 'after/ftdetect', 'after/ftplugin'] + if len(finddir(dir, path)) + if exists('#BufRead') + doautocmd BufRead + endif + return + endif + endfor + endfor +endfunction + +function! plug#load(...) + if a:0 == 0 + return s:err('Argument missing: plugin name(s) required') + endif + if !exists('g:plugs') + return s:err('plug#begin was not called') + endif + let names = a:0 == 1 && type(a:1) == s:TYPE.list ? a:1 : a:000 + let unknowns = filter(copy(names), '!has_key(g:plugs, v:val)') + if !empty(unknowns) + let s = len(unknowns) > 1 ? 's' : '' + return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', '))) + end + let unloaded = filter(copy(names), '!get(s:loaded, v:val, 0)') + if !empty(unloaded) + for name in unloaded + call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + endfor + call s:dobufread(unloaded) + return 1 + end + return 0 +endfunction + +function! s:remove_triggers(name) + if !has_key(s:triggers, a:name) + return + endif + for cmd in s:triggers[a:name].cmd + execute 'silent! delc' cmd + endfor + for map in s:triggers[a:name].map + execute 'silent! unmap' map + execute 'silent! iunmap' map + endfor + call remove(s:triggers, a:name) +endfunction + +function! s:lod(names, types, ...) + for name in a:names + call s:remove_triggers(name) + let s:loaded[name] = 1 + endfor + call s:reorg_rtp() + + for name in a:names + let rtp = s:rtp(g:plugs[name]) + for dir in a:types + call s:source(rtp, dir.'/**/*.vim') + endfor + if a:0 + if !s:source(rtp, a:1) && !empty(s:glob(rtp, a:2)) + execute 'runtime' a:1 + endif + call s:source(rtp, a:2) + endif + call s:doautocmd('User', name) + endfor +endfunction + +function! s:lod_ft(pat, names) + let syn = 'syntax/'.a:pat.'.vim' + call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn) + execute 'autocmd! PlugLOD FileType' a:pat + call s:doautocmd('filetypeplugin', 'FileType') + call s:doautocmd('filetypeindent', 'FileType') +endfunction + +function! s:lod_cmd(cmd, bang, l1, l2, args, names) + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + call s:dobufread(a:names) + execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args) +endfunction + +function! s:lod_map(map, names, with_prefix, prefix) + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + call s:dobufread(a:names) + let extra = '' + while 1 + let c = getchar(0) + if c == 0 + break + endif + let extra .= nr2char(c) + endwhile + + if a:with_prefix + let prefix = v:count ? v:count : '' + let prefix .= '"'.v:register.a:prefix + if mode(1) == 'no' + if v:operator == 'c' + let prefix = "\" . prefix + endif + let prefix .= v:operator + endif + call feedkeys(prefix, 'n') + endif + call feedkeys(substitute(a:map, '^', "\", '') . extra) +endfunction + +function! plug#(repo, ...) + if a:0 > 1 + return s:err('Invalid number of arguments (1..2)') + endif + + try + let repo = s:trim(a:repo) + let opts = a:0 == 1 ? s:parse_options(a:1) : s:base_spec + let name = get(opts, 'as', fnamemodify(repo, ':t:s?\.git$??')) + let spec = extend(s:infer_properties(name, repo), opts) + if !has_key(g:plugs, name) + call add(g:plugs_order, name) + endif + let g:plugs[name] = spec + let s:loaded[name] = get(s:loaded, name, 0) + catch + return s:err(v:exception) + endtry +endfunction + +function! s:parse_options(arg) + let opts = copy(s:base_spec) + let type = type(a:arg) + if type == s:TYPE.string + let opts.tag = a:arg + elseif type == s:TYPE.dict + call extend(opts, a:arg) + if has_key(opts, 'dir') + let opts.dir = s:dirpath(expand(opts.dir)) + endif + else + throw 'Invalid argument type (expected: string or dictionary)' + endif + return opts +endfunction + +function! s:infer_properties(name, repo) + let repo = a:repo + if s:is_local_plug(repo) + return { 'dir': s:dirpath(expand(repo)) } + else + if repo =~ ':' + let uri = repo + else + if repo !~ '/' + throw printf('Invalid argument: %s (implicit `vim-scripts'' expansion is deprecated)', repo) + endif + let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git') + let uri = printf(fmt, repo) + endif + return { 'dir': s:dirpath(g:plug_home.'/'.a:name), 'uri': uri } + endif +endfunction + +function! s:install(force, names) + call s:update_impl(0, a:force, a:names) +endfunction + +function! s:update(force, names) + call s:update_impl(1, a:force, a:names) +endfunction + +function! plug#helptags() + if !exists('g:plugs') + return s:err('plug#begin was not called') + endif + for spec in values(g:plugs) + let docd = join([s:rtp(spec), 'doc'], '/') + if isdirectory(docd) + silent! execute 'helptags' s:esc(docd) + endif + endfor + return 1 +endfunction + +function! s:syntax() + syntax clear + syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber + syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX + syn match plugNumber /[0-9]\+[0-9.]*/ contained + syn match plugBracket /[[\]]/ contained + syn match plugX /x/ contained + syn match plugDash /^-/ + syn match plugPlus /^+/ + syn match plugStar /^*/ + syn match plugMessage /\(^- \)\@<=.*/ + syn match plugName /\(^- \)\@<=[^ ]*:/ + syn match plugSha /\%(: \)\@<=[0-9a-f]\{4,}$/ + syn match plugTag /(tag: [^)]\+)/ + syn match plugInstall /\(^+ \)\@<=[^:]*/ + syn match plugUpdate /\(^* \)\@<=[^:]*/ + syn match plugCommit /^ \X*[0-9a-f]\{7,9} .*/ contains=plugRelDate,plugEdge,plugTag + syn match plugEdge /^ \X\+$/ + syn match plugEdge /^ \X*/ contained nextgroup=plugSha + syn match plugSha /[0-9a-f]\{7,9}/ contained + syn match plugRelDate /([^)]*)$/ contained + syn match plugNotLoaded /(not loaded)$/ + syn match plugError /^x.*/ + syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/ + syn match plugH2 /^.*:\n-\+$/ + syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean + hi def link plug1 Title + hi def link plug2 Repeat + hi def link plugH2 Type + hi def link plugX Exception + hi def link plugBracket Structure + hi def link plugNumber Number + + hi def link plugDash Special + hi def link plugPlus Constant + hi def link plugStar Boolean + + hi def link plugMessage Function + hi def link plugName Label + hi def link plugInstall Function + hi def link plugUpdate Type + + hi def link plugError Error + hi def link plugDeleted Ignore + hi def link plugRelDate Comment + hi def link plugEdge PreProc + hi def link plugSha Identifier + hi def link plugTag Constant + + hi def link plugNotLoaded Comment +endfunction + +function! s:lpad(str, len) + return a:str . repeat(' ', a:len - len(a:str)) +endfunction + +function! s:lines(msg) + return split(a:msg, "[\r\n]") +endfunction + +function! s:lastline(msg) + return get(s:lines(a:msg), -1, '') +endfunction + +function! s:new_window() + execute get(g:, 'plug_window', 'vertical topleft new') +endfunction + +function! s:plug_window_exists() + let buflist = tabpagebuflist(s:plug_tab) + return !empty(buflist) && index(buflist, s:plug_buf) >= 0 +endfunction + +function! s:switch_in() + if !s:plug_window_exists() + return 0 + endif + + if winbufnr(0) != s:plug_buf + let s:pos = [tabpagenr(), winnr(), winsaveview()] + execute 'normal!' s:plug_tab.'gt' + let winnr = bufwinnr(s:plug_buf) + execute winnr.'wincmd w' + call add(s:pos, winsaveview()) + else + let s:pos = [winsaveview()] + endif + + setlocal modifiable + return 1 +endfunction + +function! s:switch_out(...) + call winrestview(s:pos[-1]) + setlocal nomodifiable + if a:0 > 0 + execute a:1 + endif + + if len(s:pos) > 1 + execute 'normal!' s:pos[0].'gt' + execute s:pos[1] 'wincmd w' + call winrestview(s:pos[2]) + endif +endfunction + +function! s:finish_bindings() + nnoremap R :call retry() + nnoremap D :PlugDiff + nnoremap S :PlugStatus + nnoremap U :call status_update() + xnoremap U :call status_update() + nnoremap ]] :silent! call section('') + nnoremap [[ :silent! call section('b') +endfunction + +function! s:prepare(...) + if empty(getcwd()) + throw 'Invalid current working directory. Cannot proceed.' + endif + + for evar in ['$GIT_DIR', '$GIT_WORK_TREE'] + if exists(evar) + throw evar.' detected. Cannot proceed.' + endif + endfor + + call s:job_abort() + if s:switch_in() + if b:plug_preview == 1 + pc + endif + enew + else + call s:new_window() + endif + + nnoremap q :if b:plug_preview==1pcendifbd + if a:0 == 0 + call s:finish_bindings() + endif + let b:plug_preview = -1 + let s:plug_tab = tabpagenr() + let s:plug_buf = winbufnr(0) + call s:assign_name() + + for k in ['', 'L', 'o', 'X', 'd', 'dd'] + execute 'silent! unmap ' k + endfor + setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline modifiable nospell + if exists('+colorcolumn') + setlocal colorcolumn= + endif + setf vim-plug + if exists('g:syntax_on') + call s:syntax() + endif +endfunction + +function! s:assign_name() + " Assign buffer name + let prefix = '[Plugins]' + let name = prefix + let idx = 2 + while bufexists(name) + let name = printf('%s (%s)', prefix, idx) + let idx = idx + 1 + endwhile + silent! execute 'f' fnameescape(name) +endfunction + +function! s:chsh(swap) + let prev = [&shell, &shellcmdflag, &shellredir] + if !s:is_win && a:swap + set shell=sh shellredir=>%s\ 2>&1 + endif + return prev +endfunction + +function! s:bang(cmd, ...) + try + let [sh, shellcmdflag, shrd] = s:chsh(a:0) + " FIXME: Escaping is incomplete. We could use shellescape with eval, + " but it won't work on Windows. + let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd + if s:is_win + let [batchfile, cmd] = s:batchfile(cmd) + endif + let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%') + execute "normal! :execute g:_plug_bang\\" + finally + unlet g:_plug_bang + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win + call delete(batchfile) + endif + endtry + return v:shell_error ? 'Exit status: ' . v:shell_error : '' +endfunction + +function! s:regress_bar() + let bar = substitute(getline(2)[1:-2], '.*\zs=', 'x', '') + call s:progress_bar(2, bar, len(bar)) +endfunction + +function! s:is_updated(dir) + return !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"', a:dir)) +endfunction + +function! s:do(pull, force, todo) + for [name, spec] in items(a:todo) + if !isdirectory(spec.dir) + continue + endif + let installed = has_key(s:update.new, name) + let updated = installed ? 0 : + \ (a:pull && index(s:update.errors, name) < 0 && s:is_updated(spec.dir)) + if a:force || installed || updated + execute 'cd' s:esc(spec.dir) + call append(3, '- Post-update hook for '. name .' ... ') + let error = '' + let type = type(spec.do) + if type == s:TYPE.string + if spec.do[0] == ':' + if !get(s:loaded, name, 0) + let s:loaded[name] = 1 + call s:reorg_rtp() + endif + call s:load_plugin(spec) + try + execute spec.do[1:] + catch + let error = v:exception + endtry + if !s:plug_window_exists() + cd - + throw 'Warning: vim-plug was terminated by the post-update hook of '.name + endif + else + let error = s:bang(spec.do) + endif + elseif type == s:TYPE.funcref + try + let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') + call spec.do({ 'name': name, 'status': status, 'force': a:force }) + catch + let error = v:exception + endtry + else + let error = 'Invalid hook type' + endif + call s:switch_in() + call setline(4, empty(error) ? (getline(4) . 'OK') + \ : ('x' . getline(4)[1:] . error)) + if !empty(error) + call add(s:update.errors, name) + call s:regress_bar() + endif + cd - + endif + endfor +endfunction + +function! s:hash_match(a, b) + return stridx(a:a, a:b) == 0 || stridx(a:b, a:a) == 0 +endfunction + +function! s:checkout(spec) + let sha = a:spec.commit + let output = s:system('git rev-parse HEAD', a:spec.dir) + if !v:shell_error && !s:hash_match(sha, s:lines(output)[0]) + let output = s:system( + \ 'git fetch --depth 999999 && git checkout '.s:esc(sha).' --', a:spec.dir) + endif + return output +endfunction + +function! s:finish(pull) + let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen')) + if new_frozen + let s = new_frozen > 1 ? 's' : '' + call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s)) + endif + call append(3, '- Finishing ... ') | 4 + redraw + call plug#helptags() + call plug#end() + call setline(4, getline(4) . 'Done!') + redraw + let msgs = [] + if !empty(s:update.errors) + call add(msgs, "Press 'R' to retry.") + endif + if a:pull && len(s:update.new) < len(filter(getline(5, '$'), + \ "v:val =~ '^- ' && v:val !~# 'Already up.to.date'")) + call add(msgs, "Press 'D' to see the updated changes.") + endif + echo join(msgs, ' ') + call s:finish_bindings() +endfunction + +function! s:retry() + if empty(s:update.errors) + return + endif + echo + call s:update_impl(s:update.pull, s:update.force, + \ extend(copy(s:update.errors), [s:update.threads])) +endfunction + +function! s:is_managed(name) + return has_key(g:plugs[a:name], 'uri') +endfunction + +function! s:names(...) + return sort(filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)')) +endfunction + +function! s:check_ruby() + silent! ruby require 'thread'; VIM::command("let g:plug_ruby = '#{RUBY_VERSION}'") + if !exists('g:plug_ruby') + redraw! + return s:warn('echom', 'Warning: Ruby interface is broken') + endif + let ruby_version = split(g:plug_ruby, '\.') + unlet g:plug_ruby + return s:version_requirement(ruby_version, [1, 8, 7]) +endfunction + +function! s:update_impl(pull, force, args) abort + let sync = index(a:args, '--sync') >= 0 || has('vim_starting') + let args = filter(copy(a:args), 'v:val != "--sync"') + let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ? + \ remove(args, -1) : get(g:, 'plug_threads', 16) + + let managed = filter(copy(g:plugs), 's:is_managed(v:key)') + let todo = empty(args) ? filter(managed, '!v:val.frozen || !isdirectory(v:val.dir)') : + \ filter(managed, 'index(args, v:key) >= 0') + + if empty(todo) + return s:warn('echo', 'No plugin to '. (a:pull ? 'update' : 'install')) + endif + + if !s:is_win && s:git_version_requirement(2, 3) + let s:git_terminal_prompt = exists('$GIT_TERMINAL_PROMPT') ? $GIT_TERMINAL_PROMPT : '' + let $GIT_TERMINAL_PROMPT = 0 + for plug in values(todo) + let plug.uri = substitute(plug.uri, + \ '^https://git::@github\.com', 'https://github.com', '') + endfor + endif + + if !isdirectory(g:plug_home) + try + call mkdir(g:plug_home, 'p') + catch + return s:err(printf('Invalid plug directory: %s. '. + \ 'Try to call plug#begin with a valid directory', g:plug_home)) + endtry + endif + + if has('nvim') && !exists('*jobwait') && threads > 1 + call s:warn('echom', '[vim-plug] Update Neovim for parallel installer') + endif + + let use_job = s:nvim || s:vim8 + let python = (has('python') || has('python3')) && !use_job + let ruby = has('ruby') && !use_job && (v:version >= 703 || v:version == 702 && has('patch374')) && !(s:is_win && has('gui_running')) && threads > 1 && s:check_ruby() + + let s:update = { + \ 'start': reltime(), + \ 'all': todo, + \ 'todo': copy(todo), + \ 'errors': [], + \ 'pull': a:pull, + \ 'force': a:force, + \ 'new': {}, + \ 'threads': (python || ruby || use_job) ? min([len(todo), threads]) : 1, + \ 'bar': '', + \ 'fin': 0 + \ } + + call s:prepare(1) + call append(0, ['', '']) + normal! 2G + silent! redraw + + let s:clone_opt = get(g:, 'plug_shallow', 1) ? + \ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : '' + + if has('win32unix') || has('wsl') + let s:clone_opt .= ' -c core.eol=lf -c core.autocrlf=input' + endif + + let s:submodule_opt = s:git_version_requirement(2, 8) ? ' --jobs='.threads : '' + + " Python version requirement (>= 2.7) + if python && !has('python3') && !ruby && !use_job && s:update.threads > 1 + redir => pyv + silent python import platform; print platform.python_version() + redir END + let python = s:version_requirement( + \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 6]) + endif + + if (python || ruby) && s:update.threads > 1 + try + let imd = &imd + if s:mac_gui + set noimd + endif + if ruby + call s:update_ruby() + else + call s:update_python() + endif + catch + let lines = getline(4, '$') + let printed = {} + silent! 4,$d _ + for line in lines + let name = s:extract_name(line, '.', '') + if empty(name) || !has_key(printed, name) + call append('$', line) + if !empty(name) + let printed[name] = 1 + if line[0] == 'x' && index(s:update.errors, name) < 0 + call add(s:update.errors, name) + end + endif + endif + endfor + finally + let &imd = imd + call s:update_finish() + endtry + else + call s:update_vim() + while use_job && sync + sleep 100m + if s:update.fin + break + endif + endwhile + endif +endfunction + +function! s:log4(name, msg) + call setline(4, printf('- %s (%s)', a:msg, a:name)) + redraw +endfunction + +function! s:update_finish() + if exists('s:git_terminal_prompt') + let $GIT_TERMINAL_PROMPT = s:git_terminal_prompt + endif + if s:switch_in() + call append(3, '- Updating ...') | 4 + for [name, spec] in items(filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && (s:update.force || s:update.pull || has_key(s:update.new, v:key))')) + let [pos, _] = s:logpos(name) + if !pos + continue + endif + if has_key(spec, 'commit') + call s:log4(name, 'Checking out '.spec.commit) + let out = s:checkout(spec) + elseif has_key(spec, 'tag') + let tag = spec.tag + if tag =~ '\*' + let tags = s:lines(s:system('git tag --list '.plug#shellescape(tag).' --sort -version:refname 2>&1', spec.dir)) + if !v:shell_error && !empty(tags) + let tag = tags[0] + call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag)) + call append(3, '') + endif + endif + call s:log4(name, 'Checking out '.tag) + let out = s:system('git checkout -q '.s:esc(tag).' -- 2>&1', spec.dir) + else + let branch = s:esc(get(spec, 'branch', 'master')) + call s:log4(name, 'Merging origin/'.branch) + let out = s:system('git checkout -q '.branch.' -- 2>&1' + \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only origin/'.branch.' 2>&1')), spec.dir) + endif + if !v:shell_error && filereadable(spec.dir.'/.gitmodules') && + \ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir)) + call s:log4(name, 'Updating submodules. This may take a while.') + let out .= s:bang('git submodule update --init --recursive'.s:submodule_opt.' 2>&1', spec.dir) + endif + let msg = s:format_message(v:shell_error ? 'x': '-', name, out) + if v:shell_error + call add(s:update.errors, name) + call s:regress_bar() + silent execute pos 'd _' + call append(4, msg) | 4 + elseif !empty(out) + call setline(pos, msg[0]) + endif + redraw + endfor + silent 4 d _ + try + call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")')) + catch + call s:warn('echom', v:exception) + call s:warn('echo', '') + return + endtry + call s:finish(s:update.pull) + call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.') + call s:switch_out('normal! gg') + endif +endfunction + +function! s:job_abort() + if (!s:nvim && !s:vim8) || !exists('s:jobs') + return + endif + + for [name, j] in items(s:jobs) + if s:nvim + silent! call jobstop(j.jobid) + elseif s:vim8 + silent! call job_stop(j.jobid) + endif + if j.new + call s:system('rm -rf ' . plug#shellescape(g:plugs[name].dir)) + endif + endfor + let s:jobs = {} +endfunction + +function! s:last_non_empty_line(lines) + let len = len(a:lines) + for idx in range(len) + let line = a:lines[len-idx-1] + if !empty(line) + return line + endif + endfor + return '' +endfunction + +function! s:job_out_cb(self, data) abort + let self = a:self + let data = remove(self.lines, -1) . a:data + let lines = map(split(data, "\n", 1), 'split(v:val, "\r", 1)[-1]') + call extend(self.lines, lines) + " To reduce the number of buffer updates + let self.tick = get(self, 'tick', -1) + 1 + if !self.running || self.tick % len(s:jobs) == 0 + let bullet = self.running ? (self.new ? '+' : '*') : (self.error ? 'x' : '-') + let result = self.error ? join(self.lines, "\n") : s:last_non_empty_line(self.lines) + call s:log(bullet, self.name, result) + endif +endfunction + +function! s:job_exit_cb(self, data) abort + let a:self.running = 0 + let a:self.error = a:data != 0 + call s:reap(a:self.name) + call s:tick() +endfunction + +function! s:job_cb(fn, job, ch, data) + if !s:plug_window_exists() " plug window closed + return s:job_abort() + endif + call call(a:fn, [a:job, a:data]) +endfunction + +function! s:nvim_cb(job_id, data, event) dict abort + return a:event == 'stdout' ? + \ s:job_cb('s:job_out_cb', self, 0, join(a:data, "\n")) : + \ s:job_cb('s:job_exit_cb', self, 0, a:data) +endfunction + +function! s:spawn(name, cmd, opts) + let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''], + \ 'new': get(a:opts, 'new', 0) } + let s:jobs[a:name] = job + let cmd = has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir, 0) : a:cmd + let argv = s:is_win ? ['cmd', '/s', '/c', '"'.cmd.'"'] : ['sh', '-c', cmd] + + if s:nvim + call extend(job, { + \ 'on_stdout': function('s:nvim_cb'), + \ 'on_exit': function('s:nvim_cb'), + \ }) + let jid = jobstart(argv, job) + if jid > 0 + let job.jobid = jid + else + let job.running = 0 + let job.error = 1 + let job.lines = [jid < 0 ? argv[0].' is not executable' : + \ 'Invalid arguments (or job table is full)'] + endif + elseif s:vim8 + let jid = job_start(s:is_win ? join(argv, ' ') : argv, { + \ 'out_cb': function('s:job_cb', ['s:job_out_cb', job]), + \ 'exit_cb': function('s:job_cb', ['s:job_exit_cb', job]), + \ 'out_mode': 'raw' + \}) + if job_status(jid) == 'run' + let job.jobid = jid + else + let job.running = 0 + let job.error = 1 + let job.lines = ['Failed to start job'] + endif + else + let job.lines = s:lines(call('s:system', [cmd])) + let job.error = v:shell_error != 0 + let job.running = 0 + endif +endfunction + +function! s:reap(name) + let job = s:jobs[a:name] + if job.error + call add(s:update.errors, a:name) + elseif get(job, 'new', 0) + let s:update.new[a:name] = 1 + endif + let s:update.bar .= job.error ? 'x' : '=' + + let bullet = job.error ? 'x' : '-' + let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines) + call s:log(bullet, a:name, empty(result) ? 'OK' : result) + call s:bar() + + call remove(s:jobs, a:name) +endfunction + +function! s:bar() + if s:switch_in() + let total = len(s:update.all) + call setline(1, (s:update.pull ? 'Updating' : 'Installing'). + \ ' plugins ('.len(s:update.bar).'/'.total.')') + call s:progress_bar(2, s:update.bar, total) + call s:switch_out() + endif +endfunction + +function! s:logpos(name) + for i in range(4, line('$')) + if getline(i) =~# '^[-+x*] '.a:name.':' + for j in range(i + 1, line('$')) + if getline(j) !~ '^ ' + return [i, j - 1] + endif + endfor + return [i, i] + endif + endfor + return [0, 0] +endfunction + +function! s:log(bullet, name, lines) + if s:switch_in() + let [b, e] = s:logpos(a:name) + if b > 0 + silent execute printf('%d,%d d _', b, e) + if b > winheight('.') + let b = 4 + endif + else + let b = 4 + endif + " FIXME For some reason, nomodifiable is set after :d in vim8 + setlocal modifiable + call append(b - 1, s:format_message(a:bullet, a:name, a:lines)) + call s:switch_out() + endif +endfunction + +function! s:update_vim() + let s:jobs = {} + + call s:bar() + call s:tick() +endfunction + +function! s:tick() + let pull = s:update.pull + let prog = s:progress_opt(s:nvim || s:vim8) +while 1 " Without TCO, Vim stack is bound to explode + if empty(s:update.todo) + if empty(s:jobs) && !s:update.fin + call s:update_finish() + let s:update.fin = 1 + endif + return + endif + + let name = keys(s:update.todo)[0] + let spec = remove(s:update.todo, name) + let new = empty(globpath(spec.dir, '.git', 1)) + + call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...') + redraw + + let has_tag = has_key(spec, 'tag') + if !new + let [error, _] = s:git_validate(spec, 0) + if empty(error) + if pull + let fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : '' + call s:spawn(name, printf('git fetch %s %s 2>&1', fetch_opt, prog), { 'dir': spec.dir }) + else + let s:jobs[name] = { 'running': 0, 'lines': ['Already installed'], 'error': 0 } + endif + else + let s:jobs[name] = { 'running': 0, 'lines': s:lines(error), 'error': 1 } + endif + else + call s:spawn(name, + \ printf('git clone %s %s %s %s 2>&1', + \ has_tag ? '' : s:clone_opt, + \ prog, + \ plug#shellescape(spec.uri, {'script': 0}), + \ plug#shellescape(s:trim(spec.dir), {'script': 0})), { 'new': 1 }) + endif + + if !s:jobs[name].running + call s:reap(name) + endif + if len(s:jobs) >= s:update.threads + break + endif +endwhile +endfunction + +function! s:update_python() +let py_exe = has('python') ? 'python' : 'python3' +execute py_exe "<< EOF" +import datetime +import functools +import os +try: + import queue +except ImportError: + import Queue as queue +import random +import re +import shutil +import signal +import subprocess +import tempfile +import threading as thr +import time +import traceback +import vim + +G_NVIM = vim.eval("has('nvim')") == '1' +G_PULL = vim.eval('s:update.pull') == '1' +G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1 +G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)')) +G_CLONE_OPT = vim.eval('s:clone_opt') +G_PROGRESS = vim.eval('s:progress_opt(1)') +G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads')) +G_STOP = thr.Event() +G_IS_WIN = vim.eval('s:is_win') == '1' + +class PlugError(Exception): + def __init__(self, msg): + self.msg = msg +class CmdTimedOut(PlugError): + pass +class CmdFailed(PlugError): + pass +class InvalidURI(PlugError): + pass +class Action(object): + INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-'] + +class Buffer(object): + def __init__(self, lock, num_plugs, is_pull): + self.bar = '' + self.event = 'Updating' if is_pull else 'Installing' + self.lock = lock + self.maxy = int(vim.eval('winheight(".")')) + self.num_plugs = num_plugs + + def __where(self, name): + """ Find first line with name in current buffer. Return line num. """ + found, lnum = False, 0 + matcher = re.compile('^[-+x*] {0}:'.format(name)) + for line in vim.current.buffer: + if matcher.search(line) is not None: + found = True + break + lnum += 1 + + if not found: + lnum = -1 + return lnum + + def header(self): + curbuf = vim.current.buffer + curbuf[0] = self.event + ' plugins ({0}/{1})'.format(len(self.bar), self.num_plugs) + + num_spaces = self.num_plugs - len(self.bar) + curbuf[1] = '[{0}{1}]'.format(self.bar, num_spaces * ' ') + + with self.lock: + vim.command('normal! 2G') + vim.command('redraw') + + def write(self, action, name, lines): + first, rest = lines[0], lines[1:] + msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)] + msg.extend([' ' + line for line in rest]) + + try: + if action == Action.ERROR: + self.bar += 'x' + vim.command("call add(s:update.errors, '{0}')".format(name)) + elif action == Action.DONE: + self.bar += '=' + + curbuf = vim.current.buffer + lnum = self.__where(name) + if lnum != -1: # Found matching line num + del curbuf[lnum] + if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]): + lnum = 3 + else: + lnum = 3 + curbuf.append(msg, lnum) + + self.header() + except vim.error: + pass + +class Command(object): + CD = 'cd /d' if G_IS_WIN else 'cd' + + def __init__(self, cmd, cmd_dir=None, timeout=60, cb=None, clean=None): + self.cmd = cmd + if cmd_dir: + self.cmd = '{0} {1} && {2}'.format(Command.CD, cmd_dir, self.cmd) + self.timeout = timeout + self.callback = cb if cb else (lambda msg: None) + self.clean = clean if clean else (lambda: None) + self.proc = None + + @property + def alive(self): + """ Returns true only if command still running. """ + return self.proc and self.proc.poll() is None + + def execute(self, ntries=3): + """ Execute the command with ntries if CmdTimedOut. + Returns the output of the command if no Exception. + """ + attempt, finished, limit = 0, False, self.timeout + + while not finished: + try: + attempt += 1 + result = self.try_command() + finished = True + return result + except CmdTimedOut: + if attempt != ntries: + self.notify_retry() + self.timeout += limit + else: + raise + + def notify_retry(self): + """ Retry required for command, notify user. """ + for count in range(3, 0, -1): + if G_STOP.is_set(): + raise KeyboardInterrupt + msg = 'Timeout. Will retry in {0} second{1} ...'.format( + count, 's' if count != 1 else '') + self.callback([msg]) + time.sleep(1) + self.callback(['Retrying ...']) + + def try_command(self): + """ Execute a cmd & poll for callback. Returns list of output. + Raises CmdFailed -> return code for Popen isn't 0 + Raises CmdTimedOut -> command exceeded timeout without new output + """ + first_line = True + + try: + tfile = tempfile.NamedTemporaryFile(mode='w+b') + preexec_fn = not G_IS_WIN and os.setsid or None + self.proc = subprocess.Popen(self.cmd, stdout=tfile, + stderr=subprocess.STDOUT, + stdin=subprocess.PIPE, shell=True, + preexec_fn=preexec_fn) + thrd = thr.Thread(target=(lambda proc: proc.wait()), args=(self.proc,)) + thrd.start() + + thread_not_started = True + while thread_not_started: + try: + thrd.join(0.1) + thread_not_started = False + except RuntimeError: + pass + + while self.alive: + if G_STOP.is_set(): + raise KeyboardInterrupt + + if first_line or random.random() < G_LOG_PROB: + first_line = False + line = '' if G_IS_WIN else nonblock_read(tfile.name) + if line: + self.callback([line]) + + time_diff = time.time() - os.path.getmtime(tfile.name) + if time_diff > self.timeout: + raise CmdTimedOut(['Timeout!']) + + thrd.join(0.5) + + tfile.seek(0) + result = [line.decode('utf-8', 'replace').rstrip() for line in tfile] + + if self.proc.returncode != 0: + raise CmdFailed([''] + result) + + return result + except: + self.terminate() + raise + + def terminate(self): + """ Terminate process and cleanup. """ + if self.alive: + if G_IS_WIN: + os.kill(self.proc.pid, signal.SIGINT) + else: + os.killpg(self.proc.pid, signal.SIGTERM) + self.clean() + +class Plugin(object): + def __init__(self, name, args, buf_q, lock): + self.name = name + self.args = args + self.buf_q = buf_q + self.lock = lock + self.tag = args.get('tag', 0) + + def manage(self): + try: + if os.path.exists(self.args['dir']): + self.update() + else: + self.install() + with self.lock: + thread_vim_command("let s:update.new['{0}'] = 1".format(self.name)) + except PlugError as exc: + self.write(Action.ERROR, self.name, exc.msg) + except KeyboardInterrupt: + G_STOP.set() + self.write(Action.ERROR, self.name, ['Interrupted!']) + except: + # Any exception except those above print stack trace + msg = 'Trace:\n{0}'.format(traceback.format_exc().rstrip()) + self.write(Action.ERROR, self.name, msg.split('\n')) + raise + + def install(self): + target = self.args['dir'] + if target[-1] == '\\': + target = target[0:-1] + + def clean(target): + def _clean(): + try: + shutil.rmtree(target) + except OSError: + pass + return _clean + + self.write(Action.INSTALL, self.name, ['Installing ...']) + callback = functools.partial(self.write, Action.INSTALL, self.name) + cmd = 'git clone {0} {1} {2} {3} 2>&1'.format( + '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'], + esc(target)) + com = Command(cmd, None, G_TIMEOUT, callback, clean(target)) + result = com.execute(G_RETRIES) + self.write(Action.DONE, self.name, result[-1:]) + + def repo_uri(self): + cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url' + command = Command(cmd, self.args['dir'], G_TIMEOUT,) + result = command.execute(G_RETRIES) + return result[-1] + + def update(self): + actual_uri = self.repo_uri() + expect_uri = self.args['uri'] + regex = re.compile(r'^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$') + ma = regex.match(actual_uri) + mb = regex.match(expect_uri) + if ma is None or mb is None or ma.groups() != mb.groups(): + msg = ['', + 'Invalid URI: {0}'.format(actual_uri), + 'Expected {0}'.format(expect_uri), + 'PlugClean required.'] + raise InvalidURI(msg) + + if G_PULL: + self.write(Action.UPDATE, self.name, ['Updating ...']) + callback = functools.partial(self.write, Action.UPDATE, self.name) + fetch_opt = '--depth 99999999' if self.tag and os.path.isfile(os.path.join(self.args['dir'], '.git/shallow')) else '' + cmd = 'git fetch {0} {1} 2>&1'.format(fetch_opt, G_PROGRESS) + com = Command(cmd, self.args['dir'], G_TIMEOUT, callback) + result = com.execute(G_RETRIES) + self.write(Action.DONE, self.name, result[-1:]) + else: + self.write(Action.DONE, self.name, ['Already installed']) + + def write(self, action, name, msg): + self.buf_q.put((action, name, msg)) + +class PlugThread(thr.Thread): + def __init__(self, tname, args): + super(PlugThread, self).__init__() + self.tname = tname + self.args = args + + def run(self): + thr.current_thread().name = self.tname + buf_q, work_q, lock = self.args + + try: + while not G_STOP.is_set(): + name, args = work_q.get_nowait() + plug = Plugin(name, args, buf_q, lock) + plug.manage() + work_q.task_done() + except queue.Empty: + pass + +class RefreshThread(thr.Thread): + def __init__(self, lock): + super(RefreshThread, self).__init__() + self.lock = lock + self.running = True + + def run(self): + while self.running: + with self.lock: + thread_vim_command('noautocmd normal! a') + time.sleep(0.33) + + def stop(self): + self.running = False + +if G_NVIM: + def thread_vim_command(cmd): + vim.session.threadsafe_call(lambda: vim.command(cmd)) +else: + def thread_vim_command(cmd): + vim.command(cmd) + +def esc(name): + return '"' + name.replace('"', '\"') + '"' + +def nonblock_read(fname): + """ Read a file with nonblock flag. Return the last line. """ + fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK) + buf = os.read(fread, 100000).decode('utf-8', 'replace') + os.close(fread) + + line = buf.rstrip('\r\n') + left = max(line.rfind('\r'), line.rfind('\n')) + if left != -1: + left += 1 + line = line[left:] + + return line + +def main(): + thr.current_thread().name = 'main' + nthreads = int(vim.eval('s:update.threads')) + plugs = vim.eval('s:update.todo') + mac_gui = vim.eval('s:mac_gui') == '1' + + lock = thr.Lock() + buf = Buffer(lock, len(plugs), G_PULL) + buf_q, work_q = queue.Queue(), queue.Queue() + for work in plugs.items(): + work_q.put(work) + + start_cnt = thr.active_count() + for num in range(nthreads): + tname = 'PlugT-{0:02}'.format(num) + thread = PlugThread(tname, (buf_q, work_q, lock)) + thread.start() + if mac_gui: + rthread = RefreshThread(lock) + rthread.start() + + while not buf_q.empty() or thr.active_count() != start_cnt: + try: + action, name, msg = buf_q.get(True, 0.25) + buf.write(action, name, ['OK'] if not msg else msg) + buf_q.task_done() + except queue.Empty: + pass + except KeyboardInterrupt: + G_STOP.set() + + if mac_gui: + rthread.stop() + rthread.join() + +main() +EOF +endfunction + +function! s:update_ruby() + ruby << EOF + module PlugStream + SEP = ["\r", "\n", nil] + def get_line + buffer = '' + loop do + char = readchar rescue return + if SEP.include? char.chr + buffer << $/ + break + else + buffer << char + end + end + buffer + end + end unless defined?(PlugStream) + + def esc arg + %["#{arg.gsub('"', '\"')}"] + end + + def killall pid + pids = [pid] + if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM + pids.each { |pid| Process.kill 'INT', pid.to_i rescue nil } + else + unless `which pgrep 2> /dev/null`.empty? + children = pids + until children.empty? + children = children.map { |pid| + `pgrep -P #{pid}`.lines.map { |l| l.chomp } + }.flatten + pids += children + end + end + pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil } + end + end + + def compare_git_uri a, b + regex = %r{^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$} + regex.match(a).to_a.drop(1) == regex.match(b).to_a.drop(1) + end + + require 'thread' + require 'fileutils' + require 'timeout' + running = true + iswin = VIM::evaluate('s:is_win').to_i == 1 + pull = VIM::evaluate('s:update.pull').to_i == 1 + base = VIM::evaluate('g:plug_home') + all = VIM::evaluate('s:update.todo') + limit = VIM::evaluate('get(g:, "plug_timeout", 60)') + tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1 + nthr = VIM::evaluate('s:update.threads').to_i + maxy = VIM::evaluate('winheight(".")').to_i + vim7 = VIM::evaluate('v:version').to_i <= 703 && RUBY_PLATFORM =~ /darwin/ + cd = iswin ? 'cd /d' : 'cd' + tot = VIM::evaluate('len(s:update.todo)') || 0 + bar = '' + skip = 'Already installed' + mtx = Mutex.new + take1 = proc { mtx.synchronize { running && all.shift } } + logh = proc { + cnt = bar.length + $curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})" + $curbuf[2] = '[' + bar.ljust(tot) + ']' + VIM::command('normal! 2G') + VIM::command('redraw') + } + where = proc { |name| (1..($curbuf.length)).find { |l| $curbuf[l] =~ /^[-+x*] #{name}:/ } } + log = proc { |name, result, type| + mtx.synchronize do + ing = ![true, false].include?(type) + bar += type ? '=' : 'x' unless ing + b = case type + when :install then '+' when :update then '*' + when true, nil then '-' else + VIM::command("call add(s:update.errors, '#{name}')") + 'x' + end + result = + if type || type.nil? + ["#{b} #{name}: #{result.lines.to_a.last || 'OK'}"] + elsif result =~ /^Interrupted|^Timeout/ + ["#{b} #{name}: #{result}"] + else + ["#{b} #{name}"] + result.lines.map { |l| " " << l } + end + if lnum = where.call(name) + $curbuf.delete lnum + lnum = 4 if ing && lnum > maxy + end + result.each_with_index do |line, offset| + $curbuf.append((lnum || 4) - 1 + offset, line.gsub(/\e\[./, '').chomp) + end + logh.call + end + } + bt = proc { |cmd, name, type, cleanup| + tried = timeout = 0 + begin + tried += 1 + timeout += limit + fd = nil + data = '' + if iswin + Timeout::timeout(timeout) do + tmp = VIM::evaluate('tempname()') + system("(#{cmd}) > #{tmp}") + data = File.read(tmp).chomp + File.unlink tmp rescue nil + end + else + fd = IO.popen(cmd).extend(PlugStream) + first_line = true + log_prob = 1.0 / nthr + while line = Timeout::timeout(timeout) { fd.get_line } + data << line + log.call name, line.chomp, type if name && (first_line || rand < log_prob) + first_line = false + end + fd.close + end + [$? == 0, data.chomp] + rescue Timeout::Error, Interrupt => e + if fd && !fd.closed? + killall fd.pid + fd.close + end + cleanup.call if cleanup + if e.is_a?(Timeout::Error) && tried < tries + 3.downto(1) do |countdown| + s = countdown > 1 ? 's' : '' + log.call name, "Timeout. Will retry in #{countdown} second#{s} ...", type + sleep 1 + end + log.call name, 'Retrying ...', type + retry + end + [false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"] + end + } + main = Thread.current + threads = [] + watcher = Thread.new { + if vim7 + while VIM::evaluate('getchar(1)') + sleep 0.1 + end + else + require 'io/console' # >= Ruby 1.9 + nil until IO.console.getch == 3.chr + end + mtx.synchronize do + running = false + threads.each { |t| t.raise Interrupt } unless vim7 + end + threads.each { |t| t.join rescue nil } + main.kill + } + refresh = Thread.new { + while true + mtx.synchronize do + break unless running + VIM::command('noautocmd normal! a') + end + sleep 0.2 + end + } if VIM::evaluate('s:mac_gui') == 1 + + clone_opt = VIM::evaluate('s:clone_opt') + progress = VIM::evaluate('s:progress_opt(1)') + nthr.times do + mtx.synchronize do + threads << Thread.new { + while pair = take1.call + name = pair.first + dir, uri, tag = pair.last.values_at *%w[dir uri tag] + exists = File.directory? dir + ok, result = + if exists + chdir = "#{cd} #{iswin ? dir : esc(dir)}" + ret, data = bt.call "#{chdir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url", nil, nil, nil + current_uri = data.lines.to_a.last + if !ret + if data =~ /^Interrupted|^Timeout/ + [false, data] + else + [false, [data.chomp, "PlugClean required."].join($/)] + end + elsif !compare_git_uri(current_uri, uri) + [false, ["Invalid URI: #{current_uri}", + "Expected: #{uri}", + "PlugClean required."].join($/)] + else + if pull + log.call name, 'Updating ...', :update + fetch_opt = (tag && File.exist?(File.join(dir, '.git/shallow'))) ? '--depth 99999999' : '' + bt.call "#{chdir} && git fetch #{fetch_opt} #{progress} 2>&1", name, :update, nil + else + [true, skip] + end + end + else + d = esc dir.sub(%r{[\\/]+$}, '') + log.call name, 'Installing ...', :install + bt.call "git clone #{clone_opt unless tag} #{progress} #{uri} #{d} 2>&1", name, :install, proc { + FileUtils.rm_rf dir + } + end + mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok + log.call name, result, ok + end + } if running + end + end + threads.each { |t| t.join rescue nil } + logh.call + refresh.kill if refresh + watcher.kill +EOF +endfunction + +function! s:shellesc_cmd(arg, script) + let escaped = substitute('"'.a:arg.'"', '[&|<>()@^!"]', '^&', 'g') + return substitute(escaped, '%', (a:script ? '%' : '^') . '&', 'g') +endfunction + +function! s:shellesc_ps1(arg) + return "'".substitute(escape(a:arg, '\"'), "'", "''", 'g')."'" +endfunction + +function! plug#shellescape(arg, ...) + let opts = a:0 > 0 && type(a:1) == s:TYPE.dict ? a:1 : {} + let shell = get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh') + let script = get(opts, 'script', 1) + if shell =~# 'cmd\.exe$' + return s:shellesc_cmd(a:arg, script) + elseif shell =~# 'powershell\.exe$' || shell =~# 'pwsh$' + return s:shellesc_ps1(a:arg) + endif + return shellescape(a:arg) +endfunction + +function! s:glob_dir(path) + return map(filter(s:glob(a:path, '**'), 'isdirectory(v:val)'), 's:dirpath(v:val)') +endfunction + +function! s:progress_bar(line, bar, total) + call setline(a:line, '[' . s:lpad(a:bar, a:total) . ']') +endfunction + +function! s:compare_git_uri(a, b) + " See `git help clone' + " https:// [user@] github.com[:port] / junegunn/vim-plug [.git] + " [git@] github.com[:port] : junegunn/vim-plug [.git] + " file:// / junegunn/vim-plug [/] + " / junegunn/vim-plug [/] + let pat = '^\%(\w\+://\)\='.'\%([^@/]*@\)\='.'\([^:/]*\%(:[0-9]*\)\=\)'.'[:/]'.'\(.\{-}\)'.'\%(\.git\)\=/\?$' + let ma = matchlist(a:a, pat) + let mb = matchlist(a:b, pat) + return ma[1:2] ==# mb[1:2] +endfunction + +function! s:format_message(bullet, name, message) + if a:bullet != 'x' + return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))] + else + let lines = map(s:lines(a:message), '" ".v:val') + return extend([printf('x %s:', a:name)], lines) + endif +endfunction + +function! s:with_cd(cmd, dir, ...) + let script = a:0 > 0 ? a:1 : 1 + return printf('cd%s %s && %s', s:is_win ? ' /d' : '', plug#shellescape(a:dir, {'script': script}), a:cmd) +endfunction + +function! s:system(cmd, ...) + try + let [sh, shellcmdflag, shrd] = s:chsh(1) + let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd + if s:is_win + let [batchfile, cmd] = s:batchfile(cmd) + endif + return system(cmd) + finally + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win + call delete(batchfile) + endif + endtry +endfunction + +function! s:system_chomp(...) + let ret = call('s:system', a:000) + return v:shell_error ? '' : substitute(ret, '\n$', '', '') +endfunction + +function! s:git_validate(spec, check_branch) + let err = '' + if isdirectory(a:spec.dir) + let result = s:lines(s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url', a:spec.dir)) + let remote = result[-1] + if v:shell_error + let err = join([remote, 'PlugClean required.'], "\n") + elseif !s:compare_git_uri(remote, a:spec.uri) + let err = join(['Invalid URI: '.remote, + \ 'Expected: '.a:spec.uri, + \ 'PlugClean required.'], "\n") + elseif a:check_branch && has_key(a:spec, 'commit') + let result = s:lines(s:system('git rev-parse HEAD 2>&1', a:spec.dir)) + let sha = result[-1] + if v:shell_error + let err = join(add(result, 'PlugClean required.'), "\n") + elseif !s:hash_match(sha, a:spec.commit) + let err = join([printf('Invalid HEAD (expected: %s, actual: %s)', + \ a:spec.commit[:6], sha[:6]), + \ 'PlugUpdate required.'], "\n") + endif + elseif a:check_branch + let branch = result[0] + " Check tag + if has_key(a:spec, 'tag') + let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir) + if a:spec.tag !=# tag && a:spec.tag !~ '\*' + let err = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.', + \ (empty(tag) ? 'N/A' : tag), a:spec.tag) + endif + " Check branch + elseif a:spec.branch !=# branch + let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', + \ branch, a:spec.branch) + endif + if empty(err) + let [ahead, behind] = split(s:lastline(s:system(printf( + \ 'git rev-list --count --left-right HEAD...origin/%s', + \ a:spec.branch), a:spec.dir)), '\t') + if !v:shell_error && ahead + if behind + " Only mention PlugClean if diverged, otherwise it's likely to be + " pushable (and probably not that messed up). + let err = printf( + \ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n" + \ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', a:spec.branch, ahead, behind) + else + let err = printf("Ahead of origin/%s by %d commit(s).\n" + \ .'Cannot update until local changes are pushed.', + \ a:spec.branch, ahead) + endif + endif + endif + endif + else + let err = 'Not found' + endif + return [err, err =~# 'PlugClean'] +endfunction + +function! s:rm_rf(dir) + if isdirectory(a:dir) + call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . plug#shellescape(a:dir)) + endif +endfunction + +function! s:clean(force) + call s:prepare() + call append(0, 'Searching for invalid plugins in '.g:plug_home) + call append(1, '') + + " List of valid directories + let dirs = [] + let errs = {} + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + if !s:is_managed(name) + call add(dirs, spec.dir) + else + let [err, clean] = s:git_validate(spec, 1) + if clean + let errs[spec.dir] = s:lines(err)[0] + else + call add(dirs, spec.dir) + endif + endif + let cnt += 1 + call s:progress_bar(2, repeat('=', cnt), total) + normal! 2G + redraw + endfor + + let allowed = {} + for dir in dirs + let allowed[s:dirpath(fnamemodify(dir, ':h:h'))] = 1 + let allowed[dir] = 1 + for child in s:glob_dir(dir) + let allowed[child] = 1 + endfor + endfor + + let todo = [] + let found = sort(s:glob_dir(g:plug_home)) + while !empty(found) + let f = remove(found, 0) + if !has_key(allowed, f) && isdirectory(f) + call add(todo, f) + call append(line('$'), '- ' . f) + if has_key(errs, f) + call append(line('$'), ' ' . errs[f]) + endif + let found = filter(found, 'stridx(v:val, f) != 0') + end + endwhile + + 4 + redraw + if empty(todo) + call append(line('$'), 'Already clean.') + else + let s:clean_count = 0 + call append(3, ['Directories to delete:', '']) + redraw! + if a:force || s:ask_no_interrupt('Delete all directories?') + call s:delete([6, line('$')], 1) + else + call setline(4, 'Cancelled.') + nnoremap d :set opfunc=delete_opg@ + nmap dd d_ + xnoremap d :call delete_op(visualmode(), 1) + echo 'Delete the lines (d{motion}) to delete the corresponding directories' + endif + endif + 4 + setlocal nomodifiable +endfunction + +function! s:delete_op(type, ...) + call s:delete(a:0 ? [line("'<"), line("'>")] : [line("'["), line("']")], 0) +endfunction + +function! s:delete(range, force) + let [l1, l2] = a:range + let force = a:force + while l1 <= l2 + let line = getline(l1) + if line =~ '^- ' && isdirectory(line[2:]) + execute l1 + redraw! + let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1) + let force = force || answer > 1 + if answer + call s:rm_rf(line[2:]) + setlocal modifiable + call setline(l1, '~'.line[1:]) + let s:clean_count += 1 + call setline(4, printf('Removed %d directories.', s:clean_count)) + setlocal nomodifiable + endif + endif + let l1 += 1 + endwhile +endfunction + +function! s:upgrade() + echo 'Downloading the latest version of vim-plug' + redraw + let tmp = tempname() + let new = tmp . '/plug.vim' + + try + let out = s:system(printf('git clone --depth 1 %s %s', plug#shellescape(s:plug_src), plug#shellescape(tmp))) + if v:shell_error + return s:err('Error upgrading vim-plug: '. out) + endif + + if readfile(s:me) ==# readfile(new) + echo 'vim-plug is already up-to-date' + return 0 + else + call rename(s:me, s:me . '.old') + call rename(new, s:me) + unlet g:loaded_plug + echo 'vim-plug has been upgraded' + return 1 + endif + finally + silent! call s:rm_rf(tmp) + endtry +endfunction + +function! s:upgrade_specs() + for spec in values(g:plugs) + let spec.frozen = get(spec, 'frozen', 0) + endfor +endfunction + +function! s:status() + call s:prepare() + call append(0, 'Checking plugins') + call append(1, '') + + let ecnt = 0 + let unloaded = 0 + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + let is_dir = isdirectory(spec.dir) + if has_key(spec, 'uri') + if is_dir + let [err, _] = s:git_validate(spec, 1) + let [valid, msg] = [empty(err), empty(err) ? 'OK' : err] + else + let [valid, msg] = [0, 'Not found. Try PlugInstall.'] + endif + else + if is_dir + let [valid, msg] = [1, 'OK'] + else + let [valid, msg] = [0, 'Not found.'] + endif + endif + let cnt += 1 + let ecnt += !valid + " `s:loaded` entry can be missing if PlugUpgraded + if is_dir && get(s:loaded, name, -1) == 0 + let unloaded = 1 + let msg .= ' (not loaded)' + endif + call s:progress_bar(2, repeat('=', cnt), total) + call append(3, s:format_message(valid ? '-' : 'x', name, msg)) + normal! 2G + redraw + endfor + call setline(1, 'Finished. '.ecnt.' error(s).') + normal! gg + setlocal nomodifiable + if unloaded + echo "Press 'L' on each line to load plugin, or 'U' to update" + nnoremap L :call status_load(line('.')) + xnoremap L :call status_load(line('.')) + end +endfunction + +function! s:extract_name(str, prefix, suffix) + return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$') +endfunction + +function! s:status_load(lnum) + let line = getline(a:lnum) + let name = s:extract_name(line, '-', '(not loaded)') + if !empty(name) + call plug#load(name) + setlocal modifiable + call setline(a:lnum, substitute(line, ' (not loaded)$', '', '')) + setlocal nomodifiable + endif +endfunction + +function! s:status_update() range + let lines = getline(a:firstline, a:lastline) + let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)') + if !empty(names) + echo + execute 'PlugUpdate' join(names) + endif +endfunction + +function! s:is_preview_window_open() + silent! wincmd P + if &previewwindow + wincmd p + return 1 + endif +endfunction + +function! s:find_name(lnum) + for lnum in reverse(range(1, a:lnum)) + let line = getline(lnum) + if empty(line) + return '' + endif + let name = s:extract_name(line, '-', '') + if !empty(name) + return name + endif + endfor + return '' +endfunction + +function! s:preview_commit() + if b:plug_preview < 0 + let b:plug_preview = !s:is_preview_window_open() + endif + + let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7,9}') + if empty(sha) + return + endif + + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir) + return + endif + + if exists('g:plug_pwindow') && !s:is_preview_window_open() + execute g:plug_pwindow + execute 'e' sha + else + execute 'pedit' sha + wincmd P + endif + setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable + try + let [sh, shellcmdflag, shrd] = s:chsh(1) + let cmd = 'cd '.plug#shellescape(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha + if s:is_win + let [batchfile, cmd] = s:batchfile(cmd) + endif + execute 'silent %!' cmd + finally + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win + call delete(batchfile) + endif + endtry + setlocal nomodifiable + nnoremap q :q + wincmd p +endfunction + +function! s:section(flags) + call search('\(^[x-] \)\@<=[^:]\+:', a:flags) +endfunction + +function! s:format_git_log(line) + let indent = ' ' + let tokens = split(a:line, nr2char(1)) + if len(tokens) != 5 + return indent.substitute(a:line, '\s*$', '', '') + endif + let [graph, sha, refs, subject, date] = tokens + let tag = matchstr(refs, 'tag: [^,)]\+') + let tag = empty(tag) ? ' ' : ' ('.tag.') ' + return printf('%s%s%s%s%s (%s)', indent, graph, sha, tag, subject, date) +endfunction + +function! s:append_ul(lnum, text) + call append(a:lnum, ['', a:text, repeat('-', len(a:text))]) +endfunction + +function! s:diff() + call s:prepare() + call append(0, ['Collecting changes ...', '']) + let cnts = [0, 0] + let bar = '' + let total = filter(copy(g:plugs), 's:is_managed(v:key) && isdirectory(v:val.dir)') + call s:progress_bar(2, bar, len(total)) + for origin in [1, 0] + let plugs = reverse(sort(items(filter(copy(total), (origin ? '' : '!').'(has_key(v:val, "commit") || has_key(v:val, "tag"))')))) + if empty(plugs) + continue + endif + call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:') + for [k, v] in plugs + let range = origin ? '..origin/'.v.branch : 'HEAD@{1}..' + let cmd = 'git log --graph --color=never '.join(map(['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range], 'plug#shellescape(v:val)')) + if has_key(v, 'rtp') + let cmd .= ' -- '.plug#shellescape(v.rtp) + endif + let diff = s:system_chomp(cmd, v.dir) + if !empty(diff) + let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : '' + call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)'))) + let cnts[origin] += 1 + endif + let bar .= '=' + call s:progress_bar(2, bar, len(total)) + normal! 2G + redraw + endfor + if !cnts[origin] + call append(5, ['', 'N/A']) + endif + endfor + call setline(1, printf('%d plugin(s) updated.', cnts[0]) + \ . (cnts[1] ? printf(' %d plugin(s) have pending updates.', cnts[1]) : '')) + + if cnts[0] || cnts[1] + nnoremap (plug-preview) :silent! call preview_commit() + if empty(maparg("\", 'n')) + nmap (plug-preview) + endif + if empty(maparg('o', 'n')) + nmap o (plug-preview) + endif + endif + if cnts[0] + nnoremap X :call revert() + echo "Press 'X' on each block to revert the update" + endif + normal! gg + setlocal nomodifiable +endfunction + +function! s:revert() + if search('^Pending updates', 'bnW') + return + endif + + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || + \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y' + return + endif + + call s:system('git reset --hard HEAD@{1} && git checkout '.s:esc(g:plugs[name].branch).' --', g:plugs[name].dir) + setlocal modifiable + normal! "_dap + setlocal nomodifiable + echo 'Reverted' +endfunction + +function! s:snapshot(force, ...) abort + call s:prepare() + setf vim + call append(0, ['" Generated by vim-plug', + \ '" '.strftime("%c"), + \ '" :source this file in vim to restore the snapshot', + \ '" or execute: vim -S snapshot.vim', + \ '', '', 'PlugUpdate!']) + 1 + let anchor = line('$') - 3 + let names = sort(keys(filter(copy(g:plugs), + \'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)'))) + for name in reverse(names) + let sha = s:system_chomp('git rev-parse --short HEAD', g:plugs[name].dir) + if !empty(sha) + call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha)) + redraw + endif + endfor + + if a:0 > 0 + let fn = expand(a:1) + if filereadable(fn) && !(a:force || s:ask(a:1.' already exists. Overwrite?')) + return + endif + call writefile(getline(1, '$'), fn) + echo 'Saved as '.a:1 + silent execute 'e' s:esc(fn) + setf vim + endif +endfunction + +function! s:split_rtp() + return split(&rtp, '\\\@ 2 + exe 'syn match '.s:synID(prefix, 'o', lv, id).' '.op.' containedin='.s:synID(prefix, 'r', lv, id).' contained' + endif + + let real_contained = (lv == 0)? (contained? 'contained ' : '') : 'contained ' + let real_containedin = (lv == 0)? s:concat([containedin, '@'.gid2]) : '@'.gid2 + let real_contains = s:concat([contains_prefix, contains]) + exe 'syn region '.rid.' matchgroup='.pid.' '.real_contained.'containedin='.real_containedin.' contains='.real_contains.' '.paren + endfor + endfor + for lv in range(cycle) + exe 'syn cluster '.s:synGroupID(prefix, 'Regions', lv).' contains='.join(map(range(len(conf.parentheses)), 's:synID(prefix, "r", lv, v:val)'), ',') + exe 'syn cluster '.s:synGroupID(prefix, 'Parentheses', lv).' contains='.join(map(range(len(conf.parentheses)), 's:synID(prefix, "p", lv, v:val)'), ',') + exe 'syn cluster '.s:synGroupID(prefix, 'Operators', lv).' contains='.join(map(range(len(conf.parentheses)), 's:synID(prefix, "o", lv, v:val)'), ',') + endfor + exe 'syn cluster '.prefix.'Regions contains='.join(map(range(cycle), '"@".s:synGroupID(prefix, "Regions", v:val)'), ',') + exe 'syn cluster '.prefix.'Parentheses contains='.join(map(range(cycle), '"@".s:synGroupID(prefix, "Parentheses", v:val)'), ',') + exe 'syn cluster '.prefix.'Operators contains='.join(map(range(cycle), '"@".s:synGroupID(prefix, "Operators", v:val)'), ',') + if has_key(conf, 'after') | for cmd in conf.after | exe cmd | endfor | endif +endfun + +fun rainbow#syn_clear(config) + let conf = a:config + let prefix = conf.syn_name_prefix + + for id in range(len(conf.parentheses)) + for lv in range(conf.cycle) + let [rid, oid] = [s:synID(prefix, 'r', lv, id), s:synID(prefix, 'o', lv, id)] + exe 'syn clear '.rid + exe 'syn clear '.oid + endfor + endfor +endfun + +fun rainbow#hi(config) + let conf = a:config + let prefix = conf.syn_name_prefix + + for id in range(len(conf.parentheses)) + for lv in range(conf.cycle) + let [pid, oid] = [s:synID(prefix, 'p', lv, id), s:synID(prefix, 'o', lv, id)] + let ctermfg = conf.ctermfgs[lv % len(conf.ctermfgs)] + let guifg = conf.guifgs[lv % len(conf.guifgs)] + let cterm = conf.cterms[lv % len(conf.cterms)] + let gui = conf.guis[lv % len(conf.guis)] + let hi_style = 'ctermfg='.ctermfg.' guifg='.guifg.(len(cterm) > 0 ? ' cterm='.cterm : '').(len(gui) > 0 ? ' gui='.gui : '') + exe 'hi '.pid.' '.hi_style + exe 'hi '.oid.' '.hi_style + endfor + endfor +endfun + +fun rainbow#hi_clear(config) + let conf = a:config + let prefix = conf.syn_name_prefix + + for id in range(len(conf.parentheses)) + for lv in range(conf.cycle) + let [pid, oid] = [s:synID(prefix, 'p', lv, id), s:synID(prefix, 'o', lv, id)] + exe 'hi clear '.pid + exe 'hi clear '.oid + endfor + endfor +endfun + diff --git a/autoload/rainbow_main.vim b/autoload/rainbow_main.vim new file mode 100644 index 0000000..91499c0 --- /dev/null +++ b/autoload/rainbow_main.vim @@ -0,0 +1,132 @@ +" Copyright 2013 LuoChen (luochen1990@gmail.com). Licensed under the Apache License 2.0. + +let s:rainbow_conf = { +\ 'guifgs': ['royalblue3', 'darkorange3', 'seagreen3', 'firebrick'], +\ 'ctermfgs': ['lightblue', 'lightyellow', 'lightcyan', 'lightmagenta'], +\ 'guis': [''], +\ 'cterms': [''], +\ 'operators': '_,_', +\ 'contains_prefix': 'TOP', +\ 'parentheses_options': '', +\ 'parentheses': ['start=/(/ end=/)/ fold', 'start=/\[/ end=/\]/ fold', 'start=/{/ end=/}/ fold'], +\ 'separately': { +\ '*': {}, +\ 'markdown': { +\ 'parentheses_options': 'containedin=markdownCode contained', +\ }, +\ 'lisp': { +\ 'guifgs': ['royalblue3', 'darkorange3', 'seagreen3', 'firebrick', 'darkorchid3'], +\ }, +\ 'haskell': { +\ 'parentheses': ['start=/(/ end=/)/ fold', 'start=/\[/ end=/\]/ fold', 'start=/\v\{\ze[^-]/ end=/}/ fold'], +\ }, +\ 'ocaml': { +\ 'parentheses': ['start=/(\ze[^*]/ end=/)/ fold', 'start=/\[/ end=/\]/ fold', 'start=/\[|/ end=/|\]/ fold', 'start=/{/ end=/}/ fold'], +\ }, +\ 'tex': { +\ 'parentheses_options': 'containedin=texDocZone', +\ 'parentheses': ['start=/(/ end=/)/', 'start=/\[/ end=/\]/'], +\ }, +\ 'vim': { +\ 'parentheses_options': 'containedin=vimFuncBody,vimExecute', +\ 'parentheses': ['start=/(/ end=/)/', 'start=/\[/ end=/\]/', 'start=/{/ end=/}/ fold'], +\ }, +\ 'xml': { +\ 'syn_name_prefix': 'xmlRainbow', +\ 'parentheses': ['start=/\v\<\z([-_:a-zA-Z0-9]+)(\s+[-_:a-zA-Z0-9]+(\=("[^"]*"|'."'".'[^'."'".']*'."'".'))?)*\>/ end=## fold'], +\ }, +\ 'xhtml': { +\ 'parentheses': ['start=/\v\<\z([-_:a-zA-Z0-9]+)(\s+[-_:a-zA-Z0-9]+(\=("[^"]*"|'."'".'[^'."'".']*'."'".'))?)*\>/ end=## fold'], +\ }, +\ 'html': { +\ 'parentheses': ['start=/\v\<((script|style|area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)[ >])@!\z([-_:a-zA-Z0-9]+)(\s+[-_:a-zA-Z0-9]+(\=("[^"]*"|'."'".'[^'."'".']*'."'".'|[^ '."'".'"><=`]*))?)*\>/ end=## fold'], +\ }, +\ 'perl': { +\ 'syn_name_prefix': 'perlBlockFoldRainbow', +\ }, +\ 'php': { +\ 'syn_name_prefix': 'phpBlockRainbow', +\ 'contains_prefix': '', +\ 'parentheses': ['start=/(/ end=/)/ containedin=@htmlPreproc contains=@phpClTop', 'start=/\[/ end=/\]/ containedin=@htmlPreproc contains=@phpClTop', 'start=/{/ end=/}/ containedin=@htmlPreproc contains=@phpClTop', 'start=/\v\<((area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)[ >])@!\z([-_:a-zA-Z0-9]+)(\s+[-_:a-zA-Z0-9]+(\=("[^"]*"|'."'".'[^'."'".']*'."'".'|[^ '."'".'"><=`]*))?)*\>/ end=## fold contains_prefix=TOP'], +\ }, +\ 'stylus': { +\ 'parentheses': ['start=/{/ end=/}/ fold contains=@colorableGroup'], +\ }, +\ 'css': 0, +\ 'sh': 0, +\ } +\} + +fun s:eq(x, y) + return type(a:x) == type(a:y) && a:x == a:y +endfun + +fun s:gcd(a, b) + let [a, b, t] = [a:a, a:b, 0] + while b != 0 + let t = b + let b = a % b + let a = t + endwhile + return a +endfun + +fun s:lcm(a, b) + return (a:a / s:gcd(a:a, a:b)) * a:b +endfun + +fun rainbow_main#gen_config(ft) + let g = exists('g:rainbow_conf')? g:rainbow_conf : {} + "echom 'g:rainbow_conf:' string(g) + let s = get(g, 'separately', {}) + "echom 'g:rainbow_conf.separately:' string(s) + let dft_conf = extend(copy(s:rainbow_conf), g) | unlet dft_conf.separately + "echom 'default config options:' string(dft_conf) + let dx_conf = s:rainbow_conf.separately['*'] + "echom 'default star config:' string(dx_conf) + let ds_conf = get(s:rainbow_conf.separately, a:ft, dx_conf) + "echom 'default separately config:' string(ds_conf) + let ux_conf = get(s, '*', ds_conf) + "echom 'user star config:' string(ux_conf) + let us_conf = get(s, a:ft, ux_conf) + "echom 'user separately config:' string(us_conf) + let af_conf = (s:eq(us_conf, 'default') ? ds_conf : us_conf) + "echom 'almost finally config:' string(af_conf) + if s:eq(af_conf, 0) + return 0 + else + let conf = extend(extend({'syn_name_prefix': substitute(a:ft, '\v\A+(\a)', '\u\1', 'g').'Rainbow'}, dft_conf), af_conf) + let conf.cycle = (has('gui_running') || (has('termguicolors') && &termguicolors)) ? s:lcm(len(conf.guifgs), len(conf.guis)) : s:lcm(len(conf.ctermfgs), len(conf.cterms)) + return conf + endif +endfun + +fun rainbow_main#gen_configs(ft) + return filter(map(split(a:ft, '\v\.'), 'rainbow_main#gen_config(v:val)'), 'type(v:val) == type({})') +endfun + +fun rainbow_main#load() + let b:rainbow_confs = rainbow_main#gen_configs(&filetype) + for conf in b:rainbow_confs + call rainbow#syn(conf) + call rainbow#hi(conf) + endfor +endfun + +fun rainbow_main#clear() + if !exists('b:rainbow_confs') | return | endif + for conf in b:rainbow_confs + call rainbow#hi_clear(conf) + call rainbow#syn_clear(conf) + endfor + unlet b:rainbow_confs +endfun + +fun rainbow_main#toggle() + if exists('b:rainbow_confs') + call rainbow_main#clear() + else + call rainbow_main#load() + endif +endfun + diff --git a/base16 b/base16 deleted file mode 120000 index ce116a4..0000000 --- a/base16 +++ /dev/null @@ -1 +0,0 @@ -/home/rick/.vim/base16 \ No newline at end of file diff --git a/base16/schemes/codedark/codedark.yaml b/base16/schemes/codedark/codedark.yaml new file mode 100644 index 0000000..103598c --- /dev/null +++ b/base16/schemes/codedark/codedark.yaml @@ -0,0 +1,18 @@ +scheme: "codedark" +author: "Tomas Iser (https://github.com/tomasiser)" +base00: "1E1E1E" +base01: "262626" +base02: "303030" +base03: "3C3C3C" +base04: "808080" +base05: "D4D4D4" +base06: "E9E9E9" +base07: "FFFFFF" +base08: "D16969" +base09: "B5CEA8" +base0A: "D7BA7D" +base0B: "608B4E" +base0C: "9CDCFE" +base0D: "569CD6" +base0E: "C586C0" +base0F: "CE9178" diff --git a/base16/templates/putty/putty/base16-codedark.reg b/base16/templates/putty/putty/base16-codedark.reg new file mode 100644 index 0000000..5b74f3a --- /dev/null +++ b/base16/templates/putty/putty/base16-codedark.reg @@ -0,0 +1,72 @@ +Windows Registry Editor Version 5.00 + +; Base16 codedark +; schema by Tomas Iser (https://github.com/tomasiser) +[HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\codedark] + +; Default Foreground +"Colour0"="212,212,212" + +; Default Bold Foreground -- equals to non-bold +"Colour1"="212,212,212" + +; Default Background +"Colour2"="30,30,30" + +; Default Bold Background -- equals to non-bold +"Colour3"="30,30,30" + +; Cursor Text -- equals to default background +"Colour4"="30,30,30" + +; Cursor Colour -- equals to default foreground +"Colour5"="212,212,212" + +; ANSI Black +"Colour6"="30,30,30" + +; ANSI Black Bold +"Colour7"="60,60,60" + +; ANSI Red +"Colour8"="209,105,105" + +; ANSI Red Bold +"Colour9"="181,206,168" + +; ANSI Green +"Colour10"="96,139,78" + +; ANSI Green Bold +"Colour11"="38,38,38" + +; ANSI Yellow +"Colour12"="215,186,125" + +; ANSI Yellow Bold +"Colour13"="48,48,48" + +; ANSI Blue +"Colour14"="86,156,214" + +; ANSI Blue Bold +"Colour15"="128,128,128" + +; ANSI Magenta +"Colour16"="197,134,192" + +; ANSI Magenta Bold +"Colour17"="233,233,233" + +; ANSI Cyan +"Colour18"="156,220,254" + +; ANSI Cyan Bold +"Colour19"="206,145,120" + +; ANSI White +"Colour20"="212,212,212" + +; ANSI White Bold +"Colour21"="255,255,255" + diff --git a/base16/templates/shell/scripts/base16-codedark.sh b/base16/templates/shell/scripts/base16-codedark.sh new file mode 100644 index 0000000..ec2c545 --- /dev/null +++ b/base16/templates/shell/scripts/base16-codedark.sh @@ -0,0 +1,123 @@ +#!/bin/sh +# base16-shell (https://github.com/chriskempson/base16-shell) +# Base16 Shell template by Chris Kempson (http://chriskempson.com) +# codedark scheme by Tomas Iser (https://github.com/tomasiser) + +# This script doesn't support linux console (use 'vconsole' template instead) +if [ "${TERM%%-*}" = 'linux' ]; then + return 2>/dev/null || exit 0 +fi + +color00="1E/1E/1E" # Base 00 - Black +color01="D1/69/69" # Base 08 - Red +color02="60/8B/4E" # Base 0B - Green +color03="D7/BA/7D" # Base 0A - Yellow +color04="56/9C/D6" # Base 0D - Blue +color05="C5/86/C0" # Base 0E - Magenta +color06="9C/DC/FE" # Base 0C - Cyan +color07="D4/D4/D4" # Base 05 - White +color08="3C/3C/3C" # Base 03 - Bright Black +color09=$color01 # Base 08 - Bright Red +color10=$color02 # Base 0B - Bright Green +color11=$color03 # Base 0A - Bright Yellow +color12=$color04 # Base 0D - Bright Blue +color13=$color05 # Base 0E - Bright Magenta +color14=$color06 # Base 0C - Bright Cyan +color15="FF/FF/FF" # Base 07 - Bright White +color16="B5/CE/A8" # Base 09 +color17="CE/91/78" # Base 0F +color18="26/26/26" # Base 01 +color19="30/30/30" # Base 02 +color20="80/80/80" # Base 04 +color21="E9/E9/E9" # Base 06 +color_foreground="D4/D4/D4" # Base 05 +color_background="1E/1E/1E" # Base 00 +color_cursor="D4/D4/D4" # Base 05 + +if [ -n "$TMUX" ]; then + # Tell tmux to pass the escape sequences through + # (Source: http://permalink.gmane.org/gmane.comp.terminal-emulators.tmux.user/1324) + printf_template='\033Ptmux;\033\033]4;%d;rgb:%s\033\033\\\033\\' + printf_template_var='\033Ptmux;\033\033]%d;rgb:%s\033\033\\\033\\' + printf_template_custom='\033Ptmux;\033\033]%s%s\033\033\\\033\\' +elif [ "${TERM%%-*}" = "screen" ]; then + # GNU screen (screen, screen-256color, screen-256color-bce) + printf_template='\033P\033]4;%d;rgb:%s\033\\' + printf_template_var='\033P\033]%d;rgb:%s\033\\' + printf_template_custom='\033P\033]%s%s\033\\' +else + printf_template='\033]4;%d;rgb:%s\033\\' + printf_template_var='\033]%d;rgb:%s\033\\' + printf_template_custom='\033]%s%s\033\\' +fi + +# 16 color space +printf $printf_template 0 $color00 +printf $printf_template 1 $color01 +printf $printf_template 2 $color02 +printf $printf_template 3 $color03 +printf $printf_template 4 $color04 +printf $printf_template 5 $color05 +printf $printf_template 6 $color06 +printf $printf_template 7 $color07 +printf $printf_template 8 $color08 +printf $printf_template 9 $color09 +printf $printf_template 10 $color10 +printf $printf_template 11 $color11 +printf $printf_template 12 $color12 +printf $printf_template 13 $color13 +printf $printf_template 14 $color14 +printf $printf_template 15 $color15 + +# 256 color space +printf $printf_template 16 $color16 +printf $printf_template 17 $color17 +printf $printf_template 18 $color18 +printf $printf_template 19 $color19 +printf $printf_template 20 $color20 +printf $printf_template 21 $color21 + +# foreground / background / cursor color +if [ -n "$ITERM_SESSION_ID" ]; then + # iTerm2 proprietary escape codes + printf $printf_template_custom Pg D4D4D4 # forground + printf $printf_template_custom Ph 1E1E1E # background + printf $printf_template_custom Pi D4D4D4 # bold color + printf $printf_template_custom Pj 303030 # selection color + printf $printf_template_custom Pk D4D4D4 # selected text color + printf $printf_template_custom Pl D4D4D4 # cursor + printf $printf_template_custom Pm 1E1E1E # cursor text +else + printf $printf_template_var 10 $color_foreground + printf $printf_template_var 11 $color_background + printf $printf_template_custom 12 ";7" # cursor (reverse video) +fi + +# clean up +unset printf_template +unset printf_template_var +unset color00 +unset color01 +unset color02 +unset color03 +unset color04 +unset color05 +unset color06 +unset color07 +unset color08 +unset color09 +unset color10 +unset color11 +unset color12 +unset color13 +unset color14 +unset color15 +unset color16 +unset color17 +unset color18 +unset color19 +unset color20 +unset color21 +unset color_foreground +unset color_background +unset color_cursor diff --git a/bundle b/bundle deleted file mode 120000 index d96c49f..0000000 --- a/bundle +++ /dev/null @@ -1 +0,0 @@ -/home/rick/.vim/bundle \ No newline at end of file diff --git a/bundle/vim-doge b/bundle/vim-doge new file mode 160000 index 0000000..1aba70d --- /dev/null +++ b/bundle/vim-doge @@ -0,0 +1 @@ +Subproject commit 1aba70d1d2ff408045f8d57eec0b8103da5d2db9 diff --git a/colors b/colors deleted file mode 120000 index 7d79443..0000000 --- a/colors +++ /dev/null @@ -1 +0,0 @@ -/home/rick/.vim/colors \ No newline at end of file diff --git a/colors/codedark.vim b/colors/codedark.vim new file mode 100644 index 0000000..c8b8dd6 --- /dev/null +++ b/colors/codedark.vim @@ -0,0 +1,358 @@ +" Vim Code Dark (color scheme) +" https://github.com/tomasiser/vim-code-dark + +scriptencoding utf-8 + +set background=dark +hi clear +if exists("syntax_on") + syntax reset +endif +let g:colors_name="codedark" + +" Highlighting function (inspiration from https://github.com/chriskempson/base16-vim) +if &t_Co >= 256 + let g:codedark_term256=1 +elseif !exists("g:codedark_term256") + let g:codedark_term256=0 +endif +fun! hi(group, fg, bg, attr, sp) + if !empty(a:fg) + exec "hi " . a:group . " guifg=" . a:fg.gui . " ctermfg=" . (g:codedark_term256 ? a:fg.cterm256 : a:fg.cterm) + endif + if !empty(a:bg) + exec "hi " . a:group . " guibg=" . a:bg.gui . " ctermbg=" . (g:codedark_term256 ? a:bg.cterm256 : a:bg.cterm) + endif + if a:attr != "" + exec "hi " . a:group . " gui=" . a:attr . " cterm=" . a:attr + endif + if !empty(a:sp) + exec "hi " . a:group . " guisp=" . a:sp.gui + endif +endfun + +" ------------------ +" Color definitions: +" ------------------ + +" Terminal colors (base16): +let s:cterm00 = "00" +let s:cterm03 = "08" +let s:cterm05 = "07" +let s:cterm07 = "15" +let s:cterm08 = "01" +let s:cterm0A = "03" +let s:cterm0B = "02" +let s:cterm0C = "06" +let s:cterm0D = "04" +let s:cterm0E = "05" +if exists('base16colorspace') && base16colorspace == "256" + let s:cterm01 = "18" + let s:cterm02 = "19" + let s:cterm04 = "20" + let s:cterm06 = "21" + let s:cterm09 = "16" + let s:cterm0F = "17" +else + let s:cterm01 = "00" + let s:cterm02 = "08" + let s:cterm04 = "07" + let s:cterm06 = "07" + let s:cterm09 = "06" + let s:cterm0F = "03" +endif + +" General appearance colors: +" (some of them may be unused) + +let s:cdNone = {'gui': 'NONE', 'cterm': 'NONE', 'cterm256': 'NONE'} +let s:cdFront = {'gui': '#D4D4D4', 'cterm': s:cterm05, 'cterm256': '188'} +let s:cdBack = {'gui': '#1E1E1E', 'cterm': s:cterm00, 'cterm256': '234'} + +let s:cdTabCurrent = {'gui': '#1E1E1E', 'cterm': s:cterm00, 'cterm256': '234'} +let s:cdTabOther = {'gui': '#2D2D2D', 'cterm': s:cterm01, 'cterm256': '236'} +let s:cdTabOutside = {'gui': '#252526', 'cterm': s:cterm01, 'cterm256': '235'} + +let s:cdLeftDark = {'gui': '#252526', 'cterm': s:cterm01, 'cterm256': '235'} +let s:cdLeftMid = {'gui': '#373737', 'cterm': s:cterm03, 'cterm256': '237'} +let s:cdLeftLight = {'gui': '#3F3F46', 'cterm': s:cterm03, 'cterm256': '238'} + +let s:cdPopupFront = {'gui': '#BBBBBB', 'cterm': s:cterm06, 'cterm256': '250'} +let s:cdPopupBack = {'gui': '#2D2D30', 'cterm': s:cterm01, 'cterm256': '236'} +let s:cdPopupHighlightBlue = {'gui': '#073655', 'cterm': s:cterm0D, 'cterm256': '24'} +let s:cdPopupHighlightGray = {'gui': '#3D3D40', 'cterm': s:cterm03, 'cterm256': '237'} + +let s:cdSplitLight = {'gui': '#898989', 'cterm': s:cterm04, 'cterm256': '245'} +let s:cdSplitDark = {'gui': '#444444', 'cterm': s:cterm03, 'cterm256': '238'} +let s:cdSplitThumb = {'gui': '#424242', 'cterm': s:cterm04, 'cterm256': '238'} + +let s:cdCursorDarkDark = {'gui': '#222222', 'cterm': s:cterm01, 'cterm256': '235'} +let s:cdCursorDark = {'gui': '#51504F', 'cterm': s:cterm03, 'cterm256': '239'} +let s:cdCursorLight = {'gui': '#AEAFAD', 'cterm': s:cterm04, 'cterm256': '145'} +let s:cdSelection = {'gui': '#264F78', 'cterm': s:cterm03, 'cterm256': '24'} +let s:cdLineNumber = {'gui': '#5A5A5A', 'cterm': s:cterm04, 'cterm256': '240'} + +let s:cdDiffRedDark = {'gui': '#4B1818', 'cterm': s:cterm08, 'cterm256': '52'} +let s:cdDiffRedLight = {'gui': '#6F1313', 'cterm': s:cterm08, 'cterm256': '52'} +let s:cdDiffRedLightLight = {'gui': '#FB0101', 'cterm': s:cterm08, 'cterm256': '09'} +let s:cdDiffGreenDark = {'gui': '#373D29', 'cterm': s:cterm0B, 'cterm256': '237'} +let s:cdDiffGreenLight = {'gui': '#4B5632', 'cterm': s:cterm09, 'cterm256': '58'} + +let s:cdSearchCurrent = {'gui': '#49545F', 'cterm': s:cterm09, 'cterm256': '236'} +let s:cdSearch = {'gui': '#4C4E50', 'cterm': s:cterm0A, 'cterm256': '236'} + +" Syntax colors: + +if !exists("g:codedark_conservative") + let g:codedark_conservative=0 +endif + +let s:cdGray = {'gui': '#808080', 'cterm': s:cterm04, 'cterm256': '08'} +let s:cdViolet = {'gui': '#646695', 'cterm': s:cterm04, 'cterm256': '60'} +let s:cdBlue = {'gui': '#569CD6', 'cterm': s:cterm0D, 'cterm256': '75'} +let s:cdDarkBlue = {'gui': '#223E55', 'cterm': s:cterm0D, 'cterm256': '73'} +let s:cdLightBlue = {'gui': '#9CDCFE', 'cterm': s:cterm0C, 'cterm256': '117'} +if g:codedark_conservative | let s:cdLightBlue = s:cdFront | endif +let s:cdGreen = {'gui': '#608B4E', 'cterm': s:cterm0B, 'cterm256': '65'} +let s:cdBlueGreen = {'gui': '#4EC9B0', 'cterm': s:cterm0F, 'cterm256': '43'} +let s:cdLightGreen = {'gui': '#B5CEA8', 'cterm': s:cterm09, 'cterm256': '151'} +let s:cdRed = {'gui': '#F44747', 'cterm': s:cterm08, 'cterm256': '203'} +let s:cdOrange = {'gui': '#CE9178', 'cterm': s:cterm0F, 'cterm256': '173'} +let s:cdLightRed = {'gui': '#D16969', 'cterm': s:cterm08, 'cterm256': '167'} +if g:codedark_conservative | let s:cdLightRed = s:cdOrange | endif +let s:cdYellowOrange = {'gui': '#D7BA7D', 'cterm': s:cterm0A, 'cterm256': '179'} +let s:cdYellow = {'gui': '#DCDCAA', 'cterm': s:cterm0A, 'cterm256': '187'} +if g:codedark_conservative | let s:cdYellow = s:cdFront | endif +let s:cdPink = {'gui': '#C586C0', 'cterm': s:cterm0E, 'cterm256': '176'} +if g:codedark_conservative | let s:cdPink = s:cdBlue | endif + +" Vim editor colors +" hi(GROUP, FOREGROUND, BACKGROUND, ATTRIBUTE, SPECIAL) +call hi('Normal', s:cdFront, s:cdBack, 'none', {}) +call hi('ColorColumn', {}, s:cdCursorDarkDark, 'none', {}) +call hi('Cursor', s:cdCursorDark, s:cdCursorLight, 'none', {}) +call hi('CursorLine', {}, s:cdCursorDarkDark, 'none', {}) +call hi('CursorColumn', {}, s:cdCursorDarkDark, 'none', {}) +call hi('Directory', s:cdBlue, s:cdBack, 'none', {}) +call hi('DiffAdd', {}, s:cdDiffGreenDark, 'none', {}) +call hi('DiffChange', {}, s:cdDiffRedDark, 'none', {}) +call hi('DiffDelete', {}, s:cdDiffRedLight, 'none', {}) +call hi('DiffText', {}, s:cdDiffRedLight, 'none', {}) +call hi('EndOfBuffer', s:cdLineNumber, s:cdBack, 'none', {}) +call hi('ErrorMsg', s:cdRed, s:cdBack, 'none', {}) +call hi('VertSplit', s:cdSplitDark, s:cdBack, 'none', {}) +call hi('Folded', s:cdLeftLight, s:cdLeftDark, 'underline', {}) +call hi('FoldColumn', s:cdLineNumber, s:cdBack, 'none', {}) +call hi('SignColumn', {}, s:cdBack, 'none', {}) +call hi('IncSearch', s:cdNone, s:cdSearchCurrent, 'none', {}) +call hi('LineNr', s:cdLineNumber, s:cdBack, 'none', {}) +call hi('CursorLineNr', s:cdPopupFront, s:cdBack, 'none', {}) +call hi('MatchParen', s:cdNone, s:cdCursorDark, 'none', {}) +call hi('ModeMsg', s:cdFront, s:cdLeftDark, 'none', {}) +call hi('MoreMsg', s:cdFront, s:cdLeftDark, 'none', {}) +call hi('NonText', s:cdLineNumber, s:cdBack, 'none', {}) +call hi('Pmenu', s:cdPopupFront, s:cdPopupBack, 'none', {}) +call hi('PmenuSel', s:cdPopupFront, s:cdPopupHighlightBlue, 'none', {}) +call hi('PmenuSbar', {}, s:cdPopupHighlightGray, 'none', {}) +call hi('PmenuThumb', {}, s:cdPopupFront, 'none', {}) +call hi('Question', s:cdBlue, s:cdBack, 'none', {}) +call hi('Search', s:cdNone, s:cdSearch, 'none', {}) +call hi('SpecialKey', s:cdBlue, s:cdNone, 'none', {}) +call hi('SpellBad', s:cdNone, s:cdNone, 'undercurl', {}) +call hi('SpellCap', s:cdNone, s:cdNone, 'undercurl', {}) +call hi('SpellLocal', s:cdNone, s:cdNone, 'undercurl', {}) +call hi('StatusLine', s:cdFront, s:cdLeftMid, 'none', {}) +call hi('StatusLineNC', s:cdFront, s:cdLeftDark, 'none', {}) +call hi('TabLine', s:cdFront, s:cdTabOther, 'none', {}) +call hi('TabLineFill', s:cdFront, s:cdTabOutside, 'none', {}) +call hi('TabLineSel', s:cdFront, s:cdTabCurrent, 'none', {}) +call hi('Title', s:cdNone, s:cdNone, 'bold', {}) +call hi('Visual', s:cdNone, s:cdSelection, 'none', {}) +call hi('VisualNOS', s:cdNone, s:cdSelection, 'none', {}) +call hi('WarningMsg', s:cdOrange, s:cdBack, 'none', {}) +call hi('WildMenu', s:cdNone, s:cdSelection, 'none', {}) + +call hi('Comment', s:cdGreen, {}, 'none', {}) + +call hi('Constant', s:cdBlue, {}, 'none', {}) +call hi('String', s:cdOrange, {}, 'none', {}) +call hi('Character', s:cdOrange, {}, 'none', {}) +call hi('Number', s:cdLightGreen, {}, 'none', {}) +call hi('Boolean', s:cdBlue, {}, 'none', {}) +call hi('Float', s:cdLightGreen, {}, 'none', {}) + +call hi('Identifier', s:cdLightBlue, {}, 'none', {}) +call hi('Function', s:cdYellow, {}, 'none', {}) + +call hi('Statement', s:cdPink, {}, 'none', {}) +call hi('Conditional', s:cdPink, {}, 'none', {}) +call hi('Repeat', s:cdPink, {}, 'none', {}) +call hi('Label', s:cdPink, {}, 'none', {}) +call hi('Operator', s:cdFront, {}, 'none', {}) +call hi('Keyword', s:cdPink, {}, 'none', {}) +call hi('Exception', s:cdPink, {}, 'none', {}) + +call hi('PreProc', s:cdPink, {}, 'none', {}) +call hi('Include', s:cdPink, {}, 'none', {}) +call hi('Define', s:cdPink, {}, 'none', {}) +call hi('Macro', s:cdPink, {}, 'none', {}) +call hi('PreCondit', s:cdPink, {}, 'none', {}) + +call hi('Type', s:cdBlue, {}, 'none', {}) +call hi('StorageClass', s:cdBlue, {}, 'none', {}) +call hi('Structure', s:cdBlue, {}, 'none', {}) +call hi('Typedef', s:cdBlue, {}, 'none', {}) + +call hi('Special', s:cdFront, {}, 'none', {}) +call hi('SpecialChar', s:cdFront, {}, 'none', {}) +call hi('Tag', s:cdFront, {}, 'none', {}) +call hi('Delimiter', s:cdFront, {}, 'none', {}) +call hi('SpecialComment', s:cdGreen, {}, 'none', {}) +call hi('Debug', s:cdFront, {}, 'none', {}) + +call hi('Underlined', s:cdNone, {}, 'underline', {}) +call hi("Conceal", s:cdFront, s:cdBack, 'none', {}) + +call hi('Ignore', s:cdFront, {}, 'none', {}) + +call hi('Error', s:cdRed, s:cdBack, 'undercurl', s:cdRed) + +call hi('Todo', s:cdNone, s:cdLeftMid, 'none', {}) + +" Markdown: +call hi('markdownBold', s:cdBlue, {}, 'bold', {}) +call hi('markdownCode', s:cdOrange, {}, 'none', {}) +call hi('markdownRule', s:cdBlue, {}, 'bold', {}) +call hi('markdownCodeDelimiter', s:cdOrange, {}, 'none', {}) +call hi('markdownHeadingDelimiter', s:cdBlue, {}, 'none', {}) +call hi('markdownFootnote', s:cdOrange, {}, 'none', {}) +call hi('markdownFootnoteDefinition', s:cdOrange, {}, 'none', {}) +call hi('markdownUrl', s:cdLightBlue, {}, 'underline', {}) +call hi('markdownLinkText', s:cdOrange, {}, 'none', {}) +call hi('markdownEscape', s:cdYellowOrange, {}, 'none', {}) + +" JSON: +call hi('jsonKeyword', s:cdLightBlue, {}, 'none', {}) +call hi('jsonEscape', s:cdYellowOrange, {}, 'none', {}) +call hi('jsonNull', s:cdBlue, {}, 'none', {}) +call hi('jsonBoolean', s:cdBlue, {}, 'none', {}) + +" HTML: +call hi('htmlTag', s:cdGray, {}, 'none', {}) +call hi('htmlEndTag', s:cdGray, {}, 'none', {}) +call hi('htmlTagName', s:cdBlue, {}, 'none', {}) +call hi('htmlSpecialTagName', s:cdBlue, {}, 'none', {}) +call hi('htmlArg', s:cdLightBlue, {}, 'none', {}) + +" CSS: +call hi('cssBraces', s:cdFront, {}, 'none', {}) +call hi('cssInclude', s:cdPink, {}, 'none', {}) +call hi('cssTagName', s:cdYellowOrange, {}, 'none', {}) +call hi('cssClassName', s:cdYellowOrange, {}, 'none', {}) +call hi('cssPseudoClass', s:cdYellowOrange, {}, 'none', {}) +call hi('cssPseudoClassId', s:cdYellowOrange, {}, 'none', {}) +call hi('cssPseudoClassLang', s:cdYellowOrange, {}, 'none', {}) +call hi('cssIdentifier', s:cdYellowOrange, {}, 'none', {}) +call hi('cssProp', s:cdLightBlue, {}, 'none', {}) +call hi('cssDefinition', s:cdLightBlue, {}, 'none', {}) +call hi('cssAttr', s:cdOrange, {}, 'none', {}) +call hi('cssAttrRegion', s:cdOrange, {}, 'none', {}) +call hi('cssColor', s:cdOrange, {}, 'none', {}) +call hi('cssFunction', s:cdOrange, {}, 'none', {}) +call hi('cssFunctionName', s:cdOrange, {}, 'none', {}) +call hi('cssVendor', s:cdOrange, {}, 'none', {}) +call hi('cssValueNumber', s:cdOrange, {}, 'none', {}) +call hi('cssValueLength', s:cdOrange, {}, 'none', {}) +call hi('cssUnitDecorators', s:cdOrange, {}, 'none', {}) + +" JavaScript: +call hi('jsVariableDef', s:cdLightBlue, {}, 'none', {}) +call hi('jsFuncArgs', s:cdLightBlue, {}, 'none', {}) +call hi('jsRegexpString', s:cdLightRed, {}, 'none', {}) +call hi('jsThis', s:cdBlue, {}, 'none', {}) +call hi('jsDestructuringBlock', s:cdLightBlue, {}, 'none', {}) +call hi('jsObjectKey', s:cdLightBlue, {}, 'none', {}) +call hi('jsGlobalObjects', s:cdBlueGreen, {}, 'none', {}) +call hi('jsModuleKeyword', s:cdLightBlue, {}, 'none', {}) +call hi('jsClassDefinition', s:cdBlueGreen, {}, 'none', {}) +call hi('jsClassKeyword', s:cdBlue, {}, 'none', {}) +call hi('jsExtendsKeyword', s:cdBlue, {}, 'none', {}) +call hi('jsExportDefault', s:cdPink, {}, 'none', {}) +call hi('jsFuncCall', s:cdYellow, {}, 'none', {}) +call hi('jsObjectKey', s:cdYellow, {}, 'none', {}) +call hi('jsObjectValue', s:cdLightBlue, {}, 'none', {}) +call hi('jsParen', s:cdLightBlue, {}, 'none', {}) + +" XML: +call hi('xmlTag', s:cdBlueGreen, {}, 'none', {}) +call hi('xmlTagName', s:cdBlueGreen, {}, 'none', {}) +call hi('xmlEndTag', s:cdBlueGreen, {}, 'none', {}) + +" Ruby: +call hi('rubyClassNameTag', s:cdBlueGreen, {}, 'none', {}) +call hi('rubyClassName', s:cdBlueGreen, {}, 'none', {}) +call hi('rubyModuleName', s:cdBlueGreen, {}, 'none', {}) +call hi('rubyConstant', s:cdBlueGreen, {}, 'none', {}) + +" Golang: +call hi('goPackage', s:cdBlue, {}, 'none', {}) +call hi('goImport', s:cdBlue, {}, 'none', {}) +call hi('goVar', s:cdBlue, {}, 'none', {}) +call hi('goConst', s:cdBlue, {}, 'none', {}) +call hi('goStatement', s:cdPink, {}, 'none', {}) +call hi('goType', s:cdBlue, {}, 'none', {}) +call hi('goSignedInts', s:cdBlue, {}, 'none', {}) +call hi('goUnsignedInts', s:cdBlue, {}, 'none', {}) +call hi('goFloats', s:cdBlue, {}, 'none', {}) +call hi('goComplexes', s:cdBlue, {}, 'none', {}) +call hi('goBuiltins', s:cdYellow, {}, 'none', {}) +call hi('goBoolean', s:cdBlue, {}, 'none', {}) +call hi('goPredefinedIdentifiers', s:cdBlue, {}, 'none', {}) +call hi('goTodo', s:cdGreen, {}, 'none', {}) +call hi('goDeclaration', s:cdBlue, {}, 'none', {}) +call hi('goDeclType', s:cdBlue, {}, 'none', {}) +call hi('goTypeDecl', s:cdBlue, {}, 'none', {}) +call hi('goTypeName', s:cdBlueGreen, {}, 'none', {}) +call hi('goVarAssign', s:cdLightBlue, {}, 'none', {}) +call hi('goVarDefs', s:cdLightBlue, {}, 'none', {}) +call hi('goReceiver', s:cdFront, {}, 'none', {}) +call hi('goReceiverType', s:cdDarkBlue, {}, 'none', {}) +call hi('goFunctionCall', s:cdYellow, {}, 'none', {}) +call hi('goMethodCall', s:cdYellow, {}, 'none', {}) +call hi('goSingleDecl', s:cdLightBlue, {}, 'none', {}) + +" Python: +call hi('pythonStatement', s:cdBlue, {}, 'none', {}) +call hi('pythonOperator', s:cdBlue, {}, 'none', {}) +call hi('pythonException', s:cdPink, {}, 'none', {}) +call hi('pythonExClass', s:cdBlueGreen, {}, 'none', {}) +call hi('pythonBuiltinObj', s:cdLightBlue, {}, 'none', {}) +call hi('pythonBuiltinType', s:cdBlueGreen, {}, 'none', {}) +call hi('pythonBoolean', s:cdBlue, {}, 'none', {}) +call hi('pythonNone', s:cdBlue, {}, 'none', {}) +call hi('pythonTodo', s:cdBlue, {}, 'none', {}) +call hi('pythonClassVar', s:cdBlue, {}, 'none', {}) +call hi('pythonClassDef', s:cdBlueGreen, {}, 'none', {}) + +" TeX: +call hi('texStatement', s:cdBlue, {}, 'none', {}) +call hi('texBeginEnd', s:cdYellow, {}, 'none', {}) +call hi('texBeginEndName', s:cdLightBlue, {}, 'none', {}) +call hi('texOption', s:cdLightBlue, {}, 'none', {}) +call hi('texBeginEndModifier', s:cdLightBlue, {}, 'none', {}) +call hi('texDocType', s:cdPink, {}, 'none', {}) +call hi('texDocTypeArgs', s:cdLightBlue, {}, 'none', {}) + +" Git: +call hi('gitcommitHeader', s:cdGray, {}, 'none', {}) +call hi('gitcommitOnBranch', s:cdGray, {}, 'none', {}) +call hi('gitcommitBranch', s:cdPink, {}, 'none', {}) +call hi('gitcommitComment', s:cdGray, {}, 'none', {}) +call hi('gitcommitSelectedType', s:cdGreen, {}, 'none', {}) +call hi('gitcommitSelectedFile', s:cdGreen, {}, 'none', {}) +call hi('gitcommitDiscardedType', s:cdRed, {}, 'none', {}) +call hi('gitcommitDiscardedFile', s:cdRed, {}, 'none', {}) +call hi('gitcommitOverflow', s:cdRed, {}, 'none', {}) +call hi('gitcommitSummary', s:cdPink, {}, 'none', {}) +call hi('gitcommitBlank', s:cdPink, {}, 'none', {}) + diff --git a/doc b/doc deleted file mode 120000 index 671d547..0000000 --- a/doc +++ /dev/null @@ -1 +0,0 @@ -/home/rick/.vim/doc \ No newline at end of file diff --git a/doc/emmet.txt b/doc/emmet.txt new file mode 100644 index 0000000..dcaf776 --- /dev/null +++ b/doc/emmet.txt @@ -0,0 +1,1745 @@ +*emmet.txt* *Emmet* for Vim + + ------------------------------------------------------- + Emmet: vim plugins for HTML and CSS hi-speed coding + ------------------------------------------------------- + +Author: Yasuhiro Matsumoto +WebSite: http://mattn.kaoriya.net/ +Repository: https://github.com/mattn/emmet-vim +Site: https://mattn.github.com/emmet-vim +License: BSD style license + +============================================================================== +CONTENTS *emmet-contents* + +Introduction |emmet-introduction| +Install |emmet-install| +Tutorial |emmet-tutorial| + 1. Expand abbreviation |emmet-expand-abbr| |,| + 2. Wrap with abbreviation |emmet-wrap-with-abbreviation| |v_,| + 3. Balance tag inward |emmet-balance-tag-inward| |d| + 4. Balance tag outward |emmet-balance-tag-outward| |D| + 5. Go to next edit point |emmet-goto-next-point| |n| + 6. Go to previous edit point |emmet-goto-previous-point| |N| + 7. Add and update size |emmet-update-image-size| |i| + 8. Merge lines |emmet-merge-lines| |m| + 9. Remove tag |emmet-remove-tag| |k| + 10. Split/join tag |emmet-split-join-tag| |j| + 11. Toggle comment |emmet-toggle-comment| |/| + 12. Make anchor from URL |emmet-make-anchor-url| |a| + 13. Make quoted text from URL |emmet-quoted-text-url| |A| + 14. Code pretty |emmet-code-pretty| |c| + 15. Lorem ipsum |emmet-lorem-ipsum| +HTML expression syntax |emmet-html-expression-syntax| + 1. Elements |emmet-html-syntax-elements| + 2. Nesting operators |emmet-html-syntax-nesting-operators| + 2.1. Child |emmet->| + 2.2. Sibling |emmet-+| + 2.3. Climb-up |emmet-^| + 2.4. Multiplication |emmet-star| + 2.5. Grouping |emmet-()| + 3. Attribute operators |emmet-html-syntax-attribute-operators| + 3.1. ID and CLASS |emmet-.| |emmet-#| + 3.2. Custom attributes |emmet-[]| + 3.3. Item numbering |emmet-$| + 3.3.1. Changing numbering origin and direction |emmet-@| + 3.4. Quote character |emmet-html-attr-quote-char| + 4. Text |emmet-{}| + 5. Implicit tag names |emmet-html-implicit-tag-names| + 6. Notes on abbreviation formatting |emmet-html-syntax-notes| + 7. Choose position to insert text when wrap abbreviation |emmet-$#| +CSS expression syntax |emmet-css-expression-syntax| + 1. Properties |emmet-css-properties| + 2. Values |emmet-css-values| + 3. Units |emmet-css-units| + 4. Vendor prefixes |emmet-css-vendor-prefixes| +Commands |emmet-commands| + :Emmet |:Emmet| + :EmmetInstall |:EmmetInstall| +Variables |emmet-variables| + g:emmet_html5 |g:emmet_html5| + g:emmet_docroot |g:emmet_docroot| + g:emmet_curl_command |g:emmet_curl_command| + g:user_emmet_complete_tag |g:user_emmet_complete_tag| + g:user_emmet_leader_key |g:user_emmet_leader_key| + g:user_emmet_install_global |g:user_emmet_install_global| + g:user_emmet_install_command |g:user_emmet_install_command| + g:user_emmet_settings |g:user_emmet_settings| + g:user_emmet_mode |g:user_emmet_mode| +Customize |emmet-customize| + 1. Key mappings |emmet-customize-key-mappings| + 2. Indent size |emmet-indent-size| + 3. Define tag's behavior |emmet-define-tags-behavior| + 4. Adding custom snippets |emmet-custom-snippets| +Filters |emmet-filters-list| + Escapes XML-unsafe characters |emmet-filter-e| + Add comments around 'important tags' |emmet-filter-c| + Outputs as a single line |emmet-filter-s| + Trim list markers |emmet-filter-t| +Links |emmet-links| +ToDo |emmet-todo| + +============================================================================== +INTRODUCTION *emmet-introduction* *emmet* + +Emmet is an editor plugin for high-speed HTML, XML, XSL (or any other +structured code format) coding and editing. The core of this plugin is a +powerful abbreviation engine which allows you to expand expressions, +similar to CSS selectors, into HTML code: +> + div#page>div.logo+ul#navigation>li*5>a +< +can be expanded into: +> +

+ + +
+< +Read more about current Emmet syntax + |emmet-html-expression-syntax| + |emmet-css-expression-syntax| + http://docs.emmet.io/abbreviations/ + +Abbreviation engine has a modular structure which allows you +to expand abbreviations into different languages. +Emmet currently supports CSS, HTML, XML/XSL and HAML, Slim languages +via filters (see |emmet-filter|). + +============================================================================== +INSTALL *emmet-install* + +Install the distributed files into Vim runtime directory which is usually +'~/.vim/', or '$HOME/vimfiles' on Windows. + +If you install pathogen (https://github.com/tpope/vim-pathogen) +that provided by Tim Pope, you should extract the +file into 'bundle' directory. + +============================================================================== +TUTORIAL *emmet-tutorial* + +If you are seeing this file as :help, then you can't edit this file. +You should copy this section and create new buffer, paste and write as +'emmet-tutor.txt'. Formally, open the file to start tutorial. + +1. Expand abbreviation *emmet-expand-abbr* *,* + + Type abbreviation as 'div>p#foo$*3>a' and type ','. +> +
+

+ +

+

+ +

+

+ +

+
+< +2. Wrap with abbreviation *emmet-wrap-with-abbreviation* *v_,* + + Write as below. +> + test1 + test2 + test3 +< + Then do visual select (line wise) and type ','. + If you request 'Tag:', then type +> + ul>li* +< + Result: +> +
    +
  • test1
  • +
  • test2
  • +
  • test3
  • +
+< + If you type tag name, for example +> + blockquote +< + then you'll see as following: +> +
+ test1 + test2 + test3 +
+< + See also: |emmet-filter-t|, |emmet-$#| + +3. Balance tag inward *emmet-balance-tag-inward* *d* + + To select inward of '
    ' tag, type 'd' in insert mode. +> +
      + *
    • +
    • +
    • +
    +< + If cursor is at '*', 'd' select from begin of '
      ' to end of '
    '. + If cursor is at first of '
  • ', it select '
  • '. + +4. Balance tag outward *emmet-balance-tag-outward* *D* + + To select outward of '
      ' tag type 'D' in insert mode. +> +
        + *
      • +
      • +
      • +
      +< + If cursor is at '*', 'D' select from next letter of '
        ' + to previous letter of '
      '. + If cursor is at first of '
    • ', it select '
    • '. + +5. Go to next edit point *emmet-goto-next-point* *n* + + To jump next point that need to edit, type 'n' in insert mode. +> + *
      foo
      +
      +< + If cursor is at '*', type 'n' to move a cursor + into attribute value of '
      ' specified id as 'foo'. + And type again 'n' to move a cursor + into inner of '
      ' specified id as 'bar'. + +6. Go to previous edit point *emmet-goto-previous-point* *N* + + To jump previous point that need to edit, type 'N' in insert mode. +> +
      foo
      +
      * +< + If cursor is at '*', type 'N' to move a cursor + into '
      ' specified id as 'bar'. + And type again 'N' to move a cursor + into attribute value of 'foo'. + +7. Add and update size *emmet-update-image-size* *i* + + To add or update 'width' and 'height' attributes of image, + type 'i' on '' tag +> + +< + Type 'i' on '' tag +> + +< + If you change image, then type it again. it will be following. +> + +< + Image size retrieved using 'identify' (ImageMagick.org) (if available) + or |xxd|. + +8. Merge lines *emmet-merge-lines* *m* + + To join multi line text like following, type |J|. +> +
        +
      • +
      • +
      • +
      +< + If you select part of line include '
    • ' and type |m|, + it will be following. +> +
        +
      • +
      +< +9. Remove tag *emmet-remove-tag* *k* + + To remove tag in the block, type 'k'. +> + +< + Type 'k' in insert mode, then +> +
      + +
      +< + And type 'k' in there again, then '
      ' will be removed. + +10. Split/join tag *emmet-split-join-tag* *j* + + To join block, type 'j'. +> +
      + cursor is here +
      +< + Type 'j' in insert mode. Then, +> +
      +< + And type 'j' in there again. +> +
      +
      +< +11. Toggle comment *emmet-toggle-comment* */* + + Move cursor to block +> +
      + hello world +
      +< + Type '/' in insert mode. +> + +< + Type '/' in there again. +> +
      + hello world +
      +< +12. Make anchor from URL *emmet-make-anchor-url* *a* + + Move cursor to URL +> + http://www.google.com/ +< + Type 'a' +> + Google +< + Text retrieved using command, specified by |g:emmet_curl_command|. + +13. Make quoted text from URL *emmet-quoted-text-url* *A* + + Move cursor to URL +> + https://github.com/ +< + Type 'A' +> +
      + Secure source code hosting and collaborative development - GitHub
      +

      How does it work? Get up and running in seconds by forking a project, pushing an existing repository...

      + https://github.com/ +
      +< + Text retrieved using command, specified by |g:emmet_curl_command|. + +14. Code pretty *emmet-code-pretty* *c* + + Select code block, for example select following code from 'int main()'. +> +

      Writing in C language

      + + int main() { + puts("hello world"); + } +< + Type 'c' +> + int main() {
      +   puts("hello world");
      + }
      +< + To convert text into html used command |:TOhtml|. + +15. Lorem ipsum *emmet-lorem-ipsum* + + To insert dummy text (30 words by default). +> + div>lorem +< + Type |,| +> +
      Adipisicing asperiores deleniti ipsum fuga deserunt perferendis + molestiae sunt excepturi aut quo nihil! Optio accusantium corporis molestiae + deserunt ab, veritatis commodi. Eius nobis ab deserunt magni iure quo + laboriosam laboriosam.
      +< + For japanese user, put like follow into your |g:user_emmet_settings|: +> + let g:user_emmet_settings = { + ... + + \ 'custom_expands1' : { + \ '^\%(lorem\|lipsum\)\(\d*\)$' : function('emmet#lorem#ja#expand'), + \ }, + + ... +< + You will get japanese dummy text. Text retrieved from url + 'http://www.aozora.gr.jp/cards/000081/files/470_15407.html' + using command, specified by |g:emmet_curl_command|. + + To insert 3 words of dummy text. +> + div>lorem3 +< + Type |,| +> +
      + Elit libero id. +
      +< +============================================================================== +HTML EXPRESSION SYNTAX *emmet-html-expression-syntax* + +Emmet uses syntax similar to CSS selectors for describing elements' positions +inside generated tree and elements' attributes. + +1. Elements *emmet-html-syntax-elements* + + You can use elements' names like 'div' or 'p' to generate HTML tags. +> + p ->

      + div ->
      +< + You can write any word and transform it into a tag: +> + foo -> + bar -> +< + Emmet knowns set of empty elements: +> + br ->
      or
      + meta -> or +< + To choose between HTML '>' and XHTML ' />' use |g:emmet_html5| or + |g:user_emmet_settings|: +> + let g:user_emmet_settings = { + \ ... + \ 'html': { + \ ... + \ 'empty_element_suffix': ' />', + \ ... + \ }, + \ ... + \} +< + Emmet will automatically insert some attributes: +> + a -> + link -> +< + Set of inserted attributes can be changed using |g:user_emmet_settings|: +> + let s:emmet_settings = { + \ ... + \ 'html': { + \ ... + \ 'default_attributes': { + \ ... + \ 'a': {'href': ''}, + \ 'ins': {'datetime': '${datetime}'}, + \ 'iframe': [{'src': ''}, {'frameborder': '0'}], + \ 'textarea': [{'name': ''}, {'id': ''}, {'cols': '30'}, {'rows': '10'}], + \ ... + \ }, + \ ... + \ }, + \ ... + \} +< +2. Nesting operators *emmet-html-syntax-nesting-operators* + + Nesting operators are used to position abbreviation elements + inside generated tree: whether it should be placed + inside or near the context element. + + Operator Description Link ~ + > Child |emmet->| + + Sibling |emmet-+| + ^ Climb-up |emmet-^| + * Multiplication |emmet-star| + () Grouping |emmet-()| + +2.1. Child *emmet->* + + You can use '>' operator to nest elements inside each other: +> + div>ul>li +< + will produce +> +
      +
        +
      • +
      +
      +< +2.2. Sibling *emmet-+* + + Use '+' operator to place elements near each other, on the same level: +> + div+p+bq +< + will output +> +
      +

      +
      +< +2.3. Climb-up *emmet-^* + + With '>' operator you're descending down the generated tree and + positions of all sibling elements will be resolved + against the most deepest element: +> + div+div>p>span+em +< + will be expanded to +> +
      +
      +

      + + +

      +
      +< + With '^' operator, you can climb one level up the tree and change context + where following elements should appear: +> + div+div>p>span+em^bq +< + outputs to +> +
      +
      +

      + + +

      +
      +
      +< + You can use as many '^' operators as you like, + each operator will move one level up: +> + div+div>p>span+em^^^bq +< + will output to +> +
      +
      +

      + + +

      +
      +
      +< +2.4. Multiplication *emmet-star* + + With '*' operator you can define how many times element should be outputted: +> + ul>li*5 +< + outputs to +> +
        +
      • +
      • +
      • +
      • +
      • +
      +< + Expression may contain several '*' operators: +> + tr*2>td*3 +< + become +> + + + + + + + + + + +< +2.5. Grouping *emmet-()* + + Parentheses '()' are used by Emmets' power users for grouping subtrees + in complex abbreviations: +> + div>(header>ul>li*2>a)+footer>p +< + expands to +> +
      +
      +
        +
      • +
      • +
      +
      +
      +

      +
      +
      +< + If you're working with browser's DOM, you may think of groups + as Document Fragments: each group contains abbreviation subtree and + all the following elements are inserted at the same level + as the first element of group. + + You can nest groups inside each other and + combine them with multiplication '*' operator: +> + (div>dl>(dt+dd)*3)+footer>p +< + produces +> +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +

      +
      +< + With groups, you can literally write full page mark-up + with a single abbreviation, but please don't do that. + +3. Attribute operators *emmet-html-syntax-attribute-operators* + + Attribute operators are used to modify attributes of outputted elements. + For example, in HTML and XML you can quickly add 'class' attribute + to generated element. + + Operator Description Link ~ + . Attribute 'class' |emmet-.| + # Attribute 'id' |emmet-#| + [] Custom attributes |emmet-[]| + $ Number |emmet-$| + @ Number origin and direction |emmet-@| + +3.1. ID and CLASS *emmet-.* *emmet-#* + + In CSS, you use 'elem#id' and 'elem.class' notation to reach the elements + with specified 'id' or 'class' attributes. + In Emmet, you can use the very same syntax to add these attributes + to specified element: +> + span.class1 -> + span.class1.class2 -> + div#wrapper ->
      + div#wrapper.content ->
      +< + More complex expression: +> + div#header+div.page+div#footer.class1.class2.class3 +< + will output +> + +
      + +< +3.2. Custom attributes *emmet-[]* + + You can use '[attr]' notation (as in CSS) + to add custom attributes to your element: +> + td[title="Hello world!" colspan=3] +< + outputs +> + +< + You can place as many attributes as you like inside square brackets. + + Attribute values may be omitted: +> + td[colspan title] +< + will produce +> + +< + You can use single or double quotes for quoting attribute values. +> + div[a='value1' b="value2"] +< + become +> +
      +< + You don't need to quote values if they don't contain spaces: +> + td[title=hello colspan=3] +< + will output +> + +< +3.3. Item numbering *emmet-$* + + With multiplication '*' operator you can repeat elements, + but with '$' you can number them. + Place '$' operator inside element's name, attribute's name or + attribute's value to output current number of repeated element: +> + ul>li.item_$*5 +< + outputs to +> +
        +
      • +
      • +
      • +
      • +
      • +
      +< + You can use multiple '$' in a row to pad number with zeroes: +> + ul>li.item_$$$*5 +< + outputs to +> +
        +
      • +
      • +
      • +
      • +
      • +
      +< + Also '$' can be used in element name and in text (|emmet-{}|): +> + h$[title=item$]{Header $}*3 +< + transformed to +> +

      Header 1

      +

      Header 2

      +

      Header 3

      +< +3.3.1. Changing numbering origin and direction *emmet-@* + + With '@' modifier, you can change + - numbering direction (ascending or descending) and + - origin (i. e. start value). + + For example, to change direction, add '@-' after '$': +> + ul>li.item_$@-*5 +< + outputs to +> +
        +
      • +
      • +
      • +
      • +
      • +
      +< + To change counter origin value, add '@N' modifier to '$': +> + ul>li.item_$@3*5 +< + transforms to +> +
        +
      • +
      • +
      • +
      • +
      • +
      +< + You can use these modifiers together: +> + ul>li.item_$@-3*5 +< + is transformed to +> +
        +
      • +
      • +
      • +
      • +
      • +
      +> +3.4. Quote character *emmet-html-attr-quote-char* + + |g:user_emmet_settings| may be used to change attribute quote character: +> + let g:user_emmet_settings = { + ... + \ 'html' : { + ... + \ 'quote_char': "'", + ... + \ }, + ... + \} +< + Then abbreviation +> + a[target=_blank] +< + will expand to +> + +< + instead of +> + +< + Default quote is '"'. + +4. Text *emmet-{}* + + You can use curly braces to add text to element: +> + a{Click me} +< + will produce +> + Click me +< + Note that '{text}' is used and parsed as a separate element + (like, 'div', 'p' etc), but has a special meaning + when written right after element. For example, +> + a{click} +< + and +> + a>{click} +< + will produce the same output, but +> + a{click}+b{here} +< + and +> + a>{click}+b{here} +< + won't: +> + + clickhere + + + clickhere +< + In second example the '' element is placed inside '' element. + And that's the difference: when '{text}' is written right after element, + it doesn't change parent context. + Here's more complex example showing why it is important: +> + p>{Click }+a{here}+{ to continue} +< + produces +> +

      Click here to continue

      +< + In this example, to write 'Click here to continue' inside '

      ' element + we have explicitly move down the tree with '>' operator after 'p', + but in case of 'a' element we don't have to, since we need '' element + with here word only, without changing parent context. + + For comparison, here's the same abbreviation + written without child '>' operator: +> + p{Click }+a{here}+{ to continue} +< + produces +> +

      Click

      + here to continue +< +5. Implicit tag names *emmet-html-implicit-tag-names* + + Even with such a powerful abbreviation engine, + which can expand large HTML structures from short abbreviation, + writing tag names may be very tedious. + + In many cases you can skip typing tag names and + Emmet will substitute it for you. + For example, instead of > + div.content +< you can simply write > + .content +< and expand it into > +
      +< + Other examples: +> + .wrapper ->
      + #popup -> +< + When you expand abbreviation, Emmet tries to grab parent context, + e. g. the HTML element, inside which you're expanding the abbreviation. + If the context was grabbed successfully, + Emmet uses its name to resolve implicit names. + Emmet looks at the parent tag name every time + you're expanding the abbreviation with an implicit name. + Here's how it resolves the names for some parent elements: + + Inserted element Parent elements ~ + li ul, ol + tr table, tbody, thead, tfoot + td tr + option select, optgroup + span Inline elements + div Block elements + + Take a look at some abbreviations equivalents + with implicit and explicit tag names: +> + .wrap>.content -> div.wrap>div.content + em>.info -> em>span.info + ul>.item*3 -> ul>li.item*3 + table>.row>.col -> table>tr.row>td.col + table>#row$*4>[colspan=2] -> table>tr#row$*4>td[colspan=2] +< +6. Notes on abbreviation formatting *emmet-html-syntax-notes* + + When you get familiar with Emmet's abbreviations syntax, + you may want to use some formatting to make your abbreviations more readable. + For example, use spaces between elements and operators, like this: +> + (header > ul.nav > li*5) + footer +< + But it won't work, because space is a stop symbol + where Emmet stops abbreviation parsing. + + Many users mistakenly think that each abbreviation + should be written in a new line, but they are wrong: + you can type and expand abbreviation anywhere in the text: + + This is why Emmet needs some indicators (like spaces) + where it should stop parsing to not expand anything that you don't need. + If you're still thinking that such formatting is required + for complex abbreviations to make them more readable: + - abbreviations are not a template language, + they don't have to be "readable", + they have to be "quickly expandable and removable"; + - you don't really need to write complex abbreviations. + Stop thinking that "typing" is the slowest process in web-development. + You'll quickly find out that constructing a single complex abbreviation + is much slower and error-prone than constructing and typing + a few short ones. + +7. Choose position to insert text when wrap abbreviation *emmet-$#* + + When wrap abbreviation (|emmet-wrap-with-abbreviation|) you can choose + position to insert text using '$#' operator. + Operator '$#' may be used only inside |emmet-[]| and/or |emmet-{}|. + + For example, do visual select (line wise) following text: +> + First + Second + Third +< + Then press ',' and type +> + ul>li[ title="[$#]" ]* +< + Result: +> +
        +
      • First
      • +
      • Second
      • +
      • Third
      • +
      +< + You may type +> + input[ type=input value=$# ] +< + to get +> + + + +< + Using '$#' you can type text (|emmet-{}|) only once: +> + a[title=$#]{foo} +< + will be expanded to +> + foo +< +============================================================================== +CSS EXPRESSION SYNTAX *emmet-css-expression-syntax* + +1. Properties *emmet-css-properties* + + Emmet has a lot of predefined snippets for CSS properties. +> + +< + become +> + +< + In above example '|' denotes a cursor (caret) position. + + Other examples: +> + t -> top: ; + d -> display: ; + o -> outline: ; + ov -> overflow: ; + cu -> cursor: ; + bdrs -> border-radius: ; +< + '+' operator may be used to insert number of properties: +> + m1+p2 +< + become +> + margin: 1px; + padding: 2px; +< +2. Values *emmet-css-values* + + Some properties have default values: +> + c -> color: #000; + bgc -> background-color: #FFF; + zoo -> zoom: 1; +< + To insert predefined property value after abbreviation + type colon ':' and first character of predefined keyword: +> + d:n -> display: none; + d:b -> display: block; + d:i -> display: inline; +< + Numerical value can be typed directly after abbreviation: +> + m10 -> margin: 10px; + m2e -> margin: 2em; +< + Use a hyphen '-' to separate some numerical values: +> + m10-20 -> margin: 10px 20px; + p1-2-3 -> padding: 1px 2px 3px; +< + To negative values + precede the first value with hyphen and all the rest with double hyphens: +> + m-10 -> margin: -10px; + m-1--2 -> margin: -1px -2px; + p-2--1-0-1 -> padding: -2px -1px 0 1px; +< + To insert '!important' append '!' to property abbreviation: +> + m! -> margin: !important; + bac! -> background: !important; +< + You can use special abbreviation 'lg(...)' + to insert definition of linear gradient. Example: +> + lg(left, #fc0 30%, red) +< + will expand to +> + background-image: -webkit-gradient(left, 0 0, 0 100, from(#fc0 30%), to(red)); + background-image: -webkit-linear-gradient(#fc0 30%, red); + background-image: -moz-linear-gradient(#fc0 30%, red); + background-image: -o-linear-gradient(#fc0 30%, red); + background-image: linear-gradient(#fc0 30%, red); +< +3. Units *emmet-css-units* + + By default, when you expand an abbreviation with integer value, + Emmet outputs it with a 'px' unit: +> + bor2 -> border: 2px; + fs100 -> font-size: 100px; + miw20 -> min-width: 20px; +< + By default, if you're expanding an abbreviation with a float value, + it is outputted with an 'em' unit: +> + fs1.5 -> font-style: 1.5em; +< + But you can explicitly provide the unit name + by putting one of characters right after value: + + Character Unit ~ + p % + e em + + Examples: +> + fs2e -> font-style: 2em; + w100p -> width: 100%; +< +4. Vendor prefixes *emmet-css-vendor-prefixes* + + To automatically create vendor-prefixed copies of property, + precede abbreviation with a hyphen '-'. For example, abbreviation +> + -bdrs +< + will be expanded into +> + -webkit-border-radius: ; + -moz-border-radius: ; + border-radius: ; +< +============================================================================== +COMMANDS *emmet-commands* + +:Emmet {expression} *:Emmet* + Expand {expression} and insert result under cursor. + {expression} is |emmet-html-expression|. + Also see |g:user_emmet_install_command|. + +:EmmetInstall *:EmmetInstall* + Create Emmet mappings to current buffer + (|mapping|, |:map-|) and, + if set |g:user_emmet_complete_tag|, + change |'omnifunc'| option to emmet#completeTag() + +============================================================================== +VARIABLES *emmet-variables* + +g:emmet_html5 *g:emmet_html5* + If set to 1, enable HTML 5 support: + - use ">" instead of "/>": > + + +< - omit some HTML 4 attributes: > +