Parcourir la source

使用新的组织方式

vacant il y a 2 ans
commit
0424b2b8dd
100 fichiers modifiés avec 30361 ajouts et 0 suppressions
  1. 2 0
      .gitignore
  2. 264 0
      vimfiles/autoload/pathogen.vim
  3. 1240 0
      vimfiles/bundle/calendar-vim/autoload/calendar.vim
  4. 254 0
      vimfiles/bundle/calendar-vim/doc/calendar.txt
  5. 37 0
      vimfiles/bundle/calendar-vim/doc/tags
  6. 234 0
      vimfiles/bundle/calendar-vim/plugin/calendar.vim
  7. 183 0
      vimfiles/bundle/coc.nvim/autoload/coc.vim
  8. 678 0
      vimfiles/bundle/coc.nvim/autoload/coc/api.vim
  9. 340 0
      vimfiles/bundle/coc.nvim/autoload/coc/client.vim
  10. 283 0
      vimfiles/bundle/coc.nvim/autoload/coc/color.vim
  11. 244 0
      vimfiles/bundle/coc.nvim/autoload/coc/compat.vim
  12. 60 0
      vimfiles/bundle/coc.nvim/autoload/coc/cursor.vim
  13. 684 0
      vimfiles/bundle/coc.nvim/autoload/coc/dialog.vim
  14. 32 0
      vimfiles/bundle/coc.nvim/autoload/coc/dict.vim
  15. 1423 0
      vimfiles/bundle/coc.nvim/autoload/coc/float.vim
  16. 148 0
      vimfiles/bundle/coc.nvim/autoload/coc/helper.vim
  17. 734 0
      vimfiles/bundle/coc.nvim/autoload/coc/highlight.vim
  18. 303 0
      vimfiles/bundle/coc.nvim/autoload/coc/list.vim
  19. 11 0
      vimfiles/bundle/coc.nvim/autoload/coc/math.vim
  20. 532 0
      vimfiles/bundle/coc.nvim/autoload/coc/notify.vim
  21. 214 0
      vimfiles/bundle/coc.nvim/autoload/coc/prompt.vim
  22. 490 0
      vimfiles/bundle/coc.nvim/autoload/coc/pum.vim
  23. 130 0
      vimfiles/bundle/coc.nvim/autoload/coc/rpc.vim
  24. 155 0
      vimfiles/bundle/coc.nvim/autoload/coc/snippet.vim
  25. 154 0
      vimfiles/bundle/coc.nvim/autoload/coc/string.vim
  26. 179 0
      vimfiles/bundle/coc.nvim/autoload/coc/task.vim
  27. 115 0
      vimfiles/bundle/coc.nvim/autoload/coc/terminal.vim
  28. 446 0
      vimfiles/bundle/coc.nvim/autoload/coc/ui.vim
  29. 625 0
      vimfiles/bundle/coc.nvim/autoload/coc/util.vim
  30. 205 0
      vimfiles/bundle/coc.nvim/autoload/coc/window.vim
  31. 100 0
      vimfiles/bundle/coc.nvim/autoload/health/coc.vim
  32. 97 0
      vimfiles/bundle/coc.nvim/bin/prompt.js
  33. 12 0
      vimfiles/bundle/coc.nvim/bin/terminateProcess.sh
  34. 9 0
      vimfiles/bundle/coc.nvim/build/index.js
  35. 1666 0
      vimfiles/bundle/coc.nvim/data/schema.json
  36. 1250 0
      vimfiles/bundle/coc.nvim/doc/coc-config.txt
  37. 3534 0
      vimfiles/bundle/coc.nvim/doc/coc.txt
  38. 703 0
      vimfiles/bundle/coc.nvim/plugin/coc.vim
  39. 467 0
      vimfiles/bundle/colorizer/autoload/colorizer.vim
  40. 36 0
      vimfiles/bundle/colorizer/colortest.txt
  41. 76 0
      vimfiles/bundle/colorizer/plugin/colorizer.vim
  42. 485 0
      vimfiles/bundle/lightline.vim/autoload/lightline.vim
  43. 257 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme.vim
  44. 53 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/16color.vim
  45. 44 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/OldHope.vim
  46. 12 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/PaperColor.vim
  47. 60 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/PaperColor_dark.vim
  48. 55 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/PaperColor_light.vim
  49. 42 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/Tomorrow.vim
  50. 42 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/Tomorrow_Night.vim
  51. 43 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/Tomorrow_Night_Blue.vim
  52. 43 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/Tomorrow_Night_Bright.vim
  53. 43 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/Tomorrow_Night_Eighties.vim
  54. 46 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/apprentice.vim
  55. 42 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/ayu_dark.vim
  56. 42 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/ayu_light.vim
  57. 42 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/ayu_mirage.vim
  58. 37 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/darcula.vim
  59. 8 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/default.vim
  60. 39 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/deus.vim
  61. 41 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/jellybeans.vim
  62. 25 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/landscape.vim
  63. 63 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/materia.vim
  64. 63 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/material.vim
  65. 35 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/molokai.vim
  66. 46 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/nord.vim
  67. 60 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/one.vim
  68. 28 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/powerline.vim
  69. 28 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/powerlineish.vim
  70. 58 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/rosepine.vim
  71. 49 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/selenized_black.vim
  72. 49 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/selenized_dark.vim
  73. 49 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/selenized_light.vim
  74. 49 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/selenized_white.vim
  75. 43 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/seoul256.vim
  76. 43 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/simpleblack.vim
  77. 80 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/solarized.vim
  78. 45 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/srcery_drk.vim
  79. 42 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/wombat.vim
  80. 52 0
      vimfiles/bundle/lightline.vim/autoload/lightline/colortable.vim
  81. 33 0
      vimfiles/bundle/lightline.vim/autoload/lightline/tab.vim
  82. 153 0
      vimfiles/bundle/lightline.vim/colorscheme.md
  83. 1145 0
      vimfiles/bundle/lightline.vim/doc/lightline.txt
  84. 59 0
      vimfiles/bundle/lightline.vim/doc/tags
  85. 33 0
      vimfiles/bundle/lightline.vim/plugin/lightline.vim
  86. 3021 0
      vimfiles/bundle/nerdcommenter/autoload/nerdcommenter.vim
  87. 1004 0
      vimfiles/bundle/nerdcommenter/doc/nerdcommenter.txt
  88. 61 0
      vimfiles/bundle/nerdcommenter/doc/tags
  89. 131 0
      vimfiles/bundle/nerdcommenter/plugin/nerdcommenter.vim
  90. 249 0
      vimfiles/bundle/nerdtree/autoload/nerdtree.vim
  91. 732 0
      vimfiles/bundle/nerdtree/autoload/nerdtree/ui_glue.vim
  92. 1534 0
      vimfiles/bundle/nerdtree/doc/NERDTree.txt
  93. 143 0
      vimfiles/bundle/nerdtree/doc/tags
  94. 365 0
      vimfiles/bundle/nerdtree/lib/nerdtree/bookmark.vim
  95. 402 0
      vimfiles/bundle/nerdtree/lib/nerdtree/creator.vim
  96. 13 0
      vimfiles/bundle/nerdtree/lib/nerdtree/event.vim
  97. 58 0
      vimfiles/bundle/nerdtree/lib/nerdtree/flag_set.vim
  98. 164 0
      vimfiles/bundle/nerdtree/lib/nerdtree/key_map.vim
  99. 211 0
      vimfiles/bundle/nerdtree/lib/nerdtree/menu_controller.vim
  100. 118 0
      vimfiles/bundle/nerdtree/lib/nerdtree/menu_item.vim

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+vim??/
+*.swp

+ 264 - 0
vimfiles/autoload/pathogen.vim

@@ -0,0 +1,264 @@
+" pathogen.vim - path option manipulation
+" Maintainer:   Tim Pope <http://tpo.pe/>
+" 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,'\\\@<!\%(\\\\\)*\zs,')
+  return map(split,'substitute(v:val,''\\\([\\,]\)'',''\1'',"g")')
+endfunction
+
+" Convert a list to a path.
+function! pathogen#join(...) abort
+  if type(a:1) == type(1) && a:1
+    let i = 1
+    let space = ' '
+  else
+    let i = 0
+    let space = ''
+  endif
+  let path = ""
+  while i < a:0
+    if type(a:000[i]) == type([])
+      let list = a:000[i]
+      let j = 0
+      while j < len(list)
+        let escaped = substitute(list[j],'[,'.space.']\|\\[\,'.space.']\@=','\\&','g')
+        let path .= ',' . escaped
+        let j += 1
+      endwhile
+    else
+      let path .= "," . a:000[i]
+    endif
+    let i += 1
+  endwhile
+  return substitute(path,'^,','','')
+endfunction
+
+" Convert a list to a path with escaped spaces for 'path', 'tag', etc.
+function! pathogen#legacyjoin(...) abort
+  return call('pathogen#join',[1] + a:000)
+endfunction
+
+" Turn filetype detection off and back on again if it was already enabled.
+function! pathogen#cycle_filetype() abort
+  if exists('g:did_load_filetypes')
+    filetype off
+    filetype on
+  endif
+endfunction
+
+" Check if a bundle is disabled.  A bundle is considered disabled if its
+" basename or full name is included in the list g:pathogen_blacklist or the
+" comma delimited environment variable $VIMBLACKLIST.
+function! pathogen#is_disabled(path) abort
+  if a:path =~# '\~$'
+    return 1
+  endif
+  let sep = pathogen#slash()
+  let blacklist = get(g:, 'pathogen_blacklist', get(g:, 'pathogen_disabled', [])) + pathogen#split($VIMBLACKLIST)
+  if !empty(blacklist)
+    call map(blacklist, 'substitute(v:val, "[\\/]$", "", "")')
+  endif
+  return index(blacklist, fnamemodify(a:path, ':t')) != -1 || index(blacklist, a:path) != -1
+endfunction
+
+" Prepend the given directory to the runtime path and append its corresponding
+" after directory.  Curly braces are expanded with pathogen#expand().
+function! pathogen#surround(path) abort
+  let sep = pathogen#slash()
+  let rtp = pathogen#split(&rtp)
+  let path = fnamemodify(a:path, ':s?[\\/]\=$??')
+  let before = filter(pathogen#expand(path), '!pathogen#is_disabled(v:val)')
+  let after = filter(reverse(pathogen#expand(path, sep.'after')), '!pathogen#is_disabled(v:val[0 : -7])')
+  call filter(rtp, 'index(before + after, v:val) == -1')
+  let &rtp = pathogen#join(before, rtp, after)
+  return &rtp
+endfunction
+
+" For each directory in the runtime path, add a second entry with the given
+" argument appended.  Curly braces are expanded with pathogen#expand().
+function! pathogen#interpose(name) abort
+  let sep = pathogen#slash()
+  let name = a:name
+  if has_key(s:done_bundles, name)
+    return ""
+  endif
+  let s:done_bundles[name] = 1
+  let list = []
+  for dir in pathogen#split(&rtp)
+    if dir =~# '\<after$'
+      let list += reverse(filter(pathogen#expand(dir[0 : -6].name, sep.'after'), '!pathogen#is_disabled(v:val[0 : -7])')) + [dir]
+    else
+      let list += [dir] + filter(pathogen#expand(dir.sep.name), '!pathogen#is_disabled(v:val)')
+    endif
+  endfor
+  let &rtp = pathogen#join(pathogen#uniq(list))
+  return 1
+endfunction
+
+let s:done_bundles = {}
+
+" Invoke :helptags on all non-$VIM doc directories in runtimepath.
+function! pathogen#helptags() abort
+  let sep = pathogen#slash()
+  for glob in pathogen#split(&rtp)
+    for dir in map(split(glob(glob), "\n"), 'v:val.sep."/doc/".sep')
+      if (dir)[0 : strlen($VIMRUNTIME)] !=# $VIMRUNTIME.sep && filewritable(dir) == 2 && !empty(split(glob(dir.'*.txt'))) && (!filereadable(dir.'tags') || filewritable(dir.'tags'))
+        silent! execute 'helptags' pathogen#fnameescape(dir)
+      endif
+    endfor
+  endfor
+endfunction
+
+command! -bar Helptags :call pathogen#helptags()
+
+" Execute the given command.  This is basically a backdoor for --remote-expr.
+function! pathogen#execute(...) abort
+  for command in a:000
+    execute command
+  endfor
+  return ''
+endfunction
+
+" Section: Unofficial
+
+function! pathogen#is_absolute(path) abort
+  return a:path =~# (has('win32') ? '^\%([\\/]\|\w:\)[\\/]\|^[~$]' : '^[/~$]')
+endfunction
+
+" Given a string, returns all possible permutations of comma delimited braced
+" alternatives of that string.  pathogen#expand('/{a,b}/{c,d}') yields
+" ['/a/c', '/a/d', '/b/c', '/b/d'].  Empty braces are treated as a wildcard
+" and globbed.  Actual globs are preserved.
+function! pathogen#expand(pattern, ...) abort
+  let after = a:0 ? a:1 : ''
+  let pattern = substitute(a:pattern, '^[~$][^\/]*', '\=expand(submatch(0))', '')
+  if pattern =~# '{[^{}]\+}'
+    let [pre, pat, post] = split(substitute(pattern, '\(.\{-\}\){\([^{}]\+\)}\(.*\)', "\\1\001\\2\001\\3", ''), "\001", 1)
+    let found = map(split(pat, ',', 1), 'pre.v:val.post')
+    let results = []
+    for pattern in found
+      call extend(results, pathogen#expand(pattern))
+    endfor
+  elseif pattern =~# '{}'
+    let pat = matchstr(pattern, '^.*{}[^*]*\%($\|[\\/]\)')
+    let post = pattern[strlen(pat) : -1]
+    let results = map(split(glob(substitute(pat, '{}', '*', 'g')), "\n"), 'v:val.post')
+  else
+    let results = [pattern]
+  endif
+  let vf = pathogen#slash() . 'vimfiles'
+  call map(results, 'v:val =~# "\\*" ? v:val.after : isdirectory(v:val.vf.after) ? v:val.vf.after : isdirectory(v:val.after) ? v:val.after : ""')
+  return filter(results, '!empty(v:val)')
+endfunction
+
+" \ on Windows unless shellslash is set, / everywhere else.
+function! pathogen#slash() abort
+  return !exists("+shellslash") || &shellslash ? '/' : '\'
+endfunction
+
+function! pathogen#separator() abort
+  return pathogen#slash()
+endfunction
+
+" Convenience wrapper around glob() which returns a list.
+function! pathogen#glob(pattern) abort
+  let files = split(glob(a:pattern),"\n")
+  return map(files,'substitute(v:val,"[".pathogen#slash()."/]$","","")')
+endfunction
+
+" Like pathogen#glob(), only limit the results to directories.
+function! pathogen#glob_directories(pattern) abort
+  return filter(pathogen#glob(a:pattern),'isdirectory(v:val)')
+endfunction
+
+" Remove duplicates from a list.
+function! pathogen#uniq(list) abort
+  let i = 0
+  let seen = {}
+  while i < len(a:list)
+    if (a:list[i] ==# '' && exists('empty')) || has_key(seen,a:list[i])
+      call remove(a:list,i)
+    elseif a:list[i] ==# ''
+      let i += 1
+      let empty = 1
+    else
+      let seen[a:list[i]] = 1
+      let i += 1
+    endif
+  endwhile
+  return a:list
+endfunction
+
+" Backport of fnameescape().
+function! pathogen#fnameescape(string) abort
+  if exists('*fnameescape')
+    return fnameescape(a:string)
+  elseif a:string ==# '-'
+    return '\-'
+  else
+    return substitute(escape(a:string," \t\n*?[{`$\\%#'\"|!<"),'^[+>]','\\&','')
+  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:

+ 1240 - 0
vimfiles/bundle/calendar-vim/autoload/calendar.vim

@@ -0,0 +1,1240 @@
+if !exists("g:calendar_action")
+  let g:calendar_action = "calendar#diary"
+endif
+if !exists("g:calendar_sign")
+  let g:calendar_sign = "calendar#sign"
+endif
+if !exists("g:calendar_mark")
+ \|| (g:calendar_mark != 'left'
+ \&& g:calendar_mark != 'left-fit'
+ \&& g:calendar_mark != 'right')
+  let g:calendar_mark = 'left'
+endif
+if !exists("g:calendar_navi")
+ \|| (g:calendar_navi != 'top'
+ \&& g:calendar_navi != 'bottom'
+ \&& g:calendar_navi != 'both'
+ \&& g:calendar_navi != '')
+  let g:calendar_navi = 'top'
+endif
+if !exists("g:calendar_navi_label")
+  let g:calendar_navi_label = "Prev,Today,Next"
+endif
+if !exists("g:calendar_diary_list_curr_idx")
+  let g:calendar_diary_list_curr_idx = 0
+endif
+if !exists("g:calendar_diary")
+  if exists("g:calendar_diary_list") && len(g:calendar_diary_list) > 0 && g:calendar_diary_list_curr_idx >= 0 && g:calendar_diary_list_curr_idx < len(g:calendar_diary_list)
+    let g:calendar_diary = g:calendar_diary_list[g:calendar_diary_list_curr_idx].path
+    let g:calendar_diary_extension = g:calendar_diary_list[g:calendar_diary_list_curr_idx].ext
+  else
+    let g:calendar_diary = "~/diary"
+  endif
+endif
+if !exists("g:calendar_focus_today")
+  let g:calendar_focus_today = 0
+endif
+if !exists("g:calendar_datetime")
+ \|| (g:calendar_datetime != ''
+ \&& g:calendar_datetime != 'title'
+ \&& g:calendar_datetime != 'statusline')
+  let g:calendar_datetime = 'title'
+endif
+if !exists("g:calendar_options")
+  let g:calendar_options = "fdc=0 nonu"
+  if has("+relativenumber") || exists("+relativenumber")
+    let g:calendar_options .= " nornu"
+  endif
+endif
+if !exists("g:calendar_filetype")
+  let g:calendar_filetype = "markdown"
+endif
+if !exists("g:calendar_diary_extension")
+    let g:calendar_diary_extension = ".md"
+endif
+if !exists("g:calendar_search_grepprg")
+  let g:calendar_search_grepprg = "grep"
+endif
+
+"*****************************************************************
+"* Default Calendar key bindings
+"*****************************************************************
+let s:calendar_keys = {
+\ 'close'           : 'q',
+\ 'do_action'       : '<CR>',
+\ 'goto_today'      : 't',
+\ 'show_help'       : '?',
+\ 'redisplay'       : 'r',
+\ 'goto_next_month' : '<RIGHT>',
+\ 'goto_prev_month' : '<LEFT>',
+\ 'goto_next_year'  : '<UP>',
+\ 'goto_prev_year'  : '<DOWN>',
+\}
+
+if exists("g:calendar_keys") && type(g:calendar_keys) == 4
+  let s:calendar_keys = extend(s:calendar_keys, g:calendar_keys)
+end
+
+"*****************************************************************
+"* CalendarClose : close the calendar
+"*----------------------------------------------------------------
+"*****************************************************************
+function! calendar#close(...)
+  bw!
+endfunction
+
+"*****************************************************************
+"* CalendarDoAction : call the action handler function
+"*----------------------------------------------------------------
+"*****************************************************************
+function! calendar#action(...)
+  " for switch calendar list.
+  let text = getline(".")
+  if text =~ "^( )"
+    let list_idx = 0
+    let curl = line(".") - 1
+    while curl>1
+      if getline(curl) =~ "^([\* ])"
+        let list_idx += 1
+        let curl -= 1
+      else
+        let g:calendar_diary_list_curr_idx = list_idx
+        let g:calendar_diary = g:calendar_diary_list[list_idx].path
+        let g:calendar_diary_extension = g:calendar_diary_list[list_idx].ext
+        call calendar#show(b:CalendarDir, b:CalendarYear, b:CalendarMonth)
+        return
+      endif
+    endwhile
+  endif
+
+  " for navi
+  if exists('g:calendar_navi')
+    let navi = (a:0 > 0)? a:1 : expand("<cWORD>")
+    let curl = line(".")
+    let curp = getpos(".")
+    if navi == '<' . get(split(g:calendar_navi_label, ','), 0, '')
+      if b:CalendarMonth > 1
+        call calendar#show(b:CalendarDir, b:CalendarYear, b:CalendarMonth-1)
+      else
+        call calendar#show(b:CalendarDir, b:CalendarYear-1, 12)
+      endif
+    elseif navi == get(split(g:calendar_navi_label, ','), 2, '') . '>'
+      if b:CalendarMonth < 12
+        call calendar#show(b:CalendarDir, b:CalendarYear, b:CalendarMonth+1)
+      else
+        call calendar#show(b:CalendarDir, b:CalendarYear+1, 1)
+      endif
+    elseif navi == get(split(g:calendar_navi_label, ','), 1, '')
+      call calendar#show(b:CalendarDir)
+      if exists('g:calendar_today')
+        exe "call " . g:calendar_today . "()"
+      endif
+    elseif navi == 'NextYear'
+      call calendar#show(b:CalendarDir, b:CalendarYear + 1, b:CalendarMonth)
+      call setpos('.', curp)
+      return
+    elseif navi == 'PrevYear'
+      call calendar#show(b:CalendarDir, b:CalendarYear - 1, b:CalendarMonth)
+      call setpos('.', curp)
+      return
+    else
+      let navi = ''
+    endif
+    if navi != ''
+      if g:calendar_focus_today == 1 && search("\*","w") > 0
+        silent execute "normal! gg/\*\<cr>"
+        return
+      else
+        if curl < line('$')/2
+          silent execute "normal! gg0/".navi."\<cr>"
+        else
+          silent execute "normal! G$?".navi."\<cr>"
+        endif
+        return
+      endif
+    endif
+  endif
+
+  " if no action defined return
+  if !exists("g:calendar_action") || g:calendar_action == ""
+    return
+  endif
+
+  if b:CalendarDir == 0 || b:CalendarDir == 3
+    let dir = 'V'
+    let cnr = 1
+    let week = ((col(".")+1) / 3) - 1
+  elseif b:CalendarDir == 1
+    let dir = 'H'
+    if exists('g:calendar_weeknm')
+      let cnr = col('.') - (col('.')%(24+5)) + 1
+    else
+      let cnr = col('.') - (col('.')%(24)) + 1
+    endif
+    let week = ((col(".") - cnr - 1 + cnr/49) / 3)
+  elseif b:CalendarDir == 2
+    let dir = 'T'
+    let cnr = 1
+    let week = ((col(".")+1) / 3) - 1
+  endif
+  let lnr = 1
+  let hdr = 1
+  while 1
+    if lnr > line('.')
+      break
+    endif
+    let sline = getline(lnr)
+    if sline =~ '^\s*$'
+      let hdr = lnr + 1
+    endif
+    let lnr = lnr + 1
+  endwhile
+  let lnr = line('.')
+  if(exists('g:calendar_monday'))
+      let week = week + 1
+  elseif(week == 0)
+      let week = 7
+  endif
+  if lnr-hdr < 2
+    return
+  endif
+  let sline = substitute(strpart(getline(hdr),cnr,21),'\s*\(.*\)\s*','\1','')
+  if b:CalendarDir != 2
+    if (col(".")-cnr) > 21
+      return
+    endif
+
+    " extract day
+    if g:calendar_mark == 'right' && col('.') > 1
+      normal! h
+      let day = matchstr(expand("<cword>"), '[^0].*')
+      normal! l
+    else
+      let day = matchstr(expand("<cword>"), '[^0].*')
+    endif
+  else
+    let c = col('.')
+    let day = ''
+    let lnum = line('.')
+    let cursorchar = getline(lnum)[col('.') - 1]
+    while day == '' && lnum > 2 && cursorchar != '-' && cursorchar != '+'
+      let day = matchstr(getline(lnum), '^.*|\zs[^|]\{-}\%'.c.'c[^|]\{-}\ze|.*$')
+      let day = matchstr(day, '\d\+')
+      let lnum = lnum - 1
+      let cursorchar = getline(lnum)[col('.') - 1]
+    endwhile
+  endif
+  if day == 0
+    return
+  endif
+  " extract year and month
+  if exists('g:calendar_erafmt') && g:calendar_erafmt !~ "^\s*$"
+    let year = matchstr(substitute(sline, '/.*', '', ''), '\d\+')
+    let month = matchstr(substitute(sline, '.*/\(\d\d\=\).*', '\1', ""), '[^0].*')
+    if g:calendar_erafmt =~ '.*,[+-]*\d\+'
+      let veranum = substitute(g:calendar_erafmt,'.*,\([+-]*\d\+\)','\1','')
+      if year-veranum > 0
+        let year = year-veranum
+      endif
+    endif
+  else
+    let year  = matchstr(substitute(sline, '/.*', '', ''), '[^0].*')
+    let month = matchstr(substitute(sline, '\d*/\(\d\d\=\).*', '\1', ""), '[^0].*')
+  endif
+  " call the action function
+  exe "call " . g:calendar_action . "(day, month, year, week, dir)"
+endfunc
+
+"*****************************************************************
+"* Calendar : build calendar
+"*----------------------------------------------------------------
+"*   a1 : direction
+"*   a2 : month(if given a3, it's year)
+"*   a3 : if given, it's month
+"*****************************************************************
+function! calendar#show(...)
+
+  "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  "+++ ready for build
+  "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  " remember today
+  " divide strftime('%d') by 1 so as to get "1,2,3 .. 9" instead of "01, 02, 03 .. 09"
+  let vtoday = strftime('%Y').strftime('%m').strftime('%d')
+
+  " get arguments
+  if a:0 == 0
+    let dir = 0
+    let vyear = strftime('%Y')
+    let vmnth = matchstr(strftime('%m'), '[^0].*')
+  elseif a:0 == 1
+    let dir = a:1
+    let vyear = strftime('%Y')
+    let vmnth = matchstr(strftime('%m'), '[^0].*')
+  elseif a:0 == 2
+    let dir = a:1
+    let vyear = strftime('%Y')
+    let vmnth = matchstr(a:2, '^[^0].*')
+  else
+    let dir = a:1
+    let vyear = a:2
+    let vmnth = matchstr(a:3, '^[^0].*')
+  endif
+
+  " remember constant
+  let vmnth_org = vmnth
+  let vyear_org = vyear
+
+  if dir != 2
+    " start with last month
+    let vmnth = vmnth - 1
+    if vmnth < 1
+      let vmnth = 12
+      let vyear = vyear - 1
+    endif
+  endif
+
+  " reset display variables
+  let vdisplay1 = ''
+  let vheight = 1
+  let vmcnt = 0
+
+  "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  "+++ build display
+  "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  if exists("g:calendar_begin")
+    exe "call " . g:calendar_begin . "()"
+  endif
+  if dir == 2
+    let vmcntmax = 1
+    let whitehrz = ''
+    if !exists('b:CalendarDir') && !(bufname('%') == '' && &l:modified == 0)
+      let width = &columns
+      let height = &lines - 2
+    else
+      let width = winwidth(0)
+      let height = winheight(0)
+    endif
+    let hrz = width / 8 - 5
+    if hrz < 0
+      let hrz = 0
+    endif
+    let h = 0
+    while h < hrz
+      let whitehrz = whitehrz.' '
+      let h = h + 1
+    endwhile
+    let whitehrz = whitehrz.'|'
+    let navifix = (exists('g:calendar_navi') && g:calendar_navi == 'both') * 2
+    let vrt = (height - &cmdheight - 3 - navifix) / 6 - 2
+    if vrt < 0
+      let vrt = 0
+    endif
+    if whitehrz == '|'
+      let whitevrta = whitehrz
+    else
+      let whitevrta = whitehrz[1:]
+    endif
+    let h = 0
+    let leftmargin = (width - (strlen(whitehrz) + 3) * 7 - 1) / 2
+    let whiteleft = ''
+    while h < leftmargin
+      let whiteleft = whiteleft.' '
+      let h = h + 1
+    endwhile
+    let h = 0
+    let whitevrt = ''
+    while h < vrt
+      let whitevrt = whitevrt."\n".whiteleft.'|'
+      let i = 0
+      while i < 7
+        let whitevrt = whitevrt.'   '.whitehrz
+        let i = i + 1
+      endwhile
+      let h = h + 1
+    endwhile
+    let whitevrt = whitevrt."\n"
+    let whitevrt2 = whiteleft.'+'
+    let h = 0
+    let borderhrz = '---'.substitute(substitute(whitehrz, ' ', '-', 'g'), '|', '+', '')
+    while h < 7
+      let whitevrt2 = whitevrt2.borderhrz
+      let h = h + 1
+    endwhile
+    let whitevrtweeknm = whitevrt.whitevrt2."\n"
+    let whitevrt = whitevrta.whitevrt.whitevrt2."\n"
+    let fridaycol = (strlen(whitehrz) + 3) * 5 + strlen(whiteleft) + 1
+    let saturdaycol = (strlen(whitehrz) + 3) * 6 + strlen(whiteleft) + 1
+  else
+    let vmcntmax = get(g:, 'calendar_number_of_months', 3)
+  endif
+  while vmcnt < vmcntmax
+    let vcolumn = 22
+    let vnweek = -1
+    "--------------------------------------------------------------
+    "--- calculating
+    "--------------------------------------------------------------
+    " set boundary of the month
+    if vmnth == 1
+      let vmdays = 31
+      let vparam = 1
+      let vsmnth = 'Jan'
+    elseif vmnth == 2
+      let vmdays = 28
+      let vparam = 32
+      let vsmnth = 'Feb'
+    elseif vmnth == 3
+      let vmdays = 31
+      let vparam = 60
+      let vsmnth = 'Mar'
+    elseif vmnth == 4
+      let vmdays = 30
+      let vparam = 91
+      let vsmnth = 'Apr'
+    elseif vmnth == 5
+      let vmdays = 31
+      let vparam = 121
+      let vsmnth = 'May'
+    elseif vmnth == 6
+      let vmdays = 30
+      let vparam = 152
+      let vsmnth = 'Jun'
+    elseif vmnth == 7
+      let vmdays = 31
+      let vparam = 182
+      let vsmnth = 'Jul'
+    elseif vmnth == 8
+      let vmdays = 31
+      let vparam = 213
+      let vsmnth = 'Aug'
+    elseif vmnth == 9
+      let vmdays = 30
+      let vparam = 244
+      let vsmnth = 'Sep'
+    elseif vmnth == 10
+      let vmdays = 31
+      let vparam = 274
+      let vsmnth = 'Oct'
+    elseif vmnth == 11
+      let vmdays = 30
+      let vparam = 305
+      let vsmnth = 'Nov'
+    elseif vmnth == 12
+      let vmdays = 31
+      let vparam = 335
+      let vsmnth = 'Dec'
+    else
+      echo 'Invalid Year or Month'
+      return
+    endif
+    let vleap = 0
+    if vyear % 400 == 0
+      let vleap = 1
+      if vmnth == 2
+        let vmdays = 29
+      elseif vmnth >= 3
+        let vparam = vparam + 1
+      endif
+    elseif vyear % 100 == 0
+      if vmnth == 2
+        let vmdays = 28
+      endif
+    elseif vyear % 4 == 0
+      let vleap = 1
+      if vmnth == 2
+        let vmdays = 29
+      elseif vmnth >= 3
+        let vparam = vparam + 1
+      endif
+    endif
+
+    " calc vnweek of the day
+    if vnweek == -1
+      let vnweek = ( vyear * 365 ) + vparam
+      let vnweek = vnweek + ( vyear/4 ) - ( vyear/100 ) + ( vyear/400 )
+      if vleap
+        let vnweek = vnweek - 1
+      endif
+      let vnweek = vnweek - 1
+    endif
+
+    " fix Gregorian
+    if vyear <= 1752
+      let vnweek = vnweek - 3
+    endif
+
+    let vnweek = vnweek % 7
+
+    if exists('g:calendar_monday')
+      " if given g:calendar_monday, the week start with monday
+      if vnweek == 0
+        let vnweek = 7
+      endif
+      let vnweek = vnweek - 1
+    endif
+
+    if exists('g:calendar_weeknm')
+      " if given g:calendar_weeknm, show week number(ref:ISO8601)
+
+      "vparam <= 1. day of month
+      "vnweek <= 1. weekday of month (0-6)
+      "viweek <= number of week
+      "vfweek <= 1. day of year
+
+      " Mon Tue Wed Thu Fri Sat Sun
+      " 6   5   4   3   2   1   0  vfweek
+      " 0   1   2   3   4   5   6  vnweek
+
+      let vfweek =((vparam % 7)  -vnweek+ 14-2) % 7
+      let viweek = (vparam - vfweek-2+7 ) / 7 +1
+
+      if vfweek < 3
+         let viweek = viweek - 1
+      endif
+
+      "vfweekl  <=year length
+      let vfweekl = 52
+      if vfweek == 3 || (vfweek == 4 && vleap)
+        let vfweekl = 53
+      endif
+
+      if viweek == 0
+        "belongs to last week number of previous year
+        let viweek = 52
+        let vleap = ((vyear-1) % 4 == 0 &&
+              \ ((vyear-1) % 100 != 0 || (vyear-1) % 400 == 0))
+        if vfweek == 2 || (vfweek == 1 && vleap)
+          let viweek = 53
+        endif
+      endif
+
+      let vcolumn = vcolumn + 5
+      if g:calendar_weeknm == 5
+        let vcolumn = vcolumn - 2
+      endif
+    endif
+
+    "--------------------------------------------------------------
+    "--- displaying
+    "--------------------------------------------------------------
+    " build header
+    if exists('g:calendar_erafmt') && g:calendar_erafmt !~ "^\s*$"
+      if g:calendar_erafmt =~ '.*,[+-]*\d\+'
+        let veranum = substitute(g:calendar_erafmt,'.*,\([+-]*\d\+\)','\1','')
+        if vyear+veranum > 0
+          let vdisplay2 = substitute(g:calendar_erafmt,'\(.*\),.*','\1','')
+          let vdisplay2 = vdisplay2.(vyear+veranum).'/'.vmnth.'('
+        else
+          let vdisplay2 = vyear.'/'.vmnth.'('
+        endif
+      else
+        let vdisplay2 = vyear.'/'.vmnth.'('
+      endif
+      let vdisplay2 = strpart("                           ",
+        \ 1,(vcolumn-strlen(vdisplay2))/2-2).vdisplay2
+    else
+      let vdisplay2 = vyear.'/'.vmnth.'('
+      let vdisplay2 = strpart("                           ",
+        \ 1,(vcolumn-strlen(vdisplay2))/2-2).vdisplay2
+    endif
+    if exists('g:calendar_mruler') && g:calendar_mruler !~ "^\s*$"
+      let vdisplay2 = vdisplay2 . get(split(g:calendar_mruler, ','), vmnth-1, '').')'."\n"
+    else
+      let vdisplay2 = vdisplay2 . vsmnth.')'."\n"
+    endif
+    let vwruler = "Su Mo Tu We Th Fr Sa"
+    if exists('g:calendar_wruler') && g:calendar_wruler !~ "^\s*$"
+      let vwruler = g:calendar_wruler
+    endif
+    if exists('g:calendar_monday')
+      let vwruler = strpart(vwruler,stridx(vwruler, ' ') + 1).' '.strpart(vwruler,0,stridx(vwruler, ' '))
+    endif
+    if dir == 2
+      let whiteruler = substitute(substitute(whitehrz, ' ', '_', 'g'), '__', '  ', '')
+      let vwruler = '| '.substitute(vwruler, ' ', whiteruler.' ', 'g').whiteruler
+      let vdisplay2 = vdisplay2.whiteleft.vwruler."\n"
+    else
+      let vdisplay2 = vdisplay2.' '.vwruler."\n"
+    endif
+    if g:calendar_mark == 'right' && dir != 2
+      let vdisplay2 = vdisplay2.' '
+    endif
+
+    " build calendar
+    let vinpcur = 0
+    while (vinpcur < vnweek)
+      if dir == 2
+        if vinpcur % 7
+          let vdisplay2 = vdisplay2.whitehrz
+        else
+          let vdisplay2 = vdisplay2.whiteleft.'|'
+        endif
+      endif
+      let vdisplay2 = vdisplay2.'   '
+      let vinpcur = vinpcur + 1
+    endwhile
+    let vdaycur = 1
+    while (vdaycur <= vmdays)
+      if dir == 2
+        if vinpcur % 7
+          let vdisplay2 = vdisplay2.whitehrz
+        else
+          let vdisplay2 = vdisplay2.whiteleft.'|'
+        endif
+      endif
+      if vmnth < 10
+         let vtarget = vyear."0".vmnth
+      else
+         let vtarget = vyear.vmnth
+      endif
+      if vdaycur < 10
+         let vtarget = vtarget."0".vdaycur
+      else
+         let vtarget = vtarget.vdaycur
+      endif
+      if exists("g:calendar_sign") && g:calendar_sign != ""
+        exe "let vsign = " . g:calendar_sign . "(vdaycur, vmnth, vyear)"
+        if vsign != ""
+          let vsign = vsign[0]
+          if vsign !~ "[+!#$%&@?]"
+            let vsign = "+"
+          endif
+        endif
+      else
+        let vsign = ''
+      endif
+
+      " show mark
+      if g:calendar_mark == 'right'
+        if vdaycur < 10
+          let vdisplay2 = vdisplay2.' '
+        endif
+        let vdisplay2 = vdisplay2.vdaycur
+      elseif g:calendar_mark == 'left-fit'
+        if vdaycur < 10
+          let vdisplay2 = vdisplay2.' '
+        endif
+      endif
+      if vtarget == vtoday
+        let vdisplay2 = vdisplay2.'*'
+      elseif vsign != ''
+        let vdisplay2 = vdisplay2.vsign
+      else
+        let vdisplay2 = vdisplay2.' '
+      endif
+      if g:calendar_mark == 'left'
+        if vdaycur < 10
+          let vdisplay2 = vdisplay2.' '
+        endif
+        let vdisplay2 = vdisplay2.vdaycur
+      endif
+      if g:calendar_mark == 'left-fit'
+        let vdisplay2 = vdisplay2.vdaycur
+      endif
+      let vdaycur = vdaycur + 1
+
+      " fix Gregorian
+      if vyear == 1752 && vmnth == 9 && vdaycur == 3
+        let vdaycur = 14
+      endif
+
+      let vinpcur = vinpcur + 1
+      if vinpcur % 7 == 0
+        if exists('g:calendar_weeknm')
+          if dir == 2
+            let vdisplay2 = vdisplay2.whitehrz
+          endif
+          if g:calendar_mark != 'right'
+            let vdisplay2 = vdisplay2.' '
+          endif
+          " if given g:calendar_weeknm, show week number
+          if viweek < 10
+            if g:calendar_weeknm == 1
+              let vdisplay2 = vdisplay2.'WK0'.viweek
+            elseif g:calendar_weeknm == 2
+              let vdisplay2 = vdisplay2.'WK '.viweek
+            elseif g:calendar_weeknm == 3
+              let vdisplay2 = vdisplay2.'KW0'.viweek
+            elseif g:calendar_weeknm == 4
+              let vdisplay2 = vdisplay2.'KW '.viweek
+            elseif g:calendar_weeknm == 5
+              let vdisplay2 = vdisplay2.' '.viweek
+            endif
+          else
+            if g:calendar_weeknm <= 2
+              let vdisplay2 = vdisplay2.'WK'.viweek
+            elseif g:calendar_weeknm == 3 || g:calendar_weeknm == 4
+              let vdisplay2 = vdisplay2.'KW'.viweek
+            elseif g:calendar_weeknm == 5
+              let vdisplay2 = vdisplay2.viweek
+            endif
+          endif
+          let viweek = viweek + 1
+
+          if viweek > vfweekl
+            let viweek = 1
+          endif
+
+        endif
+        let vdisplay2 = vdisplay2."\n"
+        if g:calendar_mark == 'right' && dir != 2
+          let vdisplay2 = vdisplay2.' '
+        endif
+      endif
+    endwhile
+
+    " if it is needed, fill with space
+    if vinpcur % 7
+      while (vinpcur % 7 != 0)
+        if dir == 2
+          let vdisplay2 = vdisplay2.whitehrz
+        endif
+        let vdisplay2 = vdisplay2.'   '
+        let vinpcur = vinpcur + 1
+      endwhile
+      if exists('g:calendar_weeknm')
+        if dir == 2
+          let vdisplay2 = vdisplay2.whitehrz
+        endif
+        if g:calendar_mark != 'right'
+          let vdisplay2 = vdisplay2.' '
+        endif
+        if viweek < 10
+          if g:calendar_weeknm == 1
+            let vdisplay2 = vdisplay2.'WK0'.viweek
+          elseif g:calendar_weeknm == 2
+            let vdisplay2 = vdisplay2.'WK '.viweek
+          elseif g:calendar_weeknm == 3
+            let vdisplay2 = vdisplay2.'KW0'.viweek
+          elseif g:calendar_weeknm == 4
+            let vdisplay2 = vdisplay2.'KW '.viweek
+          elseif g:calendar_weeknm == 5
+            let vdisplay2 = vdisplay2.' '.viweek
+          endif
+        else
+          if g:calendar_weeknm <= 2
+            let vdisplay2 = vdisplay2.'WK'.viweek
+          elseif g:calendar_weeknm == 3 || g:calendar_weeknm == 4
+            let vdisplay2 = vdisplay2.'KW'.viweek
+          elseif g:calendar_weeknm == 5
+            let vdisplay2 = vdisplay2.viweek
+          endif
+        endif
+      endif
+    endif
+
+    " build display
+    let vstrline = ''
+    if dir == 1
+      " for horizontal
+      "--------------------------------------------------------------
+      " +---+   +---+   +------+
+      " |   |   |   |   |      |
+      " | 1 | + | 2 | = |  1'  |
+      " |   |   |   |   |      |
+      " +---+   +---+   +------+
+      "--------------------------------------------------------------
+      let vtokline = 1
+      while 1
+        let vtoken1 = get(split(vdisplay1, "\n"), vtokline-1, '')
+        let vtoken2 = get(split(vdisplay2, "\n"), vtokline-1, '')
+        if vtoken1 == '' && vtoken2 == ''
+          break
+        endif
+        while strlen(vtoken1) < (vcolumn+1)*vmcnt
+          if strlen(vtoken1) % (vcolumn+1) == 0
+            let vtoken1 = vtoken1.'|'
+          else
+            let vtoken1 = vtoken1.' '
+          endif
+        endwhile
+        let vstrline = vstrline.vtoken1.'|'.vtoken2.' '."\n"
+        let vtokline = vtokline + 1
+      endwhile
+      let vdisplay1 = vstrline
+      let vheight = vtokline-1
+    elseif (dir == 0 || dir == 3)
+      " for vertical
+      "--------------------------------------------------------------
+      " +---+   +---+   +---+
+      " | 1 | + | 2 | = |   |
+      " +---+   +---+   | 1'|
+      "                 |   |
+      "                 +---+
+      "--------------------------------------------------------------
+      let vtokline = 1
+      while 1
+        let vtoken1 = get(split(vdisplay1, "\n"), vtokline-1, '')
+        if vtoken1 == ''
+          break
+        endif
+        let vstrline = vstrline.vtoken1."\n"
+        let vtokline = vtokline + 1
+        let vheight = vheight + 1
+      endwhile
+      if vstrline != ''
+        let vstrline = vstrline.' '."\n"
+        let vheight = vheight + 1
+      endif
+      let vtokline = 1
+      while 1
+        let vtoken2 = get(split(vdisplay2, "\n"), vtokline-1, '')
+        if vtoken2 == ''
+          break
+        endif
+        while strlen(vtoken2) < vcolumn
+          let vtoken2 = vtoken2.' '
+        endwhile
+        let vstrline = vstrline.vtoken2."\n"
+        let vtokline = vtokline + 1
+        let vheight = vtokline + 1
+      endwhile
+      let vdisplay1 = vstrline
+    else
+      let vtokline = 1
+      while 1
+        let vtoken1 = get(split(vdisplay1, "\n"), vtokline-1, '')
+        let vtoken2 = get(split(vdisplay2, "\n"), vtokline-1, '')
+        if vtoken1 == '' && vtoken2 == ''
+          break
+        endif
+        while strlen(vtoken1) < (vcolumn+1)*vmcnt
+          if strlen(vtoken1) % (vcolumn+1) == 0
+            let vtoken1 = vtoken1.'|'
+          else
+            let vtoken1 = vtoken1.' '
+          endif
+        endwhile
+        if vtokline > 2
+          if exists('g:calendar_weeknm')
+            let vright = whitevrtweeknm
+          elseif whitehrz == '|'
+            let vright = whitevrt
+          else
+            let vright = ' '.whitevrt
+          endif
+        else
+          let vright = "\n"
+        endif
+        let vstrline = vstrline.vtoken1.vtoken2.vright
+        let vtokline = vtokline + 1
+      endwhile
+      let vdisplay1 = vstrline
+      let vheight = vtokline-1
+    endif
+    let vmnth = vmnth + 1
+    let vmcnt = vmcnt + 1
+    if vmnth > 12
+      let vmnth = 1
+      let vyear = vyear + 1
+    endif
+  endwhile
+  if exists("g:calendar_end")
+    exe "call " . g:calendar_end . "()"
+  endif
+  if a:0 == 0
+    return vdisplay1
+  endif
+
+  if exists("g:calendar_diary_list") && len(g:calendar_diary_list) > 0
+    let vdisplay1 = vdisplay1 . "\nCalendars:\n" . repeat("-", vcolumn)
+    let diary_index = 0
+    for diary in g:calendar_diary_list
+      if diary_index == g:calendar_diary_list_curr_idx
+        let diary_list = "(*) " . diary["name"]
+        let diary_list = "\n" . diary_list . repeat(" ", vcolumn-len(diary_list))
+      else
+        let diary_list = "( ) " . diary["name"]
+        let diary_list = "\n" . diary_list . repeat(" ", vcolumn-len(diary_list))
+      endif
+      let vdisplay1 = vdisplay1 . diary_list
+      let diary_index = diary_index + 1
+    endfor
+  endif
+
+  "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  "+++ build window
+  "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  " make window
+  let vwinnum = bufnr('__Calendar')
+  if getbufvar(vwinnum, 'Calendar') == 'Calendar'
+    let vwinnum = bufwinnr(vwinnum)
+  else
+    let vwinnum = -1
+  endif
+
+  if vwinnum >= 0
+    " if already exist
+    if vwinnum != bufwinnr('%')
+      exe vwinnum . 'wincmd w'
+    endif
+    setlocal modifiable
+    silent %d _
+  else
+    " make title
+    if g:calendar_datetime == "title" && (!exists('s:bufautocommandsset'))
+      auto BufEnter *Calendar let b:sav_titlestring = &titlestring | let &titlestring = '%{strftime("%c")}'
+      auto BufLeave *Calendar if exists('b:sav_titlestring') | let &titlestring = b:sav_titlestring | endif
+      let s:bufautocommandsset = 1
+    endif
+
+    if exists('g:calendar_navi') && dir
+      if g:calendar_navi == 'both'
+        let vheight = vheight + 4
+      else
+        let vheight = vheight + 2
+      endif
+    endif
+
+    " or not
+    if dir == 1
+      silent execute 'bo '.vheight.'split __Calendar'
+      setlocal winfixheight
+    elseif dir == 0
+      silent execute 'to '.vcolumn.'vsplit __Calendar'
+      setlocal winfixwidth
+    elseif dir == 3
+      silent execute 'bo '.vcolumn.'vsplit __Calendar'
+      setlocal winfixwidth
+    elseif bufname('%') == '' && &l:modified == 0
+      silent execute 'edit __Calendar'
+    else
+      silent execute 'tabnew __Calendar'
+    endif
+    call s:CalendarBuildKeymap(dir, vyear, vmnth)
+    setlocal noswapfile
+    setlocal buftype=nofile
+    setlocal bufhidden=delete
+    silent! exe "setlocal " . g:calendar_options
+    let nontext_columns = &foldcolumn + &nu * &numberwidth
+    if has("+relativenumber") || exists("+relativenumber")
+      let nontext_columns += &rnu * &numberwidth
+    endif
+    " Without this, the 'sidescrolloff' setting may cause the left side of the
+    " calendar to disappear if the last inserted element is near the right
+    " window border.
+    setlocal nowrap
+    setlocal norightleft
+    setlocal modifiable
+    setlocal nolist
+    let b:Calendar = 'Calendar'
+    setlocal filetype=calendar
+    " is this a vertical (0) or a horizontal (1) split?
+    if dir != 2
+      exe vcolumn + nontext_columns . "wincmd |"
+    endif
+  endif
+  if g:calendar_datetime == "statusline"
+    setlocal statusline=%{strftime('%c')}
+  endif
+  let b:CalendarDir = dir
+  let b:CalendarYear = vyear_org
+  let b:CalendarMonth = vmnth_org
+
+  " navi
+  if exists('g:calendar_navi')
+    let navi_label = '<'
+        \.get(split(g:calendar_navi_label, ','), 0, '').' '
+        \.get(split(g:calendar_navi_label, ','), 1, '').' '
+        \.get(split(g:calendar_navi_label, ','), 2, '').'>'
+    if dir == 1
+      let navcol = vcolumn + (vcolumn-strlen(navi_label)+2)/2
+    elseif (dir == 0 ||dir == 3)
+      let navcol = (vcolumn-strlen(navi_label)+2)/2
+    else
+      let navcol = (width - strlen(navi_label)) / 2
+    endif
+    if navcol < 3
+      let navcol = 3
+    endif
+
+    if g:calendar_navi == 'top'
+      execute "normal gg".navcol."i "
+      silent exec "normal! a".navi_label."\<cr>\<cr>"
+      silent put! =vdisplay1
+    endif
+    if g:calendar_navi == 'bottom'
+      silent put! =vdisplay1
+      silent exec "normal! Gi\<cr>"
+      execute "normal ".navcol."i "
+      silent exec "normal! a".navi_label
+    endif
+    if g:calendar_navi == 'both'
+      execute "normal gg".navcol."i "
+      silent exec "normal! a".navi_label."\<cr>\<cr>"
+      silent put! =vdisplay1
+      silent exec "normal! Gi\<cr>"
+      execute "normal ".navcol."i "
+      silent exec "normal! a".navi_label
+    endif
+  else
+    silent put! =vdisplay1
+  endif
+
+  setlocal nomodifiable
+  " In case we've gotten here from insert mode (via <C-O>:Calendar<CR>)...
+  stopinsert
+
+  let vyear = vyear_org
+  let vmnth = vmnth_org
+
+  "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  "+++ build highlight
+  "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  " today
+  syn clear
+  if g:calendar_mark =~ 'left-fit'
+    syn match CalToday display "\s*\*\d*"
+    syn match CalMemo display "\s*[+!#$%&@?]\d*"
+  elseif g:calendar_mark =~ 'right'
+    syn match CalToday display "\d*\*\s*"
+    syn match CalMemo display "\d*[+!#$%&@?]\s*"
+  else
+    syn match CalToday display "\*\s*\d*"
+    syn match CalMemo display "[+!#$%&@?]\s*\d*"
+  endif
+  " header
+  syn match CalHeader display "[^ ]*\d\+\/\d\+([^)]*)"
+
+  " navi
+  if exists('g:calendar_navi')
+    exec "silent! syn match CalNavi display \"\\(<"
+        \.get(split(g:calendar_navi_label, ','), 0, '')."\\|"
+        \.get(split(g:calendar_navi_label, ','), 2, '').">\\)\""
+    exec "silent! syn match CalNavi display \"\\s"
+        \.get(split(g:calendar_navi_label, ','), 1, '')."\\s\"hs=s+1,he=e-1"
+  endif
+
+  " saturday, sunday
+
+  if exists('g:calendar_monday')
+    if dir == 1
+      syn match CalSaturday display /|.\{15}\s\([0-9\ ]\d\)/hs=e-1 contains=ALL
+      syn match CalSunday display /|.\{18}\s\([0-9\ ]\d\)/hs=e-1 contains=ALL
+    elseif (dir == 0|| dir == 3)
+      syn match CalSaturday display /^.\{15}\s\([0-9\ ]\d\)/hs=e-1 contains=ALL
+      syn match CalSunday display /^.\{18}\s\([0-9\ ]\d\)/hs=e-1 contains=ALL
+    else
+      exec printf('syn match CalSaturday display /^.\{%d}\s\?\([0-9\ ]\d\)/hs=e-1 contains=ALL', fridaycol)
+      exec printf('syn match CalSunday display /^.\{%d}\s\?\([0-9\ ]\d\)/hs=e-1 contains=ALL', saturdaycol)
+    endif
+  else
+    if dir == 1
+      syn match CalSaturday display /|.\{18}\s\([0-9\ ]\d\)/hs=e-1 contains=ALL
+      syn match CalSunday display /|\s\([0-9\ ]\d\)/hs=e-1 contains=ALL
+    elseif (dir == 0 || dir == 3)
+      syn match CalSaturday display /^.\{18}\s\([0-9\ ]\d\)/hs=e-1 contains=ALL
+      syn match CalSunday display /^\s\([0-9\ ]\d\)/hs=e-1 contains=ALL
+    else
+      exec printf('syn match CalSaturday display /^.\{%d}\s\?\([0-9\ ]\d\)/hs=e-1 contains=ALL', saturdaycol)
+      syn match CalSunday display /^\s*|\s*\([0-9\ ]\d\)/hs=e-1 contains=ALL
+    endif
+  endif
+
+  syn match CalCurrList display "^(\*).*$"
+
+  " week number
+  if !exists('g:calendar_weeknm') || g:calendar_weeknm <= 2
+    syn match CalWeeknm display "WK[0-9\ ]\d"
+  else
+    syn match CalWeeknm display "KW[0-9\ ]\d"
+  endif
+
+  " ruler
+  execute 'syn match CalRuler "'.vwruler.'"'
+
+  if search("\*","w") > 0
+    silent execute "normal! gg/\*\<cr>"
+  endif
+
+  " --+--
+  if dir == 2
+    exec "syn match CalNormal display " string(borderhrz)
+    exec "syn match CalNormal display " string('^'.whiteleft.'+')
+  endif
+
+  return ''
+endfunction
+
+"*****************************************************************
+"* make_dir : make directory
+"*----------------------------------------------------------------
+"*   dir : directory
+"*****************************************************************
+function! s:make_dir(dir)
+  if(has("unix"))
+    call system("mkdir " . a:dir)
+    let rc = v:shell_error
+  elseif(has("win16") || has("win32") || has("win95") ||
+              \has("dos16") || has("dos32") || has("os2"))
+    call system("mkdir \"" . a:dir . "\"")
+    let rc = v:shell_error
+  else
+    let rc = 1
+  endif
+  if rc != 0
+    call confirm("can't create directory : " . a:dir, "&OK")
+  endif
+  return rc
+endfunc
+
+"*****************************************************************
+"* diary : calendar hook function
+"*----------------------------------------------------------------
+"*   day   : day you actioned
+"*   month : month you actioned
+"*   year  : year you actioned
+"*****************************************************************
+function! calendar#diary(day, month, year, week, dir)
+  " build the file name and create directories as needed
+  if !isdirectory(expand(g:calendar_diary))
+    call confirm("please create diary directory : ".g:calendar_diary, 'OK')
+    return
+  endif
+  let sfile = expand(g:calendar_diary) . "/" . printf("%04d", a:year)
+  if isdirectory(sfile) == 0
+    if s:make_dir(sfile) != 0
+      return
+    endif
+  endif
+  let sfile = sfile . "/" . printf("%02d", a:month)
+  if isdirectory(sfile) == 0
+    if s:make_dir(sfile) != 0
+      return
+    endif
+  endif
+  let sfile = expand(sfile) . "/" . printf("%02d", a:day) . g:calendar_diary_extension
+  let sfile = substitute(sfile, ' ', '\\ ', 'g')
+  let vbufnr = bufnr('__Calendar')
+
+  " load the file
+  exe "wincmd w"
+  exe "edit  " . sfile
+  exe "setfiletype " . g:calendar_filetype
+  let dir = getbufvar(vbufnr, "CalendarDir")
+  let vyear = getbufvar(vbufnr, "CalendarYear")
+  let vmnth = getbufvar(vbufnr, "CalendarMonth")
+  exe "auto BufDelete ".escape(sfile, ' \\')." call calendar#show(" . dir . "," . vyear . "," . vmnth . ")"
+endfunc
+
+"*****************************************************************
+"* sign : calendar sign function
+"*----------------------------------------------------------------
+"*   day   : day of sign
+"*   month : month of sign
+"*   year  : year of sign
+"*****************************************************************
+function! calendar#sign(day, month, year)
+  let sfile = g:calendar_diary."/".printf("%04d", a:year)."/".printf("%02d", a:month)."/".printf("%02d", a:day).g:calendar_diary_extension
+  return filereadable(expand(sfile))
+endfunction
+
+"*****************************************************************
+"* CalendarVar : get variable
+"*----------------------------------------------------------------
+"*****************************************************************
+function! s:CalendarVar(var)
+  if !exists(a:var)
+    return ''
+  endif
+  exec 'return ' . a:var
+endfunction
+
+"*****************************************************************
+"* CalendarBuildKeymap : build keymap
+"*----------------------------------------------------------------
+"*****************************************************************
+function! s:CalendarBuildKeymap(dir, vyear, vmnth)
+  " make keymap
+  nnoremap <silent> <buffer> <Plug>CalendarClose  :call calendar#close()<cr>
+  nnoremap <silent> <buffer> <Plug>CalendarDoAction  :call calendar#action()<cr>
+  nnoremap <silent> <buffer> <Plug>CalendarDoAction  :call calendar#action()<cr>
+  nnoremap <silent> <buffer> <Plug>CalendarGotoToday :call calendar#show(b:CalendarDir)<cr>
+  nnoremap <silent> <buffer> <Plug>CalendarShowHelp  :call <SID>CalendarHelp()<cr>
+  execute 'nnoremap <silent> <buffer> <Plug>CalendarReDisplay :call calendar#show(' . a:dir . ',' . a:vyear . ',' . a:vmnth . ')<cr>'
+  let pnav = get(split(g:calendar_navi_label, ','), 0, '')
+  let nnav = get(split(g:calendar_navi_label, ','), 2, '')
+  execute 'nnoremap <silent> <buffer> <Plug>CalendarGotoPrevMonth :call calendar#action("<' . pnav . '")<cr>'
+  execute 'nnoremap <silent> <buffer> <Plug>CalendarGotoNextMonth :call calendar#action("' . nnav . '>")<cr>'
+  execute 'nnoremap <silent> <buffer> <Plug>CalendarGotoPrevYear  :call calendar#action("PrevYear")<cr>'
+  execute 'nnoremap <silent> <buffer> <Plug>CalendarGotoNextYear  :call calendar#action("NextYear")<cr>'
+
+  nmap <buffer> <2-LeftMouse> <Plug>CalendarDoAction
+
+  execute 'nmap <buffer> ' . s:calendar_keys['close'] . ' <Plug>CalendarClose'
+  execute 'nmap <buffer> ' . s:calendar_keys['do_action'] . ' <Plug>CalendarDoAction'
+  execute 'nmap <buffer> ' . s:calendar_keys['goto_today'] . ' <Plug>CalendarGotoToday'
+  execute 'nmap <buffer> ' . s:calendar_keys['show_help'] . ' <Plug>CalendarShowHelp'
+  execute 'nmap <buffer> ' . s:calendar_keys['redisplay'] . ' <Plug>CalendarRedisplay'
+
+  execute 'nmap <buffer> ' . s:calendar_keys['goto_next_month'] . ' <Plug>CalendarGotoNextMonth'
+  execute 'nmap <buffer> ' . s:calendar_keys['goto_prev_month'] . ' <Plug>CalendarGotoPrevMonth'
+  execute 'nmap <buffer> ' . s:calendar_keys['goto_next_year'] . ' <Plug>CalendarGotoNextYear'
+  execute 'nmap <buffer> ' . s:calendar_keys['goto_prev_year'] . ' <Plug>CalendarGotoPrevYear'
+endfunction
+
+"*****************************************************************
+"* CalendarHelp : show help for Calendar
+"*----------------------------------------------------------------
+"*****************************************************************
+function! s:CalendarHelp()
+  let ck = s:calendar_keys
+  let max_width = max(map(values(ck), 'len(v:val)'))
+  let offsets = map(copy(ck), '1 + max_width - len(v:val)')
+
+  echohl SpecialKey
+  echo ck['goto_prev_month']  . repeat(' ', offsets['goto_prev_month']) . ': goto prev month'
+  echo ck['goto_next_month']  . repeat(' ', offsets['goto_next_month']) . ': goto next month'
+  echo ck['goto_prev_year']   . repeat(' ', offsets['goto_prev_year'])  . ': goto prev year'
+  echo ck['goto_next_year']   . repeat(' ', offsets['goto_next_year'])  . ': goto next year'
+  echo ck['goto_today']       . repeat(' ', offsets['goto_today'])      . ': goto today'
+  echo ck['close']            . repeat(' ', offsets['close'])           . ': close window'
+  echo ck['redisplay']        . repeat(' ', offsets['redisplay'])       . ': re-display window'
+  echo ck['show_help']        . repeat(' ', offsets['show_help'])       . ': show this help'
+  if g:calendar_action == "calendar#diary"
+    echo ck['do_action']      . repeat(' ', offsets['do_action'])       . ': show diary'
+  endif
+  echo ''
+  echohl Question
+
+  let vk = [
+  \ 'calendar_erafmt',
+  \ 'calendar_mruler',
+  \ 'calendar_wruler',
+  \ 'calendar_weeknm',
+  \ 'calendar_navi_label',
+  \ 'calendar_diary',
+  \ 'calendar_mark',
+  \ 'calendar_navi',
+  \]
+  let max_width = max(map(copy(vk), 'len(v:val)'))
+
+  for _ in vk
+    let v = get(g:, _, '')
+    echo _ . repeat(' ', max_width - len(_)) . ' = ' .  v
+  endfor
+  echohl MoreMsg
+  echo "[Hit any key]"
+  echohl None
+  call getchar()
+  redraw!
+endfunction
+
+function! calendar#search(keyword)
+  if g:calendar_search_grepprg == "internal"
+    exe "vimgrep /" . a:keyword."/" . escape(g:calendar_diary," ") . "/**/*" . g:calendar_diary_extension . "|cw"
+  else
+    silent execute g:calendar_search_grepprg . " '" . a:keyword . "' " . escape(g:calendar_diary," ") . "/**/*" . g:calendar_diary_extension
+    silent execute "cw"
+  endif
+endfunction
+
+hi def link CalNavi     Search
+hi def link CalSaturday Statement
+hi def link CalSunday   Type
+hi def link CalRuler    StatusLine
+hi def link CalWeeknm   Comment
+hi def link CalToday    Directory
+hi def link CalHeader   Special
+hi def link CalMemo     Identifier
+hi def link CalNormal   Normal
+hi def link CalCurrList Error

+ 254 - 0
vimfiles/bundle/calendar-vim/doc/calendar.txt

@@ -0,0 +1,254 @@
+*calendar.txt* Calendar utility for vim
+
+Author:  Yasuhiro Matsumoto <mattn.jp@gmail.com>
+
+INTRODUCTION                                    *calendar*
+
+This script creates a calendar window in vim.  It does not rely on any
+external program, such as cal, etc.
+
+COMMANDS                                        *calendar-commands*
+
+calendar.vim makes the following commands available:
+
+                                                *calendar-:Calendar*
+:Calendar [[year] month]  Show calendar at this year and this month in a
+                          vertical split.  When [year] is omitted, the
+                          calendar will show the given month in the current
+                          year.  When both [year] and [month] are omitted, the
+                          calendar will show the current month.
+
+                                                *calendar-:CalendarH*
+:CalendarH [[year] month] Show calendar at this year and this month in a
+                          horizontal split.  When [year] is omitted, the
+                          calendar will show the given month in the current
+                          year.  When both [year] and [month] are omitted, the
+                          calendar will show the current month.
+
+                                                *calendar-:CalendarT*
+:CalendarT [[year] month] Show calendar at this year and this month in a
+                          full-screen window.  When [year] is omitted, the
+                          calendar will show the given month in the current
+                          year.  When both [year] and [month] are omitted, the
+                          calendar will show the current month.
+
+                                                *calendar-:CalendarVR*
+:CalendarVR [[year] month]  Show calendar at this year and this month in a
+                          vertical split at the right site.  When [year] is
+                          omitted, the calendar will show the given month in
+                          the current year.  When both [year] and [month] are
+                          omitted, the calendar will show the current month.
+
+                                            *calendar-:CalendarSearch*
+:CalendarSearch [keyword]  Search something in current calendar diary book.
+
+
+MAPPINGS                                        *calendar-mappings*
+
+calendar.vim makes the following normal mode mappings available:
+
+                                                *calendar-cal*
+<LocalLeader>cal          Brings up the calendar in a vertical split.
+                          Equivalent to calling |:Calendar|.
+
+                                                *calendar-caL*
+<LocalLeader>caL          Brings up the calendar in a horizontal split.
+                          Equivalent to calling |:CalendarH|.
+
+SETTINGS                                        *calendar-settings*
+
+calendar.vim can be configured using the following settings:
+
+                                                *g:calendar_no_mappings*
+Disable standard mappings:
+  let g:calendar_no_mappings=0
+
+                                                *g:calendar_focus_today*
+Keeps focus when moving to next or previous calendar: >
+  let g:calendar_focus_today = 1
+<
+
+                                                *g:calendar_keys*
+To change the key bindings in the calendar window, add entries to this
+dictionary.   Possible keys, the action bound to the keycode given in the
+respective value for this key and the default binding are listed below.
+'close'                     Closes calendar window.             'q'
+'do_action'                 Executes |calendar_action|.           '<CR>'
+'goto_today'                Executes |calendar_today|.            't'
+'show_help'                 Displays a short help message.      '?'
+'redisplay'                 Redraws calendar window.            'r'
+'goto_next_month'           Jumps to the next month.            '<Right>'
+'goto_prev_month'           Jumps to the previous month.        '<Left>'
+'goto_next_year'            Jumps to the next year.             '<Up>'
+'goto_prev_year'            Jumps to the previous year.         '<Down>'
+An example in your .vimrc might look like this: >
+  let g:calendar_keys = { 'goto_next_month': '<C-Right>', 'goto_prev_month': '<C-Left>'}
+<
+
+                                                *g:calendar_mark*
+Place a '*' or '+' mark after the day.  Acceptable values are 'left',
+'left-fit', and 'right': >
+  let g:calendar_mark = 'right'
+<
+
+                                                *g:calendar_diary*
+Specify the directory for the diary files.  The default value is $HOME/diary. >
+  let g:calendar_diary=$HOME.'/.vim/diary'
+<
+
+                                           *g:calendar_diary_list*
+Specify multiple diary configurations. >
+  let g:calendar_diary_list = [
+    \   {'name': 'Note', 'path': $HOME.'/note', 'ext': '.md'},
+    \   {'name': 'Diary', 'path': $HOME.'/diary', 'ext': '.diary.md'},
+    \ ]
+<
+
+                                  *g:calendar_diary_list_curr_idx*
+Specify multiple diary default configuration. The default value is 0. >
+  let g:calendar_diary_list_curr_idx = 1
+<
+
+
+                                                *g:calendar_navi*
+To control the calendar navigator, set this variable.  Acceptable values are
+'top', 'bottom', or 'both'. >
+  let g:calendar_navi = ''
+<
+
+                                                *g:calendar_navi_label*
+To set the labels for the calendar navigator, for example to change the
+language, use this variable.  Entries should be comma separated. >
+  let g:calendar_navi_label = 'Prev,Today,Next'
+<
+
+                                                *g:calendar_erafmt*
+To change the dating system, set the following variable.  Include the name of
+the dating system and its offset from the Georgian calendar (A.D.).  For
+example, to use the current Japanese era (Heisei), you would set: >
+  let g:calendar_erafmt = 'Heisei,-1988'
+<
+
+                                                *g:calendar_mruler*
+To change the month names for the calendar headings, set this variable.  The
+value is expected to be a comma-separated list of twelve values, starting with
+January: >
+  let g:calendar_mruler = 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'
+<
+
+                                                *g:calendar_wruler*
+To change the week names for the calendar headings, set this variable.  The
+value is expected to be a space-separated list of seven values, starting with
+Sunday: >
+  let g:calendar_wruler = 'Su Mo Tu We Th Fr Sa'
+<
+
+                                                *g:calendar_monday*
+To make the week start on Monday rather than Sunday, set this variable.  Note
+that the value of |g:calendar_wruler| is not affected by this; it should
+always begin with Sunday: >
+  let g:calendar_monday = 1
+<
+
+                                                *g:calendar_weeknm*
+To show the week number, set this variable.  There are four valid settings: >
+  let g:calendar_weeknm = 1 " WK01
+  let g:calendar_weeknm = 2 " WK 1
+  let g:calendar_weeknm = 3 " KW01
+  let g:calendar_weeknm = 4 " KW 1
+  let g:calendar_weeknm = 5 " 1
+<
+
+                                                *g:calendar_datetime*
+To control display of the current date and time, set this variable.
+Acceptable values are 'title', 'statusline', and '': >
+  let g:calendar_datetime = 'title'
+<
+                                                *g:calendar_filetype*
+To control the filetype of calendar entries, set this variable. It defaults to
+'markdown'. Acceptable values are values that are acceptable for |filetype|
+like e.g. 'markdown' or 'pandoc':
+  let g:calendar_filetype = 'pandoc'
+
+                                                *g:calendar_number_of_months*
+To control the number of months per view, set this variable. The default value
+is 3. >
+  let g:calendar_number_of_months = 5
+<
+
+                                                *g:calendar_search_grepprg*
+To set the command |:CalendarSearch| grepprg config. default value is 'grep',
+using system default grep program. If you want use Vim internal grep command
+|:vimgrep|, set value to 'internal'. >
+  let g:calendar_search_grepprg = 'internal'
+<
+
+HOOKS                                           *calendar-hooks*
+
+calendar.vim provides a number of hooks which allow you to run custom code on
+certain events.  These are documented below.
+
+                                                *calendar_action*
+The function declared in the calendar_action variable is run when the user
+presses enter on a date.  Implement and set your function as follows: >
+  function MyCalAction(day,month,year,week,dir)
+    " day   : day you actioned
+    " month : month you actioned
+    " year  : year you actioned
+    " week  : day of week (Mo=1 ... Su=7)
+    " dir   : direction of calendar
+  endfunction
+  let calendar_action = 'MyCalAction'
+<
+
+                                                *calendar_begin*
+The function declared in the calendar_begin variable is run just before the
+calendar is displayed.  Implement and set your function as follows: >
+  function MyCalActionBegin()
+  endfunction
+  let calendar_begin = 'MyCalActionBegin'
+<
+
+                                                *calendar_end*
+The function declared in the calendar_end variable is run just after the
+calendar is displayed.  Implement and set your function as follows: >
+  function MyCalActionEnd()
+  endfunction
+  let calendar_end = 'MyCalActionEnd'
+<
+
+                                                *calendar_sign*
+The function declared in the calendar_sign variable can be used to set a mark
+next to certain dates.  Implement and set your function as follows: >
+  function MyCalSign(day,month,year)
+    " day   : day you actioned
+    " month : month you actioned
+    " year  : year you actioned
+    if a:day == 1 && a:month == 1
+      return 1 " happy new year
+    else
+      return 0 " or not
+    endif
+  endfunction
+  let calendar_sign = 'MyCalSign'
+<
+
+                                                *calendar_today*
+The function declared in the calendar_today variable is run when the user
+presses 'today'.  Implement and set your function as follows: >
+  function MyCalToday()
+  endfunction
+  let calendar_today = 'MyCalToday'
+<
+
+ABOUT                                           *calendar-about*
+
+calendar.vim is available on GitHub:
+
+  http://github.com/mattn/calendar-vim
+
+and also on VimScripts:
+
+  http://www.vim.org/scripts/script.php?script_id=52
+
+vim:tw=78:et:ft=help:norl:

+ 37 - 0
vimfiles/bundle/calendar-vim/doc/tags

@@ -0,0 +1,37 @@
+calendar	calendar.txt	/*calendar*
+calendar-:Calendar	calendar.txt	/*calendar-:Calendar*
+calendar-:CalendarH	calendar.txt	/*calendar-:CalendarH*
+calendar-:CalendarSearch	calendar.txt	/*calendar-:CalendarSearch*
+calendar-:CalendarT	calendar.txt	/*calendar-:CalendarT*
+calendar-:CalendarVR	calendar.txt	/*calendar-:CalendarVR*
+calendar-about	calendar.txt	/*calendar-about*
+calendar-caL	calendar.txt	/*calendar-caL*
+calendar-cal	calendar.txt	/*calendar-cal*
+calendar-commands	calendar.txt	/*calendar-commands*
+calendar-hooks	calendar.txt	/*calendar-hooks*
+calendar-mappings	calendar.txt	/*calendar-mappings*
+calendar-settings	calendar.txt	/*calendar-settings*
+calendar.txt	calendar.txt	/*calendar.txt*
+calendar_action	calendar.txt	/*calendar_action*
+calendar_begin	calendar.txt	/*calendar_begin*
+calendar_end	calendar.txt	/*calendar_end*
+calendar_sign	calendar.txt	/*calendar_sign*
+calendar_today	calendar.txt	/*calendar_today*
+g:calendar_datetime	calendar.txt	/*g:calendar_datetime*
+g:calendar_diary	calendar.txt	/*g:calendar_diary*
+g:calendar_diary_list	calendar.txt	/*g:calendar_diary_list*
+g:calendar_diary_list_curr_idx	calendar.txt	/*g:calendar_diary_list_curr_idx*
+g:calendar_erafmt	calendar.txt	/*g:calendar_erafmt*
+g:calendar_filetype	calendar.txt	/*g:calendar_filetype*
+g:calendar_focus_today	calendar.txt	/*g:calendar_focus_today*
+g:calendar_keys	calendar.txt	/*g:calendar_keys*
+g:calendar_mark	calendar.txt	/*g:calendar_mark*
+g:calendar_monday	calendar.txt	/*g:calendar_monday*
+g:calendar_mruler	calendar.txt	/*g:calendar_mruler*
+g:calendar_navi	calendar.txt	/*g:calendar_navi*
+g:calendar_navi_label	calendar.txt	/*g:calendar_navi_label*
+g:calendar_no_mappings	calendar.txt	/*g:calendar_no_mappings*
+g:calendar_number_of_months	calendar.txt	/*g:calendar_number_of_months*
+g:calendar_search_grepprg	calendar.txt	/*g:calendar_search_grepprg*
+g:calendar_weeknm	calendar.txt	/*g:calendar_weeknm*
+g:calendar_wruler	calendar.txt	/*g:calendar_wruler*

+ 234 - 0
vimfiles/bundle/calendar-vim/plugin/calendar.vim

@@ -0,0 +1,234 @@
+"=============================================================================
+" What Is This: Calendar
+" File: calendar.vim
+" Author: Yasuhiro Matsumoto <mattn.jp@gmail.com>
+" Last Change: 2013 Okt 27
+" Version: 2.9
+" Thanks:
+"     Tobias Columbus               : customizable key bindings
+"     Daniel P. Wright              : doc/calendar.txt
+"     SethMilliken                  : gave a hint for 2.4
+"     bw1                           : bug fix, new weeknm format
+"     Ingo Karkat                   : bug fix
+"     Thinca                        : bug report, bug fix
+"     Yu Pei                        : bug report
+"     Per Winkvist                  : bug fix
+"     Serge (gentoosiast) Koksharov : bug fix
+"     Vitor Antunes                 : bug fix
+"     Olivier Mengue                : bug fix
+"     Noel Henson                   : today action
+"     Per Winkvist                  : bug report
+"     Peter Findeisen               : bug fix
+"     Chip Campbell                 : gave a hint for 1.3z
+"     PAN Shizhu                    : gave a hint for 1.3y
+"     Eric Wald                     : bug fix
+"     Sascha Wuestemann             : advise
+"     Linas Vasiliauskas            : bug report
+"     Per Winkvist                  : bug report
+"     Ronald Hoelwarth              : gave a hint for 1.3s
+"     Vikas Agnihotri               : bug report
+"     Steve Hall                    : gave a hint for 1.3q
+"     James Devenish                : bug fix
+"     Carl Mueller                  : gave a hint for 1.3o
+"     Klaus Fabritius               : bug fix
+"     Stucki                        : gave a hint for 1.3m
+"     Rosta                         : bug report
+"     Richard Bair                  : bug report
+"     Yin Hao Liew                  : bug report
+"     Bill McCarthy                 : bug fix and gave a hint
+"     Srinath Avadhanula            : bug fix
+"     Ronald Hoellwarth             : few advices
+"     Juan Orlandini                : added higlighting of days with data
+"     Ray                           : bug fix
+"     Ralf.Schandl                  : gave a hint for 1.3
+"     Bhaskar Karambelkar           : bug fix
+"     Suresh Govindachar            : gave a hint for 1.2, bug fix
+"     Michael Geddes                : bug fix
+"     Leif Wickland                 : bug fix
+" ChangeLog:
+"     2.8  : bug fix
+"     2.7  : vim7ish, customizable key bindings
+"     2.6  : new week number format
+"     2.5  : bug fix, 7.2 don't have relativenumber.
+"     2.4  : added g:calendar_options.
+"     2.3  : week number like ISO8601
+"            g:calendar_monday and g:calendar_weeknm work together
+"     2.2  : http://gist.github.com/355513#file_customizable_keymap.diff
+"            http://gist.github.com/355513#file_winfixwidth.diff
+"     2.1  : bug fix, set filetype 'calendar'.
+"     2.0  : bug fix, many bug fix and enhancements.
+"     1.9  : bug fix, use nnoremap.
+"     1.8  : bug fix, E382 when close diary.
+"     1.7  : bug fix, week number was broken on 2008.
+"     1.6  : added calendar_begin action.
+"            added calendar_end action.
+"     1.5  : bug fix, fixed ruler formating with strpart.
+"            bug fix, using winfixheight.
+"     1.4a : bug fix, week number was broken on 2005.
+"            added calendar_today action.
+"            bug fix, about wrapscan.
+"            bug fix, about today mark.
+"            bug fix, about today navigation.
+"     1.4  : bug fix, and one improvement.
+"            bug 1:
+"              when marking the current date, there is not distinguished e.g. between
+"              20041103 and 20040113, both dates are marked as today
+"            bug 2:
+"              the navigation mark "today" doesn't work
+"            improvement:
+"              the mapping t worked only when today was displayed, now it works always
+"              and redisplays the cuurent month and today
+"     1.3z : few changes
+"            asign <Left>, <Right> for navigation.
+"            set ws for search navigation.
+"            add tag for GetLatestVimScripts(AutoInstall)
+"     1.3y : bug fix, few changes
+"            changed color syntax name. (ex. CalNavi, see bottom of this)
+"            changed a map CalendarV for <Leader>cal
+"            changed a map CalendarH for <Leader>caL
+"            (competitive map for cvscommand.vim)
+"            the date on the right-hand side didn't work correctoly.
+"            make a map to rebuild Calendar window(r).
+"     1.3x : bug fix
+"            viweek can't refer when not set calendar_weeknm.
+"     1.3w : bug fix
+"            on leap year, week number decreases.
+"     1.3v : bug fix
+"            add nowrapscan
+"            use s:bufautocommandsset for making title
+"            don't focus to navi when doubleclick bottom next>.
+"     1.3u : bug fix
+"             when enter diary first time,
+"              it don't warn that you don't have diary directory.
+"     1.3t : bug fix
+"             make sure the variables for help
+"     1.3s : bug fix
+"             make a map CalendarV for <Leader>ca
+"            add option calendar_navi_label
+"             see Additional:
+"            add option calendar_focus_today
+"             see Additional:
+"            add map ? for help
+"     1.3r : bug fix
+"             if clicked navigator, cursor go to strange position.
+"     1.3q : bug fix
+"             coundn't set calendar_navi
+"              in its horizontal direction
+"     1.3p : bug fix
+"             coundn't edit diary when the calendar is
+"              in its horizontal direction
+"     1.3o : add option calendar_mark, and delete calendar_rmark
+"             see Additional:
+"            add option calendar_navi
+"             see Additional:
+"     1.3n : bug fix
+"             s:CalendarSign() should use filereadable(expand(sfile)).
+"     1.3m : tuning
+"             using topleft or botright for opening Calendar.
+"            use filereadable for s:CalendarSign().
+"     1.3l : bug fix
+"             if set calendar_monday, it can see that Sep 1st is Sat
+"               as well as Aug 31st.
+"     1.3k : bug fix
+"             it didn't escape the file name on calendar.
+"     1.3j : support for fixed Gregorian
+"             added the part of Sep 1752.
+"     1.3i : bug fix
+"             Calculation mistake for week number.
+"     1.3h : add option for position of displaying '*' or '+'.
+"             see Additional:
+"     1.3g : centering header
+"            add option for show name of era.
+"             see Additional:
+"            bug fix
+"             <Leader>ca didn't show current month.
+"     1.3f : bug fix
+"            there was yet another bug of today's sign.
+"     1.3e : added usage for <Leader>
+"            support handler for sign.
+"            see Additional:
+"     1.3d : added higlighting of days that have calendar data associated
+"             with it.
+"            bug fix for calculates date.
+"     1.3c : bug fix for MakeDir()
+"            if CalendarMakeDir(sfile) != 0
+"               v
+"            if s:CalendarMakeDir(sfile) != 0
+"     1.3b : bug fix for calendar_monday.
+"            it didn't work g:calendar_monday correctly.
+"            add g:calendar_version.
+"            add argument on action handler.
+"            see Additional:
+"     1.3a : bug fix for MakeDir().
+"            it was not able to make directory.
+"     1.3  : support handler for action.
+"            see Additional:
+"     1.2g : bug fix for today's sign.
+"            it could not display today's sign correctly.
+"     1.2f : bug fix for current Date.
+"            vtoday variable calculates date as 'YYYYMMDD'
+"            while the loop calculates date as 'YYYYMMD' i.e just 1 digit
+"            for date if < 10 so if current date is < 10 , the if condiction
+"            to check for current date fails and current date is not
+"            highlighted.
+"            simple solution changed vtoday calculation line divide the
+"            current-date by 1 so as to get 1 digit date.
+"     1.2e : change the way for setting title.
+"            auto configuration for g:calendar_wruler with g:calendar_monday
+"     1.2d : add option for show week number.
+"              let g:calendar_weeknm = 1
+"            add separator if horizontal.
+"            change all option's name
+"              g:calendar_mnth -> g:calendar_mruler
+"              g:calendar_week -> g:calendar_wruler
+"              g:calendar_smnd -> g:calendar_monday
+"     1.2c : add option for that the week starts with monday.
+"              let g:calendar_smnd = 1
+"     1.2b : bug fix for modifiable.
+"            setlocal nomodifiable (was set)
+"     1.2a : add default options.
+"            nonumber,foldcolumn=0,nowrap... as making gap
+"     1.2  : support wide display.
+"            add a command CalendarH
+"            add map <s-left> <s-right>
+"     1.1c : extra.
+"            add a titlestring for today.
+"     1.1b : bug fix by Michael Geddes.
+"            it happend when do ':Calender' twice
+"     1.1a : fix misspell.
+"            Calender -> Calendar
+"     1.1  : bug fix.
+"            it"s about strftime("%m")
+"     1.0a : bug fix by Leif Wickland.
+"            it"s about strftime("%w")
+"     1.0  : first release.
+" TODO:
+"     add the option for diary which is separate or single file.
+" GetLatestVimScripts: 52 1 :AutoInstall: calendar.vim
+
+if &compatible
+  finish
+endif
+"*****************************************************************
+"* Calendar commands
+"*****************************************************************
+command! -nargs=* Calendar  call calendar#show(0,<f-args>)
+command! -nargs=* CalendarVR  call calendar#show(3,<f-args>)
+command! -nargs=* CalendarH call calendar#show(1,<f-args>)
+command! -nargs=* CalendarT call calendar#show(2,<f-args>)
+
+command! -nargs=* CalendarSearch call calendar#search("<args>")
+
+if !get(g:, 'calendar_no_mappings', 0)
+  if !hasmapto('<Plug>CalendarV')
+    nmap <unique> <Leader>cal <Plug>CalendarV
+  endif
+  if !hasmapto('<Plug>CalendarH')
+    nmap <unique> <Leader>caL <Plug>CalendarH
+  endif
+endif
+nnoremap <silent> <Plug>CalendarV :cal calendar#show(0)<CR>
+nnoremap <silent> <Plug>CalendarH :cal calendar#show(1)<CR>
+nnoremap <silent> <Plug>CalendarT :cal calendar#show(2)<CR>
+
+" vi: et sw=2 ts=2

+ 183 - 0
vimfiles/bundle/coc.nvim/autoload/coc.vim

@@ -0,0 +1,183 @@
+scriptencoding utf-8
+let g:coc#_context = {'start': 0, 'preselect': -1,'candidates': []}
+let g:coc_user_config = get(g:, 'coc_user_config', {})
+let g:coc_global_extensions = get(g:, 'coc_global_extensions', [])
+let g:coc_selected_text = ''
+let g:coc_vim_commands = []
+let s:watched_keys = []
+let s:is_vim = !has('nvim')
+let s:error_sign = get(g:, 'coc_status_error_sign', has('mac') ? '❌ ' : 'E')
+let s:warning_sign = get(g:, 'coc_status_warning_sign', has('mac') ? '⚠️ ' : 'W')
+let s:select_api = exists('*nvim_select_popupmenu_item')
+let s:callbacks = {}
+let s:hide_pum = has('nvim-0.6.1') || has('patch-8.2.3389')
+
+function! coc#expandable() abort
+  return coc#rpc#request('snippetCheck', [1, 0])
+endfunction
+
+function! coc#jumpable() abort
+  return coc#rpc#request('snippetCheck', [0, 1])
+endfunction
+
+function! coc#expandableOrJumpable() abort
+  return coc#rpc#request('snippetCheck', [1, 1])
+endfunction
+
+" add vim command to CocCommand list
+function! coc#add_command(id, cmd, ...)
+  let config = {'id':a:id, 'cmd':a:cmd, 'title': get(a:,1,'')}
+  call add(g:coc_vim_commands, config)
+  if !coc#rpc#ready() | return | endif
+  call coc#rpc#notify('addCommand', [config])
+endfunction
+
+function! coc#on_enter()
+  call coc#rpc#notify('CocAutocmd', ['Enter', bufnr('%')])
+  return ''
+endfunction
+
+function! coc#_insert_key(method, key, ...) abort
+  let prefix = ''
+  if get(a:, 1, 1)
+    if pumvisible()
+      if s:hide_pum
+        let prefix = "\<C-x>\<C-z>"
+      else
+        let g:coc_disable_space_report = 1
+        let prefix = "\<space>\<bs>"
+      endif
+    endif
+  endif
+  return prefix."\<c-r>=coc#rpc#".a:method."('doKeymap', ['".a:key."'])\<CR>"
+endfunction
+
+function! coc#_complete() abort
+  let items = get(g:coc#_context, 'candidates', [])
+  let preselect = get(g:coc#_context, 'preselect', -1)
+  let startcol = g:coc#_context.start + 1
+  if s:select_api && len(items) && preselect != -1
+    noa call complete(startcol, items)
+    call nvim_select_popupmenu_item(preselect, v:false, v:false, {})
+    " use <cmd> specific key to preselect item at once
+    call feedkeys("\<Cmd>\<CR>" , 'i')
+  else
+    if pumvisible()
+      let g:coc_disable_complete_done = 1
+    endif
+    call complete(startcol, items)
+  endif
+  return ''
+endfunction
+
+function! coc#_do_complete(start, items, preselect, changedtick)
+  if b:changedtick != a:changedtick
+    return
+  endif
+  let g:coc#_context = {
+        \ 'start': a:start,
+        \ 'candidates': a:items,
+        \ 'preselect': a:preselect
+        \}
+  if mode() =~# 'i'
+    call coc#_complete()
+  endif
+endfunction
+
+function! coc#_cancel(...)
+  call coc#pum#close()
+endfunction
+
+" used for statusline
+function! coc#status()
+  let info = get(b:, 'coc_diagnostic_info', {})
+  let msgs = []
+  if !empty(info) && get(info, 'error', 0)
+    call add(msgs, s:error_sign . info['error'])
+  endif
+  if !empty(info) && get(info, 'warning', 0)
+    call add(msgs, s:warning_sign . info['warning'])
+  endif
+  return coc#compat#trim(join(msgs, ' ') . ' ' . get(g:, 'coc_status', ''))
+endfunction
+
+function! coc#config(section, value)
+  let g:coc_user_config[a:section] = a:value
+  call coc#rpc#notify('updateConfig', [a:section, a:value])
+endfunction
+
+function! coc#add_extension(...)
+  if a:0 == 0 | return | endif
+  call extend(g:coc_global_extensions, a:000)
+endfunction
+
+function! coc#_watch(key)
+  if s:is_vim | return | endif
+  if index(s:watched_keys, a:key) == -1
+    call add(s:watched_keys, a:key)
+    call dictwatcheradd(g:, a:key, function('s:GlobalChange'))
+  endif
+endfunction
+
+function! coc#_unwatch(key)
+  if s:is_vim | return | endif
+  let idx = index(s:watched_keys, a:key)
+  if idx != -1
+    call remove(s:watched_keys, idx)
+    call dictwatcherdel(g:, a:key, function('s:GlobalChange'))
+  endif
+endfunction
+
+function! s:GlobalChange(dict, key, val)
+  call coc#rpc#notify('GlobalChange', [a:key, get(a:val, 'old', v:null), get(a:val, 'new', v:null)])
+endfunction
+
+function! coc#on_notify(id, method, Cb)
+  let key = a:id. '-'.a:method
+  let s:callbacks[key] = a:Cb
+  call coc#rpc#notify('registNotification', [a:id, a:method])
+endfunction
+
+function! coc#do_notify(id, method, result)
+  let key = a:id. '-'.a:method
+  let Fn = s:callbacks[key]
+  if !empty(Fn)
+    call Fn(a:result)
+  endif
+endfunction
+
+function! coc#start(...)
+  let opt = coc#util#get_complete_option()
+  call CocActionAsync('startCompletion', extend(opt, get(a:, 1, {})))
+  return ''
+endfunction
+
+function! coc#refresh() abort
+  return "\<c-r>=coc#start()\<CR>"
+endfunction
+
+function! coc#_select_confirm() abort
+  call timer_start(10, { -> coc#pum#select_confirm()})
+  return s:is_vim || has('nvim-0.5.0') ? "\<Ignore>" : "\<space>\<bs>" 
+endfunction
+
+function! coc#complete_indent() abort
+  let curpos = getcurpos()
+  let indent_len = len(matchstr(getline('.'), '^\s*'))
+  let startofline = &startofline
+  let virtualedit = &virtualedit
+  set nostartofline
+  set virtualedit=all
+  normal! ==
+  let &startofline = startofline
+  let &virtualedit = virtualedit
+  let shift = len(matchstr(getline('.'), '^\s*')) - indent_len
+  let curpos[2] += shift
+  let curpos[4] += shift
+  call cursor(curpos[1:])
+   if shift != 0
+    if s:is_vim
+      call timer_start(0, { -> execute('redraw')})
+    endif
+  endif
+endfunction

+ 678 - 0
vimfiles/bundle/coc.nvim/autoload/coc/api.vim

@@ -0,0 +1,678 @@
+" ============================================================================
+" Description: Client api used by vim8
+" Author: Qiming Zhao <chemzqm@gmail.com>
+" Licence: Anti 996 licence
+" Last Modified: Jun 03, 2022
+" ============================================================================
+if has('nvim') | finish | endif
+scriptencoding utf-8
+let s:funcs = {}
+let s:prop_offset = get(g:, 'coc_text_prop_offset', 1000)
+let s:namespace_id = 1
+let s:namespace_cache = {}
+let s:max_src_id = 1000
+" bufnr => max textprop id
+let s:buffer_id = {}
+" srcId => list of types
+let s:id_types = {}
+
+" helper {{
+function! s:buf_line_count(bufnr) abort
+  if bufnr('%') == a:bufnr
+    return line('$')
+  endif
+  if exists('*getbufinfo')
+    let info = getbufinfo(a:bufnr)
+    if empty(info)
+      return 0
+    endif
+    " vim 8.1 has getbufinfo but no linecount
+    if has_key(info[0], 'linecount')
+      return info[0]['linecount']
+    endif
+  endif
+  if exists('*getbufline')
+    let lines = getbufline(a:bufnr, 1, '$')
+    return len(lines)
+  endif
+  let curr = bufnr('%')
+  execute 'noa buffer '.a:bufnr
+  let n = line('$')
+  execute 'noa buffer '.curr
+  return n
+endfunction
+
+function! s:execute(cmd)
+  if a:cmd =~# '^echo'
+    execute a:cmd
+  else
+    silent! execute a:cmd
+  endif
+endfunction
+" }}"
+
+" nvim client methods {{
+function! s:funcs.set_current_dir(dir) abort
+  execute 'cd '.a:dir
+endfunction
+
+function! s:funcs.set_var(name, value) abort
+  execute 'let g:'.a:name.'= a:value'
+endfunction
+
+function! s:funcs.del_var(name) abort
+  execute 'unlet g:'.a:name
+endfunction
+
+function! s:funcs.set_option(name, value) abort
+  execute 'let &'.a:name.' = a:value'
+endfunction
+
+function! s:funcs.set_current_buf(bufnr) abort
+  if !bufexists(a:bufnr) | return | endif
+  execute 'buffer '.a:bufnr
+endfunction
+
+function! s:funcs.set_current_win(win_id) abort
+  let [tabnr, winnr] = win_id2tabwin(a:win_id)
+  if tabnr == 0 | return | endif
+  execute 'normal! '.tabnr.'gt'
+  execute winnr.' wincmd w'
+endfunction
+
+function! s:funcs.set_current_tabpage(tabnr) abort
+  execute 'normal! '.a:tabnr.'gt'
+endfunction
+
+function! s:funcs.list_wins() abort
+  return map(getwininfo(), 'v:val["winid"]')
+endfunction
+
+function s:inspect_type(v) abort
+  let types = ['Number', 'String', 'Funcref', 'List', 'Dictionary', 'Float', 'Boolean', 'Null']
+  return get(types, type(a:v), 'Unknown')
+endfunction
+
+function! s:funcs.call_atomic(calls)
+  let res = []
+  for i in range(len(a:calls))
+    let [key, arglist] = a:calls[i]
+    let name = key[5:]
+    try
+      call add(res, call(s:funcs[name], arglist))
+    catch /.*/
+      return [res, [i, "VimException(".s:inspect_type(v:exception).")", v:exception . ' on '.v:throwpoint]]
+    endtry
+  endfor
+  return [res, v:null]
+endfunction
+
+function! s:funcs.set_client_info(...) abort
+endfunction
+
+function! s:funcs.subscribe(...) abort
+endfunction
+
+function! s:funcs.unsubscribe(...) abort
+endfunction
+
+function! s:funcs.call_function(method, args) abort
+  return call(a:method, a:args)
+endfunction
+
+function! s:funcs.call_dict_function(dict, method, args) abort
+  return call(a:method, a:args, a:dict)
+endfunction
+
+function! s:funcs.command(command) abort
+  " command that could cause cursor vanish
+  if a:command =~# '^echo' || a:command =~# '^redraw' || a:command =~# '^sign place'
+    call timer_start(0, {-> s:execute(a:command)})
+  else
+    execute a:command
+    let err = get(g:, 'errmsg', '')
+    " get error from python script run.
+    if !empty(err)
+      unlet g:errmsg
+      throw err
+    endif
+  endif
+endfunction
+
+function! s:funcs.eval(expr) abort
+  return eval(a:expr)
+endfunction
+
+function! s:funcs.get_api_info()
+  let names = coc#api#func_names()
+  return [1, {'functions': map(names, '{"name": "nvim_".v:val}')}]
+endfunction
+
+function! s:funcs.list_bufs()
+  return map(getbufinfo({'bufloaded': 1}), 'v:val["bufnr"]')
+endfunction
+
+function! s:funcs.feedkeys(keys, mode, escape_csi)
+  call feedkeys(a:keys, a:mode)
+endfunction
+
+function! s:funcs.list_runtime_paths()
+  return globpath(&runtimepath, '', 0, 1)
+endfunction
+
+function! s:funcs.command_output(cmd)
+  return execute(a:cmd)
+endfunction
+
+function! s:funcs.get_current_line()
+  return getline('.')
+endfunction
+
+function! s:funcs.set_current_line(line)
+  call setline('.', a:line)
+endfunction
+
+function! s:funcs.del_current_line(line)
+  execute 'normal! dd'
+endfunction
+
+function! s:funcs.get_var(var)
+  return get(g:, a:var, v:null)
+endfunction
+
+function! s:funcs.get_vvar(var)
+  return get(v:, a:var, v:null)
+endfunction
+
+function! s:funcs.get_option(name)
+  return eval('&'.a:name)
+endfunction
+
+function! s:funcs.get_current_buf()
+  return bufnr('%')
+endfunction
+
+function! s:funcs.get_current_win()
+  return win_getid()
+endfunction
+
+function! s:funcs.get_current_tabpage()
+  return tabpagenr()
+endfunction
+
+function! s:funcs.list_tabpages()
+  return range(1, tabpagenr('$'))
+endfunction
+
+function! s:funcs.get_mode()
+  return {'blocking': v:false, 'mode': mode()}
+endfunction
+
+function! s:funcs.strwidth(str)
+  return strwidth(a:str)
+endfunction
+
+function! s:funcs.out_write(str)
+  echon a:str
+  call timer_start(0, {-> s:execute('redraw')})
+endfunction
+
+function! s:funcs.err_write(str)
+  "echoerr a:str
+endfunction
+
+function! s:funcs.err_writeln(str)
+  echohl ErrorMsg
+  echom a:str
+  echohl None
+  call timer_start(0, {-> s:execute('redraw')})
+endfunction
+
+function! s:funcs.create_namespace(name) abort
+  if empty(a:name)
+    let id = s:namespace_id
+    let s:namespace_id = s:namespace_id + 1
+    return id
+  endif
+  let id = get(s:namespace_cache, a:name, 0)
+  if !id
+    let id = s:namespace_id
+    let s:namespace_id = s:namespace_id + 1
+    let s:namespace_cache[a:name] = id
+  endif
+  return id
+endfunction
+" }}
+
+" buffer methods {{
+function! s:funcs.buf_set_option(bufnr, name, val)
+  let val = a:val
+  if val is v:true
+    let val = 1
+  elseif val is v:false
+    let val = 0
+  endif
+  return setbufvar(a:bufnr, '&'.a:name, val)
+endfunction
+
+function! s:funcs.buf_get_changedtick(bufnr)
+  return getbufvar(a:bufnr, 'changedtick')
+endfunction
+
+function! s:funcs.buf_is_valid(bufnr)
+  return bufloaded(a:bufnr) ? v:true : v:false
+endfunction
+
+function! s:funcs.buf_get_mark(bufnr, name)
+  let nr = bufnr('%')
+  if a:bufnr != 0 || a:bufnr != nr
+    throw 'buf_get_mark support current buffer only'
+  endif
+  return [line("'" . a:name), col("'" . a:name)]
+endfunction
+
+function! s:funcs.buf_add_highlight(bufnr, srcId, hlGroup, line, colStart, colEnd, ...) abort
+  if !has('patch-8.1.1719')
+    return
+  endif
+  if a:srcId == 0
+    let srcId = s:max_src_id + 1
+    let s:max_src_id = srcId
+  else
+    let srcId = a:srcId
+  endif
+  let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
+  let type = a:hlGroup.'_'.srcId
+  let types = get(s:id_types, srcId, [])
+  if index(types, type) == -1
+    call add(types, type)
+    let s:id_types[srcId] = types
+    call prop_type_add(type, extend({'highlight': a:hlGroup}, get(a:, 1, {})))
+  endif
+  let end = a:colEnd == -1 ? strlen(getbufline(bufnr, a:line + 1)[0]) + 1 : a:colEnd + 1
+  if end < a:colStart + 1
+    return
+  endif
+  let id = s:generate_id(a:bufnr)
+  try
+    call prop_add(a:line + 1, a:colStart + 1, {'bufnr': bufnr, 'type': type, 'id': id, 'end_col': end})
+  catch /^Vim\%((\a\+)\)\=:E967/
+    " ignore 967
+  endtry
+  if a:srcId == 0
+    " return generated srcId
+    return srcId
+  endif
+endfunction
+
+function! s:funcs.buf_clear_namespace(bufnr, srcId, startLine, endLine) abort
+  if !has('patch-8.1.1719')
+    return
+  endif
+  let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
+  let start = a:startLine + 1
+  let end = a:endLine == -1 ? len(getbufline(bufnr, 1, '$')) : a:endLine
+  if a:srcId == -1
+    if has_key(s:buffer_id, a:bufnr)
+      unlet s:buffer_id[a:bufnr]
+    endif
+    call prop_clear(start, end, {'bufnr' : bufnr})
+  else
+    for type in get(s:id_types, a:srcId, [])
+      try
+        call prop_remove({'bufnr': bufnr, 'all': 1, 'type': type}, start, end)
+      catch /^Vim\%((\a\+)\)\=:E968/
+        " ignore 968
+      endtry
+    endfor
+  endif
+endfunction
+
+function! s:funcs.buf_line_count(bufnr) abort
+  return s:buf_line_count(a:bufnr)
+endfunction
+
+function! s:funcs.buf_attach(...)
+  " not supported
+  return 1
+endfunction
+
+function! s:funcs.buf_detach()
+  " not supported
+  return 1
+endfunction
+
+function! s:funcs.buf_get_lines(bufnr, start, end, strict) abort
+  let lines = getbufline(a:bufnr, 1, '$')
+  let start = a:start < 0 ? a:start + 1 : a:start
+  let end = a:end < 0 ? a:end + 1 : a:end
+  if a:strict && end > len(lines)
+    throw 'line number out of range: '. end
+  endif
+  return lines[start : end - 1]
+endfunction
+
+function! s:funcs.buf_set_lines(bufnr, start, end, strict, ...) abort
+  let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
+  if !bufloaded(bufnr)
+    return
+  endif
+  let replacement = get(a:, 1, [])
+  let lineCount = s:buf_line_count(bufnr)
+  let startLnum = a:start >= 0 ? a:start + 1 : lineCount + a:start + 2
+  let end = a:end >= 0 ? a:end : lineCount + a:end + 1
+  if end == lineCount + 1
+    let end = lineCount
+  endif
+  let delCount = end - (startLnum - 1)
+  let changeBuffer = 0
+  let curr = bufnr('%')
+  if bufnr != curr && !exists('*setbufline')
+    let changeBuffer = 1
+    exe 'buffer '.bufnr
+  endif
+  if bufnr == curr || changeBuffer
+    " replace
+    let storeView = winsaveview()
+    if delCount == len(replacement)
+      call setline(startLnum, replacement)
+    else
+      if len(replacement)
+        call append(startLnum - 1, replacement)
+      endif
+      if delCount
+        let start = startLnum + len(replacement)
+        let saved_reg = @"
+        let system_reg = @*
+        if exists('*deletebufline')
+          silent call deletebufline(curr, start, start + delCount - 1)
+        else
+          silent execute start . ','.(start + delCount - 1).'d'
+        endif
+        let @" = saved_reg
+        let @* = system_reg
+      endif
+    endif
+    call winrestview(storeView)
+    if changeBuffer
+      exe 'buffer '.curr
+    endif
+  elseif exists('*setbufline')
+    " replace
+    if delCount == len(replacement)
+      " 8.0.1039
+      call setbufline(bufnr, startLnum, replacement)
+    else
+      if len(replacement)
+        " 8.10037
+        call appendbufline(bufnr, startLnum - 1, replacement)
+      endif
+      if delCount
+        let start = startLnum + len(replacement)
+        let saved_reg = @"
+        let system_reg = @*
+        "8.1.0039
+        silent call deletebufline(bufnr, start, start + delCount - 1)
+        let @" = saved_reg
+        let @* = system_reg
+      endif
+    endif
+  endif
+endfunction
+
+function! s:funcs.buf_set_name(bufnr, name) abort
+  let nr = bufnr('%')
+  if a:bufnr != nr
+    throw 'buf_set_name support current buffer only'
+  else
+    execute '0f'
+    execute 'file '.fnameescape(a:name)
+  endif
+endfunction
+
+function! s:funcs.buf_get_var(bufnr, name)
+  return getbufvar(a:bufnr, a:name)
+endfunction
+
+function! s:funcs.buf_set_var(bufnr, name, val)
+  if !bufloaded(a:bufnr) | return | endif
+  call setbufvar(a:bufnr, a:name, a:val)
+endfunction
+
+function! s:funcs.buf_del_var(bufnr, name)
+  if bufnr == bufnr('%')
+    execute 'unlet! b:'.a:name
+  elseif exists('*win_execute')
+    let winid = coc#compat#buf_win_id(a:bufnr)
+    if winid != -1
+      call win_execute(winid, 'unlet! b:'.a:name)
+    endif
+  endif
+endfunction
+
+function! s:funcs.buf_get_option(bufnr, name)
+  return getbufvar(a:bufnr, '&'.a:name)
+endfunction
+
+function! s:funcs.buf_get_name(bufnr)
+  return bufname(a:bufnr)
+endfunction
+" }}
+
+" window methods {{
+function! s:funcs.win_get_buf(winid)
+  return winbufnr(a:winid)
+endfunction
+
+function! s:funcs.win_get_position(win_id) abort
+  let [row, col] = win_screenpos(a:win_id)
+  if row == 0 && col == 0
+    throw 'Invalid window '.a:win_id
+  endif
+  return [row - 1, col - 1]
+endfunction
+
+function! s:funcs.win_get_height(win_id) abort
+  return winheight(a:win_id)
+endfunction
+
+function! s:funcs.win_get_width(win_id) abort
+  return winwidth(a:win_id)
+endfunction
+
+if exists('*win_execute')
+  function! s:win_execute(win_id, cmd, ...) abort
+    let ref = get(a:000, 0, v:null)
+    let cmd = ref is v:null ? a:cmd : 'let ref["out"] = ' . a:cmd
+    call win_execute(a:win_id, cmd)
+  endfunction
+else
+  function! s:win_execute(win_id, cmd, ...) abort
+    let ref = get(a:000, 0, v:null)
+    let cmd = ref is v:null ? a:cmd : 'let ref["out"] = ' . a:cmd
+    let winid = win_getid()
+    if winid == a:win_id
+      execute cmd
+    else
+      let goto_status = win_gotoid(a:win_id)
+      if !goto_status
+        return
+      endif
+      execute cmd
+      call win_gotoid(winid)
+    endif
+  endfunction
+endif
+
+function! s:get_tabnr(winid) abort
+  let ref = {}
+  call s:win_execute(a:winid, 'tabpagenr()', ref)
+  return get(ref, 'out', 0)
+endfunction
+
+function! s:funcs.win_get_cursor(win_id) abort
+  let ref = {}
+  call s:win_execute(a:win_id, "[line('.'), col('.')-1]", ref)
+  return get(ref, 'out', 0)
+endfunction
+
+function! s:funcs.win_get_var(win_id, name, ...) abort
+  let tabnr = s:get_tabnr(a:win_id)
+  if tabnr
+    return gettabwinvar(tabnr, a:win_id, a:name, get(a:, 1, v:null))
+  endif
+  throw 'window '.a:win_id. ' not a visible window'
+endfunction
+
+function! s:funcs.win_set_width(win_id, width) abort
+  call s:win_execute(a:win_id, 'vertical resize '.a:width)
+endfunction
+
+function! s:funcs.win_set_buf(win_id, buf_id) abort
+  call s:win_execute(a:win_id, 'buffer '.a:buf_id)
+endfunction
+
+function! s:funcs.win_get_option(win_id, name) abort
+  let tabnr = s:get_tabnr(a:win_id)
+  if tabnr
+    return gettabwinvar(tabnr, a:win_id, '&'.a:name)
+  endif
+  throw 'window '.a:win_id. ' not a valid window'
+endfunction
+
+function! s:funcs.win_set_height(win_id, height) abort
+  return s:win_execute(a:win_id, 'resize '.a:height)
+endfunction
+
+function! s:funcs.win_set_option(win_id, name, value) abort
+  let val = a:value
+  if val is v:true
+    let val = 1
+  elseif val is v:false
+    let val = 0
+  endif
+  let tabnr = s:get_tabnr(a:win_id)
+  if tabnr
+    call settabwinvar(tabnr, a:win_id, '&'.a:name, val)
+  else
+    throw 'window '.a:win_id. ' not a valid window'
+  endif
+endfunction
+
+function! s:funcs.win_set_var(win_id, name, value) abort
+  let tabnr = s:get_tabnr(a:win_id)
+  if tabnr
+    call settabwinvar(tabnr, a:win_id, a:name, a:value)
+  else
+    throw "Invalid window id ".a:win_id
+  endif
+endfunction
+
+function! s:funcs.win_del_var(win_id, name) abort
+  call s:win_execute(a:win_id, 'unlet! w:'.a:name)
+endfunction
+
+function! s:funcs.win_is_valid(win_id) abort
+  let info = getwininfo(a:win_id)
+  return empty(info) ? v:false : v:true
+endfunction
+
+function! s:funcs.win_get_number(win_id) abort
+  let info = getwininfo(a:win_id)
+  if empty(info)
+    throw 'Invalid window id '.a:win_id
+  endif
+  return info[0]['winnr']
+endfunction
+
+function! s:funcs.win_set_cursor(win_id, pos) abort
+  let [line, col] = a:pos
+  call s:win_execute(a:win_id, 'call cursor('.line.','.(col + 1).')')
+endfunction
+
+function! s:funcs.win_close(win_id, ...) abort
+  let force = get(a:, 1, 0)
+  call s:win_execute(a:win_id, 'close'.(force ? '!' : ''))
+endfunction
+
+function! s:funcs.win_get_tabpage(win_id) abort
+  let tabnr = s:get_tabnr(a:win_id)
+  if !tabnr
+    throw 'Invalid window id '.a:win_id
+  endif
+  return tabnr
+endfunction
+" }}
+
+" tabpage methods {{
+function! s:funcs.tabpage_get_number(id)
+  return a:id
+endfunction
+
+function! s:funcs.tabpage_list_wins(tabnr)
+  let info = getwininfo()
+  return map(filter(info, 'v:val["tabnr"] == a:tabnr'), 'v:val["winid"]')
+endfunction
+
+function! s:funcs.tabpage_get_var(tabnr, name)
+  return gettabvar(a:tabnr, a:name, v:null)
+endfunction
+
+function! s:funcs.tabpage_set_var(tabnr, name, value)
+  call settabvar(a:tabnr, a:name, a:value)
+endfunction
+
+function! s:funcs.tabpage_del_var(tabnr, name)
+  call settabvar(a:tabnr, a:name, v:null)
+endfunction
+
+function! s:funcs.tabpage_is_valid(tabnr)
+  let max = tabpagenr('$')
+  return a:tabnr <= max
+endfunction
+
+function! s:funcs.tabpage_get_win(tabnr)
+  let wnr = tabpagewinnr(a:tabnr)
+  return win_getid(wnr, a:tabnr)
+endfunction
+
+function! s:generate_id(bufnr) abort
+  let max = get(s:buffer_id, a:bufnr, s:prop_offset)
+  let id = max + 1
+  let s:buffer_id[a:bufnr] = id
+  return id
+endfunction
+" }}
+
+function! coc#api#get_types(srcId) abort
+  return get(s:id_types, a:srcId, [])
+endfunction
+
+function! coc#api#func_names() abort
+  return keys(s:funcs)
+endfunction
+
+function! coc#api#call(method, args) abort
+  let err = v:null
+  let res = v:null
+  try
+    let res = call(s:funcs[a:method], a:args)
+  catch /.*/
+    let err = v:exception .' on api "'.a:method.'" '.json_encode(a:args)
+  endtry
+  return [err, res]
+endfunction
+
+function! coc#api#exec(method, args) abort
+  return call(s:funcs[a:method], a:args)
+endfunction
+
+function! coc#api#notify(method, args) abort
+  try
+    call call(s:funcs[a:method], a:args)
+  catch /.*/
+    let g:b = v:exception
+    call coc#rpc#notify('nvim_error_event', [0, v:exception.' on api "'.a:method.'" '.json_encode(a:args)])
+  endtry
+endfunction
+" vim: set sw=2 ts=2 sts=2 et tw=78 foldmarker={{,}} foldmethod=marker foldlevel=0:

+ 340 - 0
vimfiles/bundle/coc.nvim/autoload/coc/client.vim

@@ -0,0 +1,340 @@
+scriptencoding utf-8
+let s:root = expand('<sfile>:h:h:h')
+let s:is_vim = !has('nvim')
+let s:is_win = has("win32") || has("win64")
+let s:clients = {}
+
+if get(g:, 'node_client_debug', 0)
+  echohl WarningMsg | echo '[coc.nvim] Enable g:node_client_debug could impact your vim experience' | echohl None
+  let $NODE_CLIENT_LOG_LEVEL = 'debug'
+  if exists('$NODE_CLIENT_LOG_FILE')
+    let s:logfile = resolve($NODE_CLIENT_LOG_FILE)
+  else
+    let s:logfile = tempname()
+    let $NODE_CLIENT_LOG_FILE = s:logfile
+  endif
+endif
+
+" create a client
+function! coc#client#create(name, command)
+  let client = {}
+  let client['command'] = a:command
+  let client['name'] = a:name
+  let client['running'] = 0
+  let client['async_req_id'] = 1
+  let client['async_callbacks'] = {}
+  " vim only
+  let client['channel'] = v:null
+  " neovim only
+  let client['chan_id'] = 0
+  let client['start'] = function('s:start', [], client)
+  let client['request'] = function('s:request', [], client)
+  let client['notify'] = function('s:notify', [], client)
+  let client['request_async'] = function('s:request_async', [], client)
+  let client['on_async_response'] = function('s:on_async_response', [], client)
+  let s:clients[a:name] = client
+  return client
+endfunction
+
+function! s:start() dict
+  if self.running | return | endif
+  if !isdirectory(getcwd())
+    echohl Error | echon '[coc.nvim] Current cwd is not a valid directory.' | echohl None
+    return
+  endif
+  let timeout = string(get(g:, 'coc_channel_timeout', 30))
+  let tmpdir = fnamemodify(tempname(), ':p:h')
+  if s:is_vim
+    if get(g:, 'node_client_debug', 0)
+      let file = tmpdir . '/coc.log'
+      call ch_logfile(file, 'w')
+      echohl MoreMsg | echo '[coc.nvim] channel log to '.file | echohl None
+    endif
+    let options = {
+          \ 'in_mode': 'json',
+          \ 'out_mode': 'json',
+          \ 'err_mode': 'nl',
+          \ 'err_cb': {channel, message -> s:on_stderr(self.name, split(message, "\n"))},
+          \ 'exit_cb': {channel, code -> s:on_exit(self.name, code)},
+          \ 'env': {
+            \ 'NODE_NO_WARNINGS': '1',
+            \ 'VIM_NODE_RPC': '1',
+            \ 'COC_NVIM': '1',
+            \ 'COC_CHANNEL_TIMEOUT': timeout,
+            \ 'TMPDIR': tmpdir,
+          \ }
+          \}
+    if has("patch-8.1.350")
+      let options['noblock'] = 1
+    endif
+    let job = job_start(self.command, options)
+    let status = job_status(job)
+    if status !=# 'run'
+      let self.running = 0
+      echohl Error | echom 'Failed to start '.self.name.' service' | echohl None
+      return
+    endif
+    let self['running'] = 1
+    let self['channel'] = job_getchannel(job)
+  else
+    let original = {}
+    let opts = {
+          \ 'rpc': 1,
+          \ 'on_stderr': {channel, msgs -> s:on_stderr(self.name, msgs)},
+          \ 'on_exit': {channel, code -> s:on_exit(self.name, code)},
+          \ }
+    if has('nvim-0.5.0')
+      " could use env option
+      let opts['env'] = {
+          \ 'COC_NVIM': '1',
+          \ 'NODE_NO_WARNINGS': '1',
+          \ 'COC_CHANNEL_TIMEOUT': timeout,
+          \ 'TMPDIR': tmpdir
+          \ }
+    else
+      if exists('*getenv')
+        let original = {
+              \ 'NODE_NO_WARNINGS': getenv('NODE_NO_WARNINGS'),
+              \ 'TMPDIR': getenv('TMPDIR'),
+              \ }
+      endif
+      if exists('*setenv')
+        call setenv('COC_NVIM', '1')
+        call setenv('NODE_NO_WARNINGS', '1')
+        call setenv('COC_CHANNEL_TIMEOUT', timeout)
+        call setenv('TMPDIR', tmpdir)
+      else
+        let $NODE_NO_WARNINGS = 1
+        let $TMPDIR = tmpdir
+      endif
+    endif
+    let chan_id = jobstart(self.command, opts)
+    if !empty(original)
+      if exists('*setenv')
+        for key in keys(original)
+          call setenv(key, original[key])
+        endfor
+      else
+        let $TMPDIR = original['TMPDIR']
+      endif
+    endif
+    if chan_id <= 0
+      echohl Error | echom 'Failed to start '.self.name.' service' | echohl None
+      return
+    endif
+    let self['chan_id'] = chan_id
+    let self['running'] = 1
+  endif
+endfunction
+
+function! s:on_stderr(name, msgs)
+  if get(g:, 'coc_vim_leaving', 0) | return | endif
+  if get(g:, 'coc_disable_uncaught_error', 0) | return | endif
+  let data = filter(copy(a:msgs), '!empty(v:val)')
+  if empty(data) | return | endif
+  let client = a:name ==# 'coc' ? '[coc.nvim]' : '['.a:name.']'
+  let data[0] = client.': '.data[0]
+  call coc#ui#echo_messages('Error', data)
+endfunction
+
+function! s:on_exit(name, code) abort
+  if get(g:, 'coc_vim_leaving', 0) | return | endif
+  let client = get(s:clients, a:name, v:null)
+  if empty(client) | return | endif
+  if client['running'] != 1 | return | endif
+  let client['running'] = 0
+  let client['chan_id'] = 0
+  let client['channel'] = v:null
+  let client['async_req_id'] = 1
+  if a:code != 0 && a:code != 143
+    echohl Error | echom 'client '.a:name. ' abnormal exit with: '.a:code | echohl None
+  endif
+endfunction
+
+function! coc#client#get_client(name) abort
+  return get(s:clients, a:name, v:null)
+endfunction
+
+function! coc#client#get_channel(client)
+  if s:is_vim
+    return a:client['channel']
+  endif
+  return a:client['chan_id']
+endfunction
+
+function! s:request(method, args) dict
+  let channel = coc#client#get_channel(self)
+  if empty(channel) | return '' | endif
+  try
+    if s:is_vim
+      let res = ch_evalexpr(channel, [a:method, a:args], {'timeout': 60 * 1000})
+      if type(res) == 1 && res ==# ''
+        throw 'request '.a:method. ' '.string(a:args).' timeout after 60s'
+      endif
+      let [l:errmsg, res] =  res
+      if !empty(l:errmsg)
+        throw l:errmsg
+      else
+        return res
+      endif
+    else
+      return call('rpcrequest', [channel, a:method] + a:args)
+    endif
+  catch /.*/
+    if v:exception =~# 'E475'
+      if get(g:, 'coc_vim_leaving', 0) | return | endif
+      echohl Error | echom '['.self.name.'] server connection lost' | echohl None
+      let name = self.name
+      call s:on_exit(name, 0)
+      execute 'silent do User ConnectionLost'.toupper(name[0]).name[1:]
+    elseif v:exception =~# 'E12'
+      " neovim's bug, ignore it
+    else
+      echohl Error | echo 'Error on request ('.a:method.'): '.v:exception | echohl None
+    endif
+  endtry
+endfunction
+
+function! s:notify(method, args) dict
+  let channel = coc#client#get_channel(self)
+  if empty(channel)
+    return ''
+  endif
+  try
+    if s:is_vim
+      call ch_sendraw(channel, json_encode([0, [a:method, a:args]])."\n")
+    else
+      call call('rpcnotify', [channel, a:method] + a:args)
+    endif
+  catch /.*/
+    if v:exception =~# 'E475'
+      if get(g:, 'coc_vim_leaving', 0)
+        return
+      endif
+      echohl Error | echom '['.self.name.'] server connection lost' | echohl None
+      let name = self.name
+      call s:on_exit(name, 0)
+      execute 'silent do User ConnectionLost'.toupper(name[0]).name[1:]
+    elseif v:exception =~# 'E12'
+      " neovim's bug, ignore it
+    else
+      echohl Error | echo 'Error on notify ('.a:method.'): '.v:exception | echohl None
+    endif
+  endtry
+endfunction
+
+function! s:request_async(method, args, cb) dict
+  let channel = coc#client#get_channel(self)
+  if empty(channel) | return '' | endif
+  if type(a:cb) != 2
+    echohl Error | echom '['.self['name'].'] Callback should be function' | echohl None
+    return
+  endif
+  let id = self.async_req_id
+  let self.async_req_id = id + 1
+  let self.async_callbacks[id] = a:cb
+  call self['notify']('nvim_async_request_event', [id, a:method, a:args])
+endfunction
+
+function! s:on_async_response(id, resp, isErr) dict
+  let Callback = get(self.async_callbacks, a:id, v:null)
+  if empty(Callback)
+    " should not happen
+    echohl Error | echom 'callback not found' | echohl None
+    return
+  endif
+  call remove(self.async_callbacks, a:id)
+  if a:isErr
+    call call(Callback, [a:resp, v:null])
+  else
+    call call(Callback, [v:null, a:resp])
+  endif
+endfunction
+
+function! coc#client#is_running(name) abort
+  let client = get(s:clients, a:name, v:null)
+  if empty(client) | return 0 | endif
+  if !client['running'] | return 0 | endif
+  if s:is_vim
+    let status = job_status(ch_getjob(client['channel']))
+    return status ==# 'run'
+  else
+    let chan_id = client['chan_id']
+    let [code] = jobwait([chan_id], 10)
+    return code == -1
+  endif
+endfunction
+
+function! coc#client#stop(name) abort
+  let client = get(s:clients, a:name, v:null)
+  if empty(client) | return 1 | endif
+  let running = coc#client#is_running(a:name)
+  if !running
+    echohl WarningMsg | echom 'client '.a:name. ' not running.' | echohl None
+    return 1
+  endif
+  if s:is_vim
+    call job_stop(ch_getjob(client['channel']), 'term')
+  else
+    call jobstop(client['chan_id'])
+  endif
+  sleep 200m
+  if coc#client#is_running(a:name)
+    echohl Error | echom 'client '.a:name. ' stop failed.' | echohl None
+    return 0
+  endif
+  call s:on_exit(a:name, 0)
+  echohl MoreMsg | echom 'client '.a:name.' stopped!' | echohl None
+  return 1
+endfunction
+
+function! coc#client#request(name, method, args)
+  let client = get(s:clients, a:name, v:null)
+  if !empty(client)
+    return client['request'](a:method, a:args)
+  endif
+endfunction
+
+function! coc#client#notify(name, method, args)
+  let client = get(s:clients, a:name, v:null)
+  if !empty(client)
+    call client['notify'](a:method, a:args)
+  endif
+endfunction
+
+function! coc#client#request_async(name, method, args, cb)
+  let client = get(s:clients, a:name, v:null)
+  if !empty(client)
+    call client['request_async'](a:method, a:args, a:cb)
+  endif
+endfunction
+
+function! coc#client#on_response(name, id, resp, isErr)
+  let client = get(s:clients, a:name, v:null)
+  if !empty(client)
+    call client['on_async_response'](a:id, a:resp, a:isErr)
+  endif
+endfunction
+
+function! coc#client#restart(name) abort
+  let stopped = coc#client#stop(a:name)
+  if !stopped | return | endif
+  let client = get(s:clients, a:name, v:null)
+  if !empty(client)
+    call client['start']()
+  endif
+endfunction
+
+function! coc#client#restart_all()
+  for key in keys(s:clients)
+    call coc#client#restart(key)
+  endfor
+endfunction
+
+function! coc#client#open_log()
+  if !get(g:, 'node_client_debug', 0)
+    echohl Error | echon '[coc.nvim] use let g:node_client_debug = 1 in your vimrc to enabled debug mode.' | echohl None
+    return
+  endif
+  execute 'vs '.s:logfile
+endfunction

+ 283 - 0
vimfiles/bundle/coc.nvim/autoload/coc/color.vim

@@ -0,0 +1,283 @@
+scriptencoding utf-8
+
+let s:activate = ""
+let s:quit = ""
+if has("gui_macvim") && has('gui_running')
+  let s:app = "MacVim"
+elseif $TERM_PROGRAM ==# "Apple_Terminal"
+  let s:app = "Terminal"
+elseif $TERM_PROGRAM ==# "iTerm.app"
+  let s:app = "iTerm2"
+elseif has('mac')
+  let s:app = "System Events"
+  let s:quit = "quit"
+  let s:activate = 'activate'
+endif
+
+" Returns an approximate grey index for the given grey level
+fun! s:grey_number(x)
+  if &t_Co == 88
+    if a:x < 23
+      return 0
+    elseif a:x < 69
+      return 1
+    elseif a:x < 103
+      return 2
+    elseif a:x < 127
+      return 3
+    elseif a:x < 150
+      return 4
+    elseif a:x < 173
+      return 5
+    elseif a:x < 196
+      return 6
+    elseif a:x < 219
+      return 7
+    elseif a:x < 243
+      return 8
+    else
+      return 9
+    endif
+  else
+    if a:x < 14
+      return 0
+    else
+      let l:n = (a:x - 8) / 10
+      let l:m = (a:x - 8) % 10
+      if l:m < 5
+        return l:n
+      else
+        return l:n + 1
+      endif
+    endif
+  endif
+endfun
+
+" Returns the actual grey level represented by the grey index
+fun! s:grey_level(n)
+  if &t_Co == 88
+    if a:n == 0
+      return 0
+    elseif a:n == 1
+      return 46
+    elseif a:n == 2
+      return 92
+    elseif a:n == 3
+      return 115
+    elseif a:n == 4
+      return 139
+    elseif a:n == 5
+      return 162
+    elseif a:n == 6
+      return 185
+    elseif a:n == 7
+      return 208
+    elseif a:n == 8
+      return 231
+    else
+      return 255
+    endif
+  else
+    if a:n == 0
+      return 0
+    else
+      return 8 + (a:n * 10)
+    endif
+  endif
+endfun
+
+" Returns the palette index for the given grey index
+fun! s:grey_colour(n)
+  if &t_Co == 88
+    if a:n == 0
+      return 16
+    elseif a:n == 9
+      return 79
+    else
+      return 79 + a:n
+    endif
+  else
+    if a:n == 0
+      return 16
+    elseif a:n == 25
+      return 231
+    else
+      return 231 + a:n
+    endif
+  endif
+endfun
+
+" Returns an approximate colour index for the given colour level
+fun! s:rgb_number(x)
+  if &t_Co == 88
+    if a:x < 69
+      return 0
+    elseif a:x < 172
+      return 1
+    elseif a:x < 230
+      return 2
+    else
+      return 3
+    endif
+  else
+    if a:x < 75
+      return 0
+    else
+      let l:n = (a:x - 55) / 40
+      let l:m = (a:x - 55) % 40
+      if l:m < 20
+        return l:n
+      else
+        return l:n + 1
+      endif
+    endif
+  endif
+endfun
+
+" Returns the palette index for the given R/G/B colour indices
+fun! s:rgb_colour(x, y, z)
+  if &t_Co == 88
+    return 16 + (a:x * 16) + (a:y * 4) + a:z
+  else
+    return 16 + (a:x * 36) + (a:y * 6) + a:z
+  endif
+endfun
+
+" Returns the actual colour level for the given colour index
+fun! s:rgb_level(n)
+  if &t_Co == 88
+    if a:n == 0
+      return 0
+    elseif a:n == 1
+      return 139
+    elseif a:n == 2
+      return 205
+    else
+      return 255
+    endif
+  else
+    if a:n == 0
+      return 0
+    else
+      return 55 + (a:n * 40)
+    endif
+  endif
+endfun
+
+" Returns the palette index to approximate the given R/G/B colour levels
+fun! s:colour(r, g, b)
+  " Get the closest grey
+  let l:gx = s:grey_number(a:r)
+  let l:gy = s:grey_number(a:g)
+  let l:gz = s:grey_number(a:b)
+
+  " Get the closest colour
+  let l:x = s:rgb_number(a:r)
+  let l:y = s:rgb_number(a:g)
+  let l:z = s:rgb_number(a:b)
+
+  if l:gx == l:gy && l:gy == l:gz
+    " There are two possibilities
+    let l:dgr = s:grey_level(l:gx) - a:r
+    let l:dgg = s:grey_level(l:gy) - a:g
+    let l:dgb = s:grey_level(l:gz) - a:b
+    let l:dgrey = (l:dgr * l:dgr) + (l:dgg * l:dgg) + (l:dgb * l:dgb)
+    let l:dr = s:rgb_level(l:gx) - a:r
+    let l:dg = s:rgb_level(l:gy) - a:g
+    let l:db = s:rgb_level(l:gz) - a:b
+    let l:drgb = (l:dr * l:dr) + (l:dg * l:dg) + (l:db * l:db)
+    if l:dgrey < l:drgb
+      " Use the grey
+      return s:grey_colour(l:gx)
+    else
+      " Use the colour
+      return s:rgb_colour(l:x, l:y, l:z)
+    endif
+  else
+    " Only one possibility
+    return s:rgb_colour(l:x, l:y, l:z)
+  endif
+endfun
+
+function! coc#color#rgb2term(rgb)
+  let l:r = ("0x" . strpart(a:rgb, 0, 2)) + 0
+  let l:g = ("0x" . strpart(a:rgb, 2, 2)) + 0
+  let l:b = ("0x" . strpart(a:rgb, 4, 2)) + 0
+  return s:colour(l:r, l:g, l:b)
+endfun
+
+" [r, g, b] ['255', '255', '255']
+" return ['65535', '65535', '65535'] or return v:false to cancel
+function! coc#color#pick_color(default_color)
+  if has('mac')
+    let default_color = map(a:default_color, {idx, val -> str2nr(val) * 65535 / 255 })
+    " This is the AppleScript magic:
+    let ascrpt = ['-e "tell application \"' . s:app . '\""',
+          \ '-e "' . s:activate . '"',
+          \ "-e \"set AppleScript's text item delimiters to {\\\",\\\"}\"",
+          \ '-e "set theColor to (choose color default color {' . default_color[0] . ", " . default_color[1] . ", " . default_color[2] . '}) as text"',
+          \ '-e "' . s:quit . '"',
+          \ '-e "end tell"',
+          \ '-e "return theColor"']
+    let res = trim(system("osascript " . join(ascrpt, ' ') . " 2>/dev/null"))
+    if empty(res)
+      return v:false
+    else
+      return split(trim(res), ',')
+    endif
+  endif
+
+  let hex_color = printf('#%02x%02x%02x', a:default_color[0], a:default_color[1], a:default_color[2])
+
+  if has('unix')
+    if executable('zenity')
+      let res = trim(system('zenity --title="Select a color" --color-selection --color="' . hex_color . '" 2> /dev/null'))
+      if empty(res)
+        return v:false
+      else
+        " res format is rgb(255,255,255)
+        return map(split(res[4:-2], ','), {idx, val -> string(str2nr(trim(val)) * 65535 / 255)})
+      endif
+    endif
+  endif
+
+  let rgb = v:false
+  if !has('python')
+    echohl Error | echom 'python support required, checkout :echo has(''python'')' | echohl None
+    return
+  endif
+  try
+    execute 'py import gtk'
+  catch /.*/
+    echohl Error | echom 'python gtk module not found' | echohl None
+    return
+  endtry
+python << endpython
+
+import vim
+import gtk, sys
+
+# message strings
+wnd_title_insert = "Insert a color"
+
+csd = gtk.ColorSelectionDialog(wnd_title_insert)
+cs = csd.colorsel
+
+cs.set_current_color(gtk.gdk.color_parse(vim.eval("hex_color")))
+
+cs.set_current_alpha(65535)
+cs.set_has_opacity_control(False)
+# cs.set_has_palette(int(vim.eval("s:display_palette")))
+
+if csd.run()==gtk.RESPONSE_OK:
+    c = cs.get_current_color()
+    s = [str(int(c.red)),',',str(int(c.green)),',',str(int(c.blue))]
+    thecolor = ''.join(s)
+    vim.command(":let rgb = split('%s',',')" % thecolor)
+
+csd.destroy()
+
+endpython
+  return rgb
+endfunction
+

+ 244 - 0
vimfiles/bundle/coc.nvim/autoload/coc/compat.vim

@@ -0,0 +1,244 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+
+" first window id for bufnr
+" builtin bufwinid returns window of current tab only
+function! coc#compat#buf_win_id(bufnr) abort
+  let info = filter(getwininfo(), 'v:val["bufnr"] =='.a:bufnr)
+  if empty(info)
+    return -1
+  endif
+  return info[0]['winid']
+endfunction
+
+function! coc#compat#buf_set_lines(bufnr, start, end, replacement) abort
+  if s:is_vim
+    call coc#api#exec('buf_set_lines', [a:bufnr, a:start, a:end, 0, a:replacement])
+  else
+    call nvim_buf_set_lines(a:bufnr, a:start, a:end, 0, a:replacement)
+  endif
+endfunction
+
+function! coc#compat#buf_line_count(bufnr) abort
+  if exists('*nvim_buf_line_count')
+    return nvim_buf_line_count(a:bufnr)
+  endif
+  if bufnr('%') == a:bufnr
+    return line('$')
+  endif
+  if exists('*getbufinfo')
+    let info = getbufinfo(a:bufnr)
+    if empty(info)
+      return 0
+    endif
+    " vim 8.1 has getbufinfo but no linecount
+    if has_key(info[0], 'linecount')
+      return info[0]['linecount']
+    endif
+  endif
+  if exists('*getbufline')
+    let lines = getbufline(a:bufnr, 1, '$')
+    return len(lines)
+  endif
+  let curr = bufnr('%')
+  execute 'noa buffer '.a:bufnr
+  let n = line('$')
+  execute 'noa buffer '.curr
+  return n
+endfunction
+
+function! coc#compat#prepend_lines(bufnr, replacement) abort
+  if exists('*appendbufline')
+    call appendbufline(a:bufnr, 0, a:replacement)
+  elseif !s:is_vim
+    call nvim_buf_set_lines(a:bufnr, 0, 0, 0, a:replacement)
+  else
+    throw 'appendbufline() required for prepend lines.'
+  endif
+endfunction
+
+function! coc#compat#win_is_valid(winid) abort
+  if exists('*nvim_win_is_valid')
+    return nvim_win_is_valid(a:winid)
+  endif
+  return !empty(getwininfo(a:winid))
+endfunction
+
+" clear matches by window id, not throw on none exists window.
+" may not work on vim < 8.1.1084 & neovim < 0.4.0
+function! coc#compat#clear_matches(winid) abort
+  if !coc#compat#win_is_valid(a:winid)
+    return
+  endif
+  let curr = win_getid()
+  if curr == a:winid
+    call clearmatches()
+    return
+  endif
+  if s:is_vim
+    if has('patch-8.1.1084')
+      call clearmatches(a:winid)
+    endif
+  else
+    if exists('*nvim_set_current_win')
+      noa call nvim_set_current_win(a:winid)
+      call clearmatches()
+      noa call nvim_set_current_win(curr)
+    endif
+  endif
+endfunction
+
+function! coc#compat#matchaddpos(group, pos, priority, winid) abort
+  let curr = win_getid()
+  if curr == a:winid
+    call matchaddpos(a:group, a:pos, a:priority, -1)
+  else
+    if s:is_vim
+      if has('patch-8.1.0218')
+        call matchaddpos(a:group, a:pos, a:priority, -1, {'window': a:winid})
+      endif
+    else
+      if has('nvim-0.4.0')
+        call matchaddpos(a:group, a:pos, a:priority, -1, {'window': a:winid})
+      elseif exists('*nvim_set_current_win')
+        noa call nvim_set_current_win(a:winid)
+        call matchaddpos(a:group, a:pos, a:priority, -1)
+        noa call nvim_set_current_win(curr)
+      endif
+    endif
+  endif
+endfunction
+
+function! coc#compat#buf_del_var(bufnr, name) abort
+  if !bufloaded(a:bufnr)
+    return
+  endif
+  if exists('*nvim_buf_del_var')
+    silent! call nvim_buf_del_var(a:bufnr, a:name)
+  else
+    if a:bufnr == bufnr('%')
+      execute 'unlet! b:'.a:name
+    elseif exists('*win_execute')
+      let winid = coc#compat#buf_win_id(a:bufnr)
+      if winid != -1
+        call win_execute(winid, 'unlet! b:'.a:name)
+      endif
+    endif
+  endif
+endfunction
+
+" hlGroup, pos, priority
+function! coc#compat#matchaddgroups(winid, groups) abort
+  " add by winid
+  if has('patch-8.1.0218') || has('nvim-0.4.0')
+    for group in a:groups
+      call matchaddpos(group['hlGroup'], [group['pos']], group['priority'], -1, {'window': a:winid})
+    endfor
+    return
+  endif
+  let curr = win_getid()
+  if curr == a:winid
+    for group in a:groups
+      call matchaddpos(group['hlGroup'], [group['pos']], group['priority'], -1)
+    endfor
+  elseif exists('*nvim_set_current_win')
+    noa call nvim_set_current_win(a:winid)
+    for group in a:groups
+      call matchaddpos(group['hlGroup'], [group['pos']], group['priority'], -1)
+    endfor
+    noa call nvim_set_current_win(curr)
+  endif
+endfunction
+
+function! coc#compat#del_var(name) abort
+  if exists('*nvim_del_var')
+    silent! call nvim_del_var(a:name)
+  else
+    execute 'unlet! '.a:name
+  endif
+endfunction
+
+" remove keymap for specific buffer
+function! coc#compat#buf_del_keymap(bufnr, mode, lhs) abort
+  if !bufloaded(a:bufnr)
+    return
+  endif
+  if exists('*nvim_buf_del_keymap')
+    try
+      call nvim_buf_del_keymap(a:bufnr, a:mode, a:lhs)
+    catch /^Vim\%((\a\+)\)\=:E5555/
+      " ignore keymap doesn't exist
+    endtry
+    return
+  endif
+  if bufnr == a:bufnr
+    execute 'silent! '.a:mode.'unmap <buffer> '.a:lhs
+    return
+  endif
+  if exists('*win_execute')
+    let winid = coc#compat#buf_win_id(a:bufnr)
+    if winid != -1
+      call win_execute(winid, a:mode.'unmap <buffer> '.a:lhs, 'silent!')
+    endif
+  endif
+endfunction
+
+function! coc#compat#buf_add_keymap(bufnr, mode, lhs, rhs, opts) abort
+  if !bufloaded(a:bufnr)
+    return
+  endif
+  if exists('*nvim_buf_set_keymap')
+    call nvim_buf_set_keymap(a:bufnr, a:mode, a:lhs, a:rhs, a:opts)
+  else
+    let cmd = a:mode . 'noremap '
+    for key in keys(a:opts)
+      if get(a:opts, key, 0)
+        let cmd .= '<'.key.'>'
+      endif
+    endfor
+    let cmd .= '<buffer> '.a:lhs.' '.a:rhs
+    if bufnr('%') == a:bufnr
+      execute cmd
+    elseif exists('*win_execute')
+      let winid = coc#compat#buf_win_id(a:bufnr)
+      if winid != -1
+        call win_execute(winid, cmd)
+      endif
+    endif
+  endif
+endfunction
+
+" execute command or list of commands in window
+function! coc#compat#execute(winid, command, ...) abort
+  if exists('*win_execute')
+    if type(a:command) == v:t_string
+      keepalt call win_execute(a:winid, a:command, get(a:, 1, ''))
+    elseif type(a:command) == v:t_list
+      keepalt call win_execute(a:winid, join(a:command, "\n"), get(a:, 1, ''))
+    endif
+  elseif has('nvim')
+    if !nvim_win_is_valid(a:winid)
+      return
+    endif
+    let curr = nvim_get_current_win()
+    noa keepalt call nvim_set_current_win(a:winid)
+    if type(a:command) == v:t_string
+      exe get(a:, 1, '').' '.a:command
+    elseif type(a:command) == v:t_list
+      for cmd in a:command
+        exe get(a:, 1, '').' '.cmd
+      endfor
+    endif
+    noa keepalt call nvim_set_current_win(curr)
+  else
+    throw 'win_execute does not exist, please upgrade vim.'
+  endif
+endfunc
+
+function! coc#compat#trim(str)
+  if exists('*trim')
+    return trim(a:str)
+  endif
+  " TODO trim from beginning
+  return substitute(a:str, '\s\+$', '', '')
+endfunction

+ 60 - 0
vimfiles/bundle/coc.nvim/autoload/coc/cursor.vim

@@ -0,0 +1,60 @@
+scriptencoding utf-8
+
+" Position of cursor relative to screen cell
+function! coc#cursor#screen_pos() abort
+  let nr = winnr()
+  let [row, col] = win_screenpos(nr)
+  return [row + winline() - 2, col + wincol() - 2]
+endfunction
+
+function! coc#cursor#move_by_col(delta)
+  let pos = getcurpos()
+  call cursor(pos[1], pos[2] + a:delta)
+endfunction
+
+" Get cursor position.
+function! coc#cursor#position()
+  return [line('.') - 1, strchars(strpart(getline('.'), 0, col('.') - 1))]
+endfunction
+
+" Move cursor to position.
+function! coc#cursor#move_to(line, character) abort
+  let content = getline(a:line + 1)
+  let pre = strcharpart(content, 0, a:character)
+  let col = strlen(pre) + 1
+  call cursor(a:line + 1, col)
+endfunction
+
+" Character offset of current cursor, vim provide bytes offset only.
+function! coc#cursor#char_offset() abort
+  let offset = 0
+  let lnum = line('.')
+  for i in range(1, lnum)
+    if i == lnum
+      let offset += strchars(strpart(getline('.'), 0, col('.')-1))
+    else
+      let offset += strchars(getline(i)) + 1
+    endif
+  endfor
+  return offset
+endfunction
+
+" Returns latest selection range
+function! coc#cursor#get_selection(char) abort
+  let m = a:char ? 'char' : visualmode()
+  if empty(m)
+    return v:null
+  endif
+  let [_, sl, sc, soff] = getpos(m ==# 'char' ? "'[" : "'<")
+  let [_, el, ec, eoff] = getpos(m ==# 'char' ? "']" : "'>")
+  let start_idx = coc#string#get_character(getline(sl), sc)
+  if m ==# 'V'
+    return [sl - 1, start_idx, el, 0]
+  endif
+  let line = getline(el)
+  let end_idx = coc#string#get_character(line, ec)
+  if m !=# 'char'
+    let end_idx = end_idx == strchars(line) ? end_idx : end_idx + 1
+  endif
+  return [sl - 1, start_idx, el - 1, end_idx]
+endfunction

+ 684 - 0
vimfiles/bundle/coc.nvim/autoload/coc/dialog.vim

@@ -0,0 +1,684 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:root = expand('<sfile>:h:h:h')
+let s:prompt_win_bufnr = 0
+let s:list_win_bufnr = 0
+let s:prompt_win_width = get(g:, 'coc_prompt_win_width', 32)
+let s:frames = ['·  ', '·· ', '···', ' ··', '  ·', '   ']
+let s:sign_group = 'PopUpCocDialog'
+let s:detail_bufnr = 0
+
+" Float window aside pum
+function! coc#dialog#create_pum_float(lines, config) abort
+  let winid = coc#float#get_float_by_kind('pumdetail')
+  if empty(a:lines) || !coc#pum#visible()
+    if winid
+      call coc#float#close(winid)
+    endif
+    return
+  endif
+  let pumbounding = coc#pum#info()
+  let border = get(a:config, 'border', [])
+  let pw = pumbounding['width'] + (empty(border) ? get(pumbounding, 'scrollbar', 0) : 0)
+  let rp = &columns - pumbounding['col'] - pw
+  let showRight = pumbounding['col'] > rp ? 0 : 1
+  let maxWidth = showRight ? coc#math#min(rp - 1, a:config['maxWidth']) : coc#math#min(pumbounding['col'] - 1, a:config['maxWidth'])
+  let bh = get(border, 0 ,0) + get(border, 2, 0)
+  let maxHeight = &lines - pumbounding['row'] - &cmdheight - 1 - bh
+  if maxWidth <= 2 || maxHeight < 1
+    return v:null
+  endif
+  let width = 0
+  for line in a:lines
+    let dw = max([1, strdisplaywidth(line)])
+    let width = max([width, dw + 2])
+  endfor
+  let width = float2nr(coc#math#min(maxWidth, width))
+  let ch = coc#string#content_height(a:lines, width - 2)
+  let height = float2nr(coc#math#min(maxHeight, ch))
+  let lines = map(a:lines, {_, s -> s =~# '^─' ? repeat('─', width - 2 + (s:is_vim && ch > height ? -1 : 0)) : s})
+  let opts = {
+        \ 'lines': lines,
+        \ 'highlights': get(a:config, 'highlights', []),
+        \ 'relative': 'editor',
+        \ 'col': showRight ? pumbounding['col'] + pw : pumbounding['col'] - width,
+        \ 'row': pumbounding['row'],
+        \ 'height': height,
+        \ 'width': width - 2 + (s:is_vim && ch > height ? -1 : 0),
+        \ 'scrollinside': showRight ? 0 : 1,
+        \ 'codes': get(a:config, 'codes', []),
+        \ }
+  for key in ['border', 'highlight', 'borderhighlight', 'winblend', 'focusable', 'shadow', 'rounded']
+    if has_key(a:config, key)
+      let opts[key] = a:config[key]
+    endif
+  endfor
+  call s:close_auto_hide_wins(winid)
+  let result = coc#float#create_float_win(winid, s:detail_bufnr, opts)
+  if empty(result)
+    return
+  endif
+  let s:detail_bufnr = result[1]
+  call setwinvar(result[0], 'kind', 'pumdetail')
+  if !s:is_vim
+    call coc#float#nvim_scrollbar(result[0])
+  endif
+endfunction
+
+" Float window below/above cursor
+function! coc#dialog#create_cursor_float(winid, bufnr, lines, config) abort
+  if coc#prompt#activated()
+    return v:null
+  endif
+  let pumAlignTop = get(a:config, 'pumAlignTop', 0)
+  let modes = get(a:config, 'modes', ['n', 'i', 'ic', 's'])
+  let mode = mode()
+  let currbuf = bufnr('%')
+  let pos = [line('.'), col('.')]
+  if index(modes, mode) == -1
+    return v:null
+  endif
+  if !s:is_vim && !has('nvim-0.5.0') && mode ==# 'i'
+    " helps to fix undo issue, don't know why.
+    call feedkeys("\<C-g>u", 'n')
+  endif
+  if mode ==# 's' && has('patch-8.2.4969') && !has('patch-8.2.4996')
+    echohl WarningMsg | echon 'Popup not created to avoid issue #10466 on vim >= 8.2.4969' | echohl None
+    return v:null
+  endif
+  let dimension = coc#dialog#get_config_cursor(a:lines, a:config)
+  if empty(dimension)
+    return v:null
+  endif
+  if coc#pum#visible() && ((pumAlignTop && dimension['row'] <0)|| (!pumAlignTop && dimension['row'] > 0))
+    return v:null
+  endif
+  let width = dimension['width']
+  let lines = map(a:lines, {_, s -> s =~# '^─' ? repeat('─', width) : s})
+  let config = extend(extend({'lines': lines, 'relative': 'cursor'}, a:config), dimension)
+  call s:close_auto_hide_wins(a:winid)
+  let res = coc#float#create_float_win(a:winid, a:bufnr, config)
+  if empty(res)
+    return v:null
+  endif
+  let alignTop = dimension['row'] < 0
+  let winid = res[0]
+  let bufnr = res[1]
+  redraw
+  if has('nvim')
+    call coc#float#nvim_scrollbar(winid)
+  endif
+  return [currbuf, pos, winid, bufnr, alignTop]
+endfunction
+
+" Create float window for input
+function! coc#dialog#create_prompt_win(title, default, opts) abort
+  call s:close_auto_hide_wins()
+  let bufnr = has('nvim') ? s:prompt_win_bufnr : 0
+  if s:is_vim
+    execute 'hi link CocPopupTerminal '.get(a:opts, 'highlight', 'CocFloating')
+    let node =  expand(get(g:, 'coc_node_path', 'node'))
+    let bufnr = term_start([node, s:root . '/bin/prompt.js', a:default], {
+          \ 'term_rows': 1,
+          \ 'term_highlight': 'CocPopupTerminal',
+          \ 'hidden': 1,
+          \ 'term_finish': 'close'
+          \ })
+    call term_setapi(bufnr, 'Coc')
+    call setbufvar(bufnr, 'current', type(a:default) == v:t_string ? a:default : '')
+  endif
+  let config = s:get_prompt_dimension(a:title, a:default, a:opts)
+  let res = coc#float#create_float_win(0, bufnr, extend(config, {
+        \ 'style': 'minimal',
+        \ 'border': get(a:opts, 'border', [1,1,1,1]),
+        \ 'rounded': get(a:opts, 'rounded', 1),
+        \ 'prompt': 1,
+        \ 'title': a:title,
+        \ 'lines': s:is_vim ? v:null : [a:default],
+        \ 'highlight': get(a:opts, 'highlight', 'CocFloating'),
+        \ 'borderhighlight': [get(a:opts, 'borderhighlight', 'CocFloating')],
+        \ }))
+  if empty(res)
+    return
+  endif
+  let winid = res[0]
+  let bufnr = res[1]
+  if has('nvim')
+    let s:prompt_win_bufnr = res[1]
+    execute 'sign unplace 6 buffer='.s:prompt_win_bufnr
+    call nvim_set_current_win(winid)
+    inoremap <buffer> <C-a> <Home>
+    inoremap <buffer><expr><C-e> pumvisible() ? "\<C-e>" : "\<End>"
+    exe 'imap <silent><nowait><buffer> <esc> <esc><esc>'
+    exe 'nnoremap <silent><buffer> <esc> :call coc#float#close('.winid.')<CR>'
+    exe 'inoremap <silent><expr><nowait><buffer> <cr> "\<C-r>=coc#dialog#prompt_insert(getline(''.''))\<cr>\<esc>"'
+    if get(a:opts, 'list', 0)
+      for key in ['<C-j>', '<C-k>', '<C-n>', '<C-p>', '<up>', '<down>', '<C-f>', '<C-b>', '<C-space>']
+        " Can't use < in remap
+        let escaped = key ==# '<C-space>' ? "C-@" : strcharpart(key, 1, strchars(key) - 2)
+        exe 'inoremap <nowait><buffer> '.key.' <Cmd>call coc#rpc#notify("PromptKeyPress", ['.bufnr.', "'.escaped.'"])<CR>'
+      endfor
+    endif
+    call feedkeys('A', 'in')
+  endif
+  call coc#util#do_autocmd('CocOpenFloatPrompt')
+  if s:is_vim
+    let pos = popup_getpos(winid)
+    " width height row col
+    let dimension = [pos['width'], pos['height'], pos['line'] - 1, pos['col'] - 1]
+  else
+    let id = coc#float#get_related(winid, 'border')
+    if !has('nvim-0.6.0')
+      redraw
+    endif
+    let pos = nvim_win_get_position(id)
+    let dimension = [nvim_win_get_width(id), nvim_win_get_height(id), pos[0], pos[1]]
+  endif
+  return [bufnr, winid, dimension]
+endfunction
+
+" Create list window under target window
+function! coc#dialog#create_list(target, dimension, opts) abort
+  let maxHeight = get(a:opts, 'maxHeight', 10)
+  let height = max([1, len(get(a:opts, 'lines', []))])
+  let height = min([maxHeight, height, &lines - &cmdheight - 1 - a:dimension['row'] + a:dimension['height']])
+  let chars = get(a:opts, 'rounded', 1) ? ['╯', '╰'] : ['┘', '└']
+  let config = extend(copy(a:opts), {
+      \ 'relative': 'editor',
+      \ 'row': a:dimension['row'] + a:dimension['height'],
+      \ 'col': a:dimension['col'],
+      \ 'width': a:dimension['width'] - 2,
+      \ 'height': height,
+      \ 'border': [1, 1, 1, 1],
+      \ 'scrollinside': 1,
+      \ 'borderchars': extend(['─', '│', '─', '│', '├', '┤'], chars)
+      \ })
+  let bufnr = 0
+  let result = coc#float#create_float_win(0, s:list_win_bufnr, config)
+  if empty(result)
+    return
+  endif
+  let winid = result[0]
+  call coc#float#add_related(winid, a:target)
+  call setwinvar(winid, 'auto_height', get(a:opts, 'autoHeight', 1))
+  call setwinvar(winid, 'max_height', maxHeight)
+  call setwinvar(winid, 'target_winid', a:target)
+  call setwinvar(winid, 'kind', 'list')
+  call coc#dialog#check_scroll_vim(a:target)
+  return result
+endfunction
+
+" Create menu picker for pick single item
+function! coc#dialog#create_menu(lines, config) abort
+  call s:close_auto_hide_wins()
+  let highlight = get(a:config, 'highlight', 'CocFloating')
+  let borderhighlight = get(a:config, 'borderhighlight', [highlight])
+  let relative = get(a:config, 'relative', 'cursor')
+  let lines = copy(a:lines)
+  let content = get(a:config, 'content', '')
+  let maxWidth = get(a:config, 'maxWidth', 80)
+  let highlights = get(a:config, 'highlights', [])
+  let contentCount = 0
+  if !empty(content)
+    let contentLines = coc#string#reflow(split(content, '\r\?\n'), maxWidth)
+    let contentCount = len(contentLines)
+    let lines = extend(contentLines, lines)
+    if !empty(highlights)
+      for item in highlights
+        let item['lnum'] = item['lnum'] + contentCount
+      endfor
+    endif
+  endif
+  let opts = {
+    \ 'lines': lines,
+    \ 'highlight': highlight,
+    \ 'title': get(a:config, 'title', ''),
+    \ 'borderhighlight': borderhighlight,
+    \ 'maxWidth': maxWidth,
+    \ 'maxHeight': get(a:config, 'maxHeight', 80),
+    \ 'rounded': get(a:config, 'rounded', 0),
+    \ 'border': [1, 1, 1, 1],
+    \ 'highlights': highlights,
+    \ 'relative': relative,
+    \ }
+  if relative ==# 'editor'
+    let dimension = coc#dialog#get_config_editor(lines, opts)
+  else
+    let dimension = coc#dialog#get_config_cursor(lines, opts)
+  endif
+  call extend(opts, dimension)
+  let ids = coc#float#create_float_win(0, s:prompt_win_bufnr, opts)
+  if empty(ids)
+    return
+  endif
+  let s:prompt_win_bufnr = ids[1]
+  call coc#dialog#set_cursor(ids[0], ids[1], contentCount + 1)
+  redraw
+  if has('nvim')
+    call coc#float#nvim_scrollbar(ids[0])
+  endif
+  return [ids[0], ids[1], contentCount]
+endfunction
+
+" Create dialog at center of screen
+function! coc#dialog#create_dialog(lines, config) abort
+  call s:close_auto_hide_wins()
+  " dialog always have borders
+  let title = get(a:config, 'title', '')
+  let buttons = get(a:config, 'buttons', [])
+  let highlight = get(a:config, 'highlight', 'CocFloating')
+  let borderhighlight = get(a:config, 'borderhighlight', [highlight])
+  let opts = {
+    \ 'title': title,
+    \ 'rounded': get(a:config, 'rounded', 0),
+    \ 'relative': 'editor',
+    \ 'border': [1,1,1,1],
+    \ 'close': get(a:config, 'close', 1),
+    \ 'highlight': highlight,
+    \ 'highlights': get(a:config, 'highlights', []),
+    \ 'buttons': buttons,
+    \ 'borderhighlight': borderhighlight,
+    \ 'getchar': get(a:config, 'getchar', 0)
+    \ }
+  call extend(opts, coc#dialog#get_config_editor(a:lines, a:config))
+  let bufnr = coc#float#create_buf(0, a:lines)
+  let res =  coc#float#create_float_win(0, bufnr, opts)
+  if empty(res)
+    return
+  endif
+  if get(a:config, 'cursorline', 0)
+    call coc#dialog#place_sign(bufnr, 1)
+  endif
+  if has('nvim')
+    redraw
+    call coc#float#nvim_scrollbar(res[0])
+  endif
+  return res
+endfunction
+
+function! coc#dialog#prompt_confirm(title, cb) abort
+  call s:close_auto_hide_wins()
+  if s:is_vim && exists('*popup_dialog')
+    try
+      call popup_dialog(a:title. ' (y/n)?', {
+        \ 'highlight': 'Normal',
+        \ 'filter': 'popup_filter_yesno',
+        \ 'callback': {id, res -> a:cb(v:null, res)},
+        \ 'borderchars': get(g:, 'coc_borderchars', ['─', '│', '─', '│', '╭', '╮', '╯', '╰']),
+        \ 'borderhighlight': ['MoreMsg']
+        \ })
+    catch /.*/
+      call a:cb(v:exception)
+    endtry
+    return
+  endif
+  if has('nvim-0.4.0')
+    let text = ' '. a:title . ' (y/n)? '
+    let maxWidth = coc#math#min(78, &columns - 2)
+    let width = coc#math#min(maxWidth, strdisplaywidth(text))
+    let maxHeight = &lines - &cmdheight - 1
+    let height = coc#math#min(maxHeight, float2nr(ceil(str2float(string(strdisplaywidth(text)))/width)))
+    let arr =  coc#float#create_float_win(0, s:prompt_win_bufnr, {
+          \ 'col': &columns/2 - width/2 - 1,
+          \ 'row': maxHeight/2 - height/2 - 1,
+          \ 'width': width,
+          \ 'height': height,
+          \ 'border': [1,1,1,1],
+          \ 'focusable': v:false,
+          \ 'relative': 'editor',
+          \ 'highlight': 'Normal',
+          \ 'borderhighlight': 'MoreMsg',
+          \ 'style': 'minimal',
+          \ 'lines': [text],
+          \ })
+    if empty(arr)
+      call a:cb('Window create failed!')
+      return
+    endif
+    let winid = arr[0]
+    let s:prompt_win_bufnr = arr[1]
+    let res = 0
+    redraw
+    " same result as vim
+    while 1
+      let key = nr2char(getchar())
+      if key == "\<C-c>"
+        let res = -1
+        break
+      elseif key == "\<esc>" || key == 'n' || key == 'N'
+        let res = 0
+        break
+      elseif key == 'y' || key == 'Y'
+        let res = 1
+        break
+      endif
+    endw
+    call coc#float#close(winid)
+    call a:cb(v:null, res)
+    " use relative editor since neovim doesn't support center position
+  elseif exists('*confirm')
+    let choice = confirm(a:title, "&Yes\n&No")
+    call a:cb(v:null, choice == 1)
+  else
+    echohl MoreMsg
+    echom a:title.' (y/n)'
+    echohl None
+    let confirm = nr2char(getchar())
+    redraw!
+    if !(confirm ==? "y" || confirm ==? "\r")
+      echohl Moremsg | echo 'Cancelled.' | echohl None
+      return 0
+      call a:cb(v:null, 0)
+    end
+    call a:cb(v:null, 1)
+  endif
+endfunction
+
+function! coc#dialog#get_config_editor(lines, config) abort
+  let title = get(a:config, 'title', '')
+  let maxheight = min([get(a:config, 'maxHeight', 78), &lines - &cmdheight - 6])
+  let maxwidth = min([get(a:config, 'maxWidth', 78), &columns - 2])
+  let buttons = get(a:config, 'buttons', [])
+  let minwidth = s:min_btns_width(buttons)
+  if maxheight <= 0 || maxwidth <= 0 || minwidth > maxwidth
+    throw 'Not enough spaces for float window'
+  endif
+  let ch = 0
+  let width = min([strdisplaywidth(title) + 1, maxwidth])
+  for line in a:lines
+    let dw = max([1, strdisplaywidth(line)])
+    if dw < maxwidth && dw > width
+      let width = dw
+    elseif dw >= maxwidth
+      let width = maxwidth
+    endif
+    let ch += float2nr(ceil(str2float(string(dw))/maxwidth))
+  endfor
+  let width = max([minwidth, width])
+  let height = coc#math#min(ch ,maxheight)
+  return {
+      \ 'row': &lines/2 - (height + 4)/2,
+      \ 'col': &columns/2 - (width + 2)/2,
+      \ 'width': width,
+      \ 'height': height,
+      \ }
+endfunction
+
+function! coc#dialog#prompt_insert(text) abort
+  call coc#rpc#notify('PromptInsert', [a:text, bufnr('%')])
+  return ''
+endfunction
+
+" Dimension of window with lines relative to cursor
+" Width & height excludes border & padding
+function! coc#dialog#get_config_cursor(lines, config) abort
+  let preferTop = get(a:config, 'preferTop', 0)
+  let title = get(a:config, 'title', '')
+  let border = get(a:config, 'border', [])
+  if empty(border) && len(title)
+    let border = [1, 1, 1, 1]
+  endif
+  let bh = get(border, 0, 0) + get(border, 2, 0)
+  let vh = &lines - &cmdheight - 1
+  if vh <= 0
+    return v:null
+  endif
+  let maxWidth = coc#math#min(get(a:config, 'maxWidth', &columns - 1), &columns - 1)
+  if maxWidth < 3
+    return v:null
+  endif
+  let maxHeight = coc#math#min(get(a:config, 'maxHeight', vh), vh)
+  let width = coc#math#min(40, strdisplaywidth(title)) + 3
+  for line in a:lines
+    let dw = max([1, strdisplaywidth(line)])
+    let width = max([width, dw + 2])
+  endfor
+  let width = coc#math#min(maxWidth, width)
+  let ch = coc#string#content_height(a:lines, width - 2)
+  let [lineIdx, colIdx] = coc#cursor#screen_pos()
+  " How much we should move left
+  let offsetX = coc#math#min(get(a:config, 'offsetX', 0), colIdx)
+  let showTop = 0
+  let hb = vh - lineIdx -1
+  if lineIdx > bh + 2 && (preferTop || (lineIdx > hb && hb < ch + bh))
+    let showTop = 1
+  endif
+  let height = coc#math#min(maxHeight, ch + bh, showTop ? lineIdx - 1 : hb)
+  if height <= bh
+    return v:null
+  endif
+  let col = - max([offsetX, colIdx - (&columns - 1 - width)])
+  let row = showTop ? - height + bh : 1
+  return {
+        \ 'row': row,
+        \ 'col': col,
+        \ 'width': width - 2,
+        \ 'height': height - bh
+        \ }
+endfunction
+
+function! coc#dialog#change_border_hl(winid, hlgroup) abort
+  if !hlexists(a:hlgroup)
+    return
+  endif
+  if s:is_vim
+    if coc#float#valid(a:winid)
+      call popup_setoptions(a:winid, {'borderhighlight': repeat([a:hlgroup], 4)})
+      redraw
+    endif
+  else
+    let winid = coc#float#get_related(a:winid, 'border')
+    if winid > 0
+      call setwinvar(winid, '&winhl', 'Normal:'.a:hlgroup.',NormalNC:'.a:hlgroup)
+    endif
+  endif
+endfunction
+
+function! coc#dialog#change_title(winid, title) abort
+  if s:is_vim
+    if coc#float#valid(a:winid)
+      call popup_setoptions(a:winid, {'title': a:title})
+      redraw
+    endif
+  else
+    let winid = coc#float#get_related(a:winid, 'border')
+    if winid > 0
+      let bufnr = winbufnr(winid)
+      let line = getbufline(bufnr, 1)[0]
+      let top = strcharpart(line, 0, 1)
+            \.repeat('─', strchars(line) - 2)
+            \.strcharpart(line, strchars(line) - 1, 1)
+      if !empty(a:title)
+        let top = coc#string#compose(top, 1, a:title.' ')
+      endif
+      call nvim_buf_set_lines(bufnr, 0, 1, v:false, [top])
+    endif
+  endif
+endfunction
+
+function! coc#dialog#change_loading(winid, loading) abort
+  if coc#float#valid(a:winid)
+    let winid = coc#float#get_related(a:winid, 'loading')
+    if !a:loading && winid > 0
+      call coc#float#close(winid)
+    endif
+    if a:loading && winid == 0
+      let bufnr = s:create_loading_buf()
+      if s:is_vim
+        let pos = popup_getpos(a:winid)
+        let winid = popup_create(bufnr, {
+            \ 'line': pos['line'] + 1,
+            \ 'col': pos['col'] + pos['width'] - 4,
+            \ 'maxheight': 1,
+            \ 'maxwidth': 3,
+            \ 'zindex': 999,
+            \ 'highlight': get(popup_getoptions(a:winid), 'highlight', 'CocFloating')
+            \ })
+      else
+        let pos = nvim_win_get_position(a:winid)
+        let width = nvim_win_get_width(a:winid)
+        let opts = {
+            \ 'relative': 'editor',
+            \ 'row': pos[0],
+            \ 'col': pos[1] + width - 3,
+            \ 'focusable': v:false,
+            \ 'width': 3,
+            \ 'height': 1,
+            \ 'style': 'minimal',
+            \ }
+        if has('nvim-0.5.1')
+          let opts['zindex'] = 900
+        endif
+        let winid = nvim_open_win(bufnr, v:false, opts)
+        call setwinvar(winid, '&winhl', getwinvar(a:winid, '&winhl'))
+      endif
+      call setwinvar(winid, 'kind', 'loading')
+      call setbufvar(bufnr, 'target_winid', a:winid)
+      call setbufvar(bufnr, 'popup', winid)
+      call coc#float#add_related(winid, a:winid)
+    endif
+  endif
+endfunction
+
+" Update list with new lines and highlights
+function! coc#dialog#update_list(winid, bufnr, lines, highlights) abort
+  if coc#window#tabnr(a:winid) == tabpagenr()
+    if getwinvar(a:winid, 'auto_height', 0)
+      let row = coc#float#get_row(a:winid)
+      " core height
+      let height = max([1, len(copy(a:lines))])
+      let height = min([getwinvar(a:winid, 'max_height', 10), height, &lines - &cmdheight - 1 - row])
+      let curr = s:is_vim ? popup_getpos(a:winid)['core_height'] : nvim_win_get_height(a:winid)
+      let delta = height - curr
+      if delta != 0
+        call coc#float#change_height(a:winid, delta)
+      endif
+    endif
+    call coc#compat#buf_set_lines(a:bufnr, 0, -1, a:lines)
+    call coc#highlight#add_highlights(a:winid, [], a:highlights)
+    if s:is_vim
+      let target = getwinvar(a:winid, 'target_winid', -1)
+      if target != -1
+        call coc#dialog#check_scroll_vim(target)
+      endif
+      call win_execute(a:winid, 'exe 1')
+    endif
+  endif
+endfunction
+
+" Fix width of prompt window same as list window on scrollbar change
+function! coc#dialog#check_scroll_vim(winid) abort
+  if s:is_vim && coc#float#valid(a:winid)
+    let winid = coc#float#get_related(a:winid, 'list')
+    if winid
+      redraw
+      let pos = popup_getpos(winid)
+      let width = pos['width'] + (pos['scrollbar'] ? 1 : 0)
+      if width != popup_getpos(a:winid)['width']
+        call popup_move(a:winid, {
+            \ 'minwidth': width - 2,
+            \ 'maxwidth': width - 2,
+            \ })
+      endif
+    endif
+  endif
+endfunction
+
+function! coc#dialog#set_cursor(winid, bufnr, line) abort
+  if s:is_vim
+    call coc#compat#execute(a:winid, 'exe '.a:line, 'silent!')
+    call popup_setoptions(a:winid, {'cursorline' : 1})
+    call popup_setoptions(a:winid, {'cursorline' : 0})
+  else
+    call nvim_win_set_cursor(a:winid, [a:line, 0])
+  endif
+  call coc#dialog#place_sign(a:bufnr, a:line)
+endfunction
+
+function! coc#dialog#place_sign(bufnr, line) abort
+  call sign_unplace(s:sign_group, { 'buffer': a:bufnr })
+  if a:line > 0
+    call sign_place(6, s:sign_group, 'CocCurrentLine', a:bufnr, {'lnum': a:line})
+  endif
+endfunction
+
+" Could be center(with optional marginTop) or cursor
+function! s:get_prompt_dimension(title, default, opts) abort
+  let relative = get(a:opts, 'position', 'cursor') ==# 'cursor' ? 'cursor' : 'editor'
+  let curr = win_screenpos(winnr())[1] + wincol() - 2
+  let minWidth = get(a:opts, 'minWidth', s:prompt_win_width)
+  let width = min([max([strwidth(a:default) + 2, strwidth(a:title) + 2, minWidth]), &columns - 2])
+  if get(a:opts, 'maxWidth', 0)
+    let width = min([width, a:opts['maxWidth']])
+  endif
+  if relative ==# 'cursor'
+    let [lineIdx, colIdx] = coc#cursor#screen_pos()
+    if width == &columns - 2
+      let col = 0 - curr
+    else
+      let col = curr + width <= &columns - 2 ? 0 : curr + width - &columns + 2
+    endif
+    let config = {
+        \ 'row': lineIdx == 0 ? 1 : 0,
+        \ 'col': colIdx == 0 ? 0 : col - 1,
+        \ }
+  else
+    let marginTop = get(a:opts, 'marginTop', v:null)
+    if marginTop is v:null
+      let row = (&lines - &cmdheight - 2) / 2
+    else
+      let row = marginTop < 2 ? 1 : min([marginTop, &columns - &cmdheight])
+    endif
+    let config = {
+          \ 'col': float2nr((&columns - width) / 2),
+          \ 'row': row - s:is_vim,
+          \ }
+  endif
+  return extend(config, {'relative': relative, 'width': width, 'height': 1})
+endfunction
+
+function! s:min_btns_width(buttons) abort
+  if empty(a:buttons)
+    return 0
+  endif
+  let minwidth = len(a:buttons)*3 - 1
+  for txt in a:buttons
+    let minwidth = minwidth + strdisplaywidth(txt)
+  endfor
+  return minwidth
+endfunction
+
+" Close windows that should auto hide
+function! s:close_auto_hide_wins(...) abort
+  let winids = coc#float#get_float_win_list()
+  let except = get(a:, 1, 0)
+  for id in winids
+    if except && id == except
+      continue
+    endif
+    if coc#window#get_var(id, 'autohide', 0)
+      call coc#float#close(id)
+    endif
+  endfor
+endfunction
+
+function! s:create_loading_buf() abort
+  let bufnr = coc#float#create_buf(0)
+  call s:change_loading_buf(bufnr, 0)
+  return bufnr
+endfunction
+
+function! s:change_loading_buf(bufnr, idx) abort
+  if bufloaded(a:bufnr)
+    let target = getbufvar(a:bufnr, 'target_winid', v:null)
+    if !empty(target) && !coc#float#valid(target)
+      call coc#float#close(getbufvar(a:bufnr, 'popup'))
+      return
+    endif
+    let line = get(s:frames, a:idx, '   ')
+    call setbufline(a:bufnr, 1, line)
+    call coc#highlight#add_highlight(a:bufnr, -1, 'CocNotificationProgress', 0, 0, -1)
+    let idx = a:idx == len(s:frames) - 1 ? 0 : a:idx + 1
+    call timer_start(100, { -> s:change_loading_buf(a:bufnr, idx)})
+  endif
+endfunction

+ 32 - 0
vimfiles/bundle/coc.nvim/autoload/coc/dict.vim

@@ -0,0 +1,32 @@
+scriptencoding utf-8
+
+function! coc#dict#equal(one, two) abort
+  for key in keys(a:one)
+    if a:one[key] != a:two[key]
+      return 0
+    endif
+  endfor
+  return 1
+endfunction
+
+" Return new dict with keys removed
+function! coc#dict#omit(dict, keys) abort
+  let res = {}
+  for key in keys(a:dict)
+    if index(a:keys, key) == -1
+      let res[key] = a:dict[key]
+    endif
+  endfor
+  return res
+endfunction
+
+" Return new dict with keys only
+function! coc#dict#pick(dict, keys) abort
+  let res = {}
+  for key in keys(a:dict)
+    if index(a:keys, key) != -1
+      let res[key] = a:dict[key]
+    endif
+  endfor
+  return res
+endfunction

+ 1423 - 0
vimfiles/bundle/coc.nvim/autoload/coc/float.vim

@@ -0,0 +1,1423 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:borderchars = get(g:, 'coc_borderchars', ['─', '│', '─', '│', '┌', '┐', '┘', '└'])
+let s:rounded_borderchars = s:borderchars[0:3] + ['╭', '╮', '╯', '╰']
+let s:borderjoinchars = get(g:, 'coc_border_joinchars', ['┬', '┤', '┴', '├'])
+let s:popup_list_api = exists('*popup_list')
+" Popup ids, used when popup_list() doesn't exist
+let s:popup_list = []
+let s:pad_bufnr = -1
+
+" Check visible float/popup exists.
+function! coc#float#has_float(...) abort
+  return len(coc#float#get_float_win_list(get(a:, 1, 0))) > 0
+endfunction
+
+function! coc#float#close_all(...) abort
+  let winids = coc#float#get_float_win_list(get(a:, 1, 0))
+  for id in winids
+    try
+      call coc#float#close(id)
+    catch /E5555:/
+      " ignore
+    endtry
+  endfor
+endfunction
+
+function! coc#float#jump() abort
+  if has('nvim')
+    let winids = coc#float#get_float_win_list()
+    if !empty(winids)
+      call win_gotoid(winids[0])
+    endif
+  endif
+endfunction
+
+function! coc#float#valid(winid) abort
+  if a:winid <= 0
+    return 0
+  endif
+  if !s:is_vim
+    if !nvim_win_is_valid(a:winid)
+      return 0
+    endif
+    return !empty(nvim_win_get_config(a:winid)['relative'])
+  endif
+  try
+    return !empty(popup_getpos(a:winid))
+  catch /^Vim\%((\a\+)\)\=:E993/
+    " not a popup window
+    return 0
+  endtry
+endfunction
+
+function! coc#float#get_height(winid) abort
+  if !s:is_vim
+    let borderwin = coc#float#get_related(a:winid, 'border')
+    if borderwin
+      return nvim_win_get_height(borderwin)
+    endif
+    return nvim_win_get_height(a:winid)
+  endif
+  return get(popup_getpos(a:winid), 'height', 0)
+endfunction
+
+function! coc#float#change_height(winid, delta) abort
+  if s:is_vim
+    let curr = get(popup_getpos(a:winid), 'core_height', v:null)
+    if curr isnot v:null
+      call popup_move(a:winid, {
+          \ 'maxheight': max([1, curr + a:delta]),
+          \ 'minheight': max([1, curr + a:delta]),
+          \ })
+    endif
+  else
+    let winids = copy(coc#window#get_var(a:winid, 'related', []))
+    call filter(winids, 'index(["border","pad","scrollbar"],coc#window#get_var(v:val,"kind","")) >= 0')
+    call add(winids, a:winid)
+    for winid in winids
+      if coc#window#get_var(winid, 'kind', '') ==# 'border'
+        let bufnr = winbufnr(winid)
+        if a:delta > 0
+          call appendbufline(bufnr, 1, repeat(getbufline(bufnr, 2), a:delta))
+        else
+          call deletebufline(bufnr, 2, 2 - a:delta - 1)
+        endif
+      endif
+      let height = nvim_win_get_height(winid)
+      call nvim_win_set_height(winid, max([1, height + a:delta]))
+    endfor
+  endif
+endfunction
+
+" create or config float window, returns [winid, bufnr], config including:
+" - relative:  could be 'editor' 'cursor'
+" - row: line count relative to editor/cursor, nagetive number means abover cursor.
+" - col: column count relative to editor/cursor, nagetive number means left of cursor.
+" - width: content width without border and title.
+" - height: content height without border and title.
+" - lines: (optional) lines to insert, default to v:null.
+" - title: (optional) title.
+" - border: (optional) border as number list, like [1, 1, 1 ,1].
+" - cursorline: (optional) enable cursorline when is 1.
+" - autohide: (optional) window should be closed on CursorMoved when is 1.
+" - highlight: (optional) highlight of window, default to 'CocFloating'
+" - borderhighlight: (optional) should be array or string for border highlights,
+"   highlight all borders with first value.
+" - close: (optional) show close button when is 1.
+" - highlights: (optional) highlight items.
+" - buttons: (optional) array of button text for create buttons at bottom.
+" - codes: (optional) list of CodeBlock.
+" - winblend: (optional) winblend option for float window, neovim only.
+" - shadow:  (optional) use shadow as border style, neovim only.
+" - focusable:  (optional) neovim only, default to true.
+" - scrollinside: (optional) neovim only, create scrollbar inside window.
+" - rounded: (optional) use rounded borderchars, ignored when borderchars exists.
+" - borderchars: (optional) borderchars, should be length of 8
+" - nopad: (optional) not add pad when 1
+" - index: (optional) line index
+function! coc#float#create_float_win(winid, bufnr, config) abort
+  let lines = get(a:config, 'lines', v:null)
+  let bufnr = a:bufnr
+  try
+    let bufnr = coc#float#create_buf(a:bufnr, lines, 'hide')
+  catch /E523:/
+    " happens when using getchar() #3921
+    return []
+  endtry
+  let lnum = max([1, get(a:config, 'index', 0) + 1])
+  " use exists
+  if a:winid && coc#float#valid(a:winid)
+    if s:is_vim
+      let [line, col] = s:popup_position(a:config)
+      let opts = {
+            \ 'firstline': 1,
+            \ 'line': line,
+            \ 'col': col,
+            \ 'minwidth': a:config['width'],
+            \ 'minheight': a:config['height'],
+            \ 'maxwidth': a:config['width'],
+            \ 'maxheight': a:config['height'],
+            \ 'title': get(a:config, 'title', ''),
+            \ 'highlight': get(a:config, 'highlight', 'CocFloating'),
+            \ 'borderhighlight':  [s:get_borderhighlight(a:config)],
+            \ }
+      if !s:empty_border(get(a:config, 'border', []))
+        let opts['border'] = a:config['border']
+      endif
+      call popup_setoptions(a:winid, opts)
+      call win_execute(a:winid, 'exe '.lnum)
+      call coc#float#vim_buttons(a:winid, a:config)
+      call s:add_highlights(a:winid, a:config, 0)
+      return [a:winid, winbufnr(a:winid)]
+    else
+      let config = s:convert_config_nvim(a:config, 0)
+      let hlgroup = get(a:config, 'highlight', 'CocFloating')
+      let winhl = 'Normal:'.hlgroup.',NormalNC:'.hlgroup.',FoldColumn:'.hlgroup
+      if winhl !=# getwinvar(a:winid, '&winhl', '')
+        call setwinvar(a:winid, '&winhl', winhl)
+      endif
+      call nvim_win_set_buf(a:winid, bufnr)
+      call nvim_win_set_config(a:winid, config)
+      call nvim_win_set_cursor(a:winid, [lnum, 0])
+      call coc#float#nvim_create_related(a:winid, config, a:config)
+      call s:add_highlights(a:winid, a:config, 0)
+      return [a:winid, bufnr]
+    endif
+  endif
+  let winid = 0
+  if s:is_vim
+    let [line, col] = s:popup_position(a:config)
+    let title = get(a:config, 'title', '')
+    let buttons = get(a:config, 'buttons', [])
+    let hlgroup = get(a:config, 'highlight',  'CocFloating')
+    let nopad = get(a:config, 'nopad', 0)
+    let border = s:empty_border(get(a:config, 'border', [])) ? [0, 0, 0, 0] : a:config['border']
+    let opts = {
+          \ 'title': title,
+          \ 'line': line,
+          \ 'col': col,
+          \ 'fixed': 1,
+          \ 'padding': [0, !nopad && !border[1], 0, !nopad && !border[3]],
+          \ 'borderchars': s:get_borderchars(a:config),
+          \ 'highlight': hlgroup,
+          \ 'minwidth': a:config['width'],
+          \ 'minheight': a:config['height'],
+          \ 'maxwidth': a:config['width'],
+          \ 'maxheight': a:config['height'],
+          \ 'close': get(a:config, 'close', 0) ? 'button' : 'none',
+          \ 'border': border,
+          \ 'callback': { -> coc#float#on_close(winid)},
+          \ 'borderhighlight': [s:get_borderhighlight(a:config)],
+          \ }
+    let winid = popup_create(bufnr, opts)
+    if !s:popup_list_api
+      call add(s:popup_list, winid)
+    endif
+    call s:set_float_defaults(winid, a:config)
+    call win_execute(winid, 'exe '.lnum)
+    call coc#float#vim_buttons(winid, a:config)
+  else
+    let config = s:convert_config_nvim(a:config, 1)
+    let border = get(a:config, 'border', [])
+    if has('nvim-0.5.0') && get(a:config, 'shadow', 0) && empty(get(a:config, 'buttons', v:null)) && empty(get(border, 2, 0))
+      let config['border'] = 'shadow'
+    endif
+    noa let winid = nvim_open_win(bufnr, 0, config)
+    if winid is 0
+      return []
+    endif
+    " cursorline highlight not work on old neovim
+    call s:set_float_defaults(winid, a:config)
+    call nvim_win_set_cursor(winid, [lnum, 0])
+    call coc#float#nvim_create_related(winid, config, a:config)
+    call coc#float#nvim_set_winblend(winid, get(a:config, 'winblend', v:null))
+  endif
+  call s:add_highlights(winid, a:config, 1)
+  let g:coc_last_float_win = winid
+  call coc#util#do_autocmd('CocOpenFloat')
+  return [winid, bufnr]
+endfunction
+
+function! coc#float#nvim_create_related(winid, config, opts) abort
+  let related = getwinvar(a:winid, 'related', [])
+  let exists = !empty(related)
+  let border = get(a:opts, 'border', [])
+  let borderhighlight = s:get_borderhighlight(a:opts)
+  let buttons = get(a:opts, 'buttons', [])
+  let pad = !get(a:opts, 'nopad', 0) && (empty(border) || get(border, 1, 0) == 0)
+  let shadow = get(a:opts, 'shadow', 0)
+  if get(a:opts, 'close', 0)
+    call coc#float#nvim_close_btn(a:config, a:winid, border, borderhighlight, related)
+  elseif exists
+    call coc#float#close_related(a:winid, 'close')
+  endif
+  if !empty(buttons)
+    call coc#float#nvim_buttons(a:config, a:winid, buttons, get(a:opts, 'getchar', 0), get(border, 2, 0), pad, borderhighlight, shadow, related)
+  elseif exists
+    call coc#float#close_related(a:winid, 'buttons')
+  endif
+  if !s:empty_border(border)
+    let borderchars = s:get_borderchars(a:opts)
+    call coc#float#nvim_border_win(a:config, borderchars, a:winid, border, get(a:opts, 'title', ''), !empty(buttons), borderhighlight, shadow, related)
+  elseif exists
+    call coc#float#close_related(a:winid, 'border')
+  endif
+  " Check right border
+  if pad
+    call coc#float#nvim_right_pad(a:config, a:winid, related)
+  elseif exists
+    call coc#float#close_related(a:winid, 'pad')
+  endif
+  call setwinvar(a:winid, 'related', filter(related, 'nvim_win_is_valid(v:val)'))
+endfunction
+
+" border window for neovim, content config with border
+function! coc#float#nvim_border_win(config, borderchars, winid, border, title, hasbtn, hlgroup, shadow, related) abort
+  let winid = coc#float#get_related(a:winid, 'border')
+  let row = a:border[0] ? a:config['row'] - 1 : a:config['row']
+  let col = a:border[3] ? a:config['col'] - 1 : a:config['col']
+  let width = a:config['width'] + a:border[1] + a:border[3]
+  let height = a:config['height'] + a:border[0] + a:border[2] + (a:hasbtn ? 2 : 0)
+  let lines = coc#float#create_border_lines(a:border, a:borderchars, a:title, a:config['width'], a:config['height'], a:hasbtn)
+  let bufnr = winid ? winbufnr(winid) : 0
+  let bufnr = coc#float#create_buf(bufnr, lines)
+  let opt = {
+        \ 'relative': a:config['relative'],
+        \ 'width': width,
+        \ 'height': height,
+        \ 'row': row,
+        \ 'col': col,
+        \ 'focusable': v:false,
+        \ 'style': 'minimal',
+        \ }
+  if has('nvim-0.5.0') && a:shadow && !a:hasbtn && a:border[2]
+    let opt['border'] = 'shadow'
+  endif
+  if winid
+    call nvim_win_set_config(winid, opt)
+    call setwinvar(winid, '&winhl', 'Normal:'.a:hlgroup.',NormalNC:'.a:hlgroup)
+  else
+    noa let winid = nvim_open_win(bufnr, 0, opt)
+    call setwinvar(winid, 'delta', -1)
+    let winhl = 'Normal:'.a:hlgroup.',NormalNC:'.a:hlgroup
+    call s:nvim_add_related(winid, a:winid, 'border', winhl, a:related)
+  endif
+endfunction
+
+" neovim only
+function! coc#float#nvim_close_btn(config, winid, border, hlgroup, related) abort
+  let winid = coc#float#get_related(a:winid, 'close')
+  let config = {
+        \ 'relative': a:config['relative'],
+        \ 'width': 1,
+        \ 'height': 1,
+        \ 'row': get(a:border, 0, 0) ? a:config['row'] - 1 : a:config['row'],
+        \ 'col': a:config['col'] + a:config['width'],
+        \ 'focusable': v:true,
+        \ 'style': 'minimal',
+        \ }
+  if has('nvim-0.5.1')
+    let config['zindex'] = 300
+  endif
+  if winid
+    call nvim_win_set_config(winid, coc#dict#pick(config, ['relative', 'row', 'col']))
+  else
+    let bufnr = coc#float#create_buf(0, ['X'])
+    noa let winid = nvim_open_win(bufnr, 0, config)
+    let winhl = 'Normal:'.a:hlgroup.',NormalNC:'.a:hlgroup
+    call s:nvim_add_related(winid, a:winid, 'close', winhl, a:related)
+  endif
+endfunction
+
+" Create padding window by config of current window & border config
+function! coc#float#nvim_right_pad(config, winid, related) abort
+  let winid = coc#float#get_related(a:winid, 'pad')
+  let config = {
+        \ 'relative': a:config['relative'],
+        \ 'width': 1,
+        \ 'height': a:config['height'],
+        \ 'row': a:config['row'],
+        \ 'col': a:config['col'] + a:config['width'],
+        \ 'focusable': v:false,
+        \ 'style': 'minimal',
+        \ }
+  if has('nvim-0.5.1')
+    let config['zindex'] = 300
+  endif
+  if winid && nvim_win_is_valid(winid)
+    if has('nvim-0.5.0')
+      call nvim_win_set_config(winid, coc#dict#pick(config, ['relative', 'row', 'col']))
+      call nvim_win_set_height(winid, config['height'])
+      return
+    endif
+    noa call nvim_win_close(winid, 1)
+  endif
+  let s:pad_bufnr = bufloaded(s:pad_bufnr) ? s:pad_bufnr : coc#float#create_buf(0, repeat([''], &lines), 'hide')
+  noa let winid = nvim_open_win(s:pad_bufnr, 0, config)
+  call s:nvim_add_related(winid, a:winid, 'pad', '', a:related)
+endfunction
+
+" draw buttons window for window with config
+function! coc#float#nvim_buttons(config, winid, buttons, getchar, borderbottom, pad, borderhighlight, shadow, related) abort
+  let winid = coc#float#get_related(a:winid, 'buttons')
+  let width = a:config['width'] + (a:pad ? 1 : 0)
+  let config = {
+        \ 'row': a:config['row'] + a:config['height'],
+        \ 'col': a:config['col'],
+        \ 'width': width,
+        \ 'height': 2 + (a:borderbottom ? 1 : 0),
+        \ 'relative': a:config['relative'],
+        \ 'focusable': 1,
+        \ 'style': 'minimal',
+        \ }
+  if has('nvim-0.5.1')
+    let config['zindex'] = 300
+    if a:shadow
+      let config['border'] = 'shadow'
+    endif
+  endif
+  if winid
+    let bufnr = winbufnr(winid)
+    call s:create_btns_buffer(bufnr, width, a:buttons, a:borderbottom)
+    call nvim_win_set_config(winid, config)
+  else
+    let bufnr = s:create_btns_buffer(0, width, a:buttons, a:borderbottom)
+    noa let winid = nvim_open_win(bufnr, 0, config)
+    if winid
+      call s:nvim_add_related(winid, a:winid, 'buttons', '', a:related)
+      call s:nvim_create_keymap(winid)
+    endif
+  endif
+  if bufnr
+    call nvim_buf_clear_namespace(bufnr, -1, 0, -1)
+    call nvim_buf_add_highlight(bufnr, 1, a:borderhighlight, 0, 0, -1)
+    if a:borderbottom
+      call nvim_buf_add_highlight(bufnr, 1, a:borderhighlight, 2, 0, -1)
+    endif
+    let vcols = getbufvar(bufnr, 'vcols', [])
+    " TODO need change vol to col
+    for col in vcols
+      call nvim_buf_add_highlight(bufnr, 1, a:borderhighlight, 1, col, col + 3)
+    endfor
+    if a:getchar
+      let keys = s:gen_filter_keys(getbufline(bufnr, 2)[0])
+      call matchaddpos('MoreMsg', map(keys[0], "[2,v:val]"), 99, -1, {'window': winid})
+      call timer_start(10, {-> coc#float#getchar(winid, keys[1])})
+    endif
+  endif
+endfunction
+
+function! coc#float#getchar(winid, keys) abort
+  let ch = coc#prompt#getc()
+  let target = getwinvar(a:winid, 'target_winid', 0)
+  if ch ==# "\<esc>"
+    call coc#float#close(target)
+    return
+  endif
+  if ch ==# "\<LeftMouse>"
+    if getwinvar(v:mouse_winid, 'kind', '') ==# 'close'
+      call coc#float#close(target)
+      return
+    endif
+    if v:mouse_winid == a:winid && v:mouse_lnum == 2
+      let vcols = getbufvar(winbufnr(a:winid), 'vcols', [])
+      let col = v:mouse_col - 1
+      if index(vcols, col) < 0
+        let filtered = filter(vcols, 'v:val < col')
+        call coc#rpc#notify('FloatBtnClick', [winbufnr(target), len(filtered)])
+        call coc#float#close(target)
+        return
+      endif
+    endif
+  else
+    let idx = index(a:keys, ch)
+    if idx >= 0
+      call coc#rpc#notify('FloatBtnClick', [winbufnr(target), idx])
+      call coc#float#close(target)
+      return
+    endif
+  endif
+  call coc#float#getchar(a:winid, a:keys)
+endfunction
+
+" Create or refresh scrollbar for winid
+" Need called on create, config, buffer change, scrolled
+function! coc#float#nvim_scrollbar(winid) abort
+  if !has('nvim-0.4.0')
+    return
+  endif
+  let winids = nvim_tabpage_list_wins(nvim_get_current_tabpage())
+  if index(winids, a:winid) == -1
+    return
+  endif
+  let config = nvim_win_get_config(a:winid)
+  let [row, column] = nvim_win_get_position(a:winid)
+  let relative = 'editor'
+  if row == 0 && column == 0
+    " fix bad value when ext_multigrid is enabled. https://github.com/neovim/neovim/issues/11935
+    let [row, column] = [config.row, config.col]
+    let relative = config.relative
+  endif
+  let width = nvim_win_get_width(a:winid)
+  let height = nvim_win_get_height(a:winid)
+  let bufnr = winbufnr(a:winid)
+  let cw = getwinvar(a:winid, '&foldcolumn', 0) ? width - 1 : width
+  let ch = coc#float#content_height(bufnr, cw, getwinvar(a:winid, '&wrap'))
+  let closewin = coc#float#get_related(a:winid, 'close')
+  let border = getwinvar(a:winid, 'border', [])
+  let scrollinside = getwinvar(a:winid, 'scrollinside', 0) && get(border, 1, 0)
+  let winblend = getwinvar(a:winid, '&winblend', 0)
+  let move_down = closewin && !get(border, 0, 0)
+  let id = coc#float#get_related(a:winid, 'scrollbar')
+  if ch <= height || height <= 1
+    " no scrollbar, remove exists
+    if id
+      call s:close_win(id)
+    endif
+    return
+  endif
+  if move_down
+    let height = height - 1
+  endif
+  call coc#float#close_related(a:winid, 'pad')
+  let sbuf = id ? winbufnr(id) : 0
+  let sbuf = coc#float#create_buf(sbuf, repeat([' '], height))
+  let opts = {
+        \ 'row': move_down ? row + 1 : row,
+        \ 'col': column + width - scrollinside,
+        \ 'relative': relative,
+        \ 'width': 1,
+        \ 'height': height,
+        \ 'focusable': v:false,
+        \ 'style': 'minimal',
+        \ }
+  if has('nvim-0.5.1')
+    let opts['zindex'] = 300
+  endif
+  if id
+    call nvim_win_set_config(id, opts)
+  else
+    noa let id = nvim_open_win(sbuf, 0 , opts)
+    if id == 0
+      return
+    endif
+    if winblend
+      call setwinvar(id, '&winblend', winblend)
+    endif
+    call setwinvar(id, 'kind', 'scrollbar')
+    call setwinvar(id, 'target_winid', a:winid)
+    call coc#float#add_related(id, a:winid)
+  endif
+  if !scrollinside
+    call coc#float#nvim_scroll_adjust(a:winid)
+  endif
+  let thumb_height = max([1, float2nr(floor(height * (height + 0.0)/ch))])
+  let wininfo = getwininfo(a:winid)[0]
+  let start = 0
+  if wininfo['topline'] != 1
+    " needed for correct getwininfo
+    let firstline = wininfo['topline']
+    let lastline = s:nvim_get_botline(firstline, height, cw, bufnr)
+    let linecount = nvim_buf_line_count(winbufnr(a:winid))
+    if lastline >= linecount
+      let start = height - thumb_height
+    else
+      let start = max([1, float2nr(round((height - thumb_height + 0.0)*(firstline - 1.0)/(ch - height)))])
+    endif
+  endif
+  " add highlights
+  call nvim_buf_clear_namespace(sbuf, -1, 0, -1)
+  for idx in range(0, height - 1)
+    if idx >= start && idx < start + thumb_height
+      call nvim_buf_add_highlight(sbuf, -1, 'PmenuThumb', idx, 0, 1)
+    else
+      call nvim_buf_add_highlight(sbuf, -1, 'PmenuSbar', idx, 0, 1)
+    endif
+  endfor
+endfunction
+
+function! coc#float#create_border_lines(border, borderchars, title, width, height, hasbtn) abort
+  let borderchars = a:borderchars
+  let list = []
+  if a:border[0]
+    let top = (a:border[3] ?  borderchars[4]: '')
+          \.repeat(borderchars[0], a:width)
+          \.(a:border[1] ? borderchars[5] : '')
+    if !empty(a:title)
+      let top = coc#string#compose(top, 1, a:title.' ')
+    endif
+    call add(list, top)
+  endif
+  let mid = (a:border[3] ?  borderchars[3]: '')
+        \.repeat(' ', a:width)
+        \.(a:border[1] ? borderchars[1] : '')
+  call extend(list, repeat([mid], a:height + (a:hasbtn ? 2 : 0)))
+  if a:hasbtn
+    let list[len(list) - 2] = (a:border[3] ?  s:borderjoinchars[3]: '')
+        \.repeat(' ', a:width)
+        \.(a:border[1] ? s:borderjoinchars[1] : '')
+  endif
+  if a:border[2]
+    let bot = (a:border[3] ?  borderchars[7]: '')
+          \.repeat(borderchars[2], a:width)
+          \.(a:border[1] ? borderchars[6] : '')
+    call add(list, bot)
+  endif
+  return list
+endfunction
+
+" Close float window by id
+function! coc#float#close(winid) abort
+  call coc#float#close_related(a:winid)
+  call s:close_win(a:winid)
+  return 1
+endfunction
+
+" Get visible float windows
+function! coc#float#get_float_win_list(...) abort
+  let res = []
+  let list_all = get(a:, 1, 0)
+  if s:is_vim
+    if s:popup_list_api
+      return filter(popup_list(), 'popup_getpos(v:val)["visible"]'.(list_all ? '' : '&& getwinvar(v:val, "float", 0)'))
+    endif
+    return filter(s:popup_list, 's:popup_visible(v:val)')
+  else
+    let res = []
+    for i in range(1, winnr('$'))
+      let id = win_getid(i)
+      let config = nvim_win_get_config(id)
+      if empty(config) || empty(config['relative'])
+        continue
+      endif
+      " ignore border & button window & others
+      if list_all == 0 && !getwinvar(id, 'float', 0)
+        continue
+      endif
+      call add(res, id)
+    endfor
+    return res
+  endif
+  return []
+endfunction
+
+function! coc#float#get_float_by_kind(kind) abort
+  if s:is_vim
+    if s:popup_list_api
+      return get(filter(popup_list(), 'popup_getpos(v:val)["visible"] && getwinvar(v:val, "kind", "") ==# "'.a:kind.'"'), 0, 0)
+    endif
+    return get(filter(s:popup_list, 's:popup_visible(v:val) && getwinvar(v:val, "kind", "") ==# "'.a:kind.'"'), 0, 0)
+  else
+    let res = []
+    for i in range(1, winnr('$'))
+      let winid = win_getid(i)
+      let config = nvim_win_get_config(winid)
+      if !empty(config['relative']) && getwinvar(winid, 'kind', '') ==# a:kind
+        return winid
+      endif
+    endfor
+  endif
+  return 0
+endfunction
+
+" Check if a float window is scrollable
+function! coc#float#scrollable(winid) abort
+  let bufnr = winbufnr(a:winid)
+  if bufnr == -1
+    return 0
+  endif
+  if s:is_vim
+    let pos = popup_getpos(a:winid)
+    if get(popup_getoptions(a:winid), 'scrollbar', 0)
+      return get(pos, 'scrollbar', 0)
+    endif
+    let ch = coc#float#content_height(bufnr, pos['core_width'], getwinvar(a:winid, '&wrap'))
+    return ch > pos['core_height']
+  else
+    let height = nvim_win_get_height(a:winid)
+    let width = nvim_win_get_width(a:winid)
+    if width > 1 && getwinvar(a:winid, '&foldcolumn', 0)
+      " since we use foldcolumn for left padding
+      let width = width - 1
+    endif
+    let ch = coc#float#content_height(bufnr, width, getwinvar(a:winid, '&wrap'))
+    return ch > height
+  endif
+endfunction
+
+function! coc#float#has_scroll() abort
+  let win_ids = filter(coc#float#get_float_win_list(), 'coc#float#scrollable(v:val)')
+  return !empty(win_ids)
+endfunction
+
+function! coc#float#scroll(forward, ...)
+  if !has('nvim-0.4.0') && !has('patch-8.2.0750')
+    throw 'coc#float#scroll() requires nvim >= 0.4.0 or vim >= 8.2.0750'
+  endif
+  let amount = get(a:, 1, 0)
+  let winids = filter(coc#float#get_float_win_list(), 'coc#float#scrollable(v:val) && getwinvar(v:val,"kind","") !=# "pum"')
+  if empty(winids)
+    return mode() =~ '^i' || mode() ==# 'v' ? "" : "\<Ignore>"
+  endif
+  for winid in winids
+    call s:scroll_win(winid, a:forward, amount)
+  endfor
+  return mode() =~ '^i' || mode() ==# 'v' ? "" : "\<Ignore>"
+endfunction
+
+function! coc#float#scroll_win(winid, forward, amount) abort
+  let opts = s:get_options(a:winid)
+  let lines = getbufline(winbufnr(a:winid), 1, '$')
+  let maxfirst = s:max_firstline(lines, opts['height'], opts['width'])
+  let topline = opts['topline']
+  let height = opts['height']
+  let width = opts['width']
+  let scrolloff = getwinvar(a:winid, '&scrolloff', 0)
+  if a:forward && topline >= maxfirst
+    return
+  endif
+  if !a:forward && topline == 1
+    return
+  endif
+  if a:amount == 0
+    let topline = s:get_topline(opts['topline'], lines, a:forward, height, width)
+  else
+    let topline = topline + (a:forward ? a:amount : - a:amount)
+  endif
+  let topline = a:forward ? min([maxfirst, topline]) : max([1, topline])
+  let lnum = s:get_cursorline(topline, lines, scrolloff, width, height)
+  call s:win_setview(a:winid, topline, lnum)
+  let top = s:get_options(a:winid)['topline']
+  " not changed
+  if top == opts['topline']
+    if a:forward
+      call s:win_setview(a:winid, topline + 1, lnum + 1)
+    else
+      call s:win_setview(a:winid, topline - 1, lnum - 1)
+    endif
+  endif
+endfunction
+
+function! coc#float#content_height(bufnr, width, wrap) abort
+  if !bufloaded(a:bufnr)
+    return 0
+  endif
+  if !a:wrap
+    return has('nvim') ? nvim_buf_line_count(a:bufnr) : len(getbufline(a:bufnr, 1, '$'))
+  endif
+  let lines = has('nvim') ? nvim_buf_get_lines(a:bufnr, 0, -1, 0) : getbufline(a:bufnr, 1, '$')
+  let total = 0
+  for line in lines
+    let dw = max([1, strdisplaywidth(line)])
+    let total += float2nr(ceil(str2float(string(dw))/a:width))
+  endfor
+  return total
+endfunction
+
+function! coc#float#nvim_refresh_scrollbar(winid) abort
+  let id = coc#float#get_related(a:winid, 'scrollbar')
+  if id && nvim_win_is_valid(id)
+    call coc#float#nvim_scrollbar(a:winid)
+  endif
+endfunction
+
+function! coc#float#on_close(winid) abort
+  let winids = coc#float#get_float_win_list()
+  for winid in winids
+    let target = getwinvar(winid, 'target_winid', -1)
+    if target == a:winid
+      call coc#float#close(winid)
+    endif
+  endfor
+endfunction
+
+" Close related windows, or specific kind
+function! coc#float#close_related(winid, ...) abort
+  if !coc#float#valid(a:winid)
+    return
+  endif
+  let timer = coc#window#get_var(a:winid, 'timer', 0)
+  if timer
+    call timer_stop(timer)
+  endif
+  let kind = get(a:, 1, '')
+  let winids = coc#window#get_var(a:winid, 'related', [])
+  for id in winids
+    let curr = coc#window#get_var(id, 'kind', '')
+    if empty(kind) || curr ==# kind
+      if curr == 'list'
+        call coc#float#close(id)
+      elseif s:is_vim
+        " vim doesn't throw
+        noa call popup_close(id)
+      else
+        silent! noa call nvim_win_close(id, 1)
+      endif
+    endif
+  endfor
+endfunction
+
+" Close related windows if target window is not visible.
+function! coc#float#check_related() abort
+  let invalids = []
+  let ids = coc#float#get_float_win_list(1)
+  for id in ids
+    let target = getwinvar(id, 'target_winid', 0)
+    if (target && index(ids, target) == -1) || getwinvar(id, 'kind', '') == 'pumdetail'
+      call add(invalids, id)
+    endif
+  endfor
+  if !s:popup_list_api
+    let s:popup_list = filter(ids, "index(invalids, v:val) == -1")
+  endif
+  for id in invalids
+    call coc#float#close(id)
+  endfor
+endfunction
+
+" Show float window/popup for user confirm.
+" Create buttons popup on vim
+function! coc#float#vim_buttons(winid, config) abort
+  if !has('patch-8.2.0750')
+    return
+  endif
+  let related = getwinvar(a:winid, 'related', [])
+  let winid = coc#float#get_related(a:winid, 'buttons')
+  let btns = get(a:config, 'buttons', [])
+  if empty(btns)
+    if winid
+      call s:close_win(winid)
+      " fix padding
+      let opts = popup_getoptions(a:winid)
+      let padding = get(opts, 'padding', v:null)
+      if !empty(padding)
+        let padding[2] = padding[2] - 2
+      endif
+      call popup_setoptions(a:winid, {'padding': padding})
+    endif
+    return
+  endif
+  let border = get(a:config, 'border', v:null)
+  if !winid
+    " adjusting popup padding
+    let opts = popup_getoptions(a:winid)
+    let padding = get(opts, 'padding', v:null)
+    if type(padding) == 7
+      let padding = [0, 0, 2, 0]
+    elseif len(padding) == 0
+      let padding = [1, 1, 3, 1]
+    else
+      let padding[2] = padding[2] + 2
+    endif
+    call popup_setoptions(a:winid, {'padding': padding})
+  endif
+  let borderhighlight = get(get(a:config, 'borderhighlight', []), 0, '')
+  let pos = popup_getpos(a:winid)
+  let bw = empty(border) ? 0 : get(border, 1, 0) + get(border, 3, 0)
+  let borderbottom = empty(border) ? 0 : get(border, 2, 0)
+  let borderleft = empty(border) ? 0 : get(border, 3, 0)
+  let width = pos['width'] - bw + get(pos, 'scrollbar', 0)
+  let bufnr = s:create_btns_buffer(winid ? winbufnr(winid): 0,width, btns, borderbottom)
+  let height = 2 + (borderbottom ? 1 : 0)
+  let keys = s:gen_filter_keys(getbufline(bufnr, 2)[0])
+  let options = {
+        \ 'filter': {id, key -> coc#float#vim_filter(id, key, keys[1])},
+        \ 'highlight': get(opts, 'highlight', 'CocFloating')
+        \ }
+  let config = {
+        \ 'line': pos['line'] + pos['height'] - height,
+        \ 'col': pos['col'] + borderleft,
+        \ 'minwidth': width,
+        \ 'minheight': height,
+        \ 'maxwidth': width,
+        \ 'maxheight': height,
+        \ }
+  if winid != 0
+    call popup_move(winid, config)
+    call popup_setoptions(winid, options)
+    call win_execute(winid, 'call clearmatches()')
+  else
+    let options = extend({
+          \ 'filtermode': 'nvi',
+          \ 'padding': [0, 0, 0, 0],
+          \ 'fixed': 1,
+          \ 'zindex': 99,
+          \ }, options)
+    call extend(options, config)
+    let winid = popup_create(bufnr, options)
+    if !s:popup_list_api
+      call add(s:popup_list, winid)
+    endif
+  endif
+  if winid != 0
+    if !empty(borderhighlight)
+      call coc#highlight#add_highlight(bufnr, -1, borderhighlight, 0, 0, -1)
+      call coc#highlight#add_highlight(bufnr, -1, borderhighlight, 2, 0, -1)
+      call win_execute(winid, 'call matchadd("'.borderhighlight.'", "'.s:borderchars[1].'")')
+    endif
+    call setwinvar(winid, 'kind', 'buttons')
+    call setwinvar(winid, 'target_winid', a:winid)
+    call add(related, winid)
+    call setwinvar(a:winid, 'related', related)
+    call matchaddpos('MoreMsg', map(keys[0], "[2,v:val]"), 99, -1, {'window': winid})
+  endif
+endfunction
+
+function! coc#float#nvim_float_click() abort
+  let kind = getwinvar(win_getid(), 'kind', '')
+  if kind == 'buttons'
+    if line('.') != 2
+      return
+    endif
+    let vw = strdisplaywidth(strpart(getline('.'), 0, col('.') - 1))
+    let vcols = getbufvar(bufnr('%'), 'vcols', [])
+    if index(vcols, vw) >= 0
+      return
+    endif
+    let idx = 0
+    if !empty(vcols)
+      let filtered = filter(vcols, 'v:val < vw')
+      let idx = idx + len(filtered)
+    endif
+    let winid = win_getid()
+    let target = getwinvar(winid, 'target_winid', 0)
+    if target
+      call coc#rpc#notify('FloatBtnClick', [winbufnr(target), idx])
+      call coc#float#close(target)
+    endif
+  elseif kind == 'close'
+    let target = getwinvar(win_getid(), 'target_winid', 0)
+    call coc#float#close(target)
+  endif
+endfunction
+
+" Add <LeftRelease> mapping if necessary
+function! coc#float#nvim_win_enter(winid) abort
+  let kind = getwinvar(a:winid, 'kind', '')
+  if kind == 'buttons' || kind == 'close'
+    if empty(maparg('<LeftRelease>', 'n'))
+      nnoremap <buffer><silent> <LeftRelease> :call coc#float#nvim_float_click()<CR>
+    endif
+  endif
+endfunction
+
+function! coc#float#vim_filter(winid, key, keys) abort
+  let key = tolower(a:key)
+  let idx = index(a:keys, key)
+  let target = getwinvar(a:winid, 'target_winid', 0)
+  if target && idx >= 0
+    call coc#rpc#notify('FloatBtnClick', [winbufnr(target), idx])
+    call coc#float#close(target)
+    return 1
+  endif
+  return 0
+endfunction
+
+function! coc#float#get_related(winid, kind, ...) abort
+  if coc#float#valid(a:winid)
+    for winid in coc#window#get_var(a:winid, 'related', [])
+      if coc#window#get_var(winid, 'kind', '') ==# a:kind
+        return winid
+      endif
+    endfor
+  endif
+  return get(a:, 1, 0)
+endfunction
+
+function! coc#float#get_row(winid) abort
+  let winid = s:is_vim ? a:winid : coc#float#get_related(a:winid, 'border', a:winid)
+  if coc#float#valid(winid)
+    if s:is_vim
+      let pos = popup_getpos(winid)
+      return pos['line'] - 1
+    endif
+    let pos = nvim_win_get_position(winid)
+    return pos[0]
+  endif
+endfunction
+
+" Create temporarily buffer with optional lines and &bufhidden
+function! coc#float#create_buf(bufnr, ...) abort
+  if a:bufnr > 0 && bufloaded(a:bufnr)
+    let bufnr = a:bufnr
+  else
+    if s:is_vim
+      noa let bufnr = bufadd('')
+      noa call bufload(bufnr)
+      call setbufvar(bufnr, '&buflisted', 0)
+    else
+      noa let bufnr = nvim_create_buf(v:false, v:true)
+    endif
+    let bufhidden = get(a:, 2, 'wipe')
+    call setbufvar(bufnr, '&buftype', 'nofile')
+    call setbufvar(bufnr, '&bufhidden', bufhidden)
+    call setbufvar(bufnr, '&swapfile', 0)
+    call setbufvar(bufnr, '&undolevels', -1)
+    " neovim's bug
+    call setbufvar(bufnr, '&modifiable', 1)
+  endif
+  let lines = get(a:, 1, v:null)
+  if type(lines) == v:t_list
+    if has('nvim')
+      call nvim_buf_set_lines(bufnr, 0, -1, v:false, lines)
+    else
+      silent noa call setbufline(bufnr, 1, lines)
+      silent noa call deletebufline(bufnr, len(lines) + 1, '$')
+    endif
+  endif
+  return bufnr
+endfunction
+
+" Change border window & close window when scrollbar is shown.
+function! coc#float#nvim_scroll_adjust(winid) abort
+  let winid = coc#float#get_related(a:winid, 'border')
+  if !winid
+    return
+  endif
+  let bufnr = winbufnr(winid)
+  let lines = nvim_buf_get_lines(bufnr, 0, -1, 0)
+  if len(lines) >= 2
+    let cw = nvim_win_get_width(a:winid)
+    let width = nvim_win_get_width(winid)
+    if width - cw != 1 + (strcharpart(lines[1], 0, 1) ==# s:borderchars[3] ? 1 : 0)
+      return
+    endif
+    call nvim_win_set_width(winid, width + 1)
+    let lastline = len(lines) - 1
+    for i in range(0, lastline)
+      let line = lines[i]
+      if i == 0
+        let add = s:borderchars[0]
+      elseif i == lastline
+        let add = s:borderchars[2]
+      else
+        let add = ' '
+      endif
+      let prev = strcharpart(line, 0, strchars(line) - 1)
+      let lines[i] = prev . add . coc#string#last_character(line)
+    endfor
+    call nvim_buf_set_lines(bufnr, 0, -1, 0, lines)
+    " Move right close button
+    if coc#window#get_var(a:winid, 'right', 0) == 0
+      let id = coc#float#get_related(a:winid, 'close')
+      if id
+        let [row, col] = nvim_win_get_position(id)
+        call nvim_win_set_config(id, {
+              \ 'relative': 'editor',
+              \ 'row': row,
+              \ 'col': col + 1,
+              \ })
+      endif
+    elseif has('nvim-0.6.0')
+      " Move winid and all related left by 1
+      let winids = [a:winid] + coc#window#get_var(a:winid, 'related', [])
+      for winid in winids
+        if nvim_win_is_valid(winid)
+          if coc#window#get_var(winid, 'kind', '') != 'close'
+            let [row, column] = nvim_win_get_position(winid)
+            call nvim_win_set_config(winid, {
+                  \ 'row': row,
+                  \ 'col': column - 1,
+                  \ 'relative': 'editor',
+                  \ })
+          endif
+        endif
+      endfor
+    endif
+  endif
+endfunction
+
+function! coc#float#nvim_set_winblend(winid, winblend) abort
+  if a:winblend is v:null
+    return
+  endif
+  call coc#window#set_var(a:winid, '&winblend', a:winblend)
+  for winid in coc#window#get_var(a:winid, 'related', [])
+    call coc#window#set_var(winid, '&winblend', a:winblend)
+  endfor
+endfunction
+
+function! s:popup_visible(id) abort
+  let pos = popup_getpos(a:id)
+  if !empty(pos) && get(pos, 'visible', 0)
+    return 1
+  endif
+  return 0
+endfunction
+
+function! s:convert_config_nvim(config, create) abort
+  let valids = ['relative', 'win', 'anchor', 'width', 'height', 'bufpos', 'col', 'row', 'focusable']
+  let result = coc#dict#pick(a:config, valids)
+  let border = get(a:config, 'border', [])
+  if !s:empty_border(border)
+    if result['relative'] ==# 'cursor' && result['row'] < 0
+      " move top when has bottom border
+      if get(border, 2, 0)
+        let result['row'] = result['row'] - 1
+      endif
+    else
+      " move down when has top border
+      if get(border, 0, 0) && !get(a:config, 'prompt', 0)
+        let result['row'] = result['row'] + 1
+      endif
+    endif
+    " move right when has left border
+    if get(border, 3, 0)
+      let result['col'] = result['col'] + 1
+    endif
+    let result['width'] = float2nr(result['width'] + 1 - get(border,3, 0))
+  else
+    let result['width'] = float2nr(result['width'] + (get(a:config, 'nopad', 0) ? 0 : 1))
+  endif
+  if has('nvim-0.5.1') && a:create
+    let result['noautocmd'] = v:true
+  endif
+  let result['height'] = float2nr(result['height'])
+  return result
+endfunction
+
+function! s:create_btns_buffer(bufnr, width, buttons, borderbottom) abort
+  let n = len(a:buttons)
+  let spaces = a:width - n + 1
+  let tw = 0
+  for txt in a:buttons
+    let tw += strdisplaywidth(txt)
+  endfor
+  if spaces < tw
+    throw 'window is too small for buttons.'
+  endif
+  let ds = (spaces - tw)/n
+  let dl = ds/2
+  let dr = ds%2 == 0 ? ds/2 : ds/2 + 1
+  let btnline = ''
+  let idxes = []
+  for idx in range(0, n - 1)
+    let txt = toupper(a:buttons[idx][0]).a:buttons[idx][1:]
+    let btnline .= repeat(' ', dl).txt.repeat(' ', dr)
+    if idx != n - 1
+      call add(idxes, strdisplaywidth(btnline))
+      let btnline .= s:borderchars[1]
+    endif
+  endfor
+  let lines = [repeat(s:borderchars[0], a:width), btnline]
+  if a:borderbottom
+    call add(lines, repeat(s:borderchars[0], a:width))
+  endif
+  for idx in idxes
+    let lines[0] = strcharpart(lines[0], 0, idx).s:borderjoinchars[0].strcharpart(lines[0], idx + 1)
+    if a:borderbottom
+      let lines[2] = strcharpart(lines[0], 0, idx).s:borderjoinchars[2].strcharpart(lines[0], idx + 1)
+    endif
+  endfor
+  let bufnr = coc#float#create_buf(a:bufnr, lines)
+  call setbufvar(bufnr, 'vcols', idxes)
+  return bufnr
+endfunction
+
+function! s:gen_filter_keys(line) abort
+  let cols = []
+  let used = []
+  let next = 1
+  for idx in  range(0, strchars(a:line) - 1)
+    let ch = strcharpart(a:line, idx, 1)
+    let nr = char2nr(ch)
+    if next
+      if (nr >= 65 && nr <= 90) || (nr >= 97 && nr <= 122)
+        let lc = tolower(ch)
+        if index(used, lc) < 0 && (!s:is_vim || empty(maparg(lc, 'n')))
+          let col = len(strcharpart(a:line, 0, idx)) + 1
+          call add(used, lc)
+          call add(cols, col)
+          let next = 0
+        endif
+      endif
+    else
+      if ch == s:borderchars[1]
+        let next = 1
+      endif
+    endif
+  endfor
+  return [cols, used]
+endfunction
+
+function! s:close_win(winid) abort
+  if a:winid <= 0
+    return
+  endif
+  " vim not throw for none exists winid
+  if s:is_vim
+    call popup_close(a:winid)
+  else
+    if nvim_win_is_valid(a:winid)
+      call nvim_win_close(a:winid, 1)
+    endif
+  endif
+endfunction
+
+function! s:nvim_create_keymap(winid) abort
+  if exists('*nvim_buf_set_keymap')
+    let bufnr = winbufnr(a:winid)
+    call nvim_buf_set_keymap(bufnr, 'n', '<LeftRelease>', ':call coc#float#nvim_float_click()<CR>', {
+        \ 'silent': v:true,
+        \ 'nowait': v:true
+        \ })
+  else
+    let curr = win_getid()
+    let m = mode()
+    if m == 'n' || m == 'i' || m == 'ic'
+      noa call win_gotoid(a:winid)
+      nnoremap <buffer><silent> <LeftRelease> :call coc#float#nvim_float_click()<CR>
+      noa call win_gotoid(curr)
+    endif
+  endif
+endfunction
+
+" getwininfo is buggy on neovim, use topline, width & height should for content
+function! s:nvim_get_botline(topline, height, width, bufnr) abort
+  let lines = getbufline(a:bufnr, a:topline, a:topline + a:height - 1)
+  let botline = a:topline
+  let count = 0
+  for i in range(0, len(lines) - 1)
+    let w = max([1, strdisplaywidth(lines[i])])
+    let lh = float2nr(ceil(str2float(string(w))/a:width))
+    let count = count + lh
+    let botline = a:topline + i
+    if count >= a:height
+      break
+    endif
+  endfor
+  return botline
+endfunction
+
+" get popup position for vim8 based on config of neovim float window
+function! s:popup_position(config) abort
+  let relative = get(a:config, 'relative', 'editor')
+  let border = get(a:config, 'border', [0, 0, 0, 0])
+  let delta = get(border, 0, 0)  + get(border, 2, 0)
+  if relative ==# 'cursor'
+    if a:config['row'] < 0
+      let delta = - delta
+    elseif a:config['row'] == 0
+      let delta = - get(border, 0, 0)
+    else
+      let delta = 0
+    endif
+    return [s:popup_cursor(a:config['row'] + delta), s:popup_cursor(a:config['col'])]
+  endif
+  return [a:config['row'] + 1, a:config['col'] + 1]
+endfunction
+
+function! coc#float#add_related(winid, target) abort
+  let arr = coc#window#get_var(a:target, 'related', [])
+  if index(arr, a:winid) >= 0
+    return
+  endif
+  call add(arr, a:winid)
+  call coc#window#set_var(a:target, 'related', arr)
+endfunction
+
+function! s:popup_cursor(n) abort
+  if a:n == 0
+    return 'cursor'
+  endif
+  if a:n < 0
+    return 'cursor'.a:n
+  endif
+  return 'cursor+'.a:n
+endfunction
+
+" max firstline of lines, height > 0, width > 0
+function! s:max_firstline(lines, height, width) abort
+  let max = len(a:lines)
+  let remain = a:height
+  for line in reverse(copy(a:lines))
+    let w = max([1, strdisplaywidth(line)])
+    let dh = float2nr(ceil(str2float(string(w))/a:width))
+    if remain - dh < 0
+      break
+    endif
+    let remain = remain - dh
+    let max = max - 1
+  endfor
+  return min([len(a:lines), max + 1])
+endfunction
+
+" Get best lnum by topline
+function! s:get_cursorline(topline, lines, scrolloff, width, height) abort
+  let lastline = len(a:lines)
+  if a:topline == lastline
+    return lastline
+  endif
+  let bottomline = a:topline
+  let used = 0
+  for lnum in range(a:topline, lastline)
+    let w = max([1, strdisplaywidth(a:lines[lnum - 1])])
+    let dh = float2nr(ceil(str2float(string(w))/a:width))
+    if used + dh >= a:height || lnum == lastline
+      let bottomline = lnum
+      break
+    endif
+    let used += dh
+  endfor
+  let cursorline = a:topline + a:scrolloff
+  if cursorline + a:scrolloff > bottomline
+    " unable to satisfy scrolloff
+    let cursorline = (a:topline + bottomline)/2
+  endif
+  return cursorline
+endfunction
+
+" Get firstline for full scroll
+function! s:get_topline(topline, lines, forward, height, width) abort
+  let used = 0
+  let lnums = a:forward ? range(a:topline, len(a:lines)) : reverse(range(1, a:topline))
+  let topline = a:forward ? len(a:lines) : 1
+  for lnum in lnums
+    let w = max([1, strdisplaywidth(a:lines[lnum - 1])])
+    let dh = float2nr(ceil(str2float(string(w))/a:width))
+    if used + dh >= a:height
+      let topline = lnum
+      break
+    endif
+    let used += dh
+  endfor
+  if topline == a:topline
+    if a:forward
+      let topline = min([len(a:lines), topline + 1])
+    else
+      let topline = max([1, topline - 1])
+    endif
+  endif
+  return topline
+endfunction
+
+" topline content_height content_width
+function! s:get_options(winid) abort
+  if has('nvim')
+    let width = nvim_win_get_width(a:winid)
+    if coc#window#get_var(a:winid, '&foldcolumn', 0)
+      let width = width - 1
+    endif
+    let info = getwininfo(a:winid)[0]
+    return {
+      \ 'topline': info['topline'],
+      \ 'height': nvim_win_get_height(a:winid),
+      \ 'width': width
+      \ }
+  else
+    let pos = popup_getpos(a:winid)
+    return {
+      \ 'topline': pos['firstline'],
+      \ 'width': pos['core_width'],
+      \ 'height': pos['core_height']
+      \ }
+  endif
+endfunction
+
+function! s:win_setview(winid, topline, lnum) abort
+  if has('nvim')
+    call coc#compat#execute(a:winid, 'call winrestview({"lnum":'.a:lnum.',"topline":'.a:topline.'})')
+    call timer_start(10, { -> coc#float#nvim_refresh_scrollbar(a:winid) })
+  else
+    call coc#compat#execute(a:winid, 'exe '.a:lnum)
+    call popup_setoptions(a:winid, {
+          \ 'firstline': a:topline,
+          \ })
+  endif
+endfunction
+
+function! s:set_float_defaults(winid, config) abort
+  if has('nvim')
+    let hlgroup = get(a:config, 'highlight', 'CocFloating')
+    call setwinvar(a:winid, '&winhl', 'Normal:'.hlgroup.',NormalNC:'.hlgroup.',FoldColumn:'.hlgroup)
+    call setwinvar(a:winid, 'border', get(a:config, 'border', []))
+    call setwinvar(a:winid, 'scrollinside', get(a:config, 'scrollinside', 0))
+    if !get(a:config, 'nopad', 0)
+      call setwinvar(a:winid, '&foldcolumn', s:nvim_enable_foldcolumn(get(a:config, 'border', v:null)))
+    endif
+  endif
+  call setwinvar(a:winid, '&spell', 0)
+  call setwinvar(a:winid, '&linebreak', 1)
+  call setwinvar(a:winid, '&conceallevel', 0)
+  call setwinvar(a:winid, '&signcolumn', 'no')
+  call setwinvar(a:winid, '&list', 0)
+  call setwinvar(a:winid, '&number', 0)
+  call setwinvar(a:winid, '&relativenumber', 0)
+  call setwinvar(a:winid, '&cursorline', 0)
+  call setwinvar(a:winid, '&cursorcolumn', 0)
+  call setwinvar(a:winid, '&colorcolumn', 0)
+  call setwinvar(a:winid, '&wrap', !get(a:config, 'cursorline', 0))
+  if s:is_vim || has('nvim-0.5.0')
+    call setwinvar(a:winid, '&scrolloff', 0)
+  endif
+  if has('nvim-0.6.0') || has("patch-8.1.2281")
+    call setwinvar(a:winid, '&showbreak', 'NONE')
+  endif
+  if exists('*win_execute')
+    call win_execute(a:winid, 'setl fillchars+=eob:\ ')
+  endif
+  if get(a:config, 'autohide', 0)
+    call setwinvar(a:winid, 'autohide', 1)
+  endif
+  call setwinvar(a:winid, 'float', 1)
+endfunction
+
+function! s:nvim_add_related(winid, target, kind, winhl, related) abort
+  if a:winid <= 0
+    return
+  endif
+  " minimal not work
+  if !has('nvim-0.4.3')
+    call setwinvar(a:winid, '&colorcolumn', 0)
+    call setwinvar(a:winid, '&number', 0)
+    call setwinvar(a:winid, '&relativenumber', 0)
+    call setwinvar(a:winid, '&foldcolumn', 0)
+    call setwinvar(a:winid, '&signcolumn', 0)
+    call setwinvar(a:winid, '&list', 0)
+  endif
+  let winhl = empty(a:winhl) ? coc#window#get_var(a:target, '&winhl', '') : a:winhl
+  call setwinvar(a:winid, '&winhl', winhl)
+  call setwinvar(a:winid, 'target_winid', a:target)
+  call setwinvar(a:winid, 'kind', a:kind)
+  call add(a:related, a:winid)
+endfunction
+
+function! s:nvim_enable_foldcolumn(border) abort
+  if a:border is 1
+    return 0
+  endif
+  if type(a:border) == v:t_list && get(a:border, 3, 0) == 1
+    return 0
+  endif
+  return 1
+endfunction
+
+function! s:add_highlights(winid, config, create) abort
+  let codes = get(a:config, 'codes', [])
+  let highlights = get(a:config, 'highlights', [])
+  if empty(codes) && empty(highlights) && a:create
+    return
+  endif
+  let bgGroup = get(a:config, 'highlight', 'CocFloating')
+  for obj in codes
+    let hlGroup = get(obj, 'hlGroup', v:null)
+    if !empty(hlGroup)
+      let obj['hlGroup'] = coc#highlight#compose_hlgroup(hlGroup, bgGroup)
+    endif
+  endfor
+  call coc#highlight#add_highlights(a:winid, codes, highlights)
+endfunction
+
+function! s:empty_border(border) abort
+  if empty(a:border) || empty(filter(copy(a:border), 'v:val != 0'))
+    return 1
+  endif
+  return 0
+endfunction
+
+function! s:get_borderchars(config) abort
+  let borderchars = get(a:config, 'borderchars', [])
+  if !empty(borderchars)
+    return borderchars
+  endif
+  return get(a:config, 'rounded', 0) ? s:rounded_borderchars : s:borderchars
+endfunction
+
+function! s:scroll_win(winid, forward, amount) abort
+  if s:is_vim
+    call coc#float#scroll_win(a:winid, a:forward, a:amount)
+  else
+    call timer_start(0, { -> coc#float#scroll_win(a:winid, a:forward, a:amount)})
+  endif
+endfunction
+
+function! s:get_borderhighlight(config) abort
+  let hlgroup = get(a:config, 'highlight',  'CocFloating')
+  let borderhighlight = get(a:config, 'borderhighlight', v:null)
+  if empty(borderhighlight)
+    return hlgroup
+  endif
+  let highlight = type(borderhighlight) == 3 ? borderhighlight[0] : borderhighlight
+  return coc#highlight#compose_hlgroup(highlight, hlgroup)
+endfunction

+ 148 - 0
vimfiles/bundle/coc.nvim/autoload/coc/helper.vim

@@ -0,0 +1,148 @@
+scriptencoding utf-8
+" Helper methods for viml
+
+function! coc#helper#get_charactor(line, col) abort
+  return strchars(strpart(a:line, 0, a:col - 1))
+endfunction
+
+function! coc#helper#last_character(line) abort
+  return strcharpart(a:line, strchars(a:line) - 1, 1)
+endfunction
+
+function! coc#helper#obj_equal(one, two) abort
+  for key in keys(a:one)
+    if a:one[key] != a:two[key]
+      return 0
+    endif
+  endfor
+  return 1
+endfunction
+
+" get change between two lines
+function! coc#helper#str_diff(curr, previous, col) abort
+  let end = strpart(a:curr, a:col - 1)
+  let start = strpart(a:curr, 0, a:col -1)
+  let endOffset = 0
+  let startOffset = 0
+  let currLen = strchars(a:curr)
+  let prevLen = strchars(a:previous)
+  if len(end)
+    let endLen = strchars(end)
+    for i in range(min([prevLen, endLen]))
+      if strcharpart(end, endLen - 1 - i, 1) ==# strcharpart(a:previous, prevLen -1 -i, 1)
+        let endOffset = endOffset + 1
+      else
+        break
+      endif
+    endfor
+  endif
+  let remain = endOffset == 0 ? a:previous : strcharpart(a:previous, 0, prevLen - endOffset)
+  if len(remain)
+    for i in range(min([strchars(remain), strchars(start)]))
+      if strcharpart(remain, i, 1) ==# strcharpart(start, i ,1)
+        let startOffset = startOffset + 1
+      else
+        break
+      endif
+    endfor
+  endif
+  return {
+      \ 'start': startOffset,
+      \ 'end': prevLen - endOffset,
+      \ 'text': strcharpart(a:curr, startOffset, currLen - startOffset - endOffset)
+      \ }
+endfunction
+
+function! coc#helper#str_apply(content, diff) abort
+  let totalLen = strchars(a:content)
+  let endLen = totalLen - a:diff['end']
+  return strcharpart(a:content, 0, a:diff['start']).a:diff['text'].strcharpart(a:content, a:diff['end'], endLen)
+endfunction
+
+" insert inserted to line at position, use ... when result is too long
+" line should only contains character has strwidth equals 1
+function! coc#helper#str_compose(line, position, inserted) abort
+  let width = strwidth(a:line)
+  let text = a:inserted
+  let res = a:line
+  let need_truncate = a:position + strwidth(text) + 1 > width
+  if need_truncate
+    let remain = width - a:position - 3
+    if remain < 2
+      " use text for full line, use first & end of a:line, ignore position
+      let res = strcharpart(a:line, 0, 1)
+      let w = strwidth(res)
+      for i in range(strchars(text))
+        let c = strcharpart(text, i, 1)
+        let a = strwidth(c)
+        if w + a <= width - 1
+          let w = w + a
+          let res = res.c
+        endif
+      endfor
+      let res = res.strcharpart(a:line, w)
+    else
+      let res = strcharpart(a:line, 0, a:position)
+      let w = strwidth(res)
+      for i in range(strchars(text))
+        let c = strcharpart(text, i, 1)
+        let a = strwidth(c)
+        if w + a <= width - 3
+          let w = w + a
+          let res = res.c
+        endif
+      endfor
+      let res = res.'..'
+      let w = w + 2
+      let res = res.strcharpart(a:line, w)
+    endif
+  else
+    let first = strcharpart(a:line, 0, a:position)
+    let res = first.text.strcharpart(a:line, a:position + strwidth(text))
+  endif
+  return res
+endfunction
+
+" Return new dict with keys removed
+function! coc#helper#dict_omit(dict, keys) abort
+  let res = {}
+  for key in keys(a:dict)
+    if index(a:keys, key) == -1
+      let res[key] = a:dict[key]
+    endif
+  endfor
+  return res
+endfunction
+
+" Return new dict with keys only
+function! coc#helper#dict_pick(dict, keys) abort
+  let res = {}
+  for key in keys(a:dict)
+    if index(a:keys, key) != -1
+      let res[key] = a:dict[key]
+    endif
+  endfor
+  return res
+endfunction
+
+" support for float values
+function! coc#helper#min(first, ...) abort
+  let val = a:first
+  for i in range(0, len(a:000) - 1)
+    if a:000[i] < val
+      let val = a:000[i]
+    endif
+  endfor
+  return val
+endfunction
+
+" support for float values
+function! coc#helper#max(first, ...) abort
+  let val = a:first
+  for i in range(0, len(a:000) - 1)
+    if a:000[i] > val
+      let val = a:000[i]
+    endif
+  endfor
+  return val
+endfunction

+ 734 - 0
vimfiles/bundle/coc.nvim/autoload/coc/highlight.vim

@@ -0,0 +1,734 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:clear_match_by_window = has('nvim-0.6.0') || has('patch-8.1.1084')
+let s:set_extmark = has('nvim') && exists('*nvim_buf_set_extmark')
+let s:prop_offset = get(g:, 'coc_text_prop_offset', 1000)
+let s:namespace_map = {}
+let s:ns_id = 1
+let s:diagnostic_hlgroups = ['CocErrorHighlight', 'CocWarningHighlight', 'CocInfoHighlight', 'CocHintHighlight', 'CocDeprecatedHighlight', 'CocUnusedHighlight']
+" Maximum count to highlight each time.
+let g:coc_highlight_maximum_count = get(g:, 'coc_highlight_maximum_count', 100)
+
+if has('nvim-0.5.0') && s:clear_match_by_window == 0
+  try
+    call getmatches(0)
+    let s:clear_match_by_window = 1
+  catch /^Vim\%((\a\+)\)\=:E118/
+    " ignored
+  endtry
+endif
+
+" Update buffer region by region.
+function! coc#highlight#buffer_update(bufnr, key, highlights, ...) abort
+  if !bufloaded(a:bufnr)
+    return
+  endif
+  if empty(a:highlights)
+    call coc#highlight#clear_highlight(a:bufnr, a:key, 0, -1)
+    return
+  endif
+  let priority = get(a:, 1, v:null)
+  let changedtick = getbufvar(a:bufnr, 'changedtick', 0)
+  if type(get(a:, 2, v:null)) == 0 && changedtick > a:2
+    return
+  endif
+  let hls = map(copy(a:highlights), "{'hlGroup':v:val[0],'lnum':v:val[1],'colStart':v:val[2],'colEnd':v:val[3],'combine':get(v:val,4,1),'start_incl':get(v:val,5,0),'end_incl':get(v:val,6,0)}")
+  if len(hls) <= g:coc_highlight_maximum_count || get(g:, 'coc_node_env', '') ==# 'test'
+    call coc#highlight#update_highlights(a:bufnr, a:key, hls, 0, -1, priority)
+    return
+  endif
+  let linecount = coc#compat#buf_line_count(a:bufnr)
+  let groups = s:group_hls(hls, linecount)
+  call s:update_highlights_timer(a:bufnr, changedtick, a:key, priority, groups, 0)
+endfunction
+
+" Update highlights by check exists highlights.
+" 0 based, end exclusive start and end
+function! coc#highlight#update_highlights(bufnr, key, highlights, ...) abort
+  let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
+  if !bufloaded(bufnr)
+    return
+  endif
+  let start = get(a:, 1, 0)
+  let end = get(a:, 2, -1)
+  if end == 0
+    return
+  endif
+  let linecount = coc#compat#buf_line_count(a:bufnr)
+  if end >= linecount
+    let end = -1
+  endif
+  if empty(a:highlights)
+    call coc#highlight#clear_highlight(bufnr, a:key, start, end)
+    return
+  endif
+  let priority = get(a:, 3, v:null)
+  let total = len(a:highlights)
+  " index list that exists with current highlights
+  let exists = []
+  let ns = coc#highlight#create_namespace(a:key)
+  if has('nvim-0.5.0') || exists('*prop_list')
+    let endLnum = end < 0 ? linecount - 1 : end - 1
+    let firstLnum = a:highlights[0]['lnum']
+    if firstLnum > start
+      call coc#highlight#clear_highlight(bufnr, a:key, start, firstLnum)
+      let start = firstLnum
+    endif
+    let lastLnum = a:highlights[total - 1]['lnum']
+    if lastLnum < endLnum
+      call coc#highlight#clear_highlight(bufnr, a:key, lastLnum + 1, endLnum + 1)
+      let endLnum = lastLnum
+    endif
+    let current = coc#highlight#get_highlights(bufnr, a:key, start, endLnum)
+    let currIndex = 0
+    if !empty(current)
+      for [lnum, items] in s:to_group(current)
+        let indexes = []
+        let currIndexes = range(0, len(items) - 1)
+        let removeIndexes = []
+        while currIndex != total
+          let hi = a:highlights[currIndex]
+          if hi['lnum'] == lnum
+            let findIndex = -1
+            for idx in currIndexes
+              let item = items[idx]
+              if hi['hlGroup'] ==# item[0] && hi['colStart'] == item[2] && hi['colEnd'] == item[3]
+                call add(indexes, currIndex)
+                let findIndex = idx
+                break
+              elseif item[2] > hi['colStart']
+                break
+              endif
+            endfor
+            if findIndex != -1
+              call filter(currIndexes, 'v:val != '.findIndex)
+            endif
+          elseif hi['lnum'] > lnum
+            break
+          endif
+          let currIndex = currIndex + 1
+        endwhile
+        for idx in currIndexes
+          if s:is_vim
+            call prop_remove({'bufnr': bufnr, 'id': items[idx][4]})
+          else
+            call nvim_buf_del_extmark(bufnr, ns, items[idx][4])
+          endif
+        endfor
+        call extend(exists, indexes)
+      endfor
+    endif
+  else
+    call coc#highlight#clear_highlight(bufnr, a:key, start, end)
+  endif
+  let indexes = range(0, total - 1)
+  if !empty(exists)
+    let indexes = filter(indexes, 'index(exists, v:val) == -1')
+  endif
+  for idx in indexes
+    let hi = a:highlights[idx]
+    let opts = {
+        \ 'combine': get(hi, 'combine', 0),
+        \ 'start_incl': get(hi, 'start_incl', 0),
+        \ 'end_incl': get(hi, 'end_incl', 0),
+        \ }
+    if type(priority) == 0
+      let opts['priority'] = s:get_priority(a:key, hi['hlGroup'], priority)
+    endif
+    call coc#highlight#add_highlight(bufnr, ns, hi['hlGroup'], hi['lnum'], hi['colStart'], hi['colEnd'], opts)
+  endfor
+endfunction
+
+" Get list of highlights by range or all buffer.
+" 0 based line, start_col and end_col
+" 0 based start & end line, end inclusive.
+function! coc#highlight#get_highlights(bufnr, key, ...) abort
+  if !bufloaded(a:bufnr)
+    return v:null
+  endif
+  if !has_key(s:namespace_map, a:key)
+    return []
+  endif
+  let start = get(a:, 1, 0)
+  let end = get(a:, 2, -1)
+  let res = []
+  let ns = s:namespace_map[a:key]
+  if exists('*prop_list')
+    let types = coc#api#get_types(ns)
+    if empty(types)
+      return res
+    endif
+    " Could filter by end_lnum and types
+    if has('patch-8.2.3652')
+      let endLnum = end == -1 ? -1 : end + 1
+      for prop in prop_list(start + 1, {'bufnr': a:bufnr, 'types': types, 'end_lnum': endLnum})
+        if prop['start'] == 0 || prop['end'] == 0
+          " multi line textprop are not supported, simply ignore it
+          continue
+        endif
+        let startCol = prop['col'] - 1
+        let endCol = startCol + prop['length']
+        call add(res, [s:prop_type_hlgroup(prop['type']), prop['lnum'] - 1, startCol, endCol, prop['id']])
+      endfor
+    else
+      if end == -1
+        let end = coc#compat#buf_line_count(a:bufnr)
+      else
+        let end = end + 1
+      endif
+      for line in range(start + 1, end)
+        for prop in prop_list(line, {'bufnr': a:bufnr})
+          if index(types, prop['type']) == -1 || prop['start'] == 0 || prop['end'] == 0
+            " multi line textprop are not supported, simply ignore it
+            continue
+          endif
+          let startCol = prop['col'] - 1
+          let endCol = startCol + prop['length']
+          call add(res, [s:prop_type_hlgroup(prop['type']), line - 1, startCol, endCol, prop['id']])
+        endfor
+      endfor
+    endif
+  elseif has('nvim-0.5.0')
+    let start = [start, 0]
+    let maximum = end == -1 ? nvim_buf_line_count(a:bufnr) : end + 1
+    let end = end == -1 ? -1 : [end + 1, 0]
+    let markers = nvim_buf_get_extmarks(a:bufnr, ns, start, -1, {'details': v:true})
+    for [marker_id, line, start_col, details] in markers
+      if line >= maximum
+        " Could be markers exceed end of line
+        continue
+      endif
+      let delta = details['end_row'] - line
+      if delta > 1 || (delta == 1 && details['end_col'] != 0)
+        " can't handle, single line only
+        continue
+      endif
+      let endCol = details['end_col']
+      if endCol == start_col
+        call nvim_buf_del_extmark(a:bufnr, ns, marker_id)
+        continue
+      endif
+      if delta == 1
+        let text = get(nvim_buf_get_lines(a:bufnr, line, line + 1, 0), 0, '')
+        let endCol = strlen(text)
+      endif
+      call add(res, [details['hl_group'], line, start_col, endCol, marker_id])
+    endfor
+  else
+    throw 'Get highlights requires neovim 0.5.0 or vim support prop_list'
+  endif
+  return res
+endfunction
+
+" Add multiple highlights to buffer.
+" type HighlightItem = [hlGroup, lnum, colStart, colEnd, combine?, start_incl?, end_incl?]
+function! coc#highlight#set(bufnr, key, highlights, priority) abort
+  if !bufloaded(a:bufnr)
+    return
+  endif
+    let ns = coc#highlight#create_namespace(a:key)
+    if len(a:highlights) > g:coc_highlight_maximum_count
+      call s:add_highlights_timer(a:bufnr, ns, a:highlights, a:priority)
+    else
+      call s:add_highlights(a:bufnr, ns, a:highlights, a:priority)
+    endif
+endfunction
+
+" Clear highlights by 0 based line numbers.
+function! coc#highlight#clear(bufnr, key, lnums) abort
+  if !bufloaded(a:bufnr) || empty(a:lnums)
+    return
+  endif
+  let ns = coc#highlight#create_namespace(a:key)
+  for lnum in a:lnums
+    if has('nvim')
+      call nvim_buf_clear_namespace(a:bufnr, ns, lnum, lnum + 1)
+    else
+      call coc#api#exec('buf_clear_namespace', [a:bufnr, ns, lnum, lnum + 1])
+    endif
+  endfor
+  " clear highlights in invalid line.
+  if has('nvim')
+    let linecount = nvim_buf_line_count(a:bufnr)
+    call nvim_buf_clear_namespace(a:bufnr, ns, linecount, -1)
+  endif
+endfunction
+
+function! coc#highlight#del_markers(bufnr, key, ids) abort
+  if !bufloaded(a:bufnr)
+    return
+  endif
+  let ns = coc#highlight#create_namespace(a:key)
+  for id in a:ids
+    if s:is_vim
+      call prop_remove({'bufnr': a:bufnr, 'id': id})
+    else
+      call nvim_buf_del_extmark(a:bufnr, ns, id)
+    endif
+  endfor
+endfunction
+
+" highlight LSP range,
+function! coc#highlight#ranges(bufnr, key, hlGroup, ranges, ...) abort
+  let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
+  if !bufloaded(bufnr) || !exists('*getbufline')
+    return
+  endif
+  let opts = get(a:, 1, {})
+  let synmaxcol = getbufvar(a:bufnr, '&synmaxcol', 1000)
+  if synmaxcol == 0
+    let synmaxcol = 1000
+  endif
+  let synmaxcol = min([synmaxcol, 1000])
+  let srcId = coc#highlight#create_namespace(a:key)
+  for range in a:ranges
+    let start = range['start']
+    let end = range['end']
+    for lnum in range(start['line'] + 1, end['line'] + 1)
+      let arr = getbufline(bufnr, lnum)
+      let line = empty(arr) ? '' : arr[0]
+      if empty(line)
+        continue
+      endif
+      if start['character'] > synmaxcol || end['character'] > synmaxcol
+        continue
+      endif
+      " TODO don't know how to count UTF16 code point, should work most cases.
+      let colStart = lnum == start['line'] + 1 ? strlen(strcharpart(line, 0, start['character'])) : 0
+      let colEnd = lnum == end['line'] + 1 ? strlen(strcharpart(line, 0, end['character'])) : strlen(line)
+      if colStart == colEnd
+        continue
+      endif
+      call coc#highlight#add_highlight(bufnr, srcId, a:hlGroup, lnum - 1, colStart, colEnd, opts)
+    endfor
+  endfor
+endfunction
+
+function! coc#highlight#add_highlight(bufnr, src_id, hl_group, line, col_start, col_end, ...) abort
+  let opts = get(a:, 1, {})
+  let priority = get(opts, 'priority', v:null)
+  if !s:is_vim
+    if s:set_extmark && a:src_id != -1
+      " get(opts, 'start_incl', 0) ? v:true : v:false,
+      try
+        call nvim_buf_set_extmark(a:bufnr, a:src_id, a:line, a:col_start, {
+              \ 'end_col': a:col_end,
+              \ 'hl_group': a:hl_group,
+              \ 'hl_mode': get(opts, 'combine', 1) ? 'combine' : 'replace',
+              \ 'right_gravity': v:true,
+              \ 'end_right_gravity': v:false,
+              \ 'priority': type(priority) == 0 ?  min([priority, 4096]) : 4096,
+              \ })
+      catch /^Vim\%((\a\+)\)\=:E5555/
+        " the end_col could be invalid, ignore this error
+      endtry
+    else
+      call nvim_buf_add_highlight(a:bufnr, a:src_id, a:hl_group, a:line, a:col_start, a:col_end)
+    endif
+  else
+    call coc#api#exec('buf_add_highlight', [a:bufnr, a:src_id, a:hl_group, a:line, a:col_start, a:col_end, opts])
+  endif
+endfunction
+
+function! coc#highlight#clear_highlight(bufnr, key, start_line, end_line) abort
+  let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
+  if !bufloaded(bufnr)
+    return
+  endif
+  let src_id = coc#highlight#create_namespace(a:key)
+  if has('nvim')
+    call nvim_buf_clear_namespace(a:bufnr, src_id, a:start_line, a:end_line)
+  else
+    call coc#api#exec('buf_clear_namespace', [a:bufnr, src_id, a:start_line, a:end_line])
+  endif
+endfunction
+
+" highlight buffer in winid with CodeBlock &HighlightItems
+" export interface HighlightItem {
+"   lnum: number // 0 based
+"   hlGroup: string
+"   colStart: number // 0 based
+"   colEnd: number
+" }
+" export interface CodeBlock {
+"   filetype?: string
+"   hlGroup?: string
+"   startLine: number // 0 based
+"   endLine: number
+" }
+function! coc#highlight#add_highlights(winid, codes, highlights) abort
+  if get(g:, 'coc_node_env', '') ==# 'test'
+    call setwinvar(a:winid, 'highlights', a:highlights)
+  endif
+  " clear highlights
+  call coc#compat#execute(a:winid, 'syntax clear')
+  let bufnr = winbufnr(a:winid)
+  call coc#highlight#clear_highlight(bufnr, -1, 0, -1)
+  if !empty(a:codes)
+    call coc#highlight#highlight_lines(a:winid, a:codes)
+  endif
+  if !empty(a:highlights)
+    for item in a:highlights
+      let hlGroup = item['hlGroup']
+      let opts = hlGroup =~# 'Search$' ? {'priority': 999, 'combine': 1} : {}
+      call coc#highlight#add_highlight(bufnr, -1, hlGroup, item['lnum'], item['colStart'], item['colEnd'])
+    endfor
+  endif
+endfunction
+
+
+" Add highlights to line groups of winid, support hlGroup and filetype
+" config should have startLine, endLine (0 based, end excluded) and filetype or hlGroup
+" endLine should > startLine and endLine is excluded
+"
+" export interface CodeBlock {
+"   filetype?: string
+"   hlGroup?: string
+"   startLine: number // 0 based
+"   endLine: number
+" }
+function! coc#highlight#highlight_lines(winid, blocks) abort
+  let region_id = 1
+  let defined = []
+  let cmds = []
+  for config in a:blocks
+    let start = config['startLine'] + 1
+    let end = config['endLine'] == -1 ? len(getbufline(winbufnr(a:winid), 1, '$')) + 1 : config['endLine'] + 1
+    let filetype = get(config, 'filetype', '')
+    let hlGroup = get(config, 'hlGroup', '')
+    if !empty(hlGroup)
+      call add(cmds, 'syntax region '.hlGroup.' start=/\%'.start.'l/ end=/\%'.end.'l/')
+    else
+      let filetype = matchstr(filetype, '\v^\w+')
+      if empty(filetype) || filetype == 'txt' || index(get(g:, 'coc_markdown_disabled_languages', []), filetype) != -1
+        continue
+      endif
+      if index(defined, filetype) == -1
+        call add(cmds, 'syntax include @'.toupper(filetype).' syntax/'.filetype.'.vim')
+        call add(cmds, 'unlet! b:current_syntax')
+        call add(defined, filetype)
+      endif
+      call add(cmds, 'syntax region CodeBlock'.region_id.' start=/\%'.start.'l/ end=/\%'.end.'l/ contains=@'.toupper(filetype).' keepend')
+      let region_id = region_id + 1
+    endif
+  endfor
+  if !empty(cmds)
+    call coc#compat#execute(a:winid, cmds, 'silent!')
+  endif
+endfunction
+
+" Compose hlGroups with foreground and background colors.
+function! coc#highlight#compose_hlgroup(fgGroup, bgGroup) abort
+  let hlGroup = 'Fg'.a:fgGroup.'Bg'.a:bgGroup
+  if a:fgGroup ==# a:bgGroup
+    return a:fgGroup
+  endif
+  if hlexists(hlGroup) && match(execute('hi '.hlGroup, 'silent!'), 'cleared') == -1
+    return hlGroup
+  endif
+  let fgId = synIDtrans(hlID(a:fgGroup))
+  let bgId = synIDtrans(hlID(a:bgGroup))
+  let isGuiReversed = synIDattr(fgId, 'reverse', 'gui') !=# '1' || synIDattr(bgId, 'reverse', 'gui') !=# '1'
+  let guifg = isGuiReversed ? synIDattr(fgId, 'fg', 'gui') : synIDattr(fgId, 'bg', 'gui')
+  let guibg = isGuiReversed ? synIDattr(bgId, 'bg', 'gui') : synIDattr(bgId, 'fg', 'gui')
+  let isCtermReversed = synIDattr(fgId, 'reverse', 'cterm') !=# '1' || synIDattr(bgId, 'reverse', 'cterm') !=# '1'
+  let ctermfg = isCtermReversed ? synIDattr(fgId, 'fg', 'cterm') : synIDattr(fgId, 'bg', 'cterm')
+  let ctermbg = isCtermReversed ? synIDattr(bgId, 'bg', 'cterm') : synIDattr(bgId, 'fg', 'cterm')
+  let bold = synIDattr(fgId, 'bold') ==# '1'
+  let italic = synIDattr(fgId, 'italic') ==# '1'
+  let underline = synIDattr(fgId, 'underline') ==# '1'
+  let cmd = 'silent hi ' . hlGroup
+  if !empty(guifg)
+    let cmd .= ' guifg=' . guifg
+  endif
+  if !empty(ctermfg)
+    let cmd .= ' ctermfg=' . ctermfg
+  elseif guifg =~# '^#'
+    let cmd .= ' ctermfg=' . coc#color#rgb2term(strpart(guifg, 1))
+  endif
+  if !empty(guibg)
+    let cmd .= ' guibg=' . guibg
+  endif
+  if !empty(ctermbg)
+    let cmd .= ' ctermbg=' . ctermbg
+  elseif guibg =~# '^#'
+    let cmd .= ' ctermbg=' . coc#color#rgb2term(strpart(guibg, 1))
+  endif
+  if bold
+    let cmd .= ' cterm=bold gui=bold'
+  elseif italic
+    let cmd .= ' cterm=italic gui=italic'
+  elseif underline
+    let cmd .= ' cterm=underline gui=underline'
+  endif
+  if cmd ==# 'silent hi ' . hlGroup
+      return 'Normal'
+  endif
+  execute cmd
+  return hlGroup
+endfunction
+
+" add matches for winid, use 0 for current window.
+function! coc#highlight#match_ranges(winid, bufnr, ranges, hlGroup, priority) abort
+  let winid = a:winid == 0 ? win_getid() : a:winid
+  let bufnr = a:bufnr == 0 ? winbufnr(winid) : a:bufnr
+  if empty(getwininfo(winid)) || (a:bufnr != 0 && winbufnr(a:winid) != a:bufnr)
+    " not valid
+    return []
+  endif
+  if !s:clear_match_by_window
+    let curr = win_getid()
+    if has('nvim')
+      noa call nvim_set_current_win(winid)
+    else
+      noa call win_gotoid(winid)
+    endif
+  endif
+  let ids = []
+  for range in a:ranges
+    let pos = []
+    let start = range['start']
+    let end = range['end']
+    for lnum in range(start['line'] + 1, end['line'] + 1)
+      let arr = getbufline(bufnr, lnum)
+      let line = empty(arr) ? '' : arr[0]
+      if empty(line)
+        continue
+      endif
+      let colStart = lnum == start['line'] + 1 ? strlen(strcharpart(line, 0, start['character'])) + 1 : 1
+      let colEnd = lnum == end['line'] + 1 ? strlen(strcharpart(line, 0, end['character'])) + 1 : strlen(line) + 1
+      if colStart == colEnd
+        continue
+      endif
+      call add(pos, [lnum, colStart, colEnd - colStart])
+    endfor
+    if !empty(pos)
+      let opts = s:clear_match_by_window ? {'window': a:winid} : {}
+      let i = 1
+      let l = []
+      for p in pos
+        call add(l, p)
+        if i % 8 == 0
+          let id = matchaddpos(a:hlGroup, l, a:priority, -1, opts)
+          call add(ids, id)
+          let l = []
+        endif
+        let i += 1
+      endfor
+      if !empty(l)
+        let id = matchaddpos(a:hlGroup, l, a:priority, -1, opts)
+        call add(ids, id)
+      endif
+    endif
+  endfor
+  if !s:clear_match_by_window
+    if has('nvim')
+      noa call nvim_set_current_win(curr)
+    else
+      noa call win_gotoid(curr)
+    endif
+  endif
+  return ids
+endfunction
+
+" Clear matches by hlGroup regexp.
+function! coc#highlight#clear_match_group(winid, match) abort
+  let winid = a:winid == 0 ? win_getid() : a:winid
+  if empty(getwininfo(winid))
+    " not valid
+    return
+  endif
+  if s:clear_match_by_window
+    let arr = filter(getmatches(winid), 'v:val["group"] =~# "'.a:match.'"')
+    for item in arr
+      call matchdelete(item['id'], winid)
+    endfor
+  else
+    let curr = win_getid()
+    let switch = exists('*nvim_set_current_win') && curr != winid
+    if switch
+      noa call nvim_set_current_win(a:winid)
+    endif
+    if win_getid() == winid
+      let arr = filter(getmatches(), 'v:val["group"] =~# "'.a:match.'"')
+      for item in arr
+        call matchdelete(item['id'])
+      endfor
+    endif
+    if switch
+      noa call nvim_set_current_win(curr)
+    endif
+  endif
+endfunction
+
+" Clear matches by match ids, use 0 for current win.
+function! coc#highlight#clear_matches(winid, ids)
+  let winid = a:winid == 0 ? win_getid() : a:winid
+  if empty(getwininfo(winid))
+    " not valid
+    return
+  endif
+  if s:clear_match_by_window
+    for id in a:ids
+      try
+        call matchdelete(id, winid)
+      catch /^Vim\%((\a\+)\)\=:E803/
+        " ignore
+      endtry
+    endfor
+  else
+    let curr = win_getid()
+    let switch = exists('*nvim_set_current_win') && curr != winid
+    if switch
+      noa call nvim_set_current_win(a:winid)
+    endif
+    if win_getid() == winid
+      for id in a:ids
+        try
+          call matchdelete(id)
+        catch /^Vim\%((\a\+)\)\=:E803/
+          " ignore
+        endtry
+      endfor
+    endif
+    if switch
+      noa call nvim_set_current_win(curr)
+    endif
+  endif
+endfunction
+
+function! coc#highlight#clear_all() abort
+  for src_id in values(s:namespace_map)
+    for bufnr in map(getbufinfo({'bufloaded': 1}), 'v:val["bufnr"]')
+      if has('nvim')
+        call nvim_buf_clear_namespace(bufnr, src_id, 0, -1)
+      else
+        call coc#api#exec('buf_clear_namespace', [bufnr, src_id, 0, -1])
+      endif
+    endfor
+  endfor
+endfunction
+
+function! coc#highlight#create_namespace(key) abort
+  if type(a:key) == 0
+    return a:key
+  endif
+  if has_key(s:namespace_map, a:key)
+    return s:namespace_map[a:key]
+  endif
+  if has('nvim')
+    let s:namespace_map[a:key] = nvim_create_namespace('coc-'.a:key)
+  else
+    let s:namespace_map[a:key] = s:ns_id
+    let s:ns_id = s:ns_id + 1
+  endif
+  return s:namespace_map[a:key]
+endfunction
+
+function! coc#highlight#get_syntax_name(lnum, col)
+  return synIDattr(synIDtrans(synID(a:lnum,a:col,1)),"name")
+endfunction
+
+function! s:prop_type_hlgroup(type) abort
+  return substitute(a:type, '_\d\+$', '', '')
+endfunction
+
+function! s:update_highlights_timer(bufnr, changedtick, key, priority, groups, idx) abort
+  if getbufvar(a:bufnr, 'changedtick', 0) != a:changedtick
+    return
+  endif
+  let group = get(a:groups, a:idx, v:null)
+  if empty(group)
+    return
+  endif
+  if empty(group['highlights'])
+    call coc#highlight#clear_highlight(a:bufnr, a:key, group['start'], group['end'])
+  else
+    call coc#highlight#update_highlights(a:bufnr, a:key, group['highlights'], group['start'], group['end'], a:priority)
+  endif
+  if a:idx < len(a:groups) - 1
+    call timer_start(50, { -> s:update_highlights_timer(a:bufnr, a:changedtick, a:key, a:priority, a:groups, a:idx + 1)})
+  endif
+endfunction
+
+function! s:add_highlights_timer(bufnr, ns, highlights, priority) abort
+  let hls = []
+  let next = []
+  for i in range(0, len(a:highlights) - 1)
+    if i < g:coc_highlight_maximum_count
+      call add(hls, a:highlights[i])
+    else
+      call add(next, a:highlights[i])
+    endif
+  endfor
+  call s:add_highlights(a:bufnr, a:ns, hls, a:priority)
+  if len(next)
+    call timer_start(30, {->s:add_highlights_timer(a:bufnr, a:ns, next, a:priority)})
+  endif
+endfunction
+
+function! s:add_highlights(bufnr, ns, highlights, priority) abort
+  for item in a:highlights
+    let opts = {
+          \ 'priority': a:priority,
+          \ 'combine': get(item, 4, 1) ? 1 : 0,
+          \ 'start_incl': get(item, 5, 0) ? 1 : 0,
+          \ 'end_incl':  get(item, 6, 0) ? 1 : 0,
+          \ }
+    call coc#highlight#add_highlight(a:bufnr, a:ns, item[0], item[1], item[2], item[3], opts)
+  endfor
+endfunction
+
+function! s:to_group(items) abort
+  let res = []
+  let before = v:null
+  for item in a:items
+    if empty(before) || before[0] != item[1]
+      let before = [item[1], [item]]
+      call add(res, before)
+    else
+      call add(before[1], item)
+    endif
+  endfor
+  return res
+endfunction
+
+function! s:get_priority(key, hlGroup, priority) abort
+  if a:hlGroup ==# 'CocSearch'
+    return 999
+  endif
+  if strpart(a:key, 0, 10) !=# 'diagnostic'
+    return a:priority
+  endif
+  return a:priority - index(s:diagnostic_hlgroups, a:hlGroup)
+endfunction
+
+function! s:group_hls(hls, linecount) abort
+  " start, end, highlights
+  let groups = []
+  if empty(a:hls)
+    call add(groups, {'start': 0, 'end': a:linecount, 'highlights': []})
+    return groups
+  endif
+  let start = 0
+  let highlights = []
+  let lastLnum = -1
+  for item in a:hls
+    let lnum = item['lnum']
+    if lnum >= a:linecount
+      break
+    endif
+    if len(highlights) < g:coc_highlight_maximum_count || lnum == lastLnum
+      call add(highlights, item)
+      let lastLnum = lnum
+    else
+      call add(groups, {'start': start, 'end': lastLnum + 1, 'highlights': highlights})
+      let highlights = []
+      let start = lastLnum + 1
+      call add(highlights, item)
+      let lastLnum = lnum
+    endif
+  endfor
+  call add(groups, {'start': start, 'end': a:linecount, 'highlights': highlights})
+  return groups
+endfunction

+ 303 - 0
vimfiles/bundle/coc.nvim/autoload/coc/list.vim

@@ -0,0 +1,303 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:prefix = '[List Preview]'
+let s:sign_group = 'CocList'
+" filetype detect could be slow.
+let s:filetype_map = {
+      \ 'c': 'c',
+      \ 'py': 'python',
+      \ 'vim': 'vim',
+      \ 'ts': 'typescript',
+      \ 'js': 'javascript',
+      \ 'html': 'html',
+      \ 'css': 'css'
+      \ }
+
+function! coc#list#getchar() abort
+  return coc#prompt#getchar()
+endfunction
+
+function! coc#list#setlines(bufnr, lines, append)
+  if a:append
+    silent call appendbufline(a:bufnr, '$', a:lines)
+  else
+    if exists('*deletebufline')
+      silent call deletebufline(a:bufnr, len(a:lines) + 1, '$')
+    else
+      let n = len(a:lines) + 1
+      let saved_reg = @"
+      silent execute n.',$d'
+      let @" = saved_reg
+    endif
+    silent call setbufline(a:bufnr, 1, a:lines)
+  endif
+endfunction
+
+function! coc#list#options(...)
+  let list = ['--top', '--tab', '--normal', '--no-sort', '--input', '--strict',
+        \ '--regex', '--interactive', '--number-select', '--auto-preview',
+        \ '--ignore-case', '--no-quit', '--first', '--reverse']
+  if get(g:, 'coc_enabled', 0)
+    let names = coc#rpc#request('listNames', [])
+    call extend(list, names)
+  endif
+  return join(list, "\n")
+endfunction
+
+function! coc#list#names(...) abort
+  let names = coc#rpc#request('listNames', [])
+  return join(names, "\n")
+endfunction
+
+function! coc#list#status(name)
+  if !exists('b:list_status') | return '' | endif
+  return get(b:list_status, a:name, '')
+endfunction
+
+function! coc#list#create(position, height, name, numberSelect)
+  if a:position ==# 'tab'
+    execute 'silent tabe list:///'.a:name
+  else
+    execute 'silent keepalt '.(a:position ==# 'top' ? '' : 'botright').a:height.'sp list:///'.a:name
+    execute 'resize '.a:height
+  endif
+  if a:numberSelect
+    setl norelativenumber
+    setl number
+  else
+    setl nonumber
+    setl norelativenumber
+  endif
+  return [bufnr('%'), win_getid(), tabpagenr()]
+endfunction
+
+" close list windows
+function! coc#list#clean_up() abort
+  for i in range(1, winnr('$'))
+    let bufname = bufname(winbufnr(i))
+    if bufname =~# 'list://'
+      execute i.'close!'
+    endif
+  endfor
+endfunction
+
+function! coc#list#setup(source)
+  let b:list_status = {}
+  setl buftype=nofile nobuflisted nofen nowrap
+  setl norelativenumber bufhidden=wipe nocursorline winfixheight
+  setl tabstop=1 nolist nocursorcolumn undolevels=-1
+  setl signcolumn=auto
+  if has('nvim-0.5.0') || has('patch-8.1.0864')
+    setl scrolloff=0
+  endif
+  setl filetype=list
+  syntax case ignore
+  let source = a:source[8:]
+  let name = toupper(source[0]).source[1:]
+  execute 'syntax match Coc'.name.'Line /\v^.*$/'
+  if !s:is_vim
+    " Repeat press <C-f> and <C-b> would invoke <esc> on vim
+    nnoremap <silent><nowait><buffer> <esc> <C-w>c
+  endif
+endfunction
+
+function! coc#list#select(bufnr, line) abort
+  call sign_unplace(s:sign_group, { 'buffer': a:bufnr })
+  if a:line > 0
+    call sign_place(6, s:sign_group, 'CocListCurrent', a:bufnr, {'lnum': a:line})
+  endif
+endfunction
+
+" Check if previewwindow exists on current tab.
+function! coc#list#has_preview()
+  for i in range(1, winnr('$'))
+    let preview = getwinvar(i, 'previewwindow', getwinvar(i, '&previewwindow', 0))
+    if preview
+      return i
+    endif
+  endfor
+  return 0
+endfunction
+
+" Get previewwindow from tabnr, use 0 for current tab
+function! coc#list#get_preview(...) abort
+  let tabnr = get(a:, 1, 0) == 0 ? tabpagenr() : a:1
+  let info = gettabinfo(tabnr)
+  if !empty(info)
+    for win in info[0]['windows']
+      if gettabwinvar(tabnr, win, 'previewwindow', 0)
+        return win
+      endif
+    endfor
+  endif
+  return -1
+endfunction
+
+function! coc#list#scroll_preview(dir) abort
+  let winnr = coc#list#has_preview()
+  if !winnr
+    return
+  endif
+  let winid = win_getid(winnr)
+  if exists('*win_execute')
+    call win_execute(winid, "normal! ".(a:dir ==# 'up' ? "\<C-u>" : "\<C-d>"))
+  else
+    let id = win_getid()
+    noa call win_gotoid(winid)
+    execute "normal! ".(a:dir ==# 'up' ? "\<C-u>" : "\<C-d>")
+    noa call win_gotoid(id)
+  endif
+endfunction
+
+function! coc#list#close_preview(tabnr) abort
+  let winid = coc#list#get_preview(a:tabnr)
+  if winid != -1
+    call coc#window#close(winid)
+  endif
+endfunction
+
+" Improve preview performance by reused window & buffer.
+" lines - list of lines
+" config.position - could be 'below' 'top' 'tab'.
+" config.winid - id of original window.
+" config.name - (optional )name of preview buffer.
+" config.splitRight - (optional) split to right when 1.
+" config.lnum - (optional) current line number
+" config.filetype - (optional) filetype of lines.
+" config.hlGroup - (optional) highlight group.
+" config.maxHeight - (optional) max height of window, valid for 'below' & 'top' position.
+function! coc#list#preview(lines, config) abort
+  let name = fnamemodify(get(a:config, 'name', ''), ':.')
+  let lines = a:lines
+  if empty(lines)
+    if get(a:config, 'scheme', 'file') != 'file'
+      let bufnr = s:load_buffer(name)
+      let lines = bufnr == 0 ? [''] : getbufline(bufnr, 1, '$')
+    else
+      " Show empty lines so not close window.
+      let lines = ['']
+    endif
+  endif
+  let winid = coc#list#get_preview(0)
+  let bufnr = winid == -1 ? 0 : winbufnr(winid)
+  " Try reuse buffer & window
+  let bufnr = coc#float#create_buf(bufnr, lines)
+  if bufnr == 0
+    return
+  endif
+  call setbufvar(bufnr, '&synmaxcol', 500)
+  let filetype = get(a:config, 'filetype', '')
+  let extname = matchstr(name, '\.\zs[^.]\+$')
+  if empty(filetype) && !empty(extname)
+    let filetype = get(s:filetype_map, extname, '')
+  endif
+  let range = get(a:config, 'range', v:null)
+  let hlGroup = get(a:config, 'hlGroup', 'Search')
+  let lnum = get(a:config, 'lnum', 1)
+  let position = get(a:config, 'position', 'below')
+  let original = get(a:config, 'winid', -1)
+  if winid == -1
+    let change = position != 'tab' && get(a:config, 'splitRight', 0)
+    let curr = win_getid()
+    if change
+      if original && win_id2win(original)
+        noa call win_gotoid(original)
+      else
+        noa wincmd t
+      endif
+      execute 'noa belowright vert sb '.bufnr
+      let winid = win_getid()
+    elseif position == 'tab' || get(a:config, 'splitRight', 0)
+      execute 'noa belowright vert sb '.bufnr
+      let winid = win_getid()
+    else
+      let mod = position == 'top' ? 'below' : 'above'
+      let height = s:get_height(lines, a:config)
+      execute 'noa '.mod.' sb +resize\ '.height.' '.bufnr
+      let winid = win_getid()
+    endif
+    noa call winrestview({"lnum": lnum ,"topline":s:get_topline(a:config, lnum, winid)})
+    call s:set_preview_options(winid)
+    noa call win_gotoid(curr)
+  else
+    let height = s:get_height(lines, a:config)
+    if height > 0
+      if s:is_vim
+        let curr = win_getid()
+        noa call win_gotoid(winid)
+        execute 'silent! noa resize '.height
+        noa call win_gotoid(curr)
+      else
+        call nvim_win_set_height(winid, height)
+      endif
+    endif
+    call coc#compat#execute(winid, ['syntax clear', 'noa call winrestview({"lnum":'.lnum.',"topline":'.s:get_topline(a:config, lnum, winid).'})'])
+  endif
+  call setwinvar(winid, '&foldenable', 0)
+  if s:prefix.' '.name != bufname(bufnr)
+    if s:is_vim
+      call win_execute(winid, 'noa file '.fnameescape(s:prefix.' '.name), 'silent!')
+    else
+      silent! noa call nvim_buf_set_name(bufnr, s:prefix.' '.name)
+    endif
+  endif
+  " highlights
+  if !empty(filetype)
+    let start = max([0, lnum - 300])
+    let end = min([len(lines), lnum + 300])
+    call coc#highlight#highlight_lines(winid, [{'filetype': filetype, 'startLine': start, 'endLine': end}])
+    call coc#compat#execute(winid, 'syn sync fromstart')
+  else
+    call coc#compat#execute(winid, 'filetype detect')
+    let ft = getbufvar(bufnr, '&filetype', '')
+    if !empty(extname) && !empty(ft)
+      let s:filetype_map[extname] = ft
+    endif
+  endif
+  call sign_unplace('CocCursorLine', {'buffer': bufnr})
+  call coc#compat#execute(winid, 'call clearmatches()')
+  if !s:is_vim
+    " vim send <esc> to buffer on FocusLost, <C-w> and other cases
+    call coc#compat#execute(winid, 'nnoremap <silent><nowait><buffer> <esc> :call CocActionAsync("listCancel")<CR>')
+  endif
+  if !empty(range)
+    call sign_place(1, 'CocCursorLine', 'CocCurrentLine', bufnr, {'lnum': lnum})
+    call coc#highlight#match_ranges(winid, bufnr, [range], hlGroup, 10)
+  endif
+endfunction
+
+function! s:get_height(lines, config) abort
+  if get(a:config, 'splitRight', 0) || get(a:config, 'position', 'below') == 'tab'
+    return 0
+  endif
+  let height = min([get(a:config, 'maxHeight', 10), len(a:lines), &lines - &cmdheight - 2])
+  return height
+endfunction
+
+function! s:load_buffer(name) abort
+  if exists('*bufadd') && exists('*bufload')
+    let bufnr = bufadd(a:name)
+    call bufload(bufnr)
+    return bufnr
+  endif
+  return 0
+endfunction
+
+function! s:get_topline(config, lnum, winid) abort
+  let toplineStyle = get(a:config, 'toplineStyle', 'offset')
+  if toplineStyle == 'middle'
+    return max([1, a:lnum - winheight(a:winid)/2])
+  endif
+
+  let toplineOffset = get(a:config, 'toplineOffset', 3)
+  return max([1, a:lnum - toplineOffset])
+endfunction
+
+function! s:set_preview_options(winid) abort
+  call setwinvar(a:winid, '&foldmethod', 'manual')
+  call setwinvar(a:winid, '&signcolumn', 'no')
+  call setwinvar(a:winid, '&number', 1)
+  call setwinvar(a:winid, '&cursorline', 0)
+  call setwinvar(a:winid, '&relativenumber', 0)
+  call setwinvar(a:winid, 'previewwindow', 1)
+endfunction

+ 11 - 0
vimfiles/bundle/coc.nvim/autoload/coc/math.vim

@@ -0,0 +1,11 @@
+
+" support for float values
+function! coc#math#min(first, ...) abort
+  let val = a:first
+  for i in range(0, len(a:000) - 1)
+    if a:000[i] < val
+      let val = a:000[i]
+    endif
+  endfor
+  return val
+endfunction

+ 532 - 0
vimfiles/bundle/coc.nvim/autoload/coc/notify.vim

@@ -0,0 +1,532 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:utf = &encoding =~# '^utf'
+let s:error_icon = get(g:, 'coc_notify_error_icon', s:utf ? '' : 'E')
+let s:warning_icon = get(g:, 'coc_notify_warning_icon', s:utf ? '⚠' : 'W')
+let s:info_icon = get(g:, 'coc_notify_info_icon', s:utf ? '' : 'I')
+let s:interval = get(g:, 'coc_notify_interval', s:is_vim ? 50 : 20)
+let s:phl = 'CocNotificationProgress'
+let s:progress_char = '─'
+let s:duration = 300.0
+let s:winids = []
+
+" Valid notify winids on current tab
+function! coc#notify#win_list() abort
+  call filter(s:winids, 'coc#float#valid(v:val)')
+  return filter(copy(s:winids), '!empty(getwinvar(v:val,"float"))')
+endfunction
+
+function! coc#notify#close_all() abort
+  for winid in coc#notify#win_list()
+    call coc#notify#close(winid)
+  endfor
+endfunction
+
+" Do action for winid or first notify window with actions.
+function! coc#notify#do_action(...) abort
+  let winids = a:0 > 0 ? a:000 : coc#notify#win_list()
+  for winid in winids
+    if coc#float#valid(winid) && getwinvar(winid, 'closing', 0) != 1
+      let actions = getwinvar(winid, 'actions', [])
+      if !empty(actions)
+        let items = map(copy(actions), '(v:key + 1).". ".v:val')
+        let msg = join(getbufline(winbufnr(winid), 1, '$'), ' ')
+        call coc#ui#quickpick(msg, items, {err, res -> s:on_action(err, res, winid) })
+        break
+      endif
+    endif
+  endfor
+endfunction
+
+" Copy notification contents
+function! coc#notify#copy() abort
+  let lines = []
+  for winid in coc#notify#win_list()
+    let key = getwinvar(winid, 'key', v:null)
+    if type(key) == v:t_string
+      call extend(lines, json_decode(key)['lines'])
+    endif
+  endfor
+  if empty(lines)
+    echohl WarningMsg | echon 'No content to copy' | echohl None
+    return
+  endif
+  call setreg('*', join(lines, "\n"))
+endfunction
+
+" Show source name in window
+function! coc#notify#show_sources() abort
+  if !exists('*getbufline') || !exists('*appendbufline')
+    throw "getbufline and appendbufline functions required, please upgrade your vim."
+  endif
+  let winids = filter(coc#notify#win_list(), 'coc#window#get_var(v:val,"closing") != 1')
+  for winid in winids
+    let key = getwinvar(winid, 'key', v:null)
+    if type(key) == v:t_string
+      let bufnr = winbufnr(winid)
+      let obj = json_decode(key)
+      let sourcename = get(obj, 'source', '')
+      let lnum = get(obj, 'kind', '') ==# 'progress' ? 1 : 0
+      let content = get(getbufline(bufnr, lnum + 1), 0, '')
+      if empty(sourcename) || content ==# sourcename
+        continue
+      endif
+      call appendbufline(bufnr, lnum, sourcename)
+      call coc#highlight#add_highlight(bufnr, -1, 'Title', lnum, 0, -1)
+      call coc#float#scroll_win(winid, 0, 1)
+    endif
+  endfor
+  redra
+endfunction
+
+function! coc#notify#close_by_source(source) abort
+  let winids = filter(coc#notify#win_list(), 'coc#window#get_var(v:val,"closing") != 1')
+  for winid in winids
+    let key = getwinvar(winid, 'key', v:null)
+    if type(key) == v:t_string
+      let obj = json_decode(key)
+      if get(obj, 'source', '') ==# a:source
+        call coc#notify#close(winid)
+      endif
+    endif
+  endfor
+endfunction
+
+" Cancel auto hide
+function! coc#notify#keep() abort
+  for winid in coc#notify#win_list()
+    call s:cancel(winid, 'close_timer')
+  endfor
+endfunction
+
+" borderhighlight - border highlight [string]
+" maxWidth - max content width, default 60 [number]
+" minWidth - minimal width [number]
+" maxHeight - max content height, default 10 [number]
+" highlight - default highlight [string]
+" winblend - winblend [number]
+" timeout - auto close timeout, default 5000 [number]
+" title - title text
+" marginRight - margin right, default 10 [number]
+" focusable - focusable [number]
+" source -  source name [string]
+" kind - kind for create icon [string]
+" actions - action names [string[]]
+function! coc#notify#create(lines, config) abort
+  let actions = get(a:config, 'actions', [])
+  let key = json_encode(extend({'lines': a:lines}, a:config))
+  let winid = s:find_win(key)
+  let kind = get(a:config, 'kind', '')
+  let row = 0
+  if winid != -1
+    let row = getwinvar(winid, 'top', 0)
+    call filter(s:winids, 'v:val != '.winid)
+    call coc#float#close(winid)
+    let winid = v:null
+  endif
+  let opts = coc#dict#pick(a:config, ['highlight', 'borderhighlight', 'focusable', 'shadow'])
+  let border = has_key(opts, 'borderhighlight') ? [1, 1, 1, 1] : []
+  let icon = s:get_icon(kind, get(a:config, 'highlight', 'CocFloating'))
+  let margin = get(a:config, 'marginRight', 10)
+  let maxWidth = min([&columns - margin - 2,  get(a:config, 'maxWidth', 80)])
+  if maxWidth <= 0
+    throw 'No enough spaces for notification'
+  endif
+  let lines = map(copy(a:lines), 'tr(v:val, "\t", " ")')
+  if has_key(a:config, 'title')
+    if !empty(border)
+      let opts['title'] = a:config['title']
+    else
+      let lines = [a:config['title']] + lines
+    endif
+  endif
+  let width = max(map(copy(lines), 'strwidth(v:val)')) + (empty(icon) ? 1 : 3)
+  if width > maxWidth
+    let lines = coc#string#reflow(lines, maxWidth)
+    let width = max(map(copy(lines), 'strwidth(v:val)')) + (empty(icon) ? 1 : 3)
+  endif
+  let highlights = []
+  if !empty(icon)
+    let ic = icon['text']
+    if empty(lines)
+      call add(lines, ic)
+    else
+      let lines[0] = ic.' '.lines[0]
+    endif
+    call add(highlights, {'lnum': 0, 'hlGroup': icon['hl'], 'colStart': 0, 'colEnd': strlen(ic)})
+  endif
+  let actionText = join(actions, ' ')
+  call map(lines, 'v:key == 0 ? v:val : repeat(" ", '.(empty(icon) ? 0 : 2).').v:val')
+  let minWidth = get(a:config, 'minWidth', kind ==# 'progress' ? 30 : 10)
+  let width = max(extend(map(lines + [get(opts, 'title', '').'   '], 'strwidth(v:val)'), [minWidth, strwidth(actionText) + 1]))
+  let width = min([maxWidth, width])
+  let height = min([get(a:config, 'maxHeight', 3), len(lines)])
+  if kind ==# 'progress'
+    let lines = [repeat(s:progress_char, width)] + lines
+    let height = height + 1
+  endif
+  if !empty(actions)
+    let before = max([width - strwidth(actionText), 0])
+    let lines = lines + [repeat(' ', before).actionText]
+    let height = height + 1
+    call s:add_action_highlights(before, height - 1, highlights, actions)
+  endif
+  if row == 0
+    let wintop = coc#notify#get_top()
+    let row = wintop - height - (empty(border) ? 0 : 2) - 1
+    if !s:is_vim && !empty(border)
+      let row = row + 1
+    endif
+  endif
+  let col = &columns - margin - width
+  if s:is_vim && !empty(border)
+    let col = col - 2
+  endif
+  let winblend = 60
+  " Avoid animate for transparent background.
+  if get(a:config, 'winblend', 30) == 0 && empty(synIDattr(synIDtrans(hlID(get(opts, 'highlight', 'CocFloating'))), 'bg', 'gui'))
+    let winblend = 0
+  endif
+  call extend(opts, {
+      \ 'relative': 'editor',
+      \ 'width': width,
+      \ 'height': height,
+      \ 'col': col,
+      \ 'row': row + 1,
+      \ 'lines': lines,
+      \ 'rounded': 1,
+      \ 'highlights': highlights,
+      \ 'winblend': winblend,
+      \ 'border': border,
+      \ })
+  let result = coc#float#create_float_win(0, 0, opts)
+  if empty(result)
+    throw 'Unable to create notify window'
+  endif
+  let winid = result[0]
+  let bufnr = result[1]
+  call setwinvar(winid, 'right', 1)
+  call setwinvar(winid, 'kind', 'notification')
+  call setwinvar(winid, 'top', row)
+  call setwinvar(winid, 'key', key)
+  call setwinvar(winid, 'actions', actions)
+  call setwinvar(winid, 'source', get(a:config, 'source', ''))
+  call setwinvar(winid, 'border', !empty(border))
+  call coc#float#nvim_scrollbar(winid)
+  call add(s:winids, winid)
+  let from = {'row': opts['row'], 'winblend': opts['winblend']}
+  let to = {'row': row, 'winblend': get(a:config, 'winblend', 30)}
+  call timer_start(s:interval, { -> s:animate(winid, from, to, 0)})
+  if kind ==# 'progress'
+    call timer_start(s:interval, { -> s:progress(winid, width, 0, -1)})
+  endif
+  if !s:is_vim
+    call coc#compat#buf_add_keymap(bufnr, 'n', '<LeftRelease>', ':call coc#notify#nvim_click('.winid.')<CR>', {
+        \ 'silent': v:true,
+        \ 'nowait': v:true
+        \ })
+  endif
+  " Enable auto close
+  if empty(actions) && kind !=# 'progress'
+    let timer = timer_start(get(a:config, 'timeout', 10000), { -> coc#notify#close(winid)})
+    call setwinvar(winid, 'close_timer', timer)
+  endif
+  return [winid, bufnr]
+endfunction
+
+function! coc#notify#nvim_click(winid) abort
+  if getwinvar(a:winid, 'closing', 0)
+    return
+  endif
+  call s:cancel(a:winid, 'close_timer')
+  let actions = getwinvar(a:winid, 'actions', [])
+  if !empty(actions)
+    let character = strpart(getline('.'), col('.') - 1, 1)
+    if character =~# '^\k'
+      let word = expand('<cword>')
+      let idx = index(actions, word)
+      if idx != -1
+        call coc#rpc#notify('FloatBtnClick', [winbufnr(a:winid), idx])
+        call coc#notify#close(a:winid)
+      endif
+    endif
+  endif
+endfunction
+
+function! coc#notify#on_close(winid) abort
+  if index(s:winids, a:winid) >= 0
+    call filter(s:winids, 'v:val != '.a:winid)
+    call coc#notify#reflow()
+  endif
+endfunction
+
+function! coc#notify#get_top() abort
+  let mintop = min(map(coc#notify#win_list(), 'coc#notify#get_win_top(v:val)'))
+  if mintop != 0
+    return mintop
+  endif
+  return &lines - &cmdheight - (&laststatus == 0 ? 0 : 1 )
+endfunction
+
+function! coc#notify#get_win_top(winid) abort
+  let row = getwinvar(a:winid, 'top', 0)
+  if row == 0
+    return row
+  endif
+  return row - (s:is_vim ? 0 : getwinvar(a:winid, 'border', 0))
+endfunction
+
+" Close with timer
+function! coc#notify#close(winid) abort
+  if !coc#float#valid(a:winid) || coc#window#get_var(a:winid, 'closing', 0) == 1
+    return
+  endif
+  if !coc#window#visible(a:winid)
+    call coc#float#close(a:winid)
+    return
+  endif
+  let row = coc#window#get_var(a:winid, 'top')
+  if type(row) != v:t_number
+    call coc#float#close(a:winid)
+    return
+  endif
+  call coc#window#set_var(a:winid, 'closing', 1)
+  call s:cancel(a:winid)
+  let winblend = coc#window#get_var(a:winid, 'winblend', 0)
+  let curr = s:is_vim ? {'row': row} : {'winblend': winblend}
+  let dest = s:is_vim ? {'row': row + 1} : {'winblend': winblend == 0 ? 0 : 60}
+  call s:animate(a:winid, curr, dest, 0, 1)
+endfunction
+
+function! s:add_action_highlights(before, lnum, highlights, actions) abort
+  let colStart = a:before
+  for text in a:actions
+    let w = strwidth(text)
+    call add(a:highlights, {
+        \ 'lnum': a:lnum,
+        \ 'hlGroup': 'CocNotificationButton',
+        \ 'colStart': colStart,
+        \ 'colEnd': colStart + w
+        \ })
+    let colStart = colStart + w + 1
+  endfor
+endfunction
+
+function! s:on_action(err, idx, winid) abort
+  if !empty(a:err)
+    throw a:err
+  endif
+  if a:idx > 0
+    call coc#rpc#notify('FloatBtnClick', [winbufnr(a:winid), a:idx - 1])
+    call coc#notify#close(a:winid)
+  endif
+endfunction
+
+function! s:cancel(winid, ...) abort
+  let name = get(a:, 1, 'timer')
+  let timer = coc#window#get_var(a:winid, name)
+  if !empty(timer)
+    call timer_stop(timer)
+    call coc#window#set_var(a:winid, name, v:null)
+  endif
+endfunction
+
+function! s:progress(winid, total, curr, index) abort
+  if !coc#float#valid(a:winid)
+    return
+  endif
+  if coc#window#visible(a:winid)
+    let total = a:total
+    let idx = float2nr(a:curr/5.0)%total
+    if idx != a:index
+      " update percent
+      let bufnr = winbufnr(a:winid)
+      let percent = coc#window#get_var(a:winid, 'percent')
+      if !empty(percent)
+        let width = strchars(getbufline(bufnr, 1)[0])
+        let line = repeat(s:progress_char, width - 4).printf('%4s', percent)
+        let total = width - 4
+        call setbufline(bufnr, 1, line)
+      endif
+      let message = coc#window#get_var(a:winid, 'message')
+      if !empty(message)
+        let linecount = coc#compat#buf_line_count(bufnr)
+        let hasAction = !empty(coc#window#get_var(a:winid, 'actions', []))
+        if getbufvar(bufnr, 'message', 0) == 0
+          call appendbufline(bufnr, linecount - hasAction, message)
+          call setbufvar(bufnr, 'message', 1)
+          call coc#float#change_height(a:winid, 1)
+          let tabnr = coc#window#tabnr(a:winid)
+          call coc#notify#reflow(tabnr)
+        else
+          call setbufline(bufnr, linecount - hasAction, message)
+        endif
+      endif
+      let bytes = strlen(s:progress_char)
+      call coc#highlight#clear_highlight(bufnr, -1, 0, 1)
+      let colStart = bytes * idx
+      if idx + 4 <= total
+        let colEnd = bytes * (idx + 4)
+        call coc#highlight#add_highlight(bufnr, -1, s:phl, 0, colStart, colEnd)
+      else
+        let colEnd = bytes * total
+        call coc#highlight#add_highlight(bufnr, -1, s:phl, 0, colStart, colEnd)
+        call coc#highlight#add_highlight(bufnr, -1, s:phl, 0, 0, bytes * (idx + 4 - total))
+      endif
+    endif
+    call timer_start(s:interval, { -> s:progress(a:winid, total, a:curr + 1, idx)})
+  else
+    " Not block CursorHold event
+    call timer_start(&updatetime + 100, { -> s:progress(a:winid, a:total, a:curr, a:index)})
+  endif
+endfunction
+
+" Optional row & winblend
+function! s:config_win(winid, props) abort
+  let change_row = has_key(a:props, 'row')
+  if s:is_vim
+    if change_row
+      call popup_move(a:winid, {'line': a:props['row'] + 1})
+    endif
+  else
+    if change_row
+      let [row, column] = nvim_win_get_position(a:winid)
+      call nvim_win_set_config(a:winid, {
+          \ 'row': a:props['row'],
+          \ 'col': column,
+          \ 'relative': 'editor',
+          \ })
+      call s:nvim_move_related(a:winid, a:props['row'])
+    endif
+    call coc#float#nvim_set_winblend(a:winid, get(a:props, 'winblend', v:null))
+    call coc#float#nvim_refresh_scrollbar(a:winid)
+  endif
+endfunction
+
+function! s:nvim_move_related(winid, row) abort
+  let winids = coc#window#get_var(a:winid, 'related')
+  if empty(winids)
+    return
+  endif
+  for winid in winids
+    if nvim_win_is_valid(winid)
+      let [row, column] = nvim_win_get_position(winid)
+      let delta = coc#window#get_var(winid, 'delta', 0)
+      call nvim_win_set_config(winid, {
+          \ 'row': a:row + delta,
+          \ 'col': column,
+          \ 'relative': 'editor',
+          \ })
+    endif
+  endfor
+endfunction
+
+function! s:animate(winid, from, to, prev, ...) abort
+  if !coc#float#valid(a:winid)
+    return
+  endif
+  let curr = a:prev + s:interval
+  let percent = coc#math#min(curr / s:duration, 1)
+  let props = s:get_props(a:from, a:to, percent)
+  call s:config_win(a:winid, props)
+  let close = get(a:, 1, 0)
+  if percent < 1
+    call timer_start(s:interval, { -> s:animate(a:winid, a:from, a:to, curr, close)})
+  elseif close
+    call filter(s:winids, 'v:val != '.a:winid)
+    let tabnr = coc#window#tabnr(a:winid)
+    if tabnr != -1
+      call coc#float#close(a:winid)
+      call coc#notify#reflow(tabnr)
+    endif
+  endif
+endfunction
+
+function! coc#notify#reflow(...) abort
+  let tabnr = get(a:, 1, tabpagenr())
+  let winids = filter(copy(s:winids), 'coc#window#tabnr(v:val) == '.tabnr.' && coc#window#get_var(v:val,"closing") != 1')
+  if empty(winids)
+    return
+  endif
+  let animate = tabnr == tabpagenr()
+  let wins = map(copy(winids), {_, val -> {
+        \ 'winid': val,
+        \ 'row': coc#window#get_var(val,'top',0),
+        \ 'top': coc#window#get_var(val,'top',0) - (s:is_vim ? 0 : coc#window#get_var(val, 'border', 0)),
+        \ 'height': coc#float#get_height(val),
+        \ }})
+  call sort(wins, {a, b -> b['top'] - a['top']})
+  let bottom = &lines - &cmdheight - (&laststatus == 0 ? 0 : 1 )
+  let moved = 0
+  for item in wins
+    let winid = item['winid']
+    let delta = bottom - (item['top'] + item['height'] + 1)
+    if delta != 0
+      call s:cancel(winid)
+      let dest = item['row'] + delta
+      call coc#window#set_var(winid, 'top', dest)
+      if animate
+        call s:move_win_timer(winid, {'row': item['row']}, {'row': dest}, 0)
+      else
+        call s:config_win(winid, {'row': dest})
+      endif
+      let moved = moved + delta
+    endif
+    let bottom = item['top'] + delta
+  endfor
+endfunction
+
+function! s:move_win_timer(winid, from, to, curr) abort
+  if !coc#float#valid(a:winid)
+    return
+  endif
+  if coc#window#get_var(a:winid, 'closing', 0) == 1
+    return
+  endif
+  let percent = coc#math#min(a:curr / s:duration, 1)
+  let next = a:curr + s:interval
+  if a:curr > 0
+    call s:config_win(a:winid, s:get_props(a:from, a:to, percent))
+  endif
+  if percent < 1
+    let timer = timer_start(s:interval, { -> s:move_win_timer(a:winid, a:from, a:to, next)})
+    call coc#window#set_var(a:winid, 'timer', timer)
+  endif
+endfunction
+
+function! s:find_win(key) abort
+  for winid in coc#notify#win_list()
+    if getwinvar(winid, 'key', '') ==# a:key
+      return winid
+    endif
+  endfor
+  return -1
+endfunction
+
+function! s:get_icon(kind, bg) abort
+  if a:kind ==# 'info'
+    return {'text': s:info_icon, 'hl': coc#highlight#compose_hlgroup('CocInfoSign', a:bg)}
+  endif
+  if a:kind ==# 'warning'
+    return {'text': s:warning_icon, 'hl': coc#highlight#compose_hlgroup('CocWarningSign', a:bg)}
+  endif
+  if a:kind ==# 'error'
+    return {'text': s:error_icon, 'hl': coc#highlight#compose_hlgroup('CocErrorSign', a:bg)}
+  endif
+  return v:null
+endfunction
+
+" percent should be float
+function! s:get_props(from, to, percent) abort
+  let obj = {}
+  for key in keys(a:from)
+    let changed = a:to[key] - a:from[key]
+    if !s:is_vim && key ==# 'row'
+      " Could be float
+      let obj[key] = a:from[key] + changed * a:percent
+    else
+      let obj[key] = a:from[key] + float2nr(round(changed * a:percent))
+    endif
+  endfor
+  return obj
+endfunction

+ 214 - 0
vimfiles/bundle/coc.nvim/autoload/coc/prompt.vim

@@ -0,0 +1,214 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:activated = 0
+let s:session_names = []
+let s:saved_ve = &t_ve
+let s:saved_cursor = &guicursor
+let s:gui = has('gui_running') || has('nvim')
+
+let s:char_map = {
+      \ "\<Plug>": '<plug>',
+      \ "\<Esc>": '<esc>',
+      \ "\<Tab>": '<tab>',
+      \ "\<S-Tab>": '<s-tab>',
+      \ "\<bs>": '<bs>',
+      \ "\<right>": '<right>',
+      \ "\<left>": '<left>',
+      \ "\<up>": '<up>',
+      \ "\<down>": '<down>',
+      \ "\<home>": '<home>',
+      \ "\<end>": '<end>',
+      \ "\<cr>": '<cr>',
+      \ "\<PageUp>":'<PageUp>' ,
+      \ "\<PageDown>":'<PageDown>' ,
+      \ "\<FocusGained>":'<FocusGained>',
+      \ "\<FocusLost>":'<FocusLost>',
+      \ "\<ScrollWheelUp>": '<ScrollWheelUp>',
+      \ "\<ScrollWheelDown>": '<ScrollWheelDown>',
+      \ "\<LeftMouse>": '<LeftMouse>',
+      \ "\<LeftDrag>": '<LeftDrag>',
+      \ "\<LeftRelease>": '<LeftRelease>',
+      \ "\<2-LeftMouse>": '<2-LeftMouse>',
+      \ "\<C-a>": '<C-a>',
+      \ "\<C-b>": '<C-b>',
+      \ "\<C-c>": '<C-c>',
+      \ "\<C-d>": '<C-d>',
+      \ "\<C-e>": '<C-e>',
+      \ "\<C-f>": '<C-f>',
+      \ "\<C-g>": '<C-g>',
+      \ "\<C-h>": '<C-h>',
+      \ "\<C-j>": '<C-j>',
+      \ "\<C-k>": '<C-k>',
+      \ "\<C-l>": '<C-l>',
+      \ "\<C-n>": '<C-n>',
+      \ "\<C-o>": '<C-o>',
+      \ "\<C-p>": '<C-p>',
+      \ "\<C-q>": '<C-q>',
+      \ "\<C-r>": '<C-r>',
+      \ "\<C-s>": '<C-s>',
+      \ "\<C-t>": '<C-t>',
+      \ "\<C-u>": '<C-u>',
+      \ "\<C-v>": '<C-v>',
+      \ "\<C-w>": '<C-w>',
+      \ "\<C-x>": '<C-x>',
+      \ "\<C-y>": '<C-y>',
+      \ "\<C-z>": '<C-z>',
+      \ "\<A-a>": '<A-a>',
+      \ "\<A-b>": '<A-b>',
+      \ "\<A-c>": '<A-c>',
+      \ "\<A-d>": '<A-d>',
+      \ "\<A-e>": '<A-e>',
+      \ "\<A-f>": '<A-f>',
+      \ "\<A-g>": '<A-g>',
+      \ "\<A-h>": '<A-h>',
+      \ "\<A-i>": '<A-i>',
+      \ "\<A-j>": '<A-j>',
+      \ "\<A-k>": '<A-k>',
+      \ "\<A-l>": '<A-l>',
+      \ "\<A-m>": '<A-m>',
+      \ "\<A-n>": '<A-n>',
+      \ "\<A-o>": '<A-o>',
+      \ "\<A-p>": '<A-p>',
+      \ "\<A-q>": '<A-q>',
+      \ "\<A-r>": '<A-r>',
+      \ "\<A-s>": '<A-s>',
+      \ "\<A-t>": '<A-t>',
+      \ "\<A-u>": '<A-u>',
+      \ "\<A-v>": '<A-v>',
+      \ "\<A-w>": '<A-w>',
+      \ "\<A-x>": '<A-x>',
+      \ "\<A-y>": '<A-y>',
+      \ "\<A-z>": '<A-z>',
+      \ }
+
+function! coc#prompt#getc() abort
+  let c = getchar()
+  return type(c) is 0 ? nr2char(c) : c
+endfunction
+
+function! coc#prompt#getchar() abort
+  let input = coc#prompt#getc()
+  if 1 != &iminsert
+    return input
+  endif
+  "a language keymap is activated, so input must be resolved to the mapped values.
+  let partial_keymap = mapcheck(input, 'l')
+  while partial_keymap !=# ''
+    let dict = maparg(input, 'l', 0, 1)
+    if empty(dict) || get(dict, 'expr', 0)
+      return input
+    endif
+    let full_keymap = get(dict, 'rhs', '')
+    if full_keymap ==# "" && len(input) >= 3 "HACK: assume there are no keymaps longer than 3.
+      return input
+    elseif full_keymap ==# partial_keymap
+      return full_keymap
+    endif
+    let c = coc#prompt#getc()
+    if c ==# "\<Esc>" || c ==# "\<CR>"
+      "if the short sequence has a valid mapping, return that.
+      if !empty(full_keymap)
+        return full_keymap
+      endif
+      return input
+    endif
+    let input .= c
+    let partial_keymap = mapcheck(input, 'l')
+  endwhile
+  return input
+endfunction
+
+function! coc#prompt#start_prompt(session) abort
+  let s:session_names = s:filter(s:session_names, a:session)
+  call add(s:session_names, a:session)
+  if s:activated | return | endif
+  if s:is_vim
+    call s:start_prompt_vim()
+  else
+    call s:start_prompt()
+  endif
+endfunction
+
+function! s:start_prompt_vim() abort
+  call timer_start(10, {-> s:start_prompt()})
+endfunction
+
+function! s:start_prompt()
+  if s:activated | return | endif
+  if !get(g:, 'coc_disable_transparent_cursor', 0)
+    if s:gui
+      if has('nvim-0.5.0') && !empty(s:saved_cursor)
+        set guicursor+=a:ver1-CocCursorTransparent/lCursor
+      endif
+    elseif s:is_vim
+      set t_ve=
+    endif
+  endif
+  let s:activated = 1
+  try
+    while s:activated
+      let ch = coc#prompt#getchar()
+      if ch ==# "\<FocusLost>" || ch ==# "\<FocusGained>" || ch ==# "\<CursorHold>"
+        continue
+      else
+        let curr = s:current_session()
+        let mapped = get(s:char_map, ch, ch)
+        if !empty(curr)
+          call coc#rpc#notify('InputChar', [curr, mapped, getcharmod()])
+        endif
+        if mapped == '<esc>'
+          let s:session_names = []
+          call s:reset()
+          break
+        endif
+      endif
+    endwhile
+  catch /^Vim:Interrupt$/
+    let s:activated = 0
+    call coc#rpc#notify('InputChar', [s:current_session(), '<esc>'])
+    return
+  endtry
+  let s:activated = 0
+endfunction
+
+function! coc#prompt#stop_prompt(session)
+  let s:session_names = s:filter(s:session_names, a:session)
+  if len(s:session_names)
+    return
+  endif
+  if s:activated
+    let s:activated = 0
+    call s:reset()
+    call feedkeys("\<esc>", 'int')
+  endif
+endfunction
+
+function! coc#prompt#activated() abort
+  return s:activated
+endfunction
+
+function! s:reset() abort
+  if !get(g:, 'coc_disable_transparent_cursor',0)
+    " neovim has bug with revert empty &guicursor
+    if s:gui && !empty(s:saved_cursor)
+      if has('nvim-0.5.0')
+        set guicursor+=a:ver1-Cursor/lCursor
+        let &guicursor = s:saved_cursor
+      endif
+    elseif s:is_vim
+      let &t_ve = s:saved_ve
+    endif
+  endif
+  echo ""
+endfunction
+
+function! s:current_session() abort
+  if empty(s:session_names)
+    return v:null
+  endif
+  return s:session_names[len(s:session_names) - 1]
+endfunction
+
+function! s:filter(list, id) abort
+  return filter(copy(a:list), 'v:val !=# a:id')
+endfunction

+ 490 - 0
vimfiles/bundle/coc.nvim/autoload/coc/pum.vim

@@ -0,0 +1,490 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:float = has('nvim-0.4.0') || has('patch-8.1.1719')
+let s:pum_bufnr = 0
+let s:pum_winid = 0
+let s:pum_index = -1
+let s:inserted = 0
+let s:virtual_text = 0
+let s:virtual_text_ns = 0
+let s:ignore = s:is_vim || has('nvim-0.5.0') ? "\<Ignore>" : "\<space>\<bs>"
+let s:hide_pum = has('nvim-0.6.1') || has('patch-8.2.3389')
+
+function! coc#pum#visible() abort
+  if !s:float || !s:pum_winid
+    return 0
+  endif
+  return getwinvar(s:pum_winid, 'float', 0) == 1
+endfunction
+
+function! coc#pum#winid() abort
+  return s:pum_winid
+endfunction
+
+function! coc#pum#close_detail() abort
+  let winid = coc#float#get_float_by_kind('pumdetail')
+  if winid
+    call coc#float#close(winid)
+    if s:is_vim
+      call timer_start(0, { -> execute('redraw')})
+    endif
+  endif
+endfunction
+
+function! coc#pum#close(...) abort
+  if coc#float#valid(s:pum_winid)
+    if get(a:, 1, '') ==# 'cancel'
+      let input = getwinvar(s:pum_winid, 'input', '')
+      let s:pum_index = -1
+      call s:insert_word(input)
+      call s:on_pum_change(0)
+      doautocmd TextChangedI
+    elseif get(a:, 1, '') ==# 'confirm'
+      let words = getwinvar(s:pum_winid, 'words', [])
+      if s:pum_index >= 0
+        let word = get(words, s:pum_index, '')
+        call s:insert_word(word)
+      endif
+      doautocmd TextChangedI
+    endif
+    call s:close_pum()
+    if !get(a:, 2, 0)
+      let pretext = strpart(getline('.'), 0, col('.') - 1)
+      call coc#rpc#notify('CompleteStop', [get(a:, 1, ''), pretext])
+    endif
+  endif
+endfunction
+
+function! coc#pum#select_confirm() abort
+  if s:pum_index < 0
+    let s:pum_index = 0
+    call s:on_pum_change(0)
+  endif
+  call coc#pum#close('confirm')
+endfunction
+
+function! coc#pum#insert() abort
+  call timer_start(10, { -> s:insert_current()})
+  return s:ignore
+endfunction
+
+function! coc#pum#_close() abort
+  if coc#float#valid(s:pum_winid)
+    call s:close_pum()
+    if s:is_vim
+      call timer_start(0, { -> execute('redraw')})
+    endif
+  endif
+endfunction
+
+function! s:insert_current() abort
+  if coc#float#valid(s:pum_winid)
+    if s:pum_index >= 0
+      let words = getwinvar(s:pum_winid, 'words', [])
+      let word = get(words, s:pum_index, '')
+      call s:insert_word(word)
+    endif
+    doautocmd TextChangedI
+    call s:close_pum()
+    let pretext = strpart(getline('.'), 0, col('.') - 1)
+    call coc#rpc#notify('CompleteStop', ['', pretext])
+  endif
+endfunction
+
+function! s:close_pum() abort
+  call s:clear_virtual_text()
+  call coc#float#close(s:pum_winid)
+  let s:pum_winid = 0
+  let winid = coc#float#get_float_by_kind('pumdetail')
+  if winid
+    call coc#float#close(winid)
+  endif
+endfunction
+
+function! coc#pum#next(insert) abort
+  call timer_start(10, { -> s:navigate(1, a:insert)})
+  return s:ignore
+endfunction
+
+function! coc#pum#prev(insert) abort
+  call timer_start(10, { -> s:navigate(0, a:insert)})
+  return s:ignore
+endfunction
+
+function! coc#pum#stop() abort
+  call timer_start(10, { -> coc#pum#close()})
+  return s:ignore
+endfunction
+
+function! coc#pum#cancel() abort
+  call timer_start(10, { -> coc#pum#close('cancel')})
+  return s:ignore
+endfunction
+
+function! coc#pum#confirm() abort
+  call timer_start(10, { -> coc#pum#close('confirm')})
+  return s:ignore
+endfunction
+
+function! coc#pum#select(index, insert, confirm) abort
+  if !coc#float#valid(s:pum_winid)
+    return ''
+  endif
+  if a:index == -1
+    call coc#pum#close('cancel')
+    return ''
+  endif
+  let total = coc#compat#buf_line_count(s:pum_bufnr)
+  if a:index < 0 || a:index >= total
+    throw 'index out of range ' . a:index
+  endif
+  call s:select_by_index(a:index, a:insert)
+  if a:confirm
+    call coc#pum#close('confirm')
+  endif
+  return ''
+endfunction
+
+function! coc#pum#info() abort
+  let bufnr = winbufnr(s:pum_winid)
+  let size = coc#compat#buf_line_count(bufnr)
+  let words = getwinvar(s:pum_winid, 'words', [])
+  let word = s:pum_index < 0 ? '' : get(words, s:pum_index, '')
+  if s:is_vim
+    let pos = popup_getpos(s:pum_winid)
+    let add = pos['scrollbar'] && has_key(popup_getoptions(s:pum_winid), 'border') ? 1 : 0
+    return {
+        \ 'word': word,
+        \ 'index': s:pum_index,
+        \ 'scrollbar': pos['scrollbar'],
+        \ 'row': pos['line'] - 1,
+        \ 'col': pos['col'] - 1,
+        \ 'width': pos['width'] + add,
+        \ 'height': pos['height'],
+        \ 'size': size,
+        \ 'inserted': s:inserted ? v:true : v:false,
+        \ }
+  else
+    let scrollbar = coc#float#get_related(s:pum_winid, 'scrollbar')
+    let winid = coc#float#get_related(s:pum_winid, 'border', s:pum_winid)
+    let pos = nvim_win_get_position(winid)
+    return {
+        \ 'word': word,
+        \ 'index': s:pum_index,
+        \ 'scrollbar': scrollbar && nvim_win_is_valid(scrollbar) ? 1 : 0,
+        \ 'row': pos[0],
+        \ 'col': pos[1],
+        \ 'width': nvim_win_get_width(winid),
+        \ 'height': nvim_win_get_height(winid),
+        \ 'size': size,
+        \ 'inserted': s:inserted ? v:true : v:false,
+        \ }
+  endif
+endfunction
+
+function! coc#pum#scroll(forward) abort
+  if coc#pum#visible()
+    let size = coc#compat#buf_line_count(s:pum_bufnr)
+    let height = s:get_height(s:pum_winid)
+    if size > height
+      call timer_start(10, { -> s:scroll_pum(a:forward, height, size)})
+    endif
+  endif
+  return s:ignore
+endfunction
+
+function! s:get_height(winid) abort
+  if has('nvim')
+    return nvim_win_get_height(a:winid)
+  endif
+  return get(popup_getpos(a:winid), 'core_height', 0)
+endfunction
+
+function! s:scroll_pum(forward, height, size) abort
+  let topline = s:get_topline(s:pum_winid)
+  if !a:forward && topline == 1
+    if s:pum_index >= 0
+      call s:select_line(s:pum_winid, 1)
+      call s:on_pum_change(1)
+    endif
+    return
+  endif
+  if a:forward && topline + a:height - 1 >= a:size
+    if s:pum_index >= 0
+      call s:select_line(s:pum_winid, a:size)
+      call s:on_pum_change(1)
+    endif
+    return
+  endif
+  call coc#float#scroll_win(s:pum_winid, a:forward, a:height)
+  if s:pum_index >= 0
+    let lnum = s:pum_index + 1
+    let topline = s:get_topline(s:pum_winid)
+    if lnum >= topline && lnum <= topline + a:height - 1
+      return
+    endif
+    call s:select_line(s:pum_winid, topline)
+    call s:on_pum_change(1)
+  endif
+endfunction
+
+function! s:get_topline(winid) abort
+  if has('nvim')
+    let info = getwininfo(a:winid)[0]
+    return info['topline']
+  else
+    let pos = popup_getpos(a:winid)
+    return pos['firstline']
+  endif
+endfunction
+
+function! s:navigate(next, insert) abort
+  if !coc#float#valid(s:pum_winid)
+    return
+  endif
+  let index = s:get_index(a:next)
+  call s:select_by_index(index, a:insert)
+endfunction
+
+function! s:select_by_index(index, insert) abort
+  call s:set_cursor(s:pum_winid, a:index + 1)
+  if !s:is_vim
+    call coc#float#nvim_scrollbar(s:pum_winid)
+  endif
+  if a:insert
+    let s:inserted = 1
+    if a:index < 0
+      let input = getwinvar(s:pum_winid, 'input', '')
+      call s:insert_word(input)
+      call coc#pum#close_detail()
+    else
+      let words = getwinvar(s:pum_winid, 'words', [])
+      let word = get(words, a:index, '')
+      call s:insert_word(word)
+    endif
+    doautocmd TextChangedP
+  endif
+  call s:on_pum_change(1)
+endfunction
+
+function! s:get_index(next) abort
+  let size = coc#compat#buf_line_count(s:pum_bufnr)
+  if a:next
+    let index = s:pum_index + 1 == size ? -1 : s:pum_index + 1
+  else
+    let index = s:pum_index == -1 ? size - 1 : s:pum_index - 1
+  endif
+  return index
+endfunction
+
+function! s:insert_word(word) abort
+  let parts = getwinvar(s:pum_winid, 'parts', [])
+  if !empty(parts) && mode() ==# 'i'
+    let curr = getline('.')
+    if curr ==# parts[0].a:word.parts[1]
+      return
+    endif
+    let saved_completeopt = &completeopt
+    if saved_completeopt =~ 'menuone'
+      noa set completeopt=menu
+    endif
+    noa call complete(strlen(parts[0]) + 1, [a:word])
+    if s:hide_pum
+      " exit complete state
+      call feedkeys("\<C-x>\<C-z>", 'in')
+    else
+      let g:coc_disable_space_report = 1
+      call feedkeys("\<space>\<bs>", 'in')
+    endif
+    execute 'noa set completeopt='.saved_completeopt
+  endif
+endfunction
+
+" create or update pum with lines, CompleteOption and config.
+" return winid & dimension
+function! coc#pum#create(lines, opt, config) abort
+  if mode() !=# 'i' || a:opt['line'] != line('.')
+    return
+  endif
+  let len = col('.') - a:opt['col'] - 1
+  if len < 0
+    return
+  endif
+  let input = len == 0 ? '' : strpart(getline('.'), a:opt['col'], len)
+  if input !=# a:opt['input']
+    return
+  endif
+  let config = s:get_pum_dimension(a:lines, a:opt['col'], a:config)
+  if empty(config)
+    return
+  endif
+  let s:virtual_text = has('nvim-0.5.0') && a:opt['virtualText']
+  if s:virtual_text && !s:virtual_text_ns
+    let s:virtual_text_ns = coc#highlight#create_namespace('pum-virtual')
+  endif
+  let selected = a:opt['index'] + 1
+  call extend(config, {
+        \ 'lines': a:lines,
+        \ 'relative': 'cursor',
+        \ 'nopad': 1,
+        \ 'cursorline': 1,
+        \ 'index': a:opt['index'],
+        \ 'focusable': v:false
+        \ })
+  call extend(config, coc#dict#pick(a:config, ['highlight', 'rounded', 'highlights', 'winblend', 'shadow', 'border', 'borderhighlight']))
+  let result =  coc#float#create_float_win(s:pum_winid, s:pum_bufnr, config)
+  if empty(result)
+    return
+  endif
+  let s:inserted = 0
+  let s:pum_winid = result[0]
+  let s:pum_bufnr = result[1]
+  call setwinvar(s:pum_winid, 'above', config['row'] < 0)
+  let lnum = max([1, a:opt['index'] + 1])
+  if s:is_vim
+    call popup_setoptions(s:pum_winid, {
+          \ 'firstline': s:get_firstline(lnum, len(a:lines), config['height'])
+          \ })
+  else
+    let firstline = s:get_firstline(lnum, len(a:lines), config['height'])
+    call coc#compat#execute(s:pum_winid, 'call winrestview({"lnum":'.lnum.',"topline":'.firstline.'})')
+  endif
+  let s:pum_index = get(config, 'index', -1)
+  call coc#dialog#place_sign(s:pum_bufnr, s:pum_index + 1)
+  call setwinvar(s:pum_winid, 'kind', 'pum')
+  " content before col and content after cursor
+  let linetext = getline('.')
+  let parts = [strpart(linetext, 0, a:opt['col']), strpart(linetext, col('.') - 1)]
+  call setwinvar(s:pum_winid, 'input', input)
+  call setwinvar(s:pum_winid, 'parts', parts)
+  call setwinvar(s:pum_winid, 'words', a:opt['words'])
+  if !s:is_vim
+    if len(a:lines) > config['height']
+      redraw
+      call coc#float#nvim_scrollbar(s:pum_winid)
+    else
+      call coc#float#close_related(s:pum_winid, 'scrollbar')
+    endif
+  endif
+  call timer_start(10, { -> s:on_pum_change(0)})
+endfunction
+
+function! s:get_firstline(lnum, total, height) abort
+  if a:lnum <= a:height
+    return 1
+  endif
+  return min([a:total - a:height + 1, a:lnum  - (a:height*2/3)])
+endfunction
+
+function! s:on_pum_change(move) abort
+  if coc#float#valid(s:pum_winid)
+    if s:virtual_text_ns
+      call s:insert_virtual_text()
+    endif
+    let ev = extend(coc#pum#info(), {'move': a:move ? v:true : v:false})
+    call coc#rpc#notify('CocAutocmd', ['MenuPopupChanged', ev, win_screenpos(winnr())[0] + winline() - 2])
+  endif
+endfunction
+
+function! s:get_pum_dimension(lines, col, config) abort
+  let linecount = len(a:lines)
+  let [lineIdx, colIdx] = coc#cursor#screen_pos()
+  let bh = empty(get(a:config, 'border', [])) ? 0 : 2
+  let width = min([&columns, max([exists('&pumwidth') ? &pumwidth : 15, a:config['width']])])
+  let vh = &lines - &cmdheight - 1 - !empty(&tabline)
+  if vh <= 0
+    return v:null
+  endif
+  let pumheight = empty(&pumheight) ? vh : &pumheight
+  let showTop = getwinvar(s:pum_winid, 'above', v:null)
+  if type(showTop) != v:t_number
+    if vh - lineIdx - bh - 1 < min([pumheight, linecount]) && lineIdx > vh - lineIdx
+      let showTop = 1
+    else
+      let showTop = 0
+    endif
+  endif
+  let height = showTop ? min([lineIdx - bh - !empty(&tabline), linecount, pumheight]) : min([vh - lineIdx - bh - 1, linecount, pumheight])
+  if height <= 0
+    return v:null
+  endif
+  let col = - (col('.') - a:col - 1) - 1
+  let row = showTop ? - height : 1
+  let delta = colIdx + col
+  if delta < 0
+    let col = col - delta
+  elseif delta + width > &columns
+    let col = max([-colIdx, col - (delta + width - &columns)])
+  endif
+  return {
+        \ 'row': row,
+        \ 'col': col,
+        \ 'width': width,
+        \ 'height': height
+        \ }
+endfunction
+
+" can't use coc#dialog#set_cursor on vim8, don't know why
+function! s:set_cursor(winid, line) abort
+  if s:is_vim
+    let pos = popup_getpos(a:winid)
+    let lastline = pos['firstline'] + pos['core_height'] - 1
+    if a:line > lastline
+      call popup_setoptions(a:winid, {
+            \ 'firstline': pos['firstline'] + a:line - lastline,
+            \ })
+    elseif a:line < pos['firstline']
+      call popup_setoptions(a:winid, {
+            \ 'firstline': max([1, a:line]),
+            \ })
+    endif
+  endif
+  call s:select_line(a:winid, a:line)
+endfunction
+
+function! s:select_line(winid, line) abort
+  let s:pum_index = a:line - 1
+  let lnum = max([1, a:line])
+  if s:is_vim
+    call coc#compat#execute(a:winid, 'exe '.lnum)
+  else
+    call nvim_win_set_cursor(a:winid, [lnum, 0])
+  endif
+  call coc#dialog#place_sign(winbufnr(a:winid), a:line)
+endfunction
+
+function! s:insert_virtual_text() abort
+  if !s:virtual_text_ns
+    return
+  endif
+  let bufnr = bufnr('%')
+  if !s:virtual_text || !coc#pum#visible() || s:pum_index < 0
+    call nvim_buf_clear_namespace(bufnr, s:virtual_text_ns, 0, -1)
+  else
+    " Check if could create
+    let insert = ''
+    let words = getwinvar(s:pum_winid, 'words', [])
+    let word = get(words, s:pum_index, '')
+    let parts = getwinvar(s:pum_winid, 'parts', [])
+    let input = strpart(getline('.'), strlen(parts[0]), col('.') - 1)
+    if strchars(word) > strchars(input) && strcharpart(word, 0, strchars(input)) ==# input
+      let insert = strcharpart(word, strchars(input))
+    endif
+    call nvim_buf_clear_namespace(bufnr, s:virtual_text_ns, 0, -1)
+    if !empty(insert)
+      let opts = {
+          \ 'hl_mode': 'combine',
+          \ 'virt_text': [[insert, 'CocPumVirtualText']],
+          \ 'virt_text_pos': 'overlay',
+          \ 'virt_text_win_col': virtcol('.') - 1,
+          \ }
+      call nvim_buf_set_extmark(bufnr, s:virtual_text_ns, line('.') - 1, col('.') - 1, opts)
+    endif
+  endif
+endfunction
+
+function! s:clear_virtual_text() abort
+  if s:virtual_text_ns
+    call nvim_buf_clear_namespace(bufnr('%'), s:virtual_text_ns, 0, -1)
+  endif
+endfunction

+ 130 - 0
vimfiles/bundle/coc.nvim/autoload/coc/rpc.vim

@@ -0,0 +1,130 @@
+scriptencoding utf-8
+let s:is_win = has("win32") || has("win64")
+let s:client = v:null
+let s:name = 'coc'
+let s:is_vim = !has('nvim')
+
+function! coc#rpc#start_server()
+  if get(g:, 'coc_node_env', '') ==# 'test'
+    " server already started
+    let s:client = coc#client#create(s:name, [])
+    let chan_id = get(g:, 'coc_node_channel_id', 0)
+    let s:client['running'] = chan_id != 0
+    let s:client['chan_id'] = chan_id
+    return
+  endif
+  if empty(s:client)
+    let cmd = coc#util#job_command()
+    if empty(cmd) | return | endif
+    let $COC_VIMCONFIG = coc#util#get_config_home()
+    let $COC_DATA_HOME = coc#util#get_data_home()
+    let s:client = coc#client#create(s:name, cmd)
+  endif
+  if !coc#client#is_running('coc')
+    call s:client['start']()
+  endif
+endfunction
+
+function! coc#rpc#started() abort
+  return !empty(s:client)
+endfunction
+
+function! coc#rpc#ready()
+  if empty(s:client) || s:client['running'] == 0
+    return 0
+  endif
+  return 1
+endfunction
+
+function! coc#rpc#set_channel(chan_id) abort
+  let g:coc_node_channel_id = a:chan_id
+  if a:chan_id != 0
+    let s:client['running'] = 1
+    let s:client['chan_id'] = a:chan_id
+  endif
+endfunction
+
+function! coc#rpc#kill()
+  let pid = get(g:, 'coc_process_pid', 0)
+  if !pid | return | endif
+  if s:is_win
+    call system('taskkill /PID '.pid)
+  else
+    call system('kill -9 '.pid)
+  endif
+endfunction
+
+function! coc#rpc#get_errors()
+  return split(execute('messages'), "\n")
+endfunction
+
+function! coc#rpc#stop()
+  if empty(s:client)
+    return
+  endif
+  try
+    if s:is_vim
+      call job_stop(ch_getjob(s:client['channel']), 'term')
+    else
+      call jobstop(s:client['chan_id'])
+    endif
+  catch /.*/
+    " ignore
+  endtry
+endfunction
+
+function! coc#rpc#restart()
+  if empty(s:client)
+    call coc#rpc#start_server()
+  else
+    call coc#highlight#clear_all()
+    call coc#ui#sign_unplace()
+    call coc#float#close_all()
+    call coc#rpc#request('detach', [])
+    sleep 100m
+    let s:client['command'] = coc#util#job_command()
+    call coc#client#restart(s:name)
+    echohl MoreMsg | echom 'starting coc.nvim service' | echohl None
+  endif
+endfunction
+
+function! coc#rpc#request(method, args) abort
+  if !coc#rpc#ready()
+    return ''
+  endif
+  return s:client['request'](a:method, a:args)
+endfunction
+
+function! coc#rpc#notify(method, args) abort
+  if !coc#rpc#ready()
+    return ''
+  endif
+  call s:client['notify'](a:method, a:args)
+  return ''
+endfunction
+
+function! coc#rpc#request_async(method, args, cb) abort
+  if !coc#rpc#ready()
+    return cb('coc.nvim service not started.')
+  endif
+  call s:client['request_async'](a:method, a:args, a:cb)
+endfunction
+
+" receive async response
+function! coc#rpc#async_response(id, resp, isErr) abort
+  if empty(s:client)
+    return
+  endif
+  call coc#client#on_response(s:name, a:id, a:resp, a:isErr)
+endfunction
+
+" send async response to server
+function! coc#rpc#async_request(id, method, args)
+  let l:Cb = {err, ... -> coc#rpc#notify('nvim_async_response_event', [a:id, err, get(a:000, 0, v:null)])}
+  let args = a:args + [l:Cb]
+  try
+    call call(a:method, args)
+  catch /.*/
+    call coc#rpc#notify('nvim_async_response_event', [a:id, v:exception, v:null])
+  endtry
+endfunction

+ 155 - 0
vimfiles/bundle/coc.nvim/autoload/coc/snippet.vim

@@ -0,0 +1,155 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:map_next = 1
+let s:map_prev = 1
+let s:cmd_mapping = has('nvim') || has('patch-8.2.1978')
+
+function! coc#snippet#_select_mappings()
+  if !get(g:, 'coc_selectmode_mapping', 1)
+    return
+  endif
+
+  redir => mappings
+    silent! smap
+  redir END
+
+  for map in map(filter(split(mappings, '\n'),
+        \ "v:val !~# '^s' && v:val !~# '^\\a*\\s*<\\S\\+>'"),
+        \ "matchstr(v:val, '^\\a*\\s*\\zs\\S\\+')")
+    silent! execute 'sunmap' map
+    silent! execute 'sunmap <buffer>' map
+  endfor
+
+  " same behaviour of ultisnips
+  snoremap <silent> <BS> <c-g>c
+  snoremap <silent> <DEL> <c-g>c
+  snoremap <silent> <c-h> <c-g>c
+  snoremap <c-r> <c-g>"_c<c-r>
+endfunction
+
+function! coc#snippet#show_choices(lnum, col, len, values) abort
+  let m = mode()
+  call cursor(a:lnum, a:col + a:len)
+  if m !=# 'i'
+    call feedkeys("\<Esc>i", 'in')
+  endif
+  let changedtick = b:changedtick
+  call timer_start(20, { -> coc#_do_complete(a:col - 1, a:values, 0, changedtick)})
+  redraw
+endfunction
+
+function! coc#snippet#enable(...)
+  if get(b:, 'coc_snippet_active', 0) == 1
+    return
+  endif
+  let complete = get(a:, 1, 0)
+  let b:coc_snippet_active = 1
+  call coc#snippet#_select_mappings()
+  let nextkey = get(g:, 'coc_snippet_next', '<C-j>')
+  let prevkey = get(g:, 'coc_snippet_prev', '<C-k>')
+  if maparg(nextkey, 'i') =~# 'snippet'
+    let s:map_next = 0
+  endif
+  if maparg(prevkey, 'i') =~# 'snippet'
+    let s:map_prev = 0
+  endif
+  if !empty(nextkey)
+    if s:map_next
+      execute 'inoremap <buffer><nowait><silent>'.nextkey." <C-R>=coc#snippet#jump(1, ".complete.")<cr>"
+    endif
+    execute 'snoremap <buffer><nowait><silent>'.nextkey." <Esc>:call coc#snippet#jump(1, ".complete.")<cr>"
+  endif
+  if !empty(prevkey)
+    if s:map_prev
+      execute 'inoremap <buffer><nowait><silent>'.prevkey." <C-R>=coc#snippet#jump(0, ".complete.")<cr>"
+    endif
+    execute 'snoremap <buffer><nowait><silent>'.prevkey." <Esc>:call coc#snippet#jump(0, ".complete.")<cr>"
+  endif
+endfunction
+
+function! coc#snippet#prev() abort
+  call coc#rpc#request('snippetPrev', [])
+  return ''
+endfunction
+
+function! coc#snippet#next() abort
+  call coc#rpc#request('snippetNext', [])
+  return ''
+endfunction
+
+function! coc#snippet#jump(direction, complete) abort
+  if a:direction == 1 && a:complete && pumvisible()
+    let pre = exists('*complete_info') && complete_info()['selected'] == -1 ? "\<C-n>" : ''
+    call feedkeys(pre."\<C-y>", 'in')
+    return ''
+  endif
+  call coc#rpc#request(a:direction == 1 ? 'snippetNext' : 'snippetPrev', [])
+  return ''
+endfunction
+
+function! coc#snippet#disable()
+  if get(b:, 'coc_snippet_active', 0) == 0
+    return
+  endif
+  let b:coc_snippet_active = 0
+  let nextkey = get(g:, 'coc_snippet_next', '<C-j>')
+  let prevkey = get(g:, 'coc_snippet_prev', '<C-k>')
+  if s:map_next
+    silent! execute 'iunmap <buffer> <silent> '.nextkey
+  endif
+  if s:map_prev
+    silent! execute 'iunmap <buffer> <silent> '.prevkey
+  endif
+  silent! execute 'sunmap <buffer> <silent> '.prevkey
+  silent! execute 'sunmap <buffer> <silent> '.nextkey
+endfunction
+
+function! coc#snippet#select(start, end, text) abort
+  if coc#pum#visible()
+    call coc#pum#close()
+  endif
+  if mode() == 's'
+    call feedkeys("\<Esc>", 'in')
+  endif
+  if &selection ==# 'exclusive'
+    let cursor = coc#snippet#to_cursor(a:start)
+    call cursor([cursor[0], cursor[1]])
+    let cmd = ''
+    let cmd .= mode()[0] ==# 'i' ? "\<Esc>".(col('.') == 1 ? '' : 'l') : ''
+    let cmd .= printf('v%s', strchars(a:text) . 'l')
+    let cmd .= "\<C-g>"
+  else
+    let cursor = coc#snippet#to_cursor(a:end)
+    call cursor([cursor[0], cursor[1] - 1])
+    let len = strchars(a:text) - 1
+    let cmd = ''
+    let cmd .= mode()[0] ==# 'i' ? "\<Esc>l" : ''
+    let cmd .= printf('v%s', len > 0 ? len . 'h' : '')
+    let cmd .= "o\<C-g>"
+  endif
+  call feedkeys(cmd, 'n')
+endfunction
+
+function! coc#snippet#move(position) abort
+  let m = mode()
+  if m == 's'
+    call feedkeys("\<Esc>", 'in')
+  elseif coc#pum#visible()
+    call coc#pum#close()
+  endif
+  let pos = coc#snippet#to_cursor(a:position)
+  call cursor(pos)
+  if pos[1] > strlen(getline(pos[0]))
+    startinsert!
+  else
+    startinsert
+  endif
+endfunction
+
+function! coc#snippet#to_cursor(position) abort
+  let line = getline(a:position.line + 1)
+  if line is v:null
+    return [a:position.line + 1, a:position.character + 1]
+  endif
+  return [a:position.line + 1, byteidx(line, a:position.character) + 1]
+endfunction

+ 154 - 0
vimfiles/bundle/coc.nvim/autoload/coc/string.vim

@@ -0,0 +1,154 @@
+scriptencoding utf-8
+
+function! coc#string#get_character(line, col) abort
+  return strchars(strpart(a:line, 0, a:col - 1))
+endfunction
+
+function! coc#string#last_character(line) abort
+  return strcharpart(a:line, strchars(a:line) - 1, 1)
+endfunction
+
+function! coc#string#reflow(lines, width) abort
+  let lines = []
+  let currlen = 0
+  let parts = []
+  for line in a:lines
+    for part in split(line, '\s\+')
+      let w = strwidth(part)
+      if currlen + w + 1 >= a:width
+        if len(parts) > 0
+          call add(lines, join(parts, ' '))
+        endif
+        if w >= a:width
+          call add(lines, part)
+          let currlen = 0
+          let parts = []
+        else
+          let currlen = w
+          let parts = [part]
+        endif
+        continue
+      endif
+      call add(parts, part)
+      let currlen = currlen + w + 1
+    endfor
+  endfor
+  if len(parts) > 0
+    call add(lines, join(parts, ' '))
+  endif
+  return empty(lines) ? [''] : lines
+endfunction
+
+function! coc#string#content_height(lines, width) abort
+  let len = 0
+  for line in a:lines
+    if strwidth(line) <= a:width
+      let len = len + 1
+    else
+      let currlen = 0
+      for part in split(line, '\<\|\>\|\ze\s')
+        let w = strwidth(part)
+        if currlen + w >= a:width
+          if currlen + w == a:width
+            let len = len + 1
+            let currlen = 0
+          else
+            let len = len + (a:width + w)/a:width
+            let currlen = w%a:width
+          endif
+        else
+          let currlen = currlen + w
+        endif
+      endfor
+      if currlen > 0
+        let len = len + 1
+      endif
+    endif
+  endfor
+  return len == 0 ? 1 : len
+endfunction
+
+" get change between two lines
+function! coc#string#diff(curr, previous, col) abort
+  let end = strpart(a:curr, a:col - 1)
+  let start = strpart(a:curr, 0, a:col -1)
+  let endOffset = 0
+  let startOffset = 0
+  let currLen = strchars(a:curr)
+  let prevLen = strchars(a:previous)
+  if len(end)
+    let endLen = strchars(end)
+    for i in range(min([prevLen, endLen]))
+      if strcharpart(end, endLen - 1 - i, 1) ==# strcharpart(a:previous, prevLen -1 -i, 1)
+        let endOffset = endOffset + 1
+      else
+        break
+      endif
+    endfor
+  endif
+  let remain = endOffset == 0 ? a:previous : strcharpart(a:previous, 0, prevLen - endOffset)
+  if len(remain)
+    for i in range(min([strchars(remain), strchars(start)]))
+      if strcharpart(remain, i, 1) ==# strcharpart(start, i ,1)
+        let startOffset = startOffset + 1
+      else
+        break
+      endif
+    endfor
+  endif
+  return {
+      \ 'start': startOffset,
+      \ 'end': prevLen - endOffset,
+      \ 'text': strcharpart(a:curr, startOffset, currLen - startOffset - endOffset)
+      \ }
+endfunction
+
+function! coc#string#apply(content, diff) abort
+  let totalLen = strchars(a:content)
+  let endLen = totalLen - a:diff['end']
+  return strcharpart(a:content, 0, a:diff['start']).a:diff['text'].strcharpart(a:content, a:diff['end'], endLen)
+endfunction
+
+" insert inserted to line at position, use ... when result is too long
+" line should only contains character has strwidth equals 1
+function! coc#string#compose(line, position, inserted) abort
+  let width = strwidth(a:line)
+  let text = a:inserted
+  let res = a:line
+  let need_truncate = a:position + strwidth(text) + 1 > width
+  if need_truncate
+    let remain = width - a:position - 3
+    if remain < 2
+      " use text for full line, use first & end of a:line, ignore position
+      let res = strcharpart(a:line, 0, 1)
+      let w = strwidth(res)
+      for i in range(strchars(text))
+        let c = strcharpart(text, i, 1)
+        let a = strwidth(c)
+        if w + a <= width - 1
+          let w = w + a
+          let res = res . c
+        endif
+      endfor
+      let res = res.strcharpart(a:line, w)
+    else
+      let res = strcharpart(a:line, 0, a:position)
+      let w = strwidth(res)
+      for i in range(strchars(text))
+        let c = strcharpart(text, i, 1)
+        let a = strwidth(c)
+        if w + a <= width - 3
+          let w = w + a
+          let res = res . c
+        endif
+      endfor
+      let res = res.'..'
+      let w = w + 2
+      let res = res . strcharpart(a:line, w)
+    endif
+  else
+    let first = strcharpart(a:line, 0, a:position)
+    let res = first . text . strcharpart(a:line, a:position + strwidth(text))
+  endif
+  return res
+endfunction

+ 179 - 0
vimfiles/bundle/coc.nvim/autoload/coc/task.vim

@@ -0,0 +1,179 @@
+" ============================================================================
+" Description: Manage long running tasks.
+" Author: Qiming Zhao <chemzqm@gmail.com>
+" Licence: Anti 966 licence
+" Version: 0.1
+" Last Modified:  Dec 12, 2020
+" ============================================================================
+scriptencoding utf-8
+
+let s:is_vim = !has('nvim')
+let s:running_task = {}
+" neovim emit strings that part of lines.
+let s:out_remain_text = {}
+let s:err_remain_text = {}
+
+function! coc#task#start(id, opts)
+  if coc#task#running(a:id)
+    call coc#task#stop(a:id)
+  endif
+  let cmd = [a:opts['cmd']] + get(a:opts, 'args', [])
+  let cwd = get(a:opts, 'cwd', getcwd())
+  let env = get(a:opts, 'env', {})
+  " cmd args cwd pty
+  if s:is_vim
+    let options = {
+          \ 'cwd': cwd,
+          \ 'err_mode': 'nl',
+          \ 'out_mode': 'nl',
+          \ 'err_cb': {channel, message -> s:on_stderr(a:id, [message])},
+          \ 'out_cb': {channel, message -> s:on_stdout(a:id, [message])},
+          \ 'exit_cb': {channel, code -> s:on_exit(a:id, code)},
+          \ 'env': env,
+          \}
+    if has("patch-8.1.350")
+      let options['noblock'] = 1
+    endif
+    if get(a:opts, 'pty', 0)
+      let options['pty'] = 1
+    endif
+    let job = job_start(cmd, options)
+    let status = job_status(job)
+    if status !=# 'run'
+      echohl Error | echom 'Failed to start '.a:id.' task' | echohl None
+      return v:false
+    endif
+    let s:running_task[a:id] = job
+  else
+    let options = {
+          \ 'cwd': cwd,
+          \ 'on_stderr': {channel, msgs -> s:on_stderr(a:id, msgs)},
+          \ 'on_stdout': {channel, msgs -> s:on_stdout(a:id, msgs)},
+          \ 'on_exit': {channel, code -> s:on_exit(a:id, code)},
+          \ 'detach': get(a:opts, 'detach', 0),
+          \}
+    let original = {}
+    if !empty(env)
+      if has('nvim-0.5.0')
+        let options['env'] = env
+      elseif exists('*setenv') && exists('*getenv')
+        for key in keys(env)
+          let original[key] = getenv(key)
+          call setenv(key, env[key])
+        endfor
+      endif
+    endif
+    if get(a:opts, 'pty', 0)
+      let options['pty'] = 1
+    endif
+    let chan_id = jobstart(cmd, options)
+    if !empty(original)
+      for key in keys(original)
+        call setenv(key, original[key])
+      endfor
+    endif
+    if chan_id <= 0
+      echohl Error | echom 'Failed to start '.a:id.' task' | echohl None
+      return v:false
+    endif
+    let s:running_task[a:id] = chan_id
+  endif
+  return v:true
+endfunction
+
+function! coc#task#stop(id)
+  let job = get(s:running_task, a:id, v:null)
+  if !job | return | endif
+  if s:is_vim
+    call job_stop(job, 'term')
+  else
+    call jobstop(job)
+  endif
+  sleep 50m
+  let running = coc#task#running(a:id)
+  if running
+    echohl Error | echom 'job '.a:id. ' stop failed.' | echohl None
+  endif
+endfunction
+
+function! s:on_exit(id, code) abort
+  if get(g:, 'coc_vim_leaving', 0) | return | endif
+  if has('nvim')
+    let s:out_remain_text[a:id] = ''
+    let s:err_remain_text[a:id] = ''
+  endif
+  if has_key(s:running_task, a:id)
+    call remove(s:running_task, a:id)
+  endif
+  call coc#rpc#notify('TaskExit', [a:id, a:code])
+endfunction
+
+function! s:on_stderr(id, msgs)
+  if get(g:, 'coc_vim_leaving', 0) | return | endif
+  if empty(a:msgs)
+    return
+  endif
+  if s:is_vim
+    call coc#rpc#notify('TaskStderr', [a:id, a:msgs])
+  else
+    let remain = get(s:err_remain_text, a:id, '')
+    let eof = (a:msgs == [''])
+    let msgs = copy(a:msgs)
+    if len(remain) > 0
+      if msgs[0] == ''
+        let msgs[0] = remain
+      else
+        let msgs[0] = remain . msgs[0]
+      endif
+    endif
+    let last = msgs[len(msgs) - 1]
+    let s:err_remain_text[a:id] = len(last) > 0 ? last : ''
+    " all lines from 0 to n - 2
+    if len(msgs) > 1
+      call coc#rpc#notify('TaskStderr', [a:id, msgs[:len(msgs)-2]])
+    elseif eof && len(msgs[0]) > 0
+      call coc#rpc#notify('TaskStderr', [a:id, msgs])
+    endif
+  endif
+endfunction
+
+function! s:on_stdout(id, msgs)
+  if empty(a:msgs)
+    return
+  endif
+  if s:is_vim
+    call coc#rpc#notify('TaskStdout', [a:id, a:msgs])
+  else
+    let remain = get(s:out_remain_text, a:id, '')
+    let eof = (a:msgs == [''])
+    let msgs = copy(a:msgs)
+    if len(remain) > 0
+      if msgs[0] == ''
+        let msgs[0] = remain
+      else
+        let msgs[0] = remain . msgs[0]
+      endif
+    endif
+    let last = msgs[len(msgs) - 1]
+    let s:out_remain_text[a:id] = len(last) > 0 ? last : ''
+    " all lines from 0 to n - 2
+    if len(msgs) > 1
+      call coc#rpc#notify('TaskStdout', [a:id, msgs[:len(msgs)-2]])
+    elseif eof && len(msgs[0]) > 0
+      call coc#rpc#notify('TaskStdout', [a:id, msgs])
+    endif
+  endif
+endfunction
+
+function! coc#task#running(id)
+  if !has_key(s:running_task, a:id) == 1
+    return v:false
+  endif
+  let job = s:running_task[a:id]
+  if s:is_vim
+    let status = job_status(job)
+    return status ==# 'run'
+  endif
+  let [code] = jobwait([job], 10)
+  return code == -1
+endfunction

+ 115 - 0
vimfiles/bundle/coc.nvim/autoload/coc/terminal.vim

@@ -0,0 +1,115 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:channel_map = {}
+let s:is_win = has('win32') || has('win64')
+
+" start terminal, return [bufnr, pid]
+function! coc#terminal#start(cmd, cwd, env, strict) abort
+  if s:is_vim && !has('terminal')
+    throw 'terminal feature not supported by current vim.'
+  endif
+  let cwd = empty(a:cwd) ? getcwd() : a:cwd
+  execute 'belowright '.get(g:, 'coc_terminal_height', 8).'new +setl\ buftype=nofile'
+  setl winfixheight
+  setl norelativenumber
+  setl nonumber
+  setl bufhidden=hide
+  if exists('#User#CocTerminalOpen')
+    exe 'doautocmd <nomodeline> User CocTerminalOpen'
+  endif
+  let bufnr = bufnr('%')
+  let env = {}
+  let original = {}
+  if !empty(a:env)
+    " use env option when possible
+    if s:is_vim
+      let env = copy(a:env)
+    elseif exists('*setenv')
+      for key in keys(a:env)
+        let original[key] = getenv(key)
+        call setenv(key, a:env[key])
+      endfor
+    endif
+  endif
+
+  function! s:OnExit(status) closure
+    call coc#rpc#notify('CocAutocmd', ['TermExit', bufnr, a:status])
+    if a:status == 0
+      execute 'silent! bd! '.bufnr
+    endif
+  endfunction
+
+  if has('nvim')
+    let job_id = termopen(a:cmd, {
+          \ 'cwd': cwd,
+          \ 'pty': v:true,
+          \ 'on_exit': {job, status -> s:OnExit(status)},
+          \ 'env': env,
+          \ 'clear_env': a:strict ? v:true : v:false
+          \ })
+    if !empty(original) && exists('*setenv')
+      for key in keys(original)
+        call setenv(key, original[key])
+      endfor
+    endif
+    if job_id == 0
+      throw 'create terminal job failed'
+    endif
+    wincmd p
+    let s:channel_map[bufnr] = job_id
+    return [bufnr, jobpid(job_id)]
+  else
+    let cmd = s:is_win ? join(a:cmd, ' ') : a:cmd
+    let res = term_start(cmd, {
+          \ 'cwd': cwd,
+          \ 'term_kill': s:is_win ? 'kill' : 'term',
+          \ 'term_finish': 'close',
+          \ 'exit_cb': {job, status -> s:OnExit(status)},
+          \ 'curwin': 1,
+          \ 'env': env,
+          \})
+    if res == 0
+      throw 'create terminal job failed'
+    endif
+    let job = term_getjob(bufnr)
+    let s:channel_map[bufnr] = job_getchannel(job)
+    wincmd p
+    return [bufnr, job_info(job).process]
+  endif
+endfunction
+
+function! coc#terminal#send(bufnr, text, add_new_line) abort
+  let chan = get(s:channel_map, a:bufnr, v:null)
+  if empty(chan) | return| endif
+  if has('nvim')
+    let lines = split(a:text, '\v\r?\n')
+    if a:add_new_line && !empty(lines[len(lines) - 1])
+      if s:is_win
+        call add(lines, "\r\n")
+      else
+        call add(lines, '')
+      endif
+    endif
+    call chansend(chan, lines)
+    let winid = bufwinid(a:bufnr)
+    if winid != -1
+      call coc#compat#execute(winid, 'noa normal! G')
+    endif
+  else
+    if !a:add_new_line
+      call ch_sendraw(chan, a:text)
+    else
+      call ch_sendraw(chan, a:text.(s:is_win ? "\r\n" : "\n"))
+    endif
+  endif
+endfunction
+
+function! coc#terminal#close(bufnr) abort
+  if has('nvim')
+    let job_id = get(s:channel_map, a:bufnr, 0)
+    if !empty(job_id)
+      silent! call chanclose(job_id)
+    endif
+  endif
+  exe 'silent! bd! '.a:bufnr
+endfunction

+ 446 - 0
vimfiles/bundle/coc.nvim/autoload/coc/ui.vim

@@ -0,0 +1,446 @@
+let s:is_vim = !has('nvim')
+let s:is_win = has('win32') || has('win64')
+let s:is_mac = has('mac')
+let s:sign_api = exists('*sign_getplaced') && exists('*sign_place')
+let s:sign_groups = []
+
+" Check <Tab> and <CR>
+function! coc#ui#check_pum_keymappings() abort
+  let keys = []
+  for key in ['<cr>', '<tab>']
+    if maparg(key, 'i') =~# 'pumvisible()'
+      call add(keys, key)
+    endif
+  endfor
+  if len(keys)
+    let lines = [
+     \ 'coc.nvim switched to custom popup menu from 0.0.82',
+     \ 'you have to change key-mappings for '.join(keys, ', ').' to make them work.',
+     \ 'see :h coc-completion-example']
+    call coc#notify#create(lines, {
+          \ 'borderhighlight': 'CocInfoSign',
+          \ 'timeout': 30000,
+          \ 'kind': 'warning',
+          \ })
+  endif
+endfunction
+
+function! coc#ui#quickpick(title, items, cb) abort
+  if exists('*popup_menu')
+    function! s:QuickpickHandler(id, result) closure
+      call a:cb(v:null, a:result)
+    endfunction
+    function! s:QuickpickFilter(id, key) closure
+      for i in range(1, len(a:items))
+        if a:key == string(i)
+          call popup_close(a:id, i)
+          return 1
+        endif
+      endfor
+      " No shortcut, pass to generic filter
+      return popup_filter_menu(a:id, a:key)
+    endfunction
+    try
+      call popup_menu(a:items, {
+        \ 'title': a:title,
+        \ 'filter': function('s:QuickpickFilter'),
+        \ 'callback': function('s:QuickpickHandler'),
+        \ })
+      redraw
+    catch /.*/
+      call a:cb(v:exception)
+    endtry
+  else
+    let res = inputlist([a:title] + a:items)
+    call a:cb(v:null, res)
+  endif
+endfunction
+
+" cmd, cwd
+function! coc#ui#open_terminal(opts) abort
+  if s:is_vim && !exists('*term_start')
+    echohl WarningMsg | echon "Your vim doesn't have terminal support!" | echohl None
+    return
+  endif
+  if get(a:opts, 'position', 'bottom') ==# 'bottom'
+    let p = '5new'
+  else
+    let p = 'vnew'
+  endif
+  execute 'belowright '.p.' +setl\ buftype=nofile '
+  setl buftype=nofile
+  setl winfixheight
+  setl norelativenumber
+  setl nonumber
+  setl bufhidden=wipe
+  if exists('#User#CocTerminalOpen')
+    exe 'doautocmd <nomodeline> User CocTerminalOpen'
+  endif
+  let cmd = get(a:opts, 'cmd', '')
+  let autoclose = get(a:opts, 'autoclose', 1)
+  if empty(cmd)
+    throw 'command required!'
+  endif
+  let cwd = get(a:opts, 'cwd', getcwd())
+  let keepfocus = get(a:opts, 'keepfocus', 0)
+  let bufnr = bufnr('%')
+  let Callback = get(a:opts, 'Callback', v:null)
+
+  function! s:OnExit(status) closure
+    let content = join(getbufline(bufnr, 1, '$'), "\n")
+    if a:status == 0 && autoclose == 1
+      execute 'silent! bd! '.bufnr
+    endif
+    if !empty(Callback)
+      call call(Callback, [a:status, bufnr, content])
+    endif
+  endfunction
+
+  if has('nvim')
+    call termopen(cmd, {
+          \ 'cwd': cwd,
+          \ 'on_exit': {job, status -> s:OnExit(status)},
+          \})
+  else
+    if s:is_win
+      let cmd = 'cmd.exe /C "'.cmd.'"'
+    endif
+    call term_start(cmd, {
+          \ 'cwd': cwd,
+          \ 'exit_cb': {job, status -> s:OnExit(status)},
+          \ 'curwin': 1,
+          \})
+  endif
+  if keepfocus
+    wincmd p
+  endif
+  return bufnr
+endfunction
+
+" run command in terminal
+function! coc#ui#run_terminal(opts, cb)
+  let cmd = get(a:opts, 'cmd', '')
+  if empty(cmd)
+    return a:cb('command required for terminal')
+  endif
+  let opts = {
+        \ 'cmd': cmd,
+        \ 'cwd': get(a:opts, 'cwd', getcwd()),
+        \ 'keepfocus': get(a:opts, 'keepfocus', 0),
+        \ 'Callback': {status, bufnr, content -> a:cb(v:null, {'success': status == 0 ? v:true : v:false, 'bufnr': bufnr, 'content': content})}
+        \}
+  call coc#ui#open_terminal(opts)
+endfunction
+
+function! coc#ui#echo_hover(msg)
+  echohl MoreMsg
+  echo a:msg
+  echohl None
+  let g:coc_last_hover_message = a:msg
+endfunction
+
+function! coc#ui#echo_messages(hl, msgs)
+  if a:hl !~# 'Error' && (mode() !~# '\v^(i|n)$')
+    return
+  endif
+  let msgs = filter(copy(a:msgs), '!empty(v:val)')
+  if empty(msgs)
+    return
+  endif
+  execute 'echohl '.a:hl
+  echom a:msgs[0]
+  redraw
+  echo join(msgs, "\n")
+  echohl None
+endfunction
+
+function! coc#ui#preview_info(lines, filetype, ...) abort
+  pclose
+  keepalt new +setlocal\ previewwindow|setlocal\ buftype=nofile|setlocal\ noswapfile|setlocal\ wrap [Document]
+  setl bufhidden=wipe
+  setl nobuflisted
+  setl nospell
+  exe 'setl filetype='.a:filetype
+  setl conceallevel=0
+  setl nofoldenable
+  for command in a:000
+    execute command
+  endfor
+  call append(0, a:lines)
+  exe "normal! z" . len(a:lines) . "\<cr>"
+  exe "normal! gg"
+  wincmd p
+endfunction
+
+function! coc#ui#open_files(files)
+  let bufnrs = []
+  " added on latest vim8
+  if exists('*bufadd') && exists('*bufload')
+    for file in a:files
+      let file = fnamemodify(file, ':.')
+      if bufloaded(file)
+        call add(bufnrs, bufnr(file))
+      else
+        let bufnr = bufadd(file)
+        call bufload(file)
+        call add(bufnrs, bufnr)
+        call setbufvar(bufnr, '&buflisted', 1)
+      endif
+    endfor
+  else
+    noa keepalt 1new +setl\ bufhidden=wipe
+    for file in a:files
+      let file = fnamemodify(file, ':.')
+      execute 'noa edit +setl\ bufhidden=hide '.fnameescape(file)
+      if &filetype ==# ''
+        filetype detect
+      endif
+      call add(bufnrs, bufnr('%'))
+    endfor
+    noa close
+  endif
+  doautocmd BufEnter
+  return bufnrs
+endfunction
+
+function! coc#ui#echo_lines(lines)
+  echo join(a:lines, "\n")
+endfunction
+
+function! coc#ui#echo_signatures(signatures) abort
+  if pumvisible() | return | endif
+  echo ""
+  for i in range(len(a:signatures))
+    call s:echo_signature(a:signatures[i])
+    if i != len(a:signatures) - 1
+      echon "\n"
+    endif
+  endfor
+endfunction
+
+function! s:echo_signature(parts)
+  for part in a:parts
+    let hl = get(part, 'type', 'Normal')
+    let text = get(part, 'text', '')
+    if !empty(text)
+      execute 'echohl '.hl
+      execute "echon '".substitute(text, "'", "''", 'g')."'"
+      echohl None
+    endif
+  endfor
+endfunction
+
+function! coc#ui#iterm_open(dir)
+  return s:osascript(
+      \ 'if application "iTerm2" is not running',
+      \   'error',
+      \ 'end if') && s:osascript(
+      \ 'tell application "iTerm2"',
+      \   'tell current window',
+      \     'create tab with default profile',
+      \     'tell current session',
+      \       'write text "cd ' . a:dir . '"',
+      \       'write text "clear"',
+      \       'activate',
+      \     'end tell',
+      \   'end tell',
+      \ 'end tell')
+endfunction
+
+function! s:osascript(...) abort
+  let args = join(map(copy(a:000), '" -e ".shellescape(v:val)'), '')
+  call  s:system('osascript'. args)
+  return !v:shell_error
+endfunction
+
+function! s:system(cmd)
+  let output = system(a:cmd)
+  if v:shell_error && output !=# ""
+    echohl Error | echom output | echohl None
+    return
+  endif
+  return output
+endfunction
+
+function! coc#ui#set_lines(bufnr, changedtick, original, replacement, start, end, changes, cursor, col) abort
+  if !bufloaded(a:bufnr)
+    return
+  endif
+  let delta = 0
+  if !empty(a:col)
+    let delta = col('.') - a:col
+  endif
+  if getbufvar(a:bufnr, 'changedtick') > a:changedtick && bufnr('%') == a:bufnr
+    " try apply current line change
+    let lnum = line('.')
+    " change for current line
+    if a:end - a:start == 1 && a:end == lnum && len(a:replacement) == 1
+      let idx = a:start - lnum + 1
+      let previous = get(a:original, idx, 0)
+      if type(previous) == 1
+        let content = getline('.')
+        if previous !=# content
+          let diff = coc#string#diff(content, previous, col('.'))
+          let changed = get(a:replacement, idx, 0)
+          if type(changed) == 1 && strcharpart(previous, 0, diff['end']) ==# strcharpart(changed, 0, diff['end'])
+            let applied = coc#string#apply(changed, diff)
+            let replacement = copy(a:replacement)
+            let replacement[idx] = applied
+            call coc#compat#buf_set_lines(a:bufnr, a:start, a:end, replacement)
+            return
+          endif
+        endif
+      endif
+    endif
+  endif
+  if exists('*nvim_buf_set_text') && !empty(a:changes)
+    for item in reverse(copy(a:changes))
+      call nvim_buf_set_text(a:bufnr, item[1], item[2], item[3], item[4], item[0])
+    endfor
+  else
+    call coc#compat#buf_set_lines(a:bufnr, a:start, a:end, a:replacement)
+  endif
+  if !empty(a:cursor)
+    call cursor(a:cursor[0], a:cursor[1] + delta)
+  endif
+endfunction
+
+function! coc#ui#change_lines(bufnr, list) abort
+  if !bufloaded(a:bufnr) | return v:null | endif
+  undojoin
+  if exists('*setbufline')
+    for [lnum, line] in a:list
+      call setbufline(a:bufnr, lnum + 1, line)
+    endfor
+  elseif a:bufnr == bufnr('%')
+    for [lnum, line] in a:list
+      call setline(lnum + 1, line)
+    endfor
+  else
+    let bufnr = bufnr('%')
+    exe 'noa buffer '.a:bufnr
+    for [lnum, line] in a:list
+      call setline(lnum + 1, line)
+    endfor
+    exe 'noa buffer '.bufnr
+  endif
+endfunction
+
+function! coc#ui#open_url(url)
+  if has('mac') && executable('open')
+    call system('open '.a:url)
+    return
+  endif
+  if executable('xdg-open')
+    call system('xdg-open '.a:url)
+    return
+  endif
+  call system('cmd /c start "" /b '. substitute(a:url, '&', '^&', 'g'))
+  if v:shell_error
+    echohl Error | echom 'Failed to open '.a:url | echohl None
+    return
+  endif
+endfunction
+
+function! coc#ui#rename_file(oldPath, newPath, write) abort
+  let bufnr = bufnr(a:oldPath)
+  if bufnr == -1
+    throw 'Unable to get bufnr of '.a:oldPath
+  endif
+  if a:oldPath =~? a:newPath && (s:is_mac || s:is_win)
+    return coc#ui#safe_rename(bufnr, a:oldPath, a:newPath, a:write)
+  endif
+  if bufloaded(a:newPath)
+    execute 'silent bdelete! '.bufnr(a:newPath)
+  endif
+  let current = bufnr == bufnr('%')
+  let bufname = fnamemodify(a:newPath, ":~:.")
+  let filepath = fnamemodify(bufname(bufnr), '%:p')
+  let winid = coc#compat#buf_win_id(bufnr)
+  let curr = -1
+  if winid == -1
+    let curr = win_getid()
+    let file = fnamemodify(bufname(bufnr), ':.')
+    execute 'keepalt tab drop '.fnameescape(bufname(bufnr))
+    let winid = win_getid()
+  endif
+  call coc#compat#execute(winid, 'keepalt file '.fnameescape(bufname), 'silent')
+  call coc#compat#execute(winid, 'doautocmd BufEnter')
+  if a:write
+    call coc#compat#execute(winid, 'noa write!', 'silent')
+    call delete(filepath, '')
+  endif
+  if curr != -1
+    call win_gotoid(curr)
+  endif
+  return bufnr
+endfunction
+
+" System is case in sensitive and newPath have different case.
+function! coc#ui#safe_rename(bufnr, oldPath, newPath, write) abort
+  let winid = win_getid()
+  let lines = getbufline(a:bufnr, 1, '$')
+  execute 'keepalt tab drop '.fnameescape(fnamemodify(a:oldPath, ':.'))
+  let view = winsaveview()
+  execute 'keepalt bwipeout! '.a:bufnr
+  if a:write
+    call delete(a:oldPath, '')
+  endif
+  execute 'keepalt edit '.fnameescape(fnamemodify(a:newPath, ':~:.'))
+  let bufnr = bufnr('%')
+  call coc#compat#buf_set_lines(bufnr, 0, -1, lines)
+  if a:write
+    execute 'noa write'
+  endif
+  call winrestview(view)
+  call win_gotoid(winid)
+  return bufnr
+endfunction
+
+function! coc#ui#sign_unplace() abort
+  if exists('*sign_unplace')
+    for group in s:sign_groups
+      call sign_unplace(group)
+    endfor
+  endif
+endfunction
+
+function! coc#ui#update_signs(bufnr, group, signs) abort
+  if !s:sign_api || !bufloaded(a:bufnr)
+    return
+  endif
+  if len(a:signs)
+    call add(s:sign_groups, a:group)
+  endif
+  let current = get(get(sign_getplaced(a:bufnr, {'group': a:group}), 0, {}), 'signs', [])
+  let exists = []
+  let unplaceList = []
+  for item in current
+    let index = 0
+    let placed = 0
+    for def in a:signs
+      if def['name'] ==# item['name'] && def['lnum'] == item['lnum']
+        let placed = 1
+        call add(exists, index)
+        break
+      endif
+      let index = index + 1
+    endfor
+    if !placed
+      call add(unplaceList, item['id'])
+    endif
+  endfor
+  for idx in range(0, len(a:signs) - 1)
+    if index(exists, idx) == -1
+      let def = a:signs[idx]
+      let opts = {'lnum': def['lnum']}
+      if has_key(def, 'priority')
+        let opts['priority'] = def['priority']
+      endif
+      call sign_place(0, a:group, def['name'], a:bufnr, opts)
+    endif
+  endfor
+  for id in unplaceList
+    call sign_unplace(a:group, {'buffer': a:bufnr, 'id': id})
+  endfor
+endfunction

+ 625 - 0
vimfiles/bundle/coc.nvim/autoload/coc/util.vim

@@ -0,0 +1,625 @@
+scriptencoding utf-8
+let s:root = expand('<sfile>:h:h:h')
+let s:is_win = has('win32') || has('win64')
+let s:is_vim = !has('nvim')
+let s:vim_api_version = 31
+
+function! coc#util#remote_fns(name)
+  let fns = ['init', 'complete', 'should_complete', 'refresh', 'get_startcol', 'on_complete', 'on_enter']
+  let res = []
+  for fn in fns
+    if exists('*coc#source#'.a:name.'#'.fn)
+      call add(res, fn)
+    endif
+  endfor
+  return res
+endfunction
+
+function! coc#util#do_complete(name, opt, cb) abort
+  let handler = 'coc#source#'.a:name.'#complete'
+  let l:Cb = {res -> a:cb(v:null, res)}
+  let args = [a:opt, l:Cb]
+  call call(handler, args)
+endfunction
+
+function! coc#util#suggest_variables(bufnr) abort
+  return {
+      \ 'disable': getbufvar(a:bufnr, 'coc_suggest_disable', 0),
+      \ 'disabled_sources': getbufvar(a:bufnr, 'coc_disabled_sources', []),
+      \ 'blacklist': getbufvar(a:bufnr, 'coc_suggest_blacklist', []),
+      \ }
+endfunction
+
+function! coc#util#api_version() abort
+  return s:vim_api_version
+endfunction
+
+function! coc#util#semantic_hlgroups() abort
+  let res = split(execute('hi'), "\n")
+  let filtered = filter(res, "v:val =~# '^CocSem'")
+  return map(filtered, "matchstr(v:val,'\\v^CocSem\\w+')")
+endfunction
+
+" get cursor position
+function! coc#util#cursor()
+  return [line('.') - 1, strchars(strpart(getline('.'), 0, col('.') - 1))]
+endfunction
+
+function! coc#util#change_info() abort
+  return {'lnum': line('.'), 'col': col('.'), 'line': getline('.'), 'changedtick': b:changedtick}
+endfunction
+
+function! coc#util#jumpTo(line, character) abort
+  echohl WarningMsg | echon 'coc#util#jumpTo is deprecated, use coc#cursor#move_to instead.' | echohl None
+  call coc#cursor#move_to(a:line, a:character)
+endfunction
+
+function! coc#util#root_patterns() abort
+  return coc#rpc#request('rootPatterns', [bufnr('%')])
+endfunction
+
+function! coc#util#get_config(key) abort
+  return coc#rpc#request('getConfig', [a:key])
+endfunction
+
+function! coc#util#open_terminal(opts) abort
+  return coc#ui#open_terminal(a:opts)
+endfunction
+
+function! coc#util#synname() abort
+  return synIDattr(synID(line('.'), col('.') - 1, 1), 'name')
+endfunction
+
+function! coc#util#setline(lnum, line)
+  keepjumps call setline(a:lnum, a:line)
+endfunction
+
+function! coc#util#path_replace_patterns() abort
+  if has('win32unix') && exists('g:coc_cygqwin_path_prefixes')
+    echohl WarningMsg 
+    echon 'g:coc_cygqwin_path_prefixes is deprecated, use g:coc_uri_prefix_replace_patterns instead' 
+    echohl None
+    return g:coc_cygqwin_path_prefixes
+  endif
+  if exists('g:coc_uri_prefix_replace_patterns')
+    return g:coc_uri_prefix_replace_patterns
+  endif
+  return v:null
+endfunction
+
+function! coc#util#version()
+  if s:is_vim
+    return string(v:versionlong)
+  endif
+  let c = execute('silent version')
+  let lines = split(matchstr(c,  'NVIM v\zs[^\n-]*'))
+  return lines[0]
+endfunction
+
+function! coc#util#check_refresh(bufnr)
+  if !bufloaded(a:bufnr)
+    return 0
+  endif
+  if getbufvar(a:bufnr, 'coc_diagnostic_disable', 0)
+    return 0
+  endif
+  if get(g: , 'EasyMotion_loaded', 0)
+    return EasyMotion#is_active() != 1
+  endif
+  return 1
+endfunction
+
+function! coc#util#diagnostic_info(bufnr, checkInsert) abort
+  let checked = coc#util#check_refresh(a:bufnr)
+  if !checked
+    return v:null
+  endif
+  if a:checkInsert && mode() =~# '^i'
+    return v:null
+  endif
+  let locationlist = ''
+  let winid = -1
+  for info in getwininfo()
+    if info['bufnr'] == a:bufnr
+      let winid = info['winid']
+      let locationlist = get(getloclist(winid, {'title': 1}), 'title', '')
+      break
+    endif
+  endfor
+  return {
+      \ 'bufnr': bufnr('%'),
+      \ 'winid': winid,
+      \ 'lnum': line('.'),
+      \ 'locationlist': locationlist
+      \ }
+endfunction
+
+function! coc#util#open_file(cmd, file)
+  execute a:cmd .' '.fnameescape(fnamemodify(a:file, ':~:.'))
+  return bufnr('%')
+endfunction
+
+function! coc#util#job_command()
+  if (has_key(g:, 'coc_node_path'))
+    let node = expand(g:coc_node_path)
+  else
+    let node = $COC_NODE_PATH == '' ? 'node' : $COC_NODE_PATH
+  endif
+  if !executable(node)
+    echohl Error | echom '[coc.nvim] "'.node.'" is not executable, checkout https://nodejs.org/en/download/' | echohl None
+    return
+  endif
+  if !filereadable(s:root.'/build/index.js')
+    if isdirectory(s:root.'/src')
+      echohl Error | echom '[coc.nvim] build/index.js not found, please install dependencies and compile coc.nvim by: yarn install' | echohl None
+    else
+      echohl Error | echon '[coc.nvim] your coc.nvim is broken.' | echohl None
+    endif
+    return
+  endif
+  return [node] + get(g:, 'coc_node_args', ['--no-warnings']) + [s:root.'/build/index.js']
+endfunction
+
+function! coc#util#jump(cmd, filepath, ...) abort
+  if a:cmd != 'pedit'
+    silent! normal! m'
+  endif
+  let path = a:filepath
+  if (has('win32unix'))
+    let path = substitute(a:filepath, '\v\\', '/', 'g')
+  endif
+  let file = fnamemodify(path, ":~:.")
+  if a:cmd == 'pedit'
+    let extra = empty(get(a:, 1, [])) ? '' : '+'.(a:1[0] + 1)
+    exe 'pedit '.extra.' '.fnameescape(file)
+    return
+  elseif a:cmd == 'drop' && exists('*bufadd')
+    let dstbuf = bufadd(path)
+    let binfo = getbufinfo(dstbuf)
+    if len(binfo) == 1 && empty(binfo[0].windows)
+      exec 'buffer '.dstbuf
+      let &buflisted = 1
+    else
+      exec 'drop '.fnameescape(file)
+    endif
+  elseif a:cmd == 'edit' && bufloaded(file)
+    exe 'b '.bufnr(file)
+  else
+    call s:safer_open(a:cmd, file)
+  endif
+  if !empty(get(a:, 1, []))
+    let line = getline(a:1[0] + 1)
+    " TODO need to use utf16 here
+    let col = byteidx(line, a:1[1]) + 1
+    if col == 0
+      let col = 999
+    endif
+    call cursor(a:1[0] + 1, col)
+  endif
+  if &filetype ==# ''
+    filetype detect
+  endif
+  if s:is_vim
+    redraw
+  endif
+endfunction
+
+function! s:safer_open(cmd, file) abort
+  " How to support :pedit and :drop?
+  let is_supported_cmd = index(["edit", "split", "vsplit", "tabe"], a:cmd) >= 0
+
+  " Use special handling only for URI.
+  let looks_like_uri = match(a:file, "^.*://") >= 0
+
+  if looks_like_uri && is_supported_cmd && has('win32') && exists('*bufadd')
+    " Workaround a bug for Win32 paths.
+    "
+    " reference:
+    " - https://github.com/vim/vim/issues/541
+    " - https://github.com/neoclide/coc-java/issues/82
+    " - https://github.com/vim-jp/issues/issues/6
+    let buf = bufadd(a:file)
+    if a:cmd != 'edit'
+      " Open split, tab, etc. by a:cmd.
+      exe a:cmd
+    endif
+    " Set current buffer to the file
+    exe 'keepjumps buffer ' . buf
+  else
+    exe a:cmd.' '.fnameescape(a:file)
+  endif
+endfunction
+
+function! coc#util#variables(bufnr) abort
+  let info = getbufinfo(a:bufnr)
+  let variables = empty(info) ? {} : copy(info[0]['variables'])
+  for key in keys(variables)
+    if key !~# '\v^coc'
+      unlet variables[key]
+    endif
+  endfor
+  return variables
+endfunction
+
+function! coc#util#with_callback(method, args, cb)
+  function! s:Cb() closure
+    try
+      let res = call(a:method, a:args)
+      call a:cb(v:null, res)
+    catch /.*/
+      call a:cb(v:exception)
+    endtry
+  endfunction
+  let timeout = s:is_vim ? 10 : 0
+  call timer_start(timeout, {-> s:Cb() })
+endfunction
+
+function! coc#util#timer(method, args)
+  call timer_start(0, { -> s:Call(a:method, a:args)})
+endfunction
+
+function! s:Call(method, args)
+  try
+    call call(a:method, a:args)
+    redraw
+  catch /.*/
+    return 0
+  endtry
+endfunction
+
+function! coc#util#vim_info()
+  return {
+        \ 'apiversion': s:vim_api_version,
+        \ 'mode': mode(),
+        \ 'config': get(g:, 'coc_user_config', {}),
+        \ 'floating': has('nvim') && exists('*nvim_open_win') ? v:true : v:false,
+        \ 'extensionRoot': coc#util#extension_root(),
+        \ 'globalExtensions': get(g:, 'coc_global_extensions', []),
+        \ 'lines': &lines,
+        \ 'columns': &columns,
+        \ 'cmdheight': &cmdheight,
+        \ 'pid': coc#util#getpid(),
+        \ 'filetypeMap': get(g:, 'coc_filetype_map', {}),
+        \ 'version': coc#util#version(),
+        \ 'completeOpt': &completeopt,
+        \ 'pumevent': 1,
+        \ 'isVim': has('nvim') ? v:false : v:true,
+        \ 'isCygwin': has('win32unix') ? v:true : v:false,
+        \ 'isMacvim': has('gui_macvim') ? v:true : v:false,
+        \ 'isiTerm': $TERM_PROGRAM ==# "iTerm.app",
+        \ 'colorscheme': get(g:, 'colors_name', ''),
+        \ 'workspaceFolders': get(g:, 'WorkspaceFolders', v:null),
+        \ 'background': &background,
+        \ 'runtimepath': join(globpath(&runtimepath, '', 0, 1), ','),
+        \ 'locationlist': get(g:,'coc_enable_locationlist', 1),
+        \ 'progpath': v:progpath,
+        \ 'guicursor': &guicursor,
+        \ 'pumwidth': exists('&pumwidth') ? &pumwidth : 15,
+        \ 'tabCount': tabpagenr('$'),
+        \ 'updateHighlight': has('nvim-0.5.0') || has('patch-8.1.1719') ? v:true : v:false,
+        \ 'vimCommands': get(g:, 'coc_vim_commands', []),
+        \ 'sign': exists('*sign_place') && exists('*sign_unplace'),
+        \ 'ambiguousIsNarrow': &ambiwidth ==# 'single' ? v:true : v:false,
+        \ 'textprop': has('textprop') && has('patch-8.1.1719') && !has('nvim') ? v:true : v:false,
+        \ 'dialog': has('nvim-0.4.0') || has('patch-8.2.0750') ? v:true : v:false,
+        \ 'semanticHighlights': coc#util#semantic_hlgroups()
+        \}
+endfunction
+
+function! coc#util#all_state()
+  return {
+        \ 'bufnr': bufnr('%'),
+        \ 'winid': win_getid(),
+        \ 'bufnrs': map(getbufinfo({'bufloaded': 1}),'v:val["bufnr"]'),
+        \ 'winids': map(getwininfo(),'v:val["winid"]'),
+        \ }
+endfunction
+
+function! coc#util#install() abort
+  let yarncmd = get(g:, 'coc_install_yarn_cmd', executable('yarnpkg') ? 'yarnpkg' : 'yarn')
+  call coc#ui#open_terminal({
+        \ 'cwd': s:root,
+        \ 'cmd': yarncmd.' install --frozen-lockfile --ignore-engines',
+        \ 'autoclose': 0,
+        \ })
+endfunction
+
+function! coc#util#extension_root() abort
+  if get(g:, 'coc_node_env', '') ==# 'test'
+    return s:root.'/src/__tests__/extensions'
+  endif
+  if !empty(get(g:, 'coc_extension_root', ''))
+    echohl Error | echon 'g:coc_extension_root not used any more, use g:coc_data_home instead' | echohl None
+  endif
+  return coc#util#get_data_home().'/extensions'
+endfunction
+
+function! coc#util#update_extensions(...) abort
+  let async = get(a:, 1, 0)
+  if async
+    call coc#rpc#notify('updateExtensions', [])
+  else
+    call coc#rpc#request('updateExtensions', [v:true])
+  endif
+endfunction
+
+function! coc#util#install_extension(args) abort
+  let names = filter(copy(a:args), 'v:val !~# "^-"')
+  let isRequest = index(a:args, '-sync') != -1
+  if isRequest
+    call coc#rpc#request('installExtensions', names)
+  else
+    call coc#rpc#notify('installExtensions', names)
+  endif
+endfunction
+
+function! coc#util#do_autocmd(name) abort
+  if exists('#User#'.a:name)
+    exe 'doautocmd <nomodeline> User '.a:name
+  endif
+endfunction
+
+function! coc#util#rebuild()
+  let dir = coc#util#extension_root()
+  if !isdirectory(dir) | return | endif
+  call coc#ui#open_terminal({
+        \ 'cwd': dir,
+        \ 'cmd': 'npm rebuild',
+        \ 'keepfocus': 1,
+        \})
+endfunction
+
+function! coc#util#unmap(bufnr, keys) abort
+  if bufnr('%') == a:bufnr
+    for key in a:keys
+      exe 'silent! nunmap <buffer> '.key
+    endfor
+  endif
+endfunction
+
+function! coc#util#refactor_foldlevel(lnum) abort
+  if a:lnum <= 2 | return 0 | endif
+  let line = getline(a:lnum)
+  if line =~# '^\%u3000\s*$' | return 0 | endif
+  return 1
+endfunction
+
+function! coc#util#refactor_fold_text(lnum) abort
+  let range = ''
+  let info = get(b:line_infos, a:lnum, [])
+  if !empty(info)
+    let range = info[0].':'.info[1]
+  endif
+  return trim(getline(a:lnum)[3:]).' '.range
+endfunction
+
+" get tabsize & expandtab option
+function! coc#util#get_format_opts(bufnr) abort
+  let bufnr = a:bufnr && bufloaded(a:bufnr) ? a:bufnr : bufnr('%')
+  let tabsize = getbufvar(bufnr, '&shiftwidth')
+  if tabsize == 0
+    let tabsize = getbufvar(bufnr, '&tabstop')
+  endif
+  return {
+      \ 'tabsize': tabsize,
+      \ 'expandtab': getbufvar(bufnr, '&expandtab'),
+      \ 'insertFinalNewline': getbufvar(bufnr, '&eol'),
+      \ 'trimTrailingWhitespace': getbufvar(bufnr, 'coc_trim_trailing_whitespace', 0),
+      \ 'trimFinalNewlines': getbufvar(bufnr, 'coc_trim_final_newlines', 0)
+      \ }
+endfunction
+
+function! coc#util#get_editoroption(winid) abort
+  if !coc#compat#win_is_valid(a:winid)
+    return v:null
+  endif
+  if has('nvim') && exists('*nvim_win_get_config')
+    " avoid float window
+    let config = nvim_win_get_config(a:winid)
+    if !empty(get(config, 'relative', ''))
+      return v:null
+    endif
+  endif
+  let info = getwininfo(a:winid)[0]
+  let bufnr = info['bufnr']
+  let buftype = getbufvar(bufnr, '&buftype')
+  " avoid window for other purpose.
+  if buftype !=# '' && buftype !=# 'acwrite'
+    return v:null
+  endif
+  let tabSize = getbufvar(bufnr, '&shiftwidth')
+  if tabSize == 0
+    let tabSize = getbufvar(bufnr, '&tabstop')
+  endif
+  return {
+        \ 'bufnr': bufnr,
+        \ 'winid': a:winid,
+        \ 'winids': map(getwininfo(), 'v:val["winid"]'),
+        \ 'tabpagenr': info['tabnr'],
+        \ 'winnr': winnr(),
+        \ 'visibleRanges': s:visible_ranges(a:winid),
+        \ 'tabSize': tabSize,
+        \ 'insertSpaces': getbufvar(bufnr, '&expandtab') ? v:true : v:false
+        \ }
+endfunction
+
+function! coc#util#getpid()
+  if !has('win32unix')
+    return getpid()
+  endif
+  let cmd = 'cat /proc/' . getpid() . '/winpid'
+  return substitute(system(cmd), '\v\n', '', 'gi')
+endfunction
+
+" Get indentkeys for indent on TextChangedP, consider = for word indent only.
+function! coc#util#get_indentkeys() abort
+  if empty(&indentexpr)
+    return ''
+  endif
+  if &indentkeys !~# '='
+    return ''
+  endif
+  return &indentkeys
+endfunction
+
+function! coc#util#get_bufoptions(bufnr) abort
+  if !bufloaded(a:bufnr) | return v:null | endif
+  let bufname = bufname(a:bufnr)
+  let buftype = getbufvar(a:bufnr, '&buftype')
+  let winid = bufwinid(a:bufnr)
+  let size = -1
+  if bufnr('%') == a:bufnr
+    let size = line2byte(line("$") + 1)
+  elseif !empty(bufname)
+    let size = getfsize(bufname)
+  endif
+  let lines = v:null
+  if getbufvar(a:bufnr, 'coc_enabled', 1) && (buftype == '' || buftype == 'acwrite') && size < get(g:, 'coc_max_filesize', 2097152)
+    let lines = getbufline(a:bufnr, 1, '$')
+  endif
+  return {
+        \ 'bufnr': a:bufnr,
+        \ 'size': size,
+        \ 'lines': lines,
+        \ 'winid': winid,
+        \ 'bufname': bufname,
+        \ 'buftype': buftype,
+        \ 'previewwindow': v:false,
+        \ 'eol': getbufvar(a:bufnr, '&eol'),
+        \ 'indentkeys': coc#util#get_indentkeys(),
+        \ 'variables': coc#util#variables(a:bufnr),
+        \ 'filetype': getbufvar(a:bufnr, '&filetype'),
+        \ 'iskeyword': getbufvar(a:bufnr, '&iskeyword'),
+        \ 'changedtick': getbufvar(a:bufnr, 'changedtick'),
+        \ 'fullpath': empty(bufname) ? '' : fnamemodify(bufname, ':p'),
+        \}
+endfunction
+
+function! coc#util#get_config_home()
+  if !empty(get(g:, 'coc_config_home', ''))
+      return resolve(expand(g:coc_config_home))
+  endif
+  if exists('$VIMCONFIG')
+    return resolve($VIMCONFIG)
+  endif
+  if has('nvim')
+    if exists('$XDG_CONFIG_HOME')
+      return resolve($XDG_CONFIG_HOME."/nvim")
+    endif
+    if s:is_win
+      return resolve($HOME.'/AppData/Local/nvim')
+    endif
+    return resolve($HOME.'/.config/nvim')
+  else
+    if s:is_win
+      return resolve($HOME."/vimfiles")
+    endif
+    return resolve($HOME.'/.vim')
+  endif
+endfunction
+
+function! coc#util#get_data_home()
+  if !empty(get(g:, 'coc_data_home', ''))
+    let dir = resolve(expand(g:coc_data_home))
+  else
+    if exists('$XDG_CONFIG_HOME')
+      let dir = resolve($XDG_CONFIG_HOME."/coc")
+    else
+      if s:is_win
+        let dir = resolve(expand('~/AppData/Local/coc'))
+      else
+        let dir = resolve(expand('~/.config/coc'))
+      endif
+    endif
+  endif
+  if !isdirectory(dir)
+    call coc#notify#create(['creating data directory: '.dir], {
+          \ 'borderhighlight': 'CocInfoSign',
+          \ 'timeout': 5000,
+          \ 'kind': 'info',
+          \ })
+    call mkdir(dir, "p", 0755)
+  endif
+  return dir
+endfunction
+
+function! coc#util#get_complete_option()
+  if get(b:,"coc_suggest_disable",0)
+    return v:null
+  endif
+  let pos = getcurpos()
+  let line = getline(pos[1])
+  let input = matchstr(strpart(line, 0, pos[2] - 1), '\k*$')
+  let col = pos[2] - strlen(input)
+  return {
+        \ 'word': matchstr(strpart(line, col - 1), '^\k\+'),
+        \ 'input': empty(input) ? '' : input,
+        \ 'line': line,
+        \ 'filetype': &filetype,
+        \ 'filepath': expand('%:p'),
+        \ 'bufnr': bufnr('%'),
+        \ 'linenr': pos[1],
+        \ 'colnr' : pos[2],
+        \ 'col': col - 1,
+        \ 'changedtick': b:changedtick,
+        \ 'blacklist': get(b:, 'coc_suggest_blacklist', []),
+        \ 'disabled': get(b:, 'coc_disabled_sources', []),
+        \ 'indentkeys': coc#util#get_indentkeys()
+        \}
+endfunction
+
+" used by vim
+function! coc#util#get_buf_lines(bufnr, changedtick)
+  if !bufloaded(a:bufnr)
+    return v:null
+  endif
+  let changedtick = getbufvar(a:bufnr, 'changedtick')
+  if changedtick == a:changedtick
+    return v:null
+  endif
+  return {
+        \ 'lines': getbufline(a:bufnr, 1, '$'),
+        \ 'changedtick': getbufvar(a:bufnr, 'changedtick')
+        \ }
+endfunction
+
+" used for TextChangedI with InsertCharPre
+function! coc#util#get_changeinfo()
+  return {
+        \ 'bufnr': bufnr('%'),
+        \ 'lnum': line('.'),
+        \ 'line': getline('.'),
+        \ 'changedtick': b:changedtick,
+        \}
+endfunction
+
+function! s:visible_ranges(winid) abort
+  let info = getwininfo(a:winid)[0]
+  let res = []
+  if !has_key(info, 'topline') || !has_key(info, 'botline')
+    return res
+  endif
+  let begin = 0
+  let curr = info['topline']
+  let max = info['botline']
+  if win_getid() != a:winid
+    return [[curr, max]]
+  endif
+  while curr <= max
+    let closedend = foldclosedend(curr)
+    if closedend == -1
+      let begin = begin == 0 ? curr : begin
+      if curr == max
+        call add(res, [begin, curr])
+      endif
+      let curr = curr + 1
+    else
+      if begin != 0
+        call add(res, [begin, curr - 1])
+        let begin = closedend + 1
+      endif
+      let curr = closedend + 1
+    endif
+  endwhile
+  return res
+endfunction

+ 205 - 0
vimfiles/bundle/coc.nvim/autoload/coc/window.vim

@@ -0,0 +1,205 @@
+let g:coc_max_treeview_width = get(g:, 'coc_max_treeview_width', 40)
+let s:is_vim = !has('nvim')
+
+" Get tabpagenr of winid, return -1 if window doesn't exist
+function! coc#window#tabnr(winid) abort
+  if exists('*nvim_win_get_tabpage')
+    try
+      return nvim_win_get_tabpage(a:winid)
+    catch /Invalid window id/
+      return -1
+    endtry
+  endif
+  if exists('*win_execute')
+    let ref = {}
+    call win_execute(a:winid, 'let ref["out"] = tabpagenr()')
+    return get(ref, 'out', -1)
+  elseif !s:is_vim
+    let info = getwininfo(a:winid)
+    return empty(info) ? -1 : info[0]['tabnr']
+  else
+    throw 'win_execute() does not exist, please upgrade your vim.'
+  endif
+endfunction
+
+function! coc#window#get_cursor(winid) abort
+  if exists('*nvim_win_get_cursor')
+    return nvim_win_get_cursor(a:winid)
+  endif
+  return coc#api#exec('win_get_cursor', [a:winid])
+endfunction
+
+" Check if winid visible on current tabpage
+function! coc#window#visible(winid) abort
+  if s:is_vim
+    if coc#window#tabnr(a:winid) != tabpagenr()
+      return 0
+    endif
+    " Check possible hidden popup
+    try
+      return get(popup_getpos(a:winid), 'visible', 0) == 1
+    catch /^Vim\%((\a\+)\)\=:E993/
+      return 1
+    endtry
+  endif
+  if !nvim_win_is_valid(a:winid)
+    return 0
+  endif
+  return coc#window#tabnr(a:winid) == tabpagenr()
+endfunction
+
+" Return v:null when name or window doesn't exist,
+" 'getwinvar' only works on window of current tab
+function! coc#window#get_var(winid, name, ...) abort
+  if !s:is_vim
+    try
+      if a:name =~# '^&'
+        return nvim_win_get_option(a:winid, a:name[1:])
+      else
+        return nvim_win_get_var(a:winid, a:name)
+      endif
+    catch /E5555/
+      return get(a:, 1, v:null)
+    endtry
+  else
+    try
+      return coc#api#exec('win_get_var', [a:winid, a:name, get(a:, 1, v:null)])
+    catch /.*/
+      return get(a:, 1, v:null)
+    endtry
+  endif
+endfunction
+
+" Not throw like setwinvar
+function! coc#window#set_var(winid, name, value) abort
+  try
+    if !s:is_vim
+      if a:name =~# '^&'
+        call nvim_win_set_option(a:winid, a:name[1:], a:value)
+      else
+        call nvim_win_set_var(a:winid, a:name, a:value)
+      endif
+    else
+      call coc#api#exec('win_set_var', [a:winid, a:name, a:value])
+    endif
+  catch /Invalid window id/
+    " ignore
+  endtry
+endfunction
+
+function! coc#window#is_float(winid) abort
+  if s:is_vim
+    if exists('*popup_list')
+      return index(popup_list(), a:winid) != -1
+    else
+      try
+        return !empty(popup_getpos(a:winid))
+      catch /^Vim\%((\a\+)\)\=:E993/
+        return 0
+      endtry
+    endif
+    return 0
+  elseif exists('*nvim_win_get_config')
+    let config = nvim_win_get_config(a:winid)
+    return !empty(config) && !empty(get(config, 'relative', ''))
+  endif
+endfunction
+
+function! coc#window#set_height(winid, height) abort
+  if empty(getwininfo(a:winid))
+    return
+  endif
+  if exists('*nvim_win_set_height')
+    call nvim_win_set_height(a:winid, a:height)
+  else
+    call coc#compat#execute(a:winid, 'noa resize '.a:height, 'silent')
+  endif
+endfunction
+
+function! coc#window#adjust_width(winid) abort
+  let bufnr = winbufnr(a:winid)
+  if bufloaded(bufnr)
+    let maxwidth = 0
+    let lines = getbufline(bufnr, 1, '$')
+    if len(lines) > 2
+      call coc#compat#execute(a:winid, 'setl nowrap')
+      for line in lines
+        let w = strwidth(line)
+        if w > maxwidth
+          let maxwidth = w
+        endif
+      endfor
+    endif
+    if maxwidth > winwidth(a:winid)
+      call coc#compat#execute(a:winid, 'vertical resize '.min([maxwidth, g:coc_max_treeview_width]))
+    endif
+  endif
+endfunction
+
+" Get single window by window variable, current tab only
+function! coc#window#find(key, val) abort
+  for i in range(1, winnr('$'))
+    let res = getwinvar(i, a:key)
+    if res == a:val
+      return win_getid(i)
+    endif
+  endfor
+  return -1
+endfunction
+
+" Visible buffer numbers
+function! coc#window#bufnrs() abort
+  let winids = []
+  if exists('*nvim_list_wins')
+    let winids = nvim_list_wins()
+  else
+    let winids = map(getwininfo(), 'v:val["winid"]')
+  endif
+  return uniq(map(winids, 'winbufnr(v:val)'))
+endfunction
+
+" Avoid errors
+function! coc#window#close(winid) abort
+  if empty(a:winid) || a:winid == -1
+    return
+  endif
+  if exists('*nvim_win_is_valid') && exists('*nvim_win_close')
+    if nvim_win_is_valid(a:winid)
+      call nvim_win_close(a:winid, 1)
+    endif
+  elseif exists('*win_execute')
+    call coc#compat#execute(a:winid, 'noa close!', 'silent!')
+  else
+    let curr = win_getid()
+    if curr == a:winid
+      silent! close!
+    else
+      let res = win_gotoid(a:winid)
+      if res
+        silent! close!
+        call win_gotoid(curr)
+      endif
+    endif
+  endif
+endfunction
+
+function! coc#window#visible_range(bufnr) abort
+  let winid = bufwinid(a:bufnr)
+  if winid == -1
+    return v:null
+  endif
+  let info = getwininfo(winid)[0]
+  return [info['topline'], info['botline']]
+endfunction
+
+function! coc#window#visible_ranges(bufnr) abort
+  let wins = gettabinfo(tabpagenr())[0]['windows']
+  let res = []
+  for id in wins
+    let info = getwininfo(id)[0]
+    if info['bufnr'] == a:bufnr
+      call add(res, [info['topline'], info['botline']])
+    endif
+  endfor
+  return res
+endfunction

+ 100 - 0
vimfiles/bundle/coc.nvim/autoload/health/coc.vim

@@ -0,0 +1,100 @@
+scriptencoding utf-8
+let s:root = expand('<sfile>:h:h:h')
+
+function! s:checkVim(test, name, patchlevel) abort
+  if a:test
+    if !has(a:patchlevel)
+      call health#report_error(a:name . ' version not satisfied, ' . a:patchlevel . ' and above required')
+      return 0
+    else
+      call health#report_ok(a:name . ' version satisfied')
+      return 1
+    endif
+  endif
+  return 0
+endfunction
+
+function! s:checkEnvironment() abort
+  let valid
+    \ = s:checkVim(has('nvim'), 'nvim', 'nvim-0.4.0')
+    \ + s:checkVim(!has('nvim'), 'vim', 'patch-8.1.1719')
+  let node = get(g:, 'coc_node_path', $COC_NODE_PATH == '' ? 'node' : $COC_NODE_PATH)
+  if !executable(node)
+    let valid = 0
+    call health#report_error('Executable node.js not found, install node.js from http://nodejs.org/')
+  endif
+  let output = system(node . ' --version')
+  if v:shell_error && output !=# ""
+    let valid = 0
+    call health#report_error(output)
+  endif
+  let ms = matchlist(output, 'v\(\d\+\).\(\d\+\).\(\d\+\)')
+  if empty(ms)
+    let valid = 0
+    call health#report_error('Unable to detect version of node, make sure your node executable is http://nodejs.org/')
+  elseif str2nr(ms[1]) < 12 || (str2nr(ms[1]) == 12 && str2nr(ms[2]) < 12)
+    let valid = 0
+    call health#report_warn('Node.js version '.trim(output).' < 12.12.0, please upgrade node.js')
+  endif
+  if valid
+    call health#report_ok('Environment check passed')
+  endif
+  if has('pythonx')
+    try
+      silent pyx print("")
+    catch /.*/
+      call health#report_warn('pyx command not work, some extensions may fail to work, checkout ":h pythonx"')
+      if has('nvim')
+        call health#report_warn('Install pynvim by command: pip install pynvim --upgrade')
+      endif
+    endtry
+  endif
+  return valid
+endfunction
+
+function! s:checkCommand()
+  let file = s:root.'/build/index.js'
+  if filereadable(file)
+    call health#report_ok('Javascript bundle build/index.js found')
+  else
+    call health#report_error('Javascript entry not found, please compile coc.nvim by esbuild.')
+  endif
+endfunction
+
+function! s:checkAutocmd()
+  let cmds = ['CursorHold', 'CursorHoldI', 'CursorMovedI', 'InsertCharPre', 'TextChangedI']
+  for cmd in cmds
+    let lines = split(execute('verbose autocmd '.cmd), '\n')
+    let n = 0
+    for line in lines
+      if line =~# 'CocAction(' && n < len(lines) - 1
+        let next = lines[n + 1]
+        let ms = matchlist(next, 'Last set from \(.*\)')
+        if !empty(ms)
+          call health#report_warn('Use CocActionAsync to replace CocAction for better performance on '.cmd)
+          call health#report_warn('Checkout the file '.ms[1])
+        endif
+      endif
+      let n = n + 1
+    endfor
+  endfor
+endfunction
+
+function! s:checkInitialize() abort
+  if coc#client#is_running('coc')
+    call health#report_ok('Service started')
+    return 1
+  endif
+  call health#report_error('service could not be initialized', [
+        \ 'Use command ":messages" to get error messages.',
+        \ 'Open a issue at https://github.com/neoclide/coc.nvim/issues for feedback.'
+        \])
+  return 0
+endfunction
+
+function! health#coc#check() abort
+    call s:checkEnvironment()
+    call s:checkCommand()
+    call s:checkInitialize()
+    call s:checkAutocmd()
+endfunction

+ 97 - 0
vimfiles/bundle/coc.nvim/bin/prompt.js

@@ -0,0 +1,97 @@
+/*
+ * Used for prompt popup on vim
+ */
+const readline = require("readline")
+const rl = readline.createInterface({
+  input: process.stdin,
+  output: process.stdout,
+  escapeCodeTimeout: 0,
+  prompt: ''
+})
+rl.setPrompt('')
+let value = process.argv[2]
+if (value) {
+  rl.write(value)
+}
+rl.on('line', input => {
+  send(['confirm', input])
+  process.exit()
+})
+
+let original_ttyWrite = rl._ttyWrite
+rl._ttyWrite = function (code, key) {
+  if (key.name === 'enter') {
+    send(['send', '<C-j>'])
+    return ''
+  }
+  original_ttyWrite.apply(rl, arguments)
+  send(['change', rl.line])
+}
+
+function createSequences(str) {
+  return '\033]51;' + str + '\x07'
+}
+
+function send(args) {
+  process.stdout.write(createSequences(JSON.stringify(['call', 'CocPopupCallback', args])))
+}
+
+process.stdin.on('keypress', (e, key) => {
+  if (key) {
+    let k = getKey(key)
+    if (k == '<bs>') {
+      return
+    }
+    if (k == '<esc>') {
+      send(['exit', ''])
+      process.exit()
+      return
+    }
+    if (k) {
+      send(['send', k])
+      return
+    }
+  }
+})
+
+function getKey(key) {
+  if (key.ctrl === true) {
+    if (key.name == 'n') {
+      return '<C-n>'
+    }
+    if (key.name == 'p') {
+      return '<C-p>'
+    }
+    if (key.name == 'j') {
+      return '<C-j>'
+    }
+    if (key.name == 'k') {
+      return '<C-k>'
+    }
+    if (key.name == 'f') {
+      return '<C-f>'
+    }
+    if (key.name == 'b') {
+      return '<C-b>'
+    }
+    if (key.sequence == '\x00') {
+      return '<C-@>'
+    }
+  }
+  if (key.sequence == '\u001b') {
+    return '<esc>'
+  }
+  if (key.sequence == '\r') {
+    return '<cr>'
+  }
+  if (key.sequence == '\t') {
+    return key.shift ? '<s-tab>' : '<tab>'
+  }
+  if (key.name == 'up') {
+    return '<up>'
+  }
+  if (key.name == 'down') {
+    return '<down>'
+  }
+  return ''
+}

+ 12 - 0
vimfiles/bundle/coc.nvim/bin/terminateProcess.sh

@@ -0,0 +1,12 @@
+#!/bin/bash
+terminateTree() {
+    for cpid in $(pgrep -P $1); do
+        terminateTree $cpid
+    done
+    kill -9 $1 > /dev/null 2>&1
+}
+
+for pid in $*; do
+    terminateTree $pid
+done
+

Fichier diff supprimé car celui-ci est trop grand
+ 9 - 0
vimfiles/bundle/coc.nvim/build/index.js


+ 1666 - 0
vimfiles/bundle/coc.nvim/data/schema.json

@@ -0,0 +1,1666 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "description": "Configuration file for coc.nvim",
+  "additionalProperties": false,
+  "definitions": {
+    "float": {
+      "type": "object",
+      "properties": {
+        "border": {
+          "type": "boolean",
+          "default": false,
+          "description": "Set to true to use borders."
+        },
+        "rounded": {
+          "type": "boolean",
+          "default": false,
+          "description": "Use rounded borders when border is true."
+        },
+        "highlight": {
+          "type": "string",
+          "default": "CocFloating",
+          "description": "Background highlight group of float window."
+        },
+        "title": {
+          "type": "string",
+          "default": "",
+          "description": "Title used by float window."
+        },
+        "borderhighlight": {
+          "type": "string",
+          "default": "CocFloating",
+          "description": "Border highlight group of float window."
+        },
+        "close": {
+          "type": "boolean",
+          "default": false,
+          "description": "Set to true to draw close icon"
+        },
+        "maxWidth": {
+          "type": "integer",
+          "description": "Maximum width of float window, include border."
+        },
+        "maxHeight": {
+          "type": "integer",
+          "minimum": 2,
+          "description": "Maximum height of float window, include border."
+        },
+        "focusable": {
+          "type": "boolean",
+          "default": true,
+          "description": "Enable focus by user actions (wincmds, mouse events), neovim only."
+        },
+        "shadow": {
+          "type": "boolean",
+          "default": false,
+          "description": "Drop shadow effect by blending with the background, neovim only."
+        },
+        "winblend": {
+          "type": "integer",
+          "default": 0,
+          "minimum": 0,
+          "maximum": 100,
+          "description": "Enables pseudo-transparency by set 'winblend' option of window, neovim only."
+        }
+      }
+    },
+    "languageServerBase": {
+      "type": "object",
+      "properties": {
+        "enable": {
+          "type": "boolean",
+          "default": true
+        },
+        "cwd": {
+          "type": "string",
+          "default": "",
+          "description": "Working directory of languageserver, absolute path or relative to workspace folder, use workspace root by default"
+        },
+        "disableDynamicRegister": {
+          "type": "boolean",
+          "default": false,
+          "description": "Disable dynamic registerCapability feature for this languageserver to avoid duplicated feature regstration."
+        },
+        "disableSnippetCompletion": {
+          "type": "boolean",
+          "default": false,
+          "description": "Disable completion snippet feature for this languageserver, the languageserver may not respect it."
+        },
+        "disabledFeatures": {
+          "type": "array",
+          "default": [],
+          "description": "Disabled features for this languageserver.",
+          "items": {
+            "type": "string",
+            "enum": [
+              "completion",
+              "configuration",
+              "workspaceFolders",
+              "diagnostics",
+              "willSave",
+              "willSaveUntil",
+              "didSaveTextDocument",
+              "fileSystemWatcher",
+              "hover",
+              "signatureHelp",
+              "definition",
+              "references",
+              "documentHighlight",
+              "documentSymbol",
+              "workspaceSymbol",
+              "codeAction",
+              "codeLens",
+              "formatting",
+              "documentFormatting",
+              "documentRangeFormatting",
+              "documentOnTypeFormatting",
+              "rename",
+              "documentLink",
+              "executeCommand",
+              "pullConfiguration",
+              "typeDefinition",
+              "implementation",
+              "declaration",
+              "color",
+              "foldingRange",
+              "selectionRange",
+              "progress",
+              "callHierarchy",
+              "linkedEditing",
+              "fileEvents",
+              "semanticTokens"
+            ]
+          }
+        },
+        "formatterPriority": {
+          "type": "number",
+          "default": 0,
+          "description": "Priority of this languageserver's formatter."
+        },
+        "env": {
+          "type": "object",
+          "default": null,
+          "description": "Environment variables for child process."
+        },
+        "stdioEncoding": {
+          "type": "string",
+          "default": "utf8",
+          "description": "Encoding used for stdio of child process."
+        },
+        "rootPatterns": {
+          "type": "array",
+          "default": [],
+          "description": "Root patterns used to resolve rootPath from current file, default to workspace root",
+          "items": {
+            "type": "string"
+          }
+        },
+        "requireRootPattern": {
+          "type": "boolean",
+          "default": false,
+          "description": "If true, doesn't start server when root pattern not found."
+        },
+        "ignoredRootPaths": {
+          "type": "array",
+          "default": [],
+          "description": "Absolute root paths that language server should not use as rootPath, higher priority than rootPatterns.",
+          "items": {
+            "type": "string"
+          }
+        },
+        "filetypes": {
+          "type": "array",
+          "default": [],
+          "description": "Supported filetypes, add * in array for all filetypes.",
+          "items": {
+            "type": "string"
+          }
+        },
+        "additionalSchemes": {
+          "type": "array",
+          "default": [],
+          "description": "Additional uri schemes, default schemes including file & untitled.",
+          "items": {
+            "type": "string"
+          }
+        },
+        "revealOutputChannelOn": {
+          "type": "string",
+          "default": "never",
+          "description": "Configure message level to show the output channel buffer",
+          "enum": ["info", "warn", "error", "never"]
+        },
+        "progressOnInitialization": {
+          "type": "boolean",
+          "default": false,
+          "description": "Enable progress report on languageserver initialize."
+        },
+        "initializationOptions": {
+          "type": "object",
+          "default": {},
+          "description": "initializationOptions passed to languageserver"
+        },
+        "settings": {
+          "type": "object",
+          "default": {},
+          "description": "Settings of languageserver"
+        },
+        "trace.server": {
+          "type": "string",
+          "default": "off",
+          "enum": ["off", "messages", "verbose"],
+          "description": "Trace level of communication between server and client"
+        }
+      }
+    },
+    "languageServerSocket": {
+      "type": "object",
+      "allOf": [{ "$ref": "#/definitions/languageServerBase" }],
+      "required": ["port", "filetypes"],
+      "additionalProperties": false,
+      "properties": {
+        "port": {
+          "type": "integer",
+          "description": "Port number of socket server"
+        },
+        "host": {
+          "type": "string",
+          "default": "127.0.0.1",
+          "description": "Host of server"
+        },
+        "disableSnippetCompletion": {},
+        "disableDynamicRegister": {},
+        "disabledFeatures": {},
+        "formatterPriority": {},
+        "enable": {},
+        "rootPatterns": {},
+        "requireRootPattern": {},
+        "ignoredRootPaths": {},
+        "filetypes": {},
+        "additionalSchemes": {},
+        "revealOutputChannelOn": {},
+        "progressOnInitialization": {},
+        "initializationOptions": {},
+        "settings": {},
+        "stdioEncoding": {},
+        "trace.server": {}
+      }
+    },
+    "languageServerModule": {
+      "type": "object",
+      "allOf": [{ "$ref": "#/definitions/languageServerBase" }],
+      "required": ["module", "filetypes"],
+      "additionalProperties": false,
+      "properties": {
+        "module": {
+          "type": "string",
+          "default": "",
+          "description": "Absolute path of javascript file, should works in IPC mode"
+        },
+        "args": {
+          "type": "array",
+          "default": [],
+          "description": "Extra arguments of module",
+          "items": {
+            "type": "string"
+          }
+        },
+        "runtime": {
+          "type": "string",
+          "default": "",
+          "description": "Absolute path of node runtime."
+        },
+        "execArgv": {
+          "type": "array",
+          "default": [],
+          "description": "Argv passed to node when using module, normally used for debugging, ex: [\"--nolazy\", \"--inspect-brk=6045\"]",
+          "items": {
+            "type": "string"
+          }
+        },
+        "transport": {
+          "type": "string",
+          "default": "ipc",
+          "description": "Transport kind used by server, could be 'ipc', 'stdio', 'socket' and 'pipe'",
+          "enum": ["ipc", "stdio", "socket", "pipe"]
+        },
+        "transportPort": {
+          "type": "integer",
+          "description": "Port number used when transport is 'socket'"
+        },
+        "cwd": {},
+        "env": {},
+        "enable": {},
+        "disableDynamicRegister": {},
+        "disableSnippetCompletion": {},
+        "disabledFeatures": {},
+        "formatterPriority": {},
+        "rootPatterns": {},
+        "requireRootPattern": {},
+        "ignoredRootPaths": {},
+        "filetypes": {},
+        "additionalSchemes": {},
+        "revealOutputChannelOn": {},
+        "progressOnInitialization": {},
+        "initializationOptions": {},
+        "stdioEncoding": {},
+        "settings": {},
+        "trace.server": {}
+      }
+    },
+    "languageServerCommand": {
+      "type": "object",
+      "required": ["command", "filetypes"],
+      "allOf": [{ "$ref": "#/definitions/languageServerBase" }],
+      "additionalProperties": false,
+      "properties": {
+        "command": {
+          "type": "string",
+          "default": "",
+          "description": "Executable in $PATH to start languageserver, should not used with module"
+        },
+        "args": {
+          "type": "array",
+          "default": [],
+          "description": "Arguments of command",
+          "items": {
+            "type": "string"
+          }
+        },
+        "detached": {
+          "type": "boolean",
+          "default": false,
+          "description": "Detach the languageserver process"
+        },
+        "shell": {
+          "type": "boolean",
+          "default": false,
+          "description": "Use shell for process"
+        },
+        "cwd": {},
+        "env": {},
+        "enable": {},
+        "disableDynamicRegister": {},
+        "disableSnippetCompletion": {},
+        "disabledFeatures": {},
+        "formatterPriority": {},
+        "rootPatterns": {},
+        "requireRootPattern": {},
+        "ignoredRootPaths": {},
+        "filetypes": {},
+        "additionalSchemes": {},
+        "revealOutputChannelOn": {},
+        "progressOnInitialization": {},
+        "initializationOptions": {},
+        "stdioEncoding": {},
+        "settings": {},
+        "trace.server": {}
+      }
+    }
+  },
+  "properties": {
+    "http.proxy": {
+      "type": "string",
+      "default": "",
+      "pattern": "^https?://([^:]*(:[^@]*)?@)?([^:]+|\\[[:0-9a-fA-F]+\\])(:\\d+)?/?$|^$",
+      "description": "The proxy setting to use. If not set, will be inherited from the `http_proxy` and `https_proxy` environment variables."
+    },
+    "http.proxyStrictSSL": {
+      "type": "boolean",
+      "description": "Controls whether the proxy server certificate should be verified against the list of supplied CAs",
+      "default": true
+    },
+    "http.proxyAuthorization": {
+      "type": ["null", "string"],
+      "description": "The value to send as the `Proxy-Authorization` header for every network request.",
+      "default": null
+    },
+    "http.proxyCA": {
+      "type": "string",
+      "description": "CA (file) to use as Certificate Authority",
+      "default": null
+    },
+    "npm.binPath": {
+      "type": "string",
+      "default": "npm",
+      "description": "Command or absolute path to npm or yarn."
+    },
+    "suggest.noselect": {
+      "type": "boolean",
+      "description": "Not make vim select first item on completion start",
+      "default": false
+    },
+    "suggest.formatItems": {
+      "type": "array",
+      "items": {
+        "enum": ["abbr", "menu", "kind", "shortcut"]
+      },
+      "contains": {
+        "enum": ["abbr"]
+      },
+      "uniqueItems": true,
+      "description": "Items shown in popup menu in order.",
+      "default": ["abbr", "menu", "kind", "shortcut"]
+    },
+    "suggest.selection": {
+      "type": "string",
+      "default": "recentlyUsed",
+      "description": "Controls how suggestions are pre-selected when showing the suggest list.",
+      "enum": ["none", "recentlyUsed", "recentlyUsedByPrefix"]
+    },
+    "suggest.enablePreselect": {
+      "type": "boolean",
+      "description": "Enable preselect feature of LSP, works when suggest.noselect is false.",
+      "default": true
+    },
+    "suggest.floatConfig": {
+      "type": "object",
+      "description": "Configure style of popup menu and documentation window of completion.",
+      "allOf": [{ "$ref": "#/definitions/float" }],
+      "additionalProperties": false,
+      "properties": {
+        "border": {},
+        "rounded": {},
+        "highlight": {},
+        "borderhighlight": {},
+        "maxWidth": {},
+        "winblend": {},
+        "shadow": {}
+      }
+    },
+    "suggest.labelMaxLength": {
+      "type": "number",
+      "description": "Max length of abbr that shown as label of complete item.",
+      "default": 200
+    },
+    "suggest.detailMaxLength": {
+      "type": "number",
+      "description": "Max length of detail that should be shown in popup menu.",
+      "default": 100
+    },
+    "suggest.detailField": {
+      "type": "string",
+      "default": "preview",
+      "description": "Where to show the detail text of CompleteItem from LS.",
+      "enum": ["abbr", "preview"]
+    },
+    "suggest.autoTrigger": {
+      "type": "string",
+      "default": "always",
+      "description": "How should completion be triggered",
+      "enum": ["always", "trigger", "none"]
+    },
+    "suggest.languageSourcePriority": {
+      "type": "number",
+      "default": 99,
+      "description": "Priority of language sources."
+    },
+    "suggest.snippetIndicator": {
+      "type": "string",
+      "default": "~",
+      "description": "The character used in abbr of complete item to indicate the item could be expand as snippet."
+    },
+    "suggest.maxCompleteItemCount": {
+      "type": "number",
+      "default": 50,
+      "description": "Maximum number of complete items shown in vim"
+    },
+    "suggest.preferCompleteThanJumpPlaceholder": {
+      "type": "boolean",
+      "description": "Confirm completion instead of jump to next placeholder when completion is activated.",
+      "default": false
+    },
+    "suggest.fixInsertedWord": {
+      "type": "boolean",
+      "description": "Make inserted word replace word characters after cursor position.",
+      "default": true
+    },
+    "suggest.localityBonus": {
+      "type": "boolean",
+      "description": "Boost suggestions that appear closer to the cursor position.",
+      "default": true
+    },
+    "suggest.triggerAfterInsertEnter": {
+      "type": "boolean",
+      "description": "Trigger completion after InsertEnter, auto trigger should be 'always' to enable this option",
+      "default": false
+    },
+    "suggest.minTriggerInputLength": {
+      "type": "integer",
+      "default": 1,
+      "description": "Minimal input length for trigger completion, default 1"
+    },
+    "suggest.triggerCompletionWait": {
+      "type": "integer",
+      "default": 0,
+      "minimum": 0,
+      "maximum": 50,
+      "description": "Wait time between text change and completion start, cancel completion when text changed during wait."
+    },
+    "suggest.timeout": {
+      "type": "integer",
+      "default": 5000,
+      "minimum": 500,
+      "maximum": 15000,
+      "description": "Timeout for completion, in milliseconds."
+    },
+    "suggest.acceptSuggestionOnCommitCharacter": {
+      "type": "boolean",
+      "default": false,
+      "description": "Controls whether suggestions should be accepted on commit characters. For example, in JavaScript, the semi-colon (`;`) can be a commit character that accepts a suggestion and types that character. Requires CompleteChanged event to work."
+    },
+    "suggest.lowPrioritySourceLimit": {
+      "type": "integer",
+      "minimum": 1,
+      "maximum": 100,
+      "description": "Max items count for source priority lower than 90."
+    },
+    "suggest.highPrioritySourceLimit": {
+      "type": "integer",
+      "minimum": 1,
+      "maximum": 100,
+      "description": "Max items count for source priority bigger than or equal to 90."
+    },
+    "suggest.removeDuplicateItems": {
+      "type": "boolean",
+      "description": "Remove completion items with duplicated word for all sources, snippet items are excluded.",
+      "default": false
+    },
+    "suggest.defaultSortMethod": {
+      "type": "string",
+      "description": "Default sorting behavior for suggested completion items.",
+      "default": "length",
+      "enum": ["length", "alphabetical", "none"]
+    },
+    "suggest.snippetsSupport": {
+      "type": "boolean",
+      "description": "Set to false to disable snippets support of completion.",
+      "default": true
+    },
+    "suggest.completionItemKindLabels": {
+      "type": "object",
+      "default": {},
+      "description": "Set custom labels to completion items' kinds.",
+      "properties": {
+        "text": { "type": "string", "maxLength": 1 },
+        "method": { "type": "string", "maxLength": 1 },
+        "function": { "type": "string", "maxLength": 1 },
+        "constructor": { "type": "string", "maxLength": 1 },
+        "field": { "type": "string", "maxLength": 1 },
+        "variable": { "type": "string", "maxLength": 1 },
+        "class": { "type": "string", "maxLength": 1 },
+        "interface": { "type": "string", "maxLength": 1 },
+        "module": { "type": "string", "maxLength": 1 },
+        "property": { "type": "string", "maxLength": 1 },
+        "unit": { "type": "string", "maxLength": 1 },
+        "value": { "type": "string", "maxLength": 1 },
+        "enum": { "type": "string", "maxLength": 1 },
+        "keyword": { "type": "string", "maxLength": 1 },
+        "snippet": { "type": "string", "maxLength": 1 },
+        "color": { "type": "string", "maxLength": 1 },
+        "file": { "type": "string", "maxLength": 1 },
+        "reference": { "type": "string", "maxLength": 1 },
+        "folder": { "type": "string", "maxLength": 1 },
+        "enumMember": { "type": "string", "maxLength": 1 },
+        "constant": { "type": "string", "maxLength": 1 },
+        "struct": { "type": "string", "maxLength": 1 },
+        "event": { "type": "string", "maxLength": 1 },
+        "operator": { "type": "string", "maxLength": 1 },
+        "typeParameter": { "type": "string", "maxLength": 1 },
+        "default": { "type": "string", "maxLength": 1 }
+      },
+      "additionalProperties": false
+    },
+    "suggest.invalidInsertCharacters": {
+      "type": "array",
+      "items": {
+        "type": "string"
+      },
+      "description": "Invalid character for strip valid word when inserting text of complete item.",
+      "default": [" ", "(", "<", "{", "[", "\r", "\n"]
+    },
+    "suggest.asciiCharactersOnly": {
+      "type": "boolean",
+      "description": "Trigger suggest with ASCII characters only",
+      "default": false
+    },
+    "suggest.ignoreRegexps": {
+      "type": "array",
+      "items": {
+        "type": "string"
+      },
+      "description": "Regexps to ignore when trigger suggest",
+      "default": []
+    },
+    "suggest.virtualText": {
+      "type": "boolean",
+      "description": "Show virtual text for insert word of selected item, works on neovim >= 0.5.0",
+      "default": false
+    },
+    "documentHighlight.priority": {
+      "type": "number",
+      "default": -1,
+      "description": "Match priority used by document highlight, see ':h matchadd'"
+    },
+    "documentHighlight.timeout": {
+      "type": "integer",
+      "default": 300,
+      "minimum": 200,
+      "maximum": 5000,
+      "description": "Timeout for document highlight, in milliseconds."
+    },
+    "colors.filetypes": {
+      "type": "array",
+      "default": [],
+      "description": "Filetypes that should be enabled for colors highlight feature, use \"*\" for all filetypes.",
+      "items": {
+        "type": "string"
+      }
+    },
+    "colors.highlightPriority": {
+      "type": "number",
+      "description": "Priority for colors highlights, works on vim8 and neovim >= 0.6.0",
+      "default": 1000,
+      "maximum": 4096
+    },
+    "links.tooltip": {
+      "type": "boolean",
+      "description": "Show tooltip of link under cursor on CursorHold, neovim only",
+      "default": false
+    },
+    "diagnostic.enable": {
+      "type": "boolean",
+      "description": "Set to false to disable diagnostic display",
+      "default": true
+    },
+    "diagnostic.highlighLimit": {
+      "type": "number",
+      "description": "Limit count for highlighted diagnostics, too many diagnostic highlights could make vim stop responding",
+      "default": 1000
+    },
+    "diagnostic.highlightPriority": {
+      "type": "number",
+      "description": "Priority for diagnostic highlights, works on vim8 and neovim >= 0.6.0",
+      "default": 4096,
+      "maximum": 4096,
+      "minimum": 110
+    },
+    "diagnostic.autoRefresh": {
+      "type": "boolean",
+      "description": "Enable automatically refresh diagnostics, use diagnosticRefresh action when it's disabled.",
+      "default": true
+    },
+    "diagnostic.level": {
+      "type": "string",
+      "description": "Used for filter diagnostics by diagnostic severity.",
+      "default": "hint",
+      "enum": ["hint", "information", "warning", "error"]
+    },
+    "diagnostic.locationlistLevel": {
+      "type": ["string", "null"],
+      "description": "Filter diagnostics in locationlist.",
+      "default": null,
+      "enum": ["hint", "information", "warning", "error"]
+    },
+    "diagnostic.signLevel": {
+      "type": ["string", "null"],
+      "description": "Filter diagnostics displayed in signcolumn.",
+      "default": null,
+      "enum": ["hint", "information", "warning", "error"]
+    },
+    "diagnostic.messageLevel": {
+      "type": ["string", "null"],
+      "description": "Filter diagnostic message in float window/popup.",
+      "default": null,
+      "enum": ["hint", "information", "warning", "error"]
+    },
+    "diagnostic.locationlistUpdate": {
+      "type": "boolean",
+      "description": "Update locationlist on diagnostics change, only works with locationlist opened by :CocDiagnostics command and first window of associated buffer.",
+      "default": true
+    },
+    "diagnostic.checkCurrentLine": {
+      "type": "boolean",
+      "description": "When enabled, show all diagnostics of current line if there are none at the current position.",
+      "default": false
+    },
+    "diagnostic.messageTarget": {
+      "type": "string",
+      "description": "Diagnostic message target.",
+      "default": "float",
+      "enum": ["echo", "float"]
+    },
+    "diagnostic.messageDelay": {
+      "type": "number",
+      "description": "How long to wait (in milliseconds) before displaying the diagnostic message with echo or float",
+      "default": 200
+    },
+    "diagnostic.refreshOnInsertMode": {
+      "type": "boolean",
+      "description": "Enable diagnostic refresh on insert mode, default false.",
+      "default": false
+    },
+    "diagnostic.displayByAle": {
+      "type": "boolean",
+      "description": "Use Ale for display diagnostics in vim, will disable coc for display diagnostics, restart required on change.",
+      "default": false
+    },
+    "diagnostic.virtualText": {
+      "type": "boolean",
+      "description": "Use NeoVim virtual text to display diagnostics",
+      "default": false
+    },
+    "diagnostic.virtualTextLevel": {
+      "type": ["string", "null"],
+      "description": "Filter diagnostic message in virtual text by level",
+      "default": null,
+      "enum": ["hint", "information", "warning", "error"]
+    },
+    "diagnostic.virtualTextWinCol": {
+      "type": ["number", "null"],
+      "description": "Window column number to align virtual text",
+      "default": null
+    },
+    "diagnostic.virtualTextCurrentLineOnly": {
+      "type": "boolean",
+      "description": "Only show virtualText diagnostic on current cursor line",
+      "default": true
+    },
+    "diagnostic.virtualTextPrefix": {
+      "type": "string",
+      "description": "The prefix added virtual text diagnostics",
+      "default": " "
+    },
+    "diagnostic.virtualTextLines": {
+      "type": "number",
+      "description": "The number of non empty lines from a diagnostic to display",
+      "default": 3
+    },
+    "diagnostic.virtualTextLineSeparator": {
+      "type": "string",
+      "description": "The text that will mark a line end from the diagnostic message",
+      "default": " \\ "
+    },
+    "diagnostic.enableSign": {
+      "type": "boolean",
+      "default": true,
+      "description": "Enable signs for diagnostics."
+    },
+    "diagnostic.enableHighlightLineNumber": {
+      "type": "boolean",
+      "default": true,
+      "description": "Enable highlighting line numbers for diagnostics, only works with neovim and diagnostic.enableSign is true."
+    },
+    "diagnostic.enableMessage": {
+      "type": "string",
+      "default": "always",
+      "description": "When to enable show messages of diagnostics.",
+      "enum": ["always", "jump", "never"]
+    },
+    "diagnostic.signPriority": {
+      "type": "number",
+      "description": "Priority of diagnostic signs, default to 10",
+      "default": 10
+    },
+    "diagnostic.errorSign": {
+      "type": "string",
+      "description": "Text of error sign",
+      "default": ">>"
+    },
+    "diagnostic.warningSign": {
+      "type": "string",
+      "description": "Text of warning sign",
+      "default": "⚠"
+    },
+    "diagnostic.infoSign": {
+      "type": "string",
+      "description": "Text of info sign",
+      "default": ">>"
+    },
+    "diagnostic.hintSign": {
+      "type": "string",
+      "description": "Text of hint sign",
+      "default": ">>"
+    },
+    "diagnostic.floatConfig": {
+      "type": "object",
+      "description": "Configure float window style of diagnostic message.",
+      "allOf": [{ "$ref": "#/definitions/float" }],
+      "additionalProperties": false,
+      "properties": {
+        "border": {},
+        "rounded": {},
+        "highlight": {},
+        "borderhighlight": {},
+        "title": {},
+        "close": {},
+        "maxHeight": {},
+        "maxWidth": {},
+        "winblend": {},
+        "focusable": {},
+        "shadow": {}
+      }
+    },
+    "diagnostic.filetypeMap": {
+      "type": "object",
+      "description": "A map between buffer filetype and the filetype assigned to diagnostics. To syntax highlight diagnostics with their parent buffer type use `\"default\": \"bufferType\"`",
+      "default": {}
+    },
+    "diagnostic.format": {
+      "type": "string",
+      "description": "Define the diagnostic format that shown in float window or echoed, available parts: source, code, severity, message",
+      "default": "[%source%code] [%severity] %message"
+    },
+    "diagnostic.separateRelatedInformationAsDiagnostics": {
+      "type": "boolean",
+      "default": false,
+      "description": "Separate related information as diagnostics."
+    },
+    "diagnostic.showUnused": {
+      "type": "boolean",
+      "default": true,
+      "description": "Show diagnostics with unused tag, affects highlight, sign, virtual text, message"
+    },
+    "diagnostic.showDeprecated": {
+      "type": "boolean",
+      "default": true,
+      "description": "Show diagnostics with deprecated tag."
+    },
+    "signature.enable": {
+      "type": "boolean",
+      "description": "Enable signature help when trigger character typed, require restart service on change.",
+      "default": true
+    },
+    "signature.triggerSignatureWait": {
+      "type": "integer",
+      "default": 500,
+      "minimum": 200,
+      "maximum": 1000,
+      "description": "Timeout for trigger signature help, in milliseconds."
+    },
+    "signature.target": {
+      "type": "string",
+      "description": "Target of signature help, use float when possible by default.",
+      "default": "float",
+      "enum": ["float", "echo"]
+    },
+    "signature.floatConfig": {
+      "type": "object",
+      "description": "Configure float window style of signature documents.",
+      "allOf": [{ "$ref": "#/definitions/float" }],
+      "additionalProperties": false,
+      "properties": {
+        "border": {},
+        "rounded": {},
+        "highlight": {},
+        "borderhighlight": {},
+        "title": {},
+        "close": {},
+        "maxHeight": {},
+        "maxWidth": {},
+        "winblend": {},
+        "focusable": {},
+        "shadow": {}
+      }
+    },
+    "signature.preferShownAbove": {
+      "type": "boolean",
+      "description": "Show signature help float window above cursor when possible, require restart service on change.",
+      "default": true
+    },
+    "signature.hideOnTextChange": {
+      "type": "boolean",
+      "description": "Hide signature float window when text changed on insert mode.",
+      "default": false
+    },
+    "codeLens.enable": {
+      "type": "boolean",
+      "description": "Enable codeLens feature, require neovim with set virtual text feature.",
+      "default": false
+    },
+    "codeLens.position": {
+      "type": "string",
+      "enum": ["top", "eol", "right_align"],
+      "description": "Position of codeLens, requires nvim >= 0.6.0",
+      "default": "top"
+    },
+    "codeLens.separator": {
+      "type": "string",
+      "description": "Separator text for codeLens in virtual text",
+      "default": ""
+    },
+    "codeLens.subseparator": {
+      "type": "string",
+      "description": "Subseparator between codeLenses in virtual text",
+      "default": " "
+    },
+    "refactor.openCommand": {
+      "type": "string",
+      "description": "Open command for refactor window.",
+      "default": "vsplit"
+    },
+    "refactor.saveToFile": {
+      "type": "boolean",
+      "description": "Save changed buffer to file when write refactor buffer with ':noa wa' command.",
+      "default": true
+    },
+    "refactor.beforeContext": {
+      "type": "number",
+      "default": 3,
+      "description": "Print num lines of leading context before each match."
+    },
+    "refactor.afterContext": {
+      "type": "number",
+      "default": 3,
+      "description": "Print num lines of trailing context after each match."
+    },
+    "refactor.showMenu": {
+      "type": "string",
+      "default": "<Tab>",
+      "description": "Refactor buffer local mapping to bring up menu for this chunk."
+    },
+    "hover.target": {
+      "type": "string",
+      "description": "Target to show hover information, default is floating window when possible.",
+      "enum": ["preview", "echo", "float"]
+    },
+    "hover.previewMaxHeight": {
+      "type": "number",
+      "default": 12,
+      "description": "Max height of preview window for hover."
+    },
+    "hover.floatConfig": {
+      "type": "object",
+      "description": "Configure float window style of hover documents.",
+      "allOf": [{ "$ref": "#/definitions/float" }],
+      "additionalProperties": false,
+      "properties": {
+        "border": {},
+        "rounded": {},
+        "highlight": {},
+        "borderhighlight": {},
+        "title": {},
+        "close": {},
+        "maxHeight": {},
+        "maxWidth": {},
+        "winblend": {},
+        "focusable": {},
+        "shadow": {}
+      }
+    },
+    "hover.autoHide": {
+      "type": "boolean",
+      "default": true,
+      "description": "Automatically hide hover float window on CursorMove or InsertEnter."
+    },
+    "dialog.maxHeight": {
+      "type": "number",
+      "default": 30,
+      "description": "Maximum height of dialog window."
+    },
+    "dialog.maxWidth": {
+      "type": "number",
+      "default": 80,
+      "description": "Maximum width of dialog window."
+    },
+    "dialog.rounded": {
+      "type": "boolean",
+      "default": true,
+      "description": "use rounded border for dialog window."
+    },
+    "dialog.confirmKey": {
+      "type": "string",
+      "default": "<cr>",
+      "description": "Confirm key for confirm selection used by menu and picker, you can always use <esc> to cancel."
+    },
+    "dialog.pickerButtons": {
+      "type": "boolean",
+      "default": true,
+      "description": "Show buttons for picker dialog window/popup."
+    },
+    "dialog.pickerButtonShortcut": {
+      "type": "boolean",
+      "default": true,
+      "description": "Show shortcut in buttons of picker dialog window/popup, used when dialog.pickerButtons is true."
+    },
+    "dialog.floatHighlight": {
+      "type": ["string", "null"],
+      "default": null,
+      "description": "Highlight group for dialog window/popup, default to 'CocFloating'"
+    },
+    "dialog.floatBorderHighlight": {
+      "type": ["string", "null"],
+      "default": null,
+      "description": "Highlight group for border of dialog window/popup, default to 'CocFloating'"
+    },
+    "dialog.shortcutHighlight": {
+      "type": "string",
+      "default": "MoreMsg",
+      "description": "Highlight group for shortcut character in menu dialog, default to 'MoreMsg'"
+    },
+    "notification.border": {
+      "type": "boolean",
+      "default": true,
+      "description": "Enable rounded border for notification windows."
+    },
+    "notification.timeout": {
+      "type": "integer",
+      "default": 10000,
+      "description": "Timeout for auto close notifications, in miniseconds."
+    },
+    "notification.marginRight": {
+      "type": "integer",
+      "default": 10,
+      "description": "Margin right to the right of editor window."
+    },
+    "notification.focusable": {
+      "type": "boolean",
+      "default": true,
+      "description": "Enable focus by user actions (wincmds, mouse events), neovim only."
+    },
+    "notification.maxWidth": {
+      "type": "integer",
+      "default": 60,
+      "description": "Maximum content width of notification dialog."
+    },
+    "notification.maxHeight": {
+      "type": "integer",
+      "default": 10,
+      "description": "Maximum content height of notification dialog."
+    },
+    "notification.disabledProgressSources": {
+      "type": "array",
+      "default": [],
+      "description": "Soureces that should be disabled for message progress, use * to disable all message only progresses",
+      "items": {
+        "type": "string"
+      }
+    },
+    "notification.minProgressWidth": {
+      "type": "integer",
+      "default": 30,
+      "description": "Minimal with of progress notification."
+    },
+    "notification.highlightGroup": {
+      "type": "string",
+      "default": "CocFloating",
+      "description": "Highlight group of notification dialog."
+    },
+    "notification.winblend": {
+      "type": "integer",
+      "default": 30,
+      "minimum": 0,
+      "maximum": 100,
+      "description": "Winblend option of notification window, neovim only."
+    },
+    "workspace.openOutputCommand": {
+      "type": "string",
+      "default": "vs",
+      "description": "Command used to open output channel."
+    },
+    "workspace.openResourceCommand": {
+      "type": "string",
+      "default": "tab drop",
+      "description": "Command to open files that not loaded, load files as hidden buffers when empty."
+    },
+    "workspace.ignoredFiletypes": {
+      "type": "array",
+      "default": [],
+      "description": "Filetypes that should be ignored for workspace folder resolve.",
+      "items": {
+        "type": "string"
+      }
+    },
+    "workspace.bottomUpFiletypes": {
+      "type": "array",
+      "default": [],
+      "description": "Filetypes that should have workspace folder should resolved from base directory of file, or [\"*\"] for any filetype.",
+      "items": {
+        "type": "string"
+      }
+    },
+    "workspace.ignoredFolders": {
+      "type": "array",
+      "default": ["$HOME"],
+      "description": "List of folders that should not be resolved as workspace folder, environment variables and minimatch patterns can be used.",
+      "items": {
+        "type": "string"
+      }
+    },
+    "workspace.workspaceFolderCheckCwd": {
+      "type": "boolean",
+      "default": true,
+      "description": "Whether the current working directory should be used first when checking patterns match for workspace folder."
+    },
+    "workspace.workspaceFolderFallbackCwd": {
+      "type": "boolean",
+      "default": true,
+      "description": "Use current working directory as workspace folder when no root patterns resolved."
+    },
+    "list.indicator": {
+      "type": "string",
+      "default": ">",
+      "description": "The character used as first character in prompt line"
+    },
+    "list.alignColumns": {
+      "type": "boolean",
+      "default": false,
+      "description": "Whether to align lists in columns, default: `false`"
+    },
+    "list.menuAction": {
+      "type": "boolean",
+      "default": false,
+      "description": "Use menu picker instead of confirm() for choose action."
+    },
+    "list.interactiveDebounceTime": {
+      "type": "number",
+      "default": 100,
+      "description": "Debounce time for input change on interactive mode."
+    },
+    "list.height": {
+      "type": "number",
+      "default": 10,
+      "description": "Height of split list window."
+    },
+    "list.statusLineSegments": {
+      "type": ["array", "null"],
+      "default": [
+        "%#CocListMode#-- %{coc#list#status(\"mode\")} --%*",
+        "%{coc#list#status(\"loading\")}",
+        "%{coc#list#status(\"args\")}",
+        "(%L/%{coc#list#status(\"total\")})",
+        "%=",
+        "%#CocListPath# %{coc#list#status(\"cwd\")} %l/%L%*"
+      ],
+      "items": {
+        "types": "string"
+      },
+      "description": "An array of statusline segments that will be used to draw the status line for list windows."
+    },
+    "list.signOffset": {
+      "type": "number",
+      "default": 900,
+      "description": "Sign offset of list, should be different from other plugins."
+    },
+    "list.selectedSignText": {
+      "type": "string",
+      "default": "*",
+      "description": "Sign text for selected lines."
+    },
+    "list.extendedSearchMode": {
+      "type": "boolean",
+      "default": true,
+      "description": "Enable extended search mode which allows multiple search patterns delimited by spaces."
+    },
+    "list.limitLines": {
+      "type": ["number", "null"],
+      "default": null,
+      "description": "Limit lines for list buffer."
+    },
+    "list.maxPreviewHeight": {
+      "type": "number",
+      "default": 12,
+      "description": "Max height for preview window of list."
+    },
+    "list.previewSplitRight": {
+      "type": "boolean",
+      "default": false,
+      "description": "Use vsplit for preview window."
+    },
+    "list.previewHighlightGroup": {
+      "type": "string",
+      "default": "Search",
+      "description": "Highlight group used for highlight the range in preview window."
+    },
+    "list.previewToplineStyle": {
+      "type": "string",
+      "default": "offset",
+      "description": "Topline style for list previews",
+      "enum": ["offset", "middle"]
+    },
+    "list.previewToplineOffset": {
+      "type": "number",
+      "default": 3,
+      "description": "Topline offset for list previews"
+    },
+    "list.nextKeymap": {
+      "type": "string",
+      "default": "<C-j>",
+      "description": "Key used for select next line on insert mode."
+    },
+    "list.previousKeymap": {
+      "type": "string",
+      "default": "<C-k>",
+      "description": "Key used for select previous line on insert mode."
+    },
+    "list.normalMappings": {
+      "type": "object",
+      "default": {},
+      "description": "Custom keymappings on normal mode."
+    },
+    "list.insertMappings": {
+      "type": "object",
+      "default": {},
+      "description": "Custom keymappings on insert mode."
+    },
+    "list.source.diagnostics.includeCode": {
+      "type": "boolean",
+      "description": "Whether to show the diagnostic code in the list.",
+      "default": true
+    },
+    "list.source.diagnostics.pathFormat": {
+      "type": "string",
+      "description": "Decide how the filepath is shown in the list.",
+      "enum": ["full", "short", "filename", "hidden"],
+      "default": "full"
+    },
+    "list.source.symbols.excludes": {
+      "type": "array",
+      "default": [],
+      "description": "Patterns of minimatch for filepath to execlude from symbols list.",
+      "items": {
+        "type": "string"
+      }
+    },
+    "list.source.outline.ctagsFilestypes": {
+      "type": "array",
+      "default": [],
+      "description": "Filetypes that should use ctags for outline instead of language server.",
+      "items": {
+        "type": "string"
+      }
+    },
+    "cursors.cancelKey": {
+      "type": "string",
+      "default": "<esc>",
+      "description": "Key used for cancel cursors session."
+    },
+    "cursors.nextKey": {
+      "type": "string",
+      "default": "<C-n>",
+      "description": "Key used for jump to next cursors position."
+    },
+    "cursors.previousKey": {
+      "type": "string",
+      "default": "<C-p>",
+      "description": "Key used for jump to previous cursors position."
+    },
+    "cursors.wrapscan": {
+      "type": "boolean",
+      "default": true,
+      "description": "Searches wrap around the first or last cursors range."
+    },
+    "semanticTokens.filetypes": {
+      "type": "array",
+      "description": "Filetypes that enable semanticTokens highlighting or [\"*\"] for any filetype",
+      "default": [],
+      "items": {
+        "type": "string"
+      }
+    },
+    "semanticTokens.highlightPriority": {
+      "type": "number",
+      "description": "Priority for semantic tokens highlight.",
+      "default": 2048,
+      "maximum": 4096
+    },
+    "semanticTokens.incrementTypes": {
+      "type": "array",
+      "description": "Semantic token types that should increase highlight when insert at the start and end position of token.",
+      "default": ["variable", "string", "parameter"],
+      "items": {
+        "type": "string"
+      }
+    },
+    "semanticTokens.combinedModifiers": {
+      "type": "array",
+      "description": "Semantic token modifiers that should have highlight combined with syntax highlights.",
+      "default": ["deprecated"],
+      "items": {
+        "type": "string"
+      }
+    },
+    "tree.closedIcon": {
+      "type": "string",
+      "default": "+",
+      "description": "Closed icon of tree view."
+    },
+    "tree.openedIcon": {
+      "type": "string",
+      "default": "-",
+      "description": "Opend icon of tree view."
+    },
+    "tree.key.toggleSelection": {
+      "type": "string",
+      "default": "<space>",
+      "description": "Trigger key to select/unselect item"
+    },
+    "tree.key.toggle": {
+      "type": "string",
+      "default": "t",
+      "description": "Trigger key to toggle expand state of tree node, does nothing with leaf node."
+    },
+    "tree.key.actions": {
+      "type": "string",
+      "default": "<tab>",
+      "description": "Trigger key to invoke actions."
+    },
+    "tree.key.collapseAll": {
+      "type": "string",
+      "default": "M",
+      "description": "Trigger key to collapse all tree node."
+    },
+    "tree.key.invoke": {
+      "type": "string",
+      "default": "<cr>",
+      "description": "Trigger key to invoke default command of current node or selection."
+    },
+    "tree.key.close": {
+      "type": "string",
+      "default": "<esc>",
+      "description": "Trigger key to dispose the tree and close tree window."
+    },
+    "tree.key.activeFilter": {
+      "type": "string",
+      "default": "f",
+      "description": "Trigger key active filter."
+    },
+    "tree.key.selectNext": {
+      "type": "string",
+      "default": "<C-j>",
+      "description": "Trigger key to select next item during filter."
+    },
+    "tree.key.selectPrevious": {
+      "type": "string",
+      "default": "<C-k>",
+      "description": "Trigger key to select previous item during filter."
+    },
+    "outline.showLineNumber": {
+      "type": "boolean",
+      "default": true,
+      "description": "Show line number of symbols."
+    },
+    "outline.detailAsDescription": {
+      "type": "boolean",
+      "default": true,
+      "description": "Show detail as description aside with label, when false detail will be shown in tooltip on cursor hold."
+    },
+    "outline.splitCommand": {
+      "type": "string",
+      "default": "botright 30vs",
+      "description": "Window split command used by outline."
+    },
+    "outline.followCursor": {
+      "type": "boolean",
+      "default": true,
+      "description": "Reveal item in outline tree on cursor hold."
+    },
+    "outline.autoWidth": {
+      "type": "boolean",
+      "default": true,
+      "description": "Automatically increase window width to avoid wrapped lines."
+    },
+    "outline.keepWindow": {
+      "type": "boolean",
+      "default": false,
+      "description": "Jump back to original window after outline is shown."
+    },
+    "outline.sortBy": {
+      "type": "string",
+      "default": "category",
+      "description": "Sort method for symbols.",
+      "enum": ["position", "name", "category"]
+    },
+    "outline.switchSortKey": {
+      "type": "string",
+      "default": "<C-s>",
+      "description": "The key used to switch sort method for symbols provider of current tree view."
+    },
+    "outline.expandLevel": {
+      "type": "number",
+      "default": 1,
+      "description": "Expand level of tree nodes."
+    },
+    "outline.checkBufferSwitch": {
+      "type": "boolean",
+      "default": true,
+      "description": "Recreate outline view after user changed to another buffer on current tab."
+    },
+    "outline.codeActionKinds": {
+      "type": "array",
+      "default": ["", "quickfix", "refactor"],
+      "description": "Filter code actions in actions menu by kinds.",
+      "items": {
+        "type": "string",
+        "enum": ["", "quickfix", "refactor", "source"]
+      }
+    },
+    "callHierarchy.openCommand": {
+      "type": "string",
+      "default": "edit",
+      "description": "Open command for callHierarchy tree view."
+    },
+    "callHierarchy.splitCommand": {
+      "type": "string",
+      "default": "botright 30vs",
+      "description": "Window split command used by callHierarchy tree view."
+    },
+    "callHierarchy.enableTooltip": {
+      "type": "boolean",
+      "default": true,
+      "description": "Enable tooltip to show relative filepath of call hierarchy."
+    },
+    "coc.preferences.enableLinkedEditing": {
+      "type": "boolean",
+      "default": false,
+      "description": "Enable linked editing support."
+    },
+    "coc.preferences.enableMessageDialog": {
+      "type": "boolean",
+      "default": false,
+      "description": "Enable messages shown in notification dialog."
+    },
+    "coc.preferences.maxFileSize": {
+      "type": "string",
+      "default": "10MB",
+      "description": "Maximum file size in bytes that coc.nvim should handle, default '10MB'"
+    },
+    "coc.preferences.useQuickfixForLocations": {
+      "type": "boolean",
+      "description": "Use vim's quickfix list for jump locations,\n need restart on change.",
+      "default": false
+    },
+    "coc.preferences.extensionUpdateCheck": {
+      "type": "string",
+      "default": "never",
+      "description": "Interval for check extension update, could be daily, weekly, never",
+      "enum": ["daily", "weekly", "never"]
+    },
+    "coc.preferences.snippetStatusText": {
+      "type": "string",
+      "default": "SNIP",
+      "description": "Text shown in statusline to indicate snippet session is activated."
+    },
+    "coc.preferences.snippetHighlight": {
+      "type": "boolean",
+      "description": "Use highlight group 'CocSnippetVisual' to highlight placeholders with same index of current one.",
+      "default": false
+    },
+    "coc.preferences.currentFunctionSymbolAutoUpdate": {
+      "type": "boolean",
+      "description": "Automatically update the value of b:coc_current_function on CursorHold event",
+      "default": false
+    },
+    "coc.preferences.formatOnSaveFiletypes": {
+      "type": "array",
+      "default": [],
+      "description": "Filetypes that should run format on save.",
+      "items": {
+        "type": "string"
+      }
+    },
+    "coc.preferences.rootPatterns": {
+      "type": "array",
+      "default": [".git", ".hg", ".projections.json"],
+      "description": "Root patterns to resolve workspaceFolder from parent folders of opened files, resolved from up to down.",
+      "items": {
+        "type": "string"
+      }
+    },
+    "coc.preferences.watchmanPath": {
+      "type": "string",
+      "description": "executable path for https://facebook.github.io/watchman/, detected from $PATH by default",
+      "default": null
+    },
+    "coc.preferences.jumpCommand": {
+      "anyOf": [
+        {
+          "type": "string",
+          "enum": [
+            "edit",
+            "split",
+            "vsplit",
+            "tabe",
+            "drop",
+            "tab drop",
+            "pedit"
+          ]
+        },
+        { "type": "string", "minimum": 1 }
+      ],
+      "description": "Command used for location jump, like goto definition, goto references etc. Can be also a custom command that gives file as an argument.",
+      "default": "edit"
+    },
+    "coc.preferences.messageLevel": {
+      "type": "string",
+      "description": "Message level for filter echoed messages, could be 'more', 'warning' and 'error'",
+      "default": "more",
+      "enum": ["more", "warning", "error"]
+    },
+    "coc.preferences.bracketEnterImprove": {
+      "type": "boolean",
+      "description": "Improve enter inside bracket `<> {} [] ()` by add new empty line below and place cursor to it. Works with `coc#on_enter()`",
+      "default": true
+    },
+    "coc.preferences.formatOnType": {
+      "type": "boolean",
+      "description": "Set to true to enable formatting on typing",
+      "default": false
+    },
+    "coc.preferences.formatOnTypeFiletypes": {
+      "type": "array",
+      "default": [],
+      "description": "Filetypes that should run format on typing. Only take effect when `coc.preferences.formatOnType` set `true`",
+      "items": {
+        "type": "string"
+      }
+    },
+    "coc.preferences.floatActions": {
+      "type": "boolean",
+      "description": "Set to false to disable float/popup support for actions menu, won't work on vim without float or popup window support.",
+      "default": true
+    },
+    "coc.preferences.promptInput": {
+      "type": "boolean",
+      "description": "Use prompt buffer in float window for user input.",
+      "default": true
+    },
+    "coc.preferences.enableMarkdown": {
+      "type": "boolean",
+      "description": "Tell the language server that markdown text format is supported, note that markdown text may not rendered as expected.",
+      "default": true
+    },
+    "coc.preferences.excludeImageLinksInMarkdownDocument": {
+      "type": "boolean",
+      "description": "Exclude image links from markdown text in float window.",
+      "default": true
+    },
+    "coc.preferences.silentAutoupdate": {
+      "type": "boolean",
+      "description": "Not open split window with update status when performing auto update.",
+      "default": true
+    },
+    "coc.preferences.willSaveHandlerTimeout": {
+      "type": "integer",
+      "default": 500,
+      "minimum": 200,
+      "maximum": 5000,
+      "description": "Will save handler timeout"
+    },
+    "coc.preferences.renameFillCurrent": {
+      "type": "boolean",
+      "default": true,
+      "description": "Disable to stop Refactor-Rename float/popup window from populating with old name in the New Name field."
+    },
+    "coc.source.around.enable": {
+      "type": "boolean",
+      "default": true
+    },
+    "coc.source.around.shortcut": {
+      "type": "string",
+      "default": "A"
+    },
+    "coc.source.around.priority": {
+      "type": "integer",
+      "default": 1
+    },
+    "coc.source.around.disableSyntaxes": {
+      "type": "array",
+      "default": [],
+      "items": {
+        "type": "string"
+      }
+    },
+    "coc.source.buffer.enable": {
+      "type": "boolean",
+      "default": true
+    },
+    "coc.source.buffer.shortcut": {
+      "type": "string",
+      "default": "B"
+    },
+    "coc.source.buffer.priority": {
+      "type": "integer",
+      "default": 1
+    },
+    "coc.source.buffer.ignoreGitignore": {
+      "type": "boolean",
+      "default": true,
+      "description": "Ignore git ignored files for buffer words"
+    },
+    "coc.source.buffer.disableSyntaxes": {
+      "type": "array",
+      "default": [],
+      "items": {
+        "type": "string"
+      }
+    },
+    "coc.source.file.enable": {
+      "type": "boolean",
+      "default": true
+    },
+    "coc.source.file.shortcut": {
+      "type": "string",
+      "default": "F"
+    },
+    "coc.source.file.priority": {
+      "type": "integer",
+      "default": 10
+    },
+    "coc.source.file.disableSyntaxes": {
+      "type": "array",
+      "default": [],
+      "items": {
+        "type": "string"
+      }
+    },
+    "coc.source.file.triggerCharacters": {
+      "type": "array",
+      "default": ["/", "\\"],
+      "items": {
+        "type": "string"
+      }
+    },
+    "coc.source.file.trimSameExts": {
+      "type": "array",
+      "default": [".ts", ".js"],
+      "description": "Trim same extension on file completion",
+      "items": {
+        "type": "string"
+      }
+    },
+    "coc.source.file.ignoreHidden": {
+      "type": "boolean",
+      "default": true,
+      "description": "Ignore completion for hidden files"
+    },
+    "coc.source.file.ignorePatterns": {
+      "type": "array",
+      "default": [],
+      "description": "Ignore patterns of matcher",
+      "items": {
+        "type": "string"
+      }
+    },
+    "languageserver": {
+      "type": "object",
+      "default": {},
+      "description": "Dictionary of languageservers, key is used as id of languageserver.",
+      "patternProperties": {
+        "^[_a-zA-Z]+$": {
+          "oneOf": [
+            {
+              "$ref": "#/definitions/languageServerModule"
+            },
+            {
+              "$ref": "#/definitions/languageServerCommand"
+            },
+            {
+              "$ref": "#/definitions/languageServerSocket"
+            }
+          ]
+        }
+      }
+    }
+  }
+}

+ 1250 - 0
vimfiles/bundle/coc.nvim/doc/coc-config.txt

@@ -0,0 +1,1250 @@
+*coc-config.txt*				NodeJS client for Vim & Neovim.
+
+CONTENTS
+
+Http 						|coc-config-http|
+Completion 					|coc-config-suggest|
+Document highlight 				|coc-config-documentHighlight|
+Colors 						|coc-config-colors|
+Links 						|coc-config-links|
+Diagnostics 					|coc-config-diagnostic|
+Signature 					|coc-config-signature|
+Cursors 					|coc-config-cursors|
+Refactor 					|coc-config-refactor|
+Hover 						|coc-config-hvoer|
+Dialog 						|coc-config-dialog|
+Notification 					|coc-config-notification|
+CodeLens 					|coc-config-codelens|
+Workspace 					|coc-config-workspace|
+List 						|coc-config-list|
+Preferences 					|coc-config-preferences|
+Semantic tokens 				|coc-config-semanticTokens|
+Tree 						|coc-config-tree|
+Outline 					|coc-config-outline|
+Call Hierarchy 					|coc-config-callHierarchy|
+Npm 						|coc-config-npm|
+Float 						|coc-config-float|
+Language server 				|coc-config-languageserver|
+
+==============================================================================
+BUILTIN CONFIGURATIONS 					*coc-config*
+
+Builtin configurations of coc.nvim, it's recommended to use `coc-json`
+extension for completion and validation support.
+
+------------------------------------------------------------------------------
+Http request~
+							*coc-config-http*
+"http.proxy"						*coc-config-http-proxy*
+
+	HTTP proxy URI, used for extensions that send request, default: `""`
+
+"http.proxyStrictSSL"					*coc-config-http-proxyStrictSSL*
+
+	Controls whether the proxy server certificate should be verified
+	against the list of supplied CAs, default: `true`
+
+"http.proxyAuthorization"				*coc-config-http-proxyAuthorization*
+
+	The value to send as the `Proxy-Authorization` header for every
+	network request.
+
+"http.proxyCA"						*coc-config-http-proxyCA*
+
+	CA (file) to use as Certificate Authority.
+
+------------------------------------------------------------------------------
+Completion related~
+							*coc-config-suggest*
+"suggest.noselect"					*coc-config-suggest-noselect*
+
+	Avoid select complete item on completion start, default: `false`.
+
+	Note: default changed to `false` on coc.nvim 0.0.82 to provide preselect
+	item.
+
+"suggest.selection"					*coc-config-suggest-selection*
+
+	Controls how suggestions are pre-selected when showing the suggest
+	list. Default: "recentlyUsed".
+
+	Could be "none", "recentlyUsed" and "recentlyUsedByPrefix".
+
+"suggest.formatItems" 					*coc-config-suggest-formatItems*
+
+	Items shown in popup menu in order.
+	Default to : `["abbr", "menu", "kind", "shortcut"]`
+
+"suggest.enablePreselect" 				*coc-config-suggest-enablePreselect*
+
+	Enable preselect feature of LSP, works when "suggest.noselect" is false.
+	Default: `true`.
+
+"suggest.labelMaxLength"				*coc-config-suggest-labelMaxLength*
+
+	Maximum length of label shown in popup menu, default: `200`
+
+"suggest.floatConfig"					*coc-config-suggest-floatConfig*
+
+	Configure style of popup menu and documentation window for completion,
+	see |coc-config-float|.
+
+	Note: some properties not work, including: "title", "focusable",
+	"close" and "maxHeight" (use 'pumheight' option for maximum height of
+	popup menu).
+
+	Note: "maxWidth" not works for popup menu, use
+	|coc-config-suggest-detailMaxLength| instead.
+
+"suggest.detailMaxLength"				*coc-config-suggest-detailMaxLength*
+
+	Max length of detail that will be shown in popup menu, default: `100`
+
+"suggest.detailField"					*coc-config-suggest-detailField*
+
+	Where to add the detail in complete item when it's less than max
+	length, default: `"preview"` when floating documentation is enabled.
+
+	Valid options: ["abbr", "menu", "preview"]
+
+"suggest.autoTrigger"					*coc-config-suggest-autoTrigger*
+
+	How should completion be triggered, default: `"always"`
+
+	Valid options: ["always", "trigger", "none"]
+
+	- `always`: trigger suggest on word characters and trigger
+	  characters.
+	- `trigger`: trigger suggest on trigger characters only.
+	- `none`: no auto trigger at all.
+
+"suggest.languageSourcePriority"			*coc-config-suggest-languageSourcePriority*
+
+	Priority of language sources, default: `99`
+
+"suggest.snippetIndicator"				*coc-config-suggest-snippetIndicator*
+
+	The character used in completion item abbreviation to indicate it
+	expands as code snippet, default: `~`.
+
+"suggest.maxCompleteItemCount"				*coc-config-suggest-maxCompleteItemCount*
+
+	Maximum number of complete items shown in Vim, default: `50`
+
+"suggest.preferCompleteThanJumpPlaceholder"		*coc-config-suggest-preferCompleteThanJumpPlaceholder*
+
+	Confirm completion instead of jump to next placeholder when completion
+	activates, default: `false`
+
+"suggest.snippetsSupport"				*coc-config-suggest-snippetsSupport*
+
+	Enable snippets expands expand on confirm completion. When set to
+	`false` coc.nvim would set language client option:
+	`CompletionClientCapabilities.completionItem.snippetSupport` to
+	`false` as well.
+
+	Note: the language server may still send completion items with
+	snippets when falsy.
+
+"suggest.fixInsertedWord"				*coc-config-suggest-fixInsertedWord*
+
+	Inserted word replaces the next one, default: `true`
+
+"suggest.localityBonus"					*coc-config-suggest-localityBonus*
+
+	Boost suggestions that appear closer to the cursor position,
+	default: `true`
+
+"suggest.triggerAfterInsertEnter"			*coc-config-suggest-triggerAfterInsertEnter*
+
+	Trigger completion after |InsertEnter|. Requires "suggest.autoTrigger"
+	to be set, default: `false`
+
+"suggest.timeout"					*coc-config-suggest-timeout*
+
+	Timeout for completion (unit: milliseconds), default: `5000`
+
+"suggest.minTriggerInputLength"				*coc-config-suggest-minTriggerInputLength*
+
+	Number of characters in the current word after which the completion
+	triggers, default: `1`
+
+"suggest.triggerCompletionWait"				*coc-config-suggest-triggerCompletionWait*
+
+	Delay between typing the trigger character and completion start which
+	initiates server synchronization, default: `0`
+
+"suggest.acceptSuggestionOnCommitCharacter"		*coc-config-suggest-acceptSuggestionOnCommitCharacter*
+
+	The server provides a set of commit characters: these characters can
+	trigger completion item acceptance. This also inserts commit character
+	after the completion item text. Requires `CompleteChanged` event to work,
+	default: `false`
+
+"suggest.lowPrioritySourceLimit"			*coc-config-suggest-lowPrioritySourceLimit*
+
+	Max items count for source priority lower than `90`.
+
+"suggest.highPrioritySourceLimit"			*coc-config-suggest-highPrioritySourceLimit*
+
+	Max items count for source priority bigger than or equal to `90`.
+
+"suggest.removeDuplicateItems"				*coc-config-suggest-removeDuplicateItems*
+
+	Remove completion items with duplicated word for all sources, snippet
+	items are excluded, default: `false`
+
+"suggest.defaultSortMethod"				*coc-config-suggest-defaultSortMethod*
+
+	Default sorting behavior for suggested completion items, default:
+	`length`
+
+"suggest.invalidInsertCharacters"			*coc-config-suggest-invalidInsertCharacters*
+
+	Invalid character for strip valid word when inserting text of complete
+	item, default: ` ,(,<,{,[,\r,\n`
+
+"suggest.asciiCharactersOnly"				*coc-config-suggest-asciiCharactersOnly*
+
+	Trigger suggest with ASCII characters only, default: `false`
+
+"suggest.ignoreRegexps"					*coc-config-suggest-ignoreRegexps*
+
+	Array of regexps, when input matched one of them, not trigger
+	completion, default: `[]`
+
+"suggest.virtualText" 					*coc-config-suggest-virtualText*
+
+	Show virtual text for insert word of selected item, works on neovim >=
+	0.5.0, default: `false`
+
+"suggest.completionItemKindLabels"			*coc-config-suggest-completionItemKindLabels*
+
+	Set custom labels to completion item kinds, default: `{}`.
+
+	Example configuration: with https://nerdfonts.com:  >
+
+	  "suggest.completionItemKindLabels": {
+		"keyword": "\uf1de",
+		"variable": "\ue79b",
+		"value": "\uf89f",
+		"operator": "\u03a8",
+		"constructor": "\uf0ad",
+		"function": "\u0192",
+		"reference": "\ufa46",
+		"constant": "\uf8fe",
+		"method": "\uf09a",
+		"struct": "\ufb44",
+		"class": "\uf0e8",
+		"interface": "\uf417",
+		"text": "\ue612",
+		"enum": "\uf435",
+		"enumMember": "\uf02b",
+		"module": "\uf40d",
+		"color": "\ue22b",
+		"property": "\ue624",
+		"field": "\uf9be",
+		"unit": "\uf475",
+		"event": "\ufacd",
+		"file": "\uf723",
+		"folder": "\uf114",
+		"snippet": "\ue60b",
+		"typeParameter": "\uf728",
+		"default": "\uf29c"
+	}
+<
+------------------------------------------------------------------------------
+Document highlight~
+							*coc-config-documentHighlight*
+"documentHighlight.priority"				*coc-config-documentHighlight-priority*
+
+	Match priority used by document highlight, see ':h matchadd'.
+	Default `-1`
+
+"documentHighlight.timeout"				*coc-config-documentHighlight-timeout*
+
+	Timeout for document highlight, in milliseconds.
+	Default `500`
+
+------------------------------------------------------------------------------
+Colors highlight~
+							*coc-config-colors*
+"colors.filetypes"					*coc-config-colors-filetypes*
+
+	Filetypes that should enable colors highlight feature.
+	Use `*` for all filetypes.
+
+	Default: `[]`
+
+------------------------------------------------------------------------------
+Links~
+							*coc-config-links*
+"links.tooltip"						*coc-config-links-tooltip*
+
+	Show tooltip of link under cursor on CursorHold, neovim only.
+	Default: `false`
+
+------------------------------------------------------------------------------
+Diagnostics~
+							*coc-config-diagnostic*
+"diagnostic.enable"					*coc-config-diagnostic-enable*
+
+	Display diagnostics, default: `true`
+
+"diagnostic.autoRefresh"				*coc-config-diagnostic-autoRefresh*
+
+	Enable automatically refresh diagnostics, use
+	|CocAction('diagnosticRefresh')| action to refresh diagnostics when it's
+	disabled, default: `true`
+
+"diagnostic.refreshOnInsertMode"			*coc-config-diagnostic-refreshOnInsertMode*
+
+	Refresh diagnostics when in insert mode, default: `false`
+
+"diagnostic.displayByAle"				*coc-config-diagnostic-displayByAle*
+
+	Use ALE for displaying diagnostics. This will disable coc.nvim for
+	displaying diagnostics. Restart to make changes take the effect,
+	default: `false`
+
+"diagnostic.level"					*coc-config-diagnostic-level*
+
+	Filter diagnostics by severity level (affect both UI and diagnostic
+	list), default: `"hint"`
+
+	Valid options: ["hint", "information", "warning", "error"]
+
+"diagnostic.highlighLimit"				*coc-config-diagnostic-highlighLimit*
+
+	Limit count for highlighted diagnostics, too many diagnostic
+	highlights could make vim stop responding.
+
+	Default: `1000`
+
+"diagnostic.highlightPriority"				*coc-config-diagnostic-highlightPriority*
+
+	Priority for diagnostic highlights, works on vim8 and neovim >= 0.6.0
+
+	Default: `4096`
+
+"diagnostic.enableSign"					*coc-config-diagnostic-enableSign*
+
+	Enable signs for diagnostics, default: `true`
+
+"diagnostic.signLevel"					*coc-config-diagnostic-signLevel*
+
+	Filter diagnostics in sign column, default: `null`.
+
+"diagnostic.signPriority"				*coc-config-diagnostic-signPriority*
+
+	Priority of diagnostic sign, default to `10`, check |sign-priority|.
+
+"diagnostic.errorSign"					*coc-config-diagnostic-errorSign*
+
+	Sign of error diagnostics shown in the 'signcolumn', default: `">>"`
+
+"diagnostic.warningSign"				*coc-config-diagnostic-warningSign*
+
+	Sign of warning diagnostics shown in the 'signcolumn', default: `"⚠"`
+
+"diagnostic.infoSign"					*coc-config-diagnostic-infoSign*
+
+	Sign of info diagnostics shown in the 'signcolumn', default: `">>"`
+
+"diagnostic.hintSign"					*coc-config-diagnostic-hintSign*
+
+	Sign of hint diagnostics shown in the 'signcolumn', default: `">>"`
+
+
+"diagnostic.enableHighlightLineNumber"			*coc-config-diagnostic-enableHighlightLineNumber*
+
+	Enable highlighting line numbers for diagnostics, only works with
+	neovim and `diagnostic.enableSign` is true.
+
+	default: `true`
+
+"diagnostic.locationlistUpdate"				*coc-config-diagnostic-locationlistUpdate*
+
+	Update locationlist on diagnostics change, only works with
+	locationlist opened by :CocDiagnostics command and first window of
+	associated buffer.
+
+	default: `true`
+
+"diagnostic.locationlistLevel"				*coc-config-diagnostic-locationlistLevel*
+
+	Filter diagnostics in locationlist, default: `null`.
+
+"diagnostic.enableMessage"				*coc-config-diagnostic-enableMessage*
+
+	When to enable show messages of diagnostics.
+
+	Valid options: ["always","jump","never"], always means including
+	cursor hold and after jump to another diagnostic.
+
+	default: `"always"`
+
+"diagnostic.messageLevel"				*coc-config-diagnostic-messageLevel*
+
+	Filter diagnostic message in float window/popup, default: `null`.
+
+"diagnostic.checkCurrentLine"				*coc-config-diagnostic-checkCurrentLine*
+
+	Show all diagnostics of the current line if none of them are at the
+	current position, default: `false`
+
+"diagnostic.messageDelay"				*coc-config-diagnostic-messageDelay*
+
+	How long to wait (in milliseconds) before displaying the diagnostic
+	message with echo or float.
+
+	Default: `200`
+
+"diagnostic.messageTarget"				*coc-config-diagnostic-messageTarget*
+
+	Diagnostic message target, default: `"float"`
+
+	Valid options: ["echo", "float"]
+
+"diagnostic.format"					*coc-config-diagnostic-format*
+
+	Define the diagnostic message format.
+	Available parts: source, code, severity, message
+
+	Default: `[%source%code] [%severity] %message`
+
+"diagnostic.floatConfig"				*coc-config-diagnostic-floatConfig*
+
+	Configuration of floating window/popup, see |coc-config-float|.
+
+"diagnostic.filetypeMap"				*coc-config-diagnostic-filetypeMap*
+
+	A map between buffer filetype and the filetype assigned to diagnostics
+	in float window. To syntax highlight diagnostics with their parent
+	buffer type use `"default": "bufferType"`, default: `{}`
+
+"diagnostic.virtualText"				*coc-config-diagnostic-virtualText*
+
+	Use Neovim virtual text to display diagnostics, default: `false`
+
+"diagnostic.virtualTextLevel"				*coc-config-diagnostic-virtualTextLevel*
+
+	Filter diagnostic message in virtual text by level, default: `null`
+
+"diagnostic.virtualTextWinCol"				*coc-config-diagnostic-virtualTextWinCol*
+
+	Window column number to align virtual text, default: `null`
+
+"diagnostic.virtualTextCurrentLineOnly"			*coc-config-diagnostic-virtualTextCurrentLineOnly*
+
+	Only show virtualText diagnostic on current cursor line, default:
+	`true`
+
+"diagnostic.virtualTextPrefix"				*coc-config-diagnostic-virtualTextPrefix*
+
+	The prefix added for virtual text diagnostics, default: `" "`
+
+"diagnostic.virtualTextLines"				*coc-config-diagnostic-virtualTextLines*
+
+	The number of non-empty lines from a diagnostic to display, default: `3`
+
+"diagnostic.virtualTextLineSeparator"			*coc-config-diagnostic-virtualTextLineSeparator*
+
+	The text that will mark a line end from the diagnostic message,
+	default: `" \\ "`
+
+"diagnostic.separateRelatedInformationAsDiagnostics"	*coc-config-diagnostic-separateRelatedInformationAsDiagnostics*
+
+	Separate related information as diagnostics, default: `false`
+
+------------------------------------------------------------------------------
+Signature~
+							*coc-config-signature*
+"signature.enable"					*coc-config-signature-enable*
+
+	Enable signature help when trigger character typed. Requires service
+	restart on change, default: `true`
+
+"signature.floatConfig"					*coc-config-signature-floatConfig*
+
+	Configuration of floating window/popup for signature documents, see
+	|coc-config-float|.
+
+"signature.triggerSignatureWait"			*coc-config-signature-triggerSignatureWait*
+
+	Timeout for signature request trigger (milliseconds), default: `500`.
+	Change to higher value for slow Language Servers.
+
+"signature.target"					*coc-config-signature-target*
+
+	Target of signature help, use `"float"` when possible by default.
+
+	Valid options: ["float", "echo"]
+
+"signature.preferShownAbove"				*coc-config-signature-preferShownAbove*
+
+	Show signature help's floating window above cursor when possible.
+	Requires restart on change, default: `true`
+
+"signature.hideOnTextChange"				*coc-config-signature-hideOnTextChange*
+
+	Hide signature help's floating window when text changed. Requires
+	restart on change, default: `false`
+
+------------------------------------------------------------------------------
+Multiple cursors~
+							*coc-config-cursors*
+"cursors.cancelKey"					*coc-config-cursors-cancelKey*
+
+	Key used for cancel cursors session, default: `<esc>`
+
+"cursors.nextKey"					*coc-config-cursors-nextKey*
+
+	Key used for jump to next cursors position. , default: `<C-n>`
+
+"cursors.previousKey" 					*coc-config-cursors-previousKey*
+
+	Key used for jump to previous cursors position, default: `<C-p>`
+
+"cursors.wrapscan"					*coc-config-cursors-wrapscan*
+
+	Searches wrap around the first or last cursors range, default: `true`
+
+------------------------------------------------------------------------------
+Refactor buffer~
+							*coc-config-refactor*
+"refactor.saveToFile"					*coc-config-refactor-saveToFile*
+
+	Save changed buffer to file when write refactor buffer with ':noa wa'
+	command. set to false if you want save buffer by yourself.
+
+"refactor.openCommand"					*coc-config-refactor-openCommand*
+
+	Open command for refactor window, default: `vsplit`
+
+"refactor.beforeContext"				*coc-config-refactor-beforeContext*
+
+	Print num lines of leading context before each match, default: `3`
+
+"refactor.afterContext"					*coc-config-refactor-afterContext*
+
+	Print num lines of trailing context after each match, default: `3`
+
+"refactor.showMenu"					*coc-config-refactor-showMenu*
+
+	Refactor buffer local mapping to bring up menu for this chunk,
+	default: `<Tab>`
+
+------------------------------------------------------------------------------
+Hover~
+							*coc-config-hover*
+"hover.target"						*coc-config-hover-target*
+
+	Target to show hover information, default is floating window when
+	possible.
+
+	Valid options: ["preview", "echo", "float"]
+
+"hover.previewMaxHeight"				*coc-config-hover-previewMaxHeight*
+
+	Max height of preview window for hover, default: `12`
+
+"hover.floatConfig"					*coc-config-hover-floatConfig*
+
+	Configuration of floating window/popup for hover documents, see
+	|coc-config-float|.
+
+"hover.autoHide"					*coc-config-hover-autoHide*
+
+	Automatically hide hover float window on CursorMove or InsertEnter,
+	default `true`.
+
+------------------------------------------------------------------------------
+Dialog~
+							*coc-config-dialog*
+"dialog.maxWidth"					*coc-config-dialog-maxWidth*
+
+	Maximum width of dialog window.
+
+"dialog.maxHeight"					*coc-config-dialog-maxHeight*
+
+	Maximum height of dialog window.
+
+"dialog.rounded" 					*coc-config-dialog-rounded*
+
+	Use rounded border for dialog window, default `true`.
+
+"dialog.confirmKey"					*coc-config-dialog-confirmKey*
+
+	Confirm key for confirm selection used by menu and picker, you can
+	always use <esc> to cancel, default to `<cr>`.
+
+"dialog.pickerButtons"					*coc-config-dialog-pickerButtons*
+
+	Show buttons for picker dialog window/popup, default `true`.
+
+"dialog.pickerButtonShortcut"				*coc-config-dialog-pickerButtonShortcut*
+
+	Show shortcut in buttons of picker dialog window/popup, used when
+	dialog.pickerButtons is true, default `true`.
+
+"dialog.floatHighlight"					*coc-config-dialog-floatHighlight*
+
+	Highlight group for dialog window/popup, default to 'CocFloating'.
+
+"dialog.floatBorderHighlight"				*coc-config-dialog-floatBorderHighlight*
+
+	Highlight group for border of dialog window/popup, default to
+	'CocFloating'.
+
+"dialog.shortcutHighlight"				*coc-config-dialog-shortcutHighlight*
+
+	Highlight group for shortcut character in menu dialog, default to
+	'MoreMsg'
+
+------------------------------------------------------------------------------
+Notification~
+							*coc-config-notification*
+
+"notification.maxWidth"					*coc-config-notification-maxWidth*
+
+	Maximum content width of notification dialog, default to `60`.
+
+"notification.maxHeight"				*coc-config-notification-maxHeight*
+
+	Maximum content height of notification dialog, default to `10`.
+
+"notification.disabledProgressSources"			*coc-config-notification-disabledProgressSources*
+
+	Sources that should be disabled for message progress, use "*" to
+	disable all message only progress notifications, default to `[]`
+
+	Source name could be extension id or `language-client-{id}`.
+
+"notification.minProgressWidth" 			*coc-config-notification-minProgressWidth*
+
+	Minimal with of progress notification.
+
+"notification.highlightGroup"				*coc-config-notification-highlightGroup*
+
+	Highlight group of notification dialog, default to `CocFloating`.
+
+"notification.winblend" 				*coc-config-notification-winblend*
+
+	Winblend option of notification window, neovim only, default `30`.
+
+"notification.border" 					*coc-config-notification-border*
+
+	Enable rounded border for notification windows, default `true`.
+
+"notification.timeout" 					*coc-config-notification-timeout*
+
+	Timeout for auto close notifications, in miniseconds, default `10000`.
+
+"notification.marginRight" 				*coc-config-notification-marginRight*
+
+	Margin right to the right of editor window, default `10`.
+
+"notification.focusable" 				*coc-config-notification-focusable*
+
+	Enable focus by user actions (wincmds, mouse events), neovim only,
+	default `true`.
+
+------------------------------------------------------------------------------
+CodeLens~
+							*coc-config-codelens*
+"codeLens.enable"					*coc-config-codeLens-enable*
+
+	Enable `codeLens` feature. Requires Neovim with virtual text feature,
+	default: `false`.
+
+"codeLens.position"					*coc-config-codeLens-position*
+
+	Position of codeLens, works on nvim >= 0.6.0, valid options
+	["top", "eol", "right_align"], default: `top`.
+
+"codeLens.separator"					*coc-config-codeLens-separator*
+
+	Separator text for `codeLens` in virtual text, default: `""`.
+
+"codeLens.subseparator"					*coc-config-codeLens-subseparator*
+
+	Subseparator text for multiple codelens in virtual text, default: `" "`
+
+------------------------------------------------------------------------------
+Workspace related~
+							*coc-config-workspace*
+"workspace.openOutputCommand" 				*coc-config-workspace-openOutputCommand*
+
+	Command used to open output channel, default: `vs`
+
+"workspace.openResourceCommand" 			*coc-config-workspace-openResourceCommand*
+
+	Command to open files that not loaded, default: `tab drop`
+
+"workspace.ignoredFiletypes				*coc-config-workspace-ignoredFiletypes*
+
+	Filetypes to ignore for workspace folder resolution, default: `[]`
+
+	Note: This is the filetype after mapping by `g:coc_filetype_map`.
+
+"workspace.ignoredFolders"				*coc-config-workspace-ignoredFolders*
+
+	List of folders that should not be resolved as workspace folder.
+	Environment variables and minimatch patterns can be used.
+
+	Default: ["$HOME"]
+
+"workspace.bottomUpFiletypes"				*coc-config-workspace-bottomUpFiletypes*
+
+	Filetypes that should have workspace folder resolved from base
+	directory of file, or `["*"]` for any filetype.
+
+	Default: []
+
+"workspace.workspaceFolderCheckCwd"			*coc-config-workspace-workspaceFolderCheckCwd*
+
+	Whether the cwd directory should be checked first when resolving
+	workspace folder of current buffer.
+
+	Default: `true`
+
+"workspace.workspaceFolderFallbackCwd"			*coc-config-workspace-workspaceFolderFallbackCwd*
+
+	Use current working directory as workspace folder when no root
+	patterns resolved.
+
+	Default: `true`
+
+------------------------------------------------------------------------------
+List~
+							*coc-config-list*
+"list.indicator"					*coc-config-list-indicator*
+
+	The character used as first character in prompt line, default: `">"`
+
+"list.alignColumns"					*coc-config-list-alignColumns*
+
+	Whether to align lists in columns, default: `false`
+
+"list.menuAction"					*coc-config-list-menuAction*
+
+	Use menu picker instead of confirm() for choose action.
+	Default: `false`
+
+"list.height"						*coc-config-list-height*
+
+	Height of list window (when splited), default: `10`
+
+"list.signOffset"					*coc-config-list-signOffset*
+
+	Sign offset of list, should be different from other plugins, default:
+	`900`
+
+"list.selectedSignText"					*coc-config-list-selectedSignText*
+
+	Sign text for selected lines, default: `"*"`
+
+"list.limitLines"					*coc-config-list-limitLines*
+
+	Limit lines shown in the list buffer, no limit by default, default: `null`
+
+"list.maxPreviewHeight"					*coc-config-list-maxPreviewHeight*
+
+	Max height for preview window of list, default: `12`
+
+"list.previewHighlightGroup"				*coc-config-list-previewHighlightGroup*
+
+	Highlight group used for highlighting the range in preview window,
+	default: `"Search"`
+
+"list.previewToplineStyle"				*coc-config-list-previewToplineStyle*
+
+	Topline style for list previews
+	default: `"offset"`
+	Valid options: ["offset","middle"]
+
+"list.previewToplineOffset"				*coc-config-list-previewToplineOffset*
+
+	Topline offset for list previews
+	default: `3`
+
+"list.nextKeymap"					*coc-config-list-nextKeymap*
+
+	Key for selecting next line in the insert mode, default: `"<C-j>"`
+
+"list.previousKeymap"					*coc-config-list-previousKeymap*
+
+	Key for selecting previous line in the insert mode, default: `"<C-k>"`
+
+"list.extendedSearchMode"				*coc-config-list-extendedSearchMode*
+
+	Enable extended search mode which allows multiple search patterns
+	delimited by whitespace, default: `true`
+
+"list.normalMappings"					*coc-config-list-normalMappings*
+
+	Custom key mappings in the normal mode, default: `{}`
+
+"list.insertMappings"					*coc-config-list-insertMappings*
+
+	Custom key mappings in the insert mode, default: `{}`
+
+"list.interactiveDebounceTime"				*coc-config-list-interactiveDebounceTime*
+
+	Debounce time for input change on interactive mode, default: `100`
+
+"list.previewSplitRight"				*coc-config-list-previewSplitRight*
+
+	Use vsplit for preview window, default: `false`
+
+"list.source.symbols.excludes"				*coc-config-list-source-symbols-excludes*
+
+	Patterns of minimatch for filepath to exclude from symbols list,
+	default: `[]`
+
+"list.source.outline.ctagsFilestypes"			*coc-config-list-source-outline-ctagsFilestypes*
+
+	Filetypes that should use `ctags` for outline instead of language server,
+	default: `[]`
+
+
+"list.source.diagnostics.pathFormat"			*coc-config-list-source-diagnostics-pathFormat*
+
+	Decide how the filepath is shown in the list.
+
+	Valid options: ["full", "short", "filename", "hidden"].
+
+	default: `"full"`
+
+"list.source.diagnostics.includeCode"			*coc-config-list-source-diagnostics-includeCode*
+
+	Whether to show the diagnostic code in the list.
+
+	default: `true`
+
+------------------------------------------------------------------------------
+Preferences~
+							*coc-config-preferences*
+"coc.preferences.enableLinkedEditing"			*coc-preferences-enableLinkedEditing*
+
+	Enable linked editing support, default: `false`
+
+"coc.preferences.enableMessageDialog"			*coc-preferences-enableMessageDialog*
+
+	Enable messages shown in notification dialog, default: `false`
+
+"coc.preferences.maxFileSize"				*coc-preferences-maxFileSize*
+
+	Maximum file size in bytes that coc.nvim should handle, default: `'10MB'`
+
+"coc.preferences.useQuickfixForLocations"		*coc-preferences-useQuickfixForLocations*
+
+	Use Vim's quickfix list for jump locations. Requires restart on change,
+	default: `false`
+
+"coc.preferences.extensionUpdateCheck"			*coc-preferences-extensionUpdateCheck*
+
+	Interval for checking extension updates, default: `"never"`
+
+	Valid options: ["daily","weekly","never"]
+
+"coc.preferences.snippetHighlight"			*coc-preferences-snippetHighlight*
+
+	Use highlight group 'CocSnippetVisual' to highlight placeholders with
+	same index of current one.
+
+	default: `false`
+
+"coc.preferences.snippetStatusText"			*coc-preferences-snippetStatusText*
+
+	Text shown in 'statusline' to indicate snippet session is activate.
+	Check |coc-status| for statusline integration.
+
+	Default: `"SNIP"`
+
+"coc.preferences.currentFunctionSymbolAutoUpdate"	*coc-preferences-currentFunctionSymbolAutoUpdate*
+
+	Automatically update the value of `b:coc_current_function` on `CursorHold`
+	event, default: `false`
+
+"coc.preferences.formatOnSaveFiletypes"			*coc-preferences-formatOnSaveFiletypes*
+
+	Filetypes for which formatting triggers when saving, default: `[]`
+
+	The operation only format the document by one format provider that
+	have highest priority, timeout is 500ms to avoid vim blocked for too
+	long time.
+
+	Note: This is the filetype after mapping by `g:coc_filetype_map`.
+
+	Note since vim's autocmd not nested by default, coc.nvim may not
+	receive latest code when you're using other vim plugin to format
+	document at the same time.
+
+"coc.preferences.rootPatterns"				*coc-preferences-rootPatterns*
+
+	Root patterns to resolve `workspaceFolder` from parent folders of opened
+	files, resolved from up to down, default:
+	`[".git",".hg",".projections.json"]`
+
+"coc.preferences.watchmanPath"				*coc-preferences-watchmanPath*
+
+	Executable path for https://facebook.github.io/watchman/, detected
+	from $PATH by default, default: `null`
+
+"coc.preferences.jumpCommand"				*coc-preferences-jumpCommand*
+
+	Command used for location jump performed for goto definition, goto
+	references etc, default: `"edit"`
+
+	Valid options: ["edit", "split", "vsplit", "tabe", "drop", "tab drop"]
+
+"coc.preferences.messageLevel"				*coc-preferences-messageLevel*
+
+	Message level for filter echoed messages default: `"more"`
+
+	Valid options: ["more", "warning", "error"]
+
+"coc.preferences.bracketEnterImprove"			*coc-preferences-bracketEnterImprove*
+
+	Improve handling of pressing enter inside brackets (`<> {} [] ()`) by
+	create a new empty line in the middle, the indent is calculated by vim,
+	checkout |indentexpr| for details.
+
+	Works with |coc#on_enter()|, default: `true`
+
+"coc.preferences.formatOnType"				*coc-preferences-formatOnType*
+
+	Set to true to enable format on type, default: `false`
+
+"coc.preferences.formatOnTypeFiletypes"			*coc-preferences-formatOnTypeFiletypes*
+
+	Filetypes that should run format on typing specific characters,
+	default: `[]`, requires `onTypeEdit` provider |CocHasProvider|.
+
+	Note: takes effect when `coc.preferences.formatOnType` set `true`.
+	Note: Use filetypes after mapped by `g:coc_filetype_map`.
+
+"coc.preferences.floatActions"				*coc-preferences-floatActions*
+
+	Set to false to disable float/popup support for actions menu.
+	Default: `true`
+
+"coc.preferences.promptInput"				*coc-preferences-promptInput*
+
+	Use prompt buffer in float window for user input.
+	Default: `true`
+
+"coc.preferences.enableMarkdown"			*coc-preferences-enableMarkdown*
+
+	Tell the language server that markdown text format is supported,
+	note that you may have additional escaped characters for markdown
+	text.
+
+"coc.preferences.silentAutoupdate"			*coc-preferences-silentAutoupdate*
+
+	Not open split window with update status when performing auto update.
+
+"coc.preferences.willSaveHandlerTimeout"		*coc-preferences-willSaveHandlerTimeout*
+
+	Will save handler timeout, default: `500`
+
+"coc.preferences.renameFillCurrent"			*coc-preferences-renameFillCurrent*
+
+	Disable to stop Refactor-Rename float/popup window from populating
+	with old name in the New Name field.
+	Default: `true`
+
+------------------------------------------------------------------------------
+Semantic tokens~
+							*coc-config-semanticTokens*
+"semanticTokens.filetypes"				*coc-config-semanticTokens-filetypes*
+
+	Filetypes that should enable semantic tokens highlight feature. Use
+	`["*"]` for all filetypes, default: `[]`
+
+	Note: semantic tokens highlight requires nvim >= 0.5.0 and vim >=
+	8.1.0579 to work.
+
+"semanticTokens.highlightPriority"			*coc-config-semanticTokens-highlightPriority*
+
+	Priority for semantic tokens highlight, default `2048`
+
+"semanticTokens.incrementTypes"				*coc-config-semanticTokens-incrementTypes*
+
+	Semantic token types that should increase highlight when insert at
+	the start and end position of token.
+
+	Default: `['variable', 'string']`
+
+"semanticTokens.combinedModifiers"			*coc-config-semanticTokens-combinedModifiers*
+
+	Semantic token modifiers that should combine with syntax highlights.
+
+	Default: `['deprecated']`
+
+------------------------------------------------------------------------------
+Tree~
+							*coc-config-tree*
+"tree.closedIcon"					*coc-config-tree-closedIcon*
+
+	Closed icon of tree view, use '' to make it look better when you
+	have patched font, default: '+'.
+
+"tree.openedIcon"					*coc-config-tree-openedIcon*
+
+	Opened icon of tree view, use '' to make it look better when you
+	have patched font, default: '-'
+
+"tree.key.toggleSelection"				*coc-config-tree-key-toggleSelection*
+
+	Trigger key to select/unselect item, default: <space>
+
+"tree.key.toggle"					*coc-config-tree-key-toggle*
+
+	Trigger key to toggle expand state of tree node, default: 't'
+
+"tree.key.actions"					*coc-config-tree-key-actions*
+
+	Trigger key to invoke actions, default: <tab>
+
+"tree.key.collapseAll"					*coc-config-tree-key-collapseAll*
+
+	Trigger key to collapse all tree node, default: 'M'
+
+"tree.key.invoke"					*coc-config-tree-key-invoke*
+
+	Trigger key to invoke default command of current node or selection,
+	default: <cr>
+
+"tree.key.close"					*coc-config-tree-key-close*
+
+	Trigger key to dispose the tree and close tree window, default: <esc>
+
+"tree.key.activeFilter"					*coc-config-tree-key-activeFilter*
+
+	Trigger key active filter, only works when tree view support filter,
+	default: 'f'
+
+"tree.key.selectNext"					*coc-config-tree-key-selectNext*
+
+	Trigger key to select next item during filter, default <C-j>
+
+"tree.key.selectPrevious"				*coc-config-tree-key-selectPrevious*
+
+	Trigger key to select previous item during filter, default <C-k>
+
+------------------------------------------------------------------------------
+Outline~
+							*coc-config-outline*
+"outline.splitCommand"					*coc-config-outline-splitCommand*
+
+	Window split command used by outline, default 'botright 30vs'
+
+"outline.followCursor"					*coc-config-outline-followCursor*
+
+	Reveal item in outline tree on cursor hold, default `true`
+
+"outline.keepWindow"					*coc-config-outline-keepWindow*
+
+	Jump back to original window after outline is shown, default `false`
+
+"outline.autoWidth"					*coc-config-outline-autoWidth*
+
+	Automatically increase window width to avoid wrapped lines, default
+	`true`, use |g:coc_max_treeview_width| to change maximum width.
+
+"outline.sortBy"					*coc-config-outline-sortBy*
+
+	Sort method for symbols, available options: 'position', 'name' and
+	'category'. Default: 'category'.
+
+"outline.switchSortKey"					*coc-config-outline-switchSortKey*
+
+	The key used to switch sort method for symbols provider of current
+	tree view. Default <C-s>
+
+"outline.expandLevel"					*coc-config-outline-expandLevel*
+
+	Default expand level of tree nodes, default `1`
+
+"outline.checkBufferSwitch"				*coc-config-outline-checkBufferSwitch*
+
+	Recreate outline view after changed to another buffer on current tab.
+	Default `true`
+
+"outline.showLineNumber"				*coc-config-outline-showLineNumber*
+
+	Show line number of document symbols.
+	Default `true`
+
+"outline.detailAsDescription"				*coc-config-outline-detailAsDescription*
+
+	Show detail as description aside with label.
+	Default: `true`
+
+"outline.codeActionKinds"				*coc-config-outline-codeActionKinds*
+
+	Filter code actions in actions menu by kinds.
+	Default: ['', 'quickfix', 'refactor', 'source']
+
+------------------------------------------------------------------------------
+Call hierarchy~
+							*coc-config-callHierarchy*
+"callHierarchy.openCommand"				*coc-config-callHierarchy-openCommand*
+
+	Open command for callHierarchy tree view, default to 'edit'.
+
+"callHierarchy.splitCommand"				*coc-config-callHierarchy-splitCommand*
+
+	Window split command used by callHierarchy tree view.
+
+"callHierarchy.enableTooltip"				*coc-config-callHierarchy-enableTooltip*
+
+	Enable tooltip to show relative filepath of call hierarchy.
+	Default: `true`
+
+------------------------------------------------------------------------------
+Npm~
+							*coc-config-npm*
+"npm.binPath"						*coc-config-npm-binPath*
+
+	Command or full path of npm or yarn executable for install/update
+	extensions, default: `npm`
+
+------------------------------------------------------------------------------
+Float configuration~
+							*coc-config-float*
+
+Used by `suggest.floatConfig`, `diagnostic.floatConfig`,
+`signature.floatConfig` and `hover.floatConfig`, following properties are
+supported:
+
+	- "border": Change to `true` to enable border.
+	- "rounded": Use rounded borders when border is `true`.
+	- "highlight": Background highlight group of float window.
+	- "title": Title used by float window.
+	- "borderhighlight": Border highlight group of float window.
+	- "close": Set to true to draw close icon.
+	- "maxWidth": Maximum width of float window, contains border.
+	- "maxHeight": Maximum height of float window, contains border.
+	- "winblend": Set 'winblend' option of window, neovim only.
+	- "focusable": Set to false to make window not focusable, neovim only.
+	- "shadow": Set to true to enable shadow, neovim only.
+
+------------------------------------------------------------------------------
+Languageserver~
+							*coc-config-languageserver*
+
+	Dictionary of Language Servers, key is the ID of corresponding server,
+	and value is configuration of languageserver. Default: `{}`
+
+	Properties of languageserver configuration:
+
+	- "enable": Change to `false` to disable that languageserver.
+
+	- "filetypes": Supported filetypes, add * in array for all filetypes.
+	  Note: it's required for start the languageserver, please make sure
+	  your filetype is expected by `:CocCommand document.echoFiletype` command
+
+	- "additionalSchemes": Additional uri schemes, default schemes
+	  including file & untitled.
+	  Note: you have to setup vim provide content for custom uri as well.
+
+	- "cwd": Working directory used to start languageserver, vim's cwd is
+	  used by default.
+
+	- "env": Environment variables for child process.
+
+	- "settings": Settings for languageserver, received on server
+	  initialization.
+
+	- "trace.server": Trace level of communication between server and
+	  client that showed with output channel, open output channel by
+	  command `:CocCommand workspace.showOutput`
+
+	- "stdioEncoding": Encoding used for stdio of child process.
+
+	- "initializationOptions": Initialization options passed to
+	  languageserver (it's deprecated)
+
+	- "rootPatterns": Root patterns used to resolve rootPath from current
+	  file.
+
+	- "requireRootPattern": If true, doesn't start server when root
+	  pattern not found.
+
+	- "ignoredRootPaths": Absolute root paths that language server should
+	  not use as rootPath, higher priority than rootPatterns.
+
+	- "disableDynamicRegister": Disable dynamic registerCapability feature
+	  for this languageserver to avoid duplicated feature regstration.
+
+	- "disableSnippetCompletion": Disable snippet completion feature for
+	  this languageserver.
+
+	- "disabledFeatures": Disable features for this languageserver,
+	  valid keys:
+>
+	  ["completion", "configuration", "workspaceFolders", "diagnostics",
+	  "willSave", "willSaveUntil", "didSaveTextDocument",
+	  "fileSystemWatcher", "hover", "signatureHelp", "definition",
+	  "references", "documentHighlight", "documentSymbol",
+	  "workspaceSymbol", "codeAction", "codeLens", "formatting",
+	  "documentFormatting", "documentRangeFormatting",
+	  "documentOnTypeFormatting", "rename", "documentLink",
+	  "executeCommand", "pullConfiguration", "typeDefinition",
+	  "implementation", "declaration", "color", "foldingRange",
+	  "selectionRange", "progress", "callHierarchy", "linkedEditing",
+	  "fileEvents", "semanticTokens"]
+<
+	- "formatterPriority": Priority of this languageserver's formatter.
+
+	- "revealOutputChannelOn": Configure message level to show the output
+	  channel buffer.
+
+	- "progressOnInitialization": Enable progress report on languageserver
+	  initialize.
+
+Language server start with command:~
+
+	Additional fields can be used for a command languageserver:
+
+	- "command": Executable program name in $PATH or absolute path of
+	  executable used for start languageserver.
+
+	- "args": Command line arguments of command.
+
+	- "detached": Detach language server when is true.
+
+	- "shell": Use shell for server process, default: `false`
+
+Language server start with module:~
+
+	Additional fields can be used for a languageserver started by node
+	module:
+
+	- "module": Absolute filepath of javascript file.
+
+	- "args": Extra arguments used on fork javascript module.
+
+	- "runtime": Absolute path of node runtime, node runtime of coc.nvim
+	  is used by default.
+
+	- "execArgv": Argv passed to node on fork, normally used for
+	  debugging, example: `["--nolazy", "--inspect-brk=6045"]`
+
+	- "transport": Transport kind used by server, could be 'ipc', 'stdio',
+	  'socket' and 'pipe'. 'ipc' is used by default (recommended).
+
+	- "transportPort": Port number used when transport is 'socket'.
+
+Language server use initialized socket server:~
+
+	- "port": Port number of socket server.
+
+	- "host": Host of socket server, default to `127.0.0.1`.
+
+==============================================================================
+vim:tw=78:nosta:noet:ts=8:sts=0:ft=help:noet:fen:

+ 3534 - 0
vimfiles/bundle/coc.nvim/doc/coc.txt

@@ -0,0 +1,3534 @@
+*coc-nvim.txt*					NodeJS client for Vim & Neovim.
+
+Version: 0.0.82
+Author: Qiming Zhao <chemzqm at gmail.com>
+License: Anti 996 license
+
+CONTENTS					*coc-contents*
+
+Introduction					|coc-introduction|
+Requirements					|coc-requirements|
+Installation					|coc-installation|
+Configuration					|coc-configuration|
+LSP features 					|coc-lsp|
+  Document 					|coc-document|
+  Completion					|coc-completion|
+  Diagnostics 					|coc-diagnostics|
+  Locations 					|coc-locations|
+  Signature help 				|coc-signature|
+  Format 					|coc-format|
+  Code action 					|coc-code-actions|
+  Document highlights 				|coc-document-highlights|
+  Document color 				|coc-document-color|
+  Snippets 					|coc-snippets|
+  Workspace					|coc-workspace|
+  Cursors 					|coc-cursors|
+  Outline 					|coc-outline|
+  Call hierarchy 				|coc-callHierarchy|
+  Semantic highlights 				|coc-semantic-highlights|
+Interface					|coc-interface|
+  Key mappings					|coc-key-mappings|
+  Variables					|coc-variables|
+    Buffer variables 				|coc-buffer-variables|
+    Global variables 				|coc-global-variables|
+  Functions					|coc-functions|
+  Commands					|coc-commands|
+  Autocmds					|coc-autocmds|
+  Highlights					|coc-highlights|
+Tree 						|coc-tree|
+  Tree mappings 				|coc-tree-mappings|
+  Tree filter 					|coc-tree-filter|
+List						|coc-list|
+  List command					|coc-list-command|
+  List command options 				|coc-list-options|
+  List configuration				|coc-list-configuration|
+  List mappings					|coc-list-mappings|
+  list sources					|coc-list-sources|
+Dialog 						|coc-dialog|
+  Dialog basic 					|coc-dialog-basic|
+  Dialog confirm  				|coc-dialog-confirm|
+  Dialog input 					|coc-dialog-input|
+  Dialog menu 					|coc-dialog-menu|
+  Dialog picker                                 |coc-dialog-picker|
+Notification					|coc-notification|	
+Statusline integration				|coc-status|
+  Manual					|coc-status-manual|
+  Airline					|coc-status-airline|
+  Lightline					|coc-status-lightline|
+FAQ						|coc-faq|
+Changelog					|coc-changelog|
+
+==============================================================================
+INTRODUCTION						*coc-introduction*
+
+Coc.nvim enhances your (Neo)Vim to match the user experience provided by
+VSCode through a rich extension ecosystem and implemented features of Language
+Server Protocol (3.16 for now).
+
+Some of its key features include:~
+
+- APIs compatible with both Vim8 and Neovim.
+- Loading VSCode-like extensions.
+- Configuring coc.nvim and its extensions with JSON configuration
+  |coc-configuration|.
+- Configuring Language Servers that using Language Server Protocol (LSP)
+  |coc-config-languageserver|.
+
+It is designed for best possible integration with other Vim plugins.
+
+Note: This plugin doesn't come with support for any specific language. You
+will need to install a coc.nvim extension or set up the language server by
+configuration.
+
+Note: multiple language servers for same document is allowed, but you should
+avoid configure same language server that already used by coc.nvim extension.
+
+Note: Automatic completion plugins can't play nicely together, you can disable
+automatic completion of coc.nvim through `"suggest.autoTrigger": "none"` (or
+`"suggest.autoTrigger": "trigger"`) in your configuration file.
+
+==============================================================================
+REQUIREMENTS						*coc-requirements*
+
+Neovim >= 0.4.0 or Vim >= 8.1.1719.
+
+NodeJS https://nodejs.org/ >= 12.12.0.
+
+Yarn https://yarnpkg.com/ required to build coc.nvim from typescript source
+code.
+
+==============================================================================
+INSTALLATION						*coc-installation*
+
+If you're using [vim-plug](https://github.com/junegunn/vim-plug), add this to
+your `init.vim` or `.vimrc`: >
+
+  Plug 'neoclide/coc.nvim', {'branch': 'release'}
+<
+And run: >
+
+  :PlugInstall
+
+For other plugin managers, make sure to use code from the release branch.
+
+To use Vim's native |packages| on Linux or MaxOS, use script like: >
+
+  #!/bin/sh
+  # for vim8
+  mkdir -p ~/.vim/pack/coc/start
+  cd ~/.vim/pack/coc/start
+  curl --fail -L https://github.com/neoclide/coc.nvim/archive/release.tar.gz|tar xzfv -
+  vim -c 'helptags ~/.vim/pack/coc/start/doc|q'
+
+  # for neovim
+  mkdir -p ~/.local/share/nvim/site/pack/coc/start
+  cd ~/.local/share/nvim/site/pack/coc/start
+  curl --fail -L https://github.com/neoclide/coc.nvim/archive/release.tar.gz|tar xzfv -
+  nvim -c 'helptags ~/.local/share/nvim/site/pack/coc/start|q'
+
+when using source code of coc.nvim, you'll have to install
+https://yarnpkg.com/ and run `yarn install` in project root of coc.nvim.
+
+==============================================================================
+CONFIGURATION						*coc-configuration*
+
+The configuration of coc.nvim is stored in file `coc-settings.json`.
+
+Command |:CocConfig| will open (create when necessary) a user settings
+file in the folder returned by |coc#util#get_config_home()|.
+
+To create a local configuration file for a specific workspace, use
+|:CocLocalConfig|.
+
+The global configuration file can be created in another directory by setting
+`g:coc_config_home` in your `.vimrc` or `init.vim`: >
+
+	let g:coc_config_home = '/path/to/folder'
+
+The configuration files are all in JSON format (with comment supported), it's
+recommended to enable JSON completion and validation by install the `coc-json`
+extension: >
+
+	:CocInstall coc-json
+<
+The user configuration can also be changed by |coc#config()|.
+
+Configurations are composed with builtin configurations and configurations
+contributed by coc extensions, see |coc-config| for builtin configurations.
+
+==============================================================================
+LSP FEATURES 						*coc-lsp*
+
+All features (except for telemetry) of LSP 3.16 are supported, checkout
+the specification at
+https://microsoft.github.io/language-server-protocol/specifications/specification-3-16/
+
+LSP features only works with attached document, see |coc-document-attached|.
+
+To check exists providers of current buffer, use command
+`:CocCommand document.checkBuffer` or |CocHasProvider()|.
+
+For historic reason, some features just works, but some are not.
+
+Features automatically work by default:~
+
+- Trigger completion |coc-completion|.
+- Diagnostics refresh |coc-diagnostics|.
+- Trigger signature help |coc-signature|.
+- Inlay hints (only works with some coc extensions, but not
+  |coc-config-languageserver| yet).
+
+Note all features could be disabled/enabled by |coc-configuration| and some
+vim variables.
+
+Features require enabled by configuration:~
+
+- Semantic highlights |coc-semantic-highlights|.
+- Document color highlights |coc-document-color|.
+- Code lens, enabled by |coc-config-codeLens-enable|.
+- Linked editing, enabled by |coc-preferences-enableLinkedEditing|.
+- Format on type, enabled by |coc-preferences-formatOnType|
+- Format on save, enabled by |coc-preferences-formatOnSaveFiletypes|.
+
+Features requested by user:~
+
+- Locations related (including definitions, references etc.) |coc-locations|
+- Invoke code action |coc-code-actions|.
+- Show call hierarchy tree |coc-callHierarchy|.
+- Format, range format and on type format |coc-format|.
+- Highlight same symbol ranges |coc-document-highlights|.
+- Outline of document symbols |coc-outline| and |coc-list-symbols|.
+- Show hover information |CocAction('doHover')| and |CocAction('definitionHover')|.
+- Rename symbol under cursor |CocAction('rename')|.
+- Open link under cursor |CocAction('openlink')|.
+- Range selection |CocAction('rangeSelect').|
+- Create folds |CocAction('fold')|.
+
+For convenient, some actions have associated |coc-key-mappings| provided.
+Prefer |CocAction()| for more options.
+
+Features triggered by languageserver or extension:~
+
+- Show message notification.
+- Show message request.
+- Log message (use `:CocCommand workspace.showOutput` to show output).
+- Show document request.
+- Work done progress.
+
+To make coc.nvim provide LSP features for your languages, checkout
+https://github.com/neoclide/coc.nvim/wiki/Language-servers
+
+To debug issues with languageserver, checkout
+https://github.com/neoclide/coc.nvim/wiki/Debug-language-server
+
+==============================================================================
+
+DOCUMENT 						*coc-document*
+
+An associated document is created on buffer create, and disposed on buffer
+unload.
+
+Attached document:~
+							*coc-document-attached*
+
+An attached document means coc.nvim synchronize the lines of vim's buffer with
+associated document automatically.
+
+Only attached documents are synchronized with language servers and therefore
+LSP features could be provided for the attached buffer.
+
+The buffer may not be attached by following reasons:
+
+- The 'buftype' is neither <empty> nor 'acwrite'.
+- Buffer variable |b:coc_enabled| is `0`.
+- Byte length of buffer exceed |coc-preferences-maxFileSize|.
+- Buffer is used for command line window.
+
+Use |CocAction('ensureDocument')| or `:CocCommand document.checkBuffer` to
+check attached state of current buffer.
+
+Filetype map:~
+							*coc-document-filetype*
+
+Some filetypes are mapped to others to match the languageId used by VSCode,
+including:
+
+- javascript.jsx -> javascriptreact
+- typescript.jsx -> typescriptreact
+- typescript.tsx -> typescriptreact
+- tex -> latex
+
+Use |g:coc_filetype_map| to create additional filetype maps.
+
+Use `:CocCommand document.echoFiletype` to echo mapped filetype of current
+document.
+
+Note make sure use mapped filetypes for configurations that expect filetypes.
+
+==============================================================================
+COMPLETION						*coc-completion*
+
+The builtin completion of vim is no longer used, the default completion
+behavior works like VSCode:
+
+- Completion is automatically triggered by default.
+- Item selection is enabled by default, use |coc-config-suggest-noselect| to
+  disable default selection.
+- When selection enabled and no preselect item exists, recent used item that
+  matched will be selected by default.
+- Snippet and additional edits only work after confirm completion.
+- 'completeopt' is not used and APIs of builtin popupmenu not work.
+
+Default Key-mappings:~
+
+To make the completion work like builtin completion without configuration,
+following key-mappings are used when the {lhs} is not mapped:
+
+Use <C-n>, <C-p>, <up> and <down> to navigate completion list: >
+
+  inoremap <silent><expr> <C-n> coc#pum#visible() ? coc#pum#next(1) : "\<C-n>"
+  inoremap <silent><expr> <C-p> coc#pum#visible() ? coc#pum#prev(1) : "\<C-n>"
+  inoremap <silent><expr> <down> coc#pum#visible() ? coc#pum#next(0) : "\<down>"
+  inoremap <silent><expr> <up> coc#pum#visible() ? coc#pum#prev(0) : "\<up>"
+<
+Use <PageDown> and <PageUp> to scroll: >
+
+  inoremap <silent><expr> <PageDown> coc#pum#visible() ? coc#pum#scroll(1) : "\<PageDown>"
+  inoremap <silent><expr> <PageUp> coc#pum#visible() ? coc#pum#scroll(0) : "\<PageUp>"
+<
+Use <C-e> and <C-y> to cancel and confirm completion: >
+
+  inoremap <silent><expr> <C-e> coc#pum#visible() ? coc#pum#cancel() : "\<C-e>"
+  inoremap <silent><expr> <C-y> coc#pum#visible() ? coc#pum#confirm() : "\<C-y>"
+
+Note: <CR> and <Tab> are not remapped by coc.nvim.
+>
+Related variables:~
+
+- Disable completion for buffer: |b:coc_suggest_disable|
+- Disable specific sources for buffer: |b:coc_disabled_sources|
+- Disable words for trigger completion: |b:coc_suggest_blacklist|
+- Add additional keyword characters: |b:coc_additional_keywords|
+
+Related functions:~
+
+- Trigger completion with options: |coc#start()|.
+- Trigger completion refresh: |coc#refresh()|.
+- Select and confirm completion: |coc#_select_confirm()|.
+- Check if customized popupmenu is visible: |coc#pum#visible()|.
+- Select next complete item: |coc#pum#next()|.
+- Select previous complete item: |coc#pum#prev()|.
+- Cancel completion and reset trigger text: |coc#pum#cancel()|.
+- Confirm completion: |coc#pum#confirm()|.
+- Close the popupmenu only: |coc#pum#stop()|.
+- Get information of the popupmenu: |coc#pum#info()|.
+- Select specific complete item: |coc#pum#select()|.
+- Insert word of selected item and finish completion: |coc#pum#insert()|.
+- Scroll popupmenu: |coc#pum#scroll()|.
+
+Customize completion:~
+
+Use |coc-config-suggest| to change behavior of completion.
+
+Use 'pumwidth' for configure minimal width of popupmenu and 'pumheight'
+for maximum height.
+
+Related Highlight groups:
+	|CocPum| 	for highlight groups of customized pum.
+	|CocSymbol| 	for kind icons.
+	|CocMenuSel| 	for background highlight of selected item.
+
+Note: background, border and winblend are configured by
+|coc-config-suggest-floatConfig|.
+
+Example user key-mappings:~
+							*coc-completion-example*
+
+Note: use command `:verbose imap` to check current insert
+key-mappings when your key-mappings not work.
+
+Use <tab> and <S-tab> to navigate completion list: >
+
+  function! s:check_back_space() abort
+    let col = col('.') - 1
+    return !col || getline('.')[col - 1]  =~ '\s'
+  endfunction
+
+  " Insert <tab> when previous text is space, refresh completion if not.
+  inoremap <silent><expr> <TAB>
+	\ coc#pum#visible() ? coc#pum#next(1):
+	\ <SID>check_back_space() ? "\<Tab>" :
+	\ coc#refresh()
+  inoremap <expr><S-TAB> coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"
+
+Use <c-space> to trigger completion: >
+
+  if has('nvim')
+    inoremap <silent><expr> <c-space> coc#refresh()
+  else
+    inoremap <silent><expr> <c-@> coc#refresh()
+  endif
+<
+Use <CR> to confirm completion, use: >
+
+  inoremap <expr> <cr> coc#pum#visible() ? coc#_select_confirm() : "\<CR>"
+<
+To make <CR> to confirm selection of selected complete item or notify coc.nvim
+to format on enter, use: >
+
+  inoremap <silent><expr> <CR> coc#pum#visible() ? coc#_select_confirm()
+				\: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
+
+Map <tab> for trigger completion, completion confirm, snippet expand and jump
+like VSCode: >
+
+  inoremap <silent><expr> <TAB>
+    \ coc#pum#visible() ? coc#_select_confirm() :
+    \ coc#expandableOrJumpable() ?
+    \ "\<C-r>=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\<CR>" :
+    \ <SID>check_back_space() ? "\<TAB>" :
+    \ coc#refresh()
+
+  function! s:check_back_space() abort
+    let col = col('.') - 1
+    return !col || getline('.')[col - 1]  =~# '\s'
+  endfunction
+
+  let g:coc_snippet_next = '<tab>'
+<
+Note: the `coc-snippets` extension is required for this to work.
+
+==============================================================================
+DIAGNOSTICS SUPPORT 					*coc-diagnostics*
+
+Diagnostics of coc.nvim are automatically refreshed to UI by default, checkout
+|coc-config-diagnostic| for available configurations.
+
+Note most language servers only send diagnostics for opened buffers for
+performance reason, some lint tools could provide diagnostics for all files in
+workspace.
+
+Note pull diagnostics feature is added in LSP 3.17, which is not available
+yet.
+
+Changes on diagnostics refresh~
+
+- Add highlights for diagnostic ranges and virtual text (when enabled on
+  neovim with virtual text support), see |coc-highlights-diagnostics|.
+- Add diagnostic signs to 'signcolumn', use `set signcolumn=yes` to avoid
+  unnecessary UI refresh.
+- Update variable |b:coc_diagnostic_info|.
+- Refresh related |location-list| which was opened by |:CocDiagnostics|.
+
+Diagnostics are not refreshed when buffer is hidden, and refresh on insert
+mode is disabled by default.
+
+Diagnostics highlights:~
+
+See |coc-highlights-diagnostics|.
+
+Enable and disable diagnostics~
+
+Use |coc-config-diagnostic-enable| to toggle diagnostics feature.
+
+Use |CocAction('diagnosticToggle')| for enable/disable diagnostics of current
+buffer.
+
+Show diagnostic messages~
+
+Diagnostic messages would be automatically shown/hide when the diagnostics
+under cursor position changed (use float window/popup when possible) by
+default.
+
+To manually refresh diagnostics messages, use |<Plug>(coc-diagnostic-info)|
+and |CocAction('diagnosticPreview')|.
+
+Jump between diagnostics~
+
+Use key-mappings:
+
+	|<Plug>(coc-diagnostic-next)| jump to next diagnostic.
+	|<Plug>(coc-diagnostic-prev)| jump to previous diagnostic.
+	|<Plug>(coc-diagnostic-next-error)| jump to next error.
+	|<Plug>(coc-diagnostic-prev-error)| jump to previous error.
+
+Check all diagnostics~
+
+Use |coc-list-diagnostics| to open |coc-list| with all available diagnostics.
+
+Use API |CocAction('diagnosticList')| to get list of all diagnostics.
+
+==============================================================================
+LOCATIONS SUPPORT 					*coc-locations*
+
+There're different kinds of locations, including "definitions", "declarations",
+"implementations", "typeDefinitions" and "references", the languageserver used
+by current document may support some of them.
+
+Key-mappings for invoke locations request~
+
+- |<plug>(coc-definition)|
+- |<plug>(coc-declaration)|
+- |<plug>(coc-implementation)|
+- |<plug>(coc-type-definition)|
+- |<plug>(coc-references)|
+- |<plug>(coc-references-used)|
+
+Error will be shown when the buffer not attached |coc-document-attached|.
+
+Location jump behavior~
+
+When there's only one location returned, the location is opened by command
+specified by |coc-preferences-jumpCommand| ("edit" by default), context mark
+is added by |m'|, so you can jump back previous location by <C-o>.
+
+When multiple locations returned, |coc-list-location| is opened for preview
+and other further actions.
+
+To use |coc-list-location| for single location as well, use
+|coc-locations-api| (instead key-mappings provided by coc.nvim).
+
+To change default options of |coc-list-location| or use other plugin for
+list of locations, see |g:coc_enable_locationlist|.
+
+To use vim's quickfix for locations, use configuration
+|coc-preferences-useQuickfixForLocations|.
+
+To use vim's tag list for definitions, use |CocTagFunc()|.
+
+							*coc-locations-api*
+Related APIs~
+
+APIs for jump locations:
+
+- Jump to definition locations |CocAction('jumpDefinition')|.
+- Jump to declaration locations |CocAction('jumpDeclaration')|.
+- Jump to implementation locations |CocAction('jumpImplementation')|.
+- Jump to type definition locations |CocAction('jumpTypeDefinition')|.
+- Jump to references |CocAction('jumpReferences')| and |CocAction('jumpUsed')|.
+
+APIs for get location list:
+
+- |CocAction('definitions')|
+- |CocAction('declarations')|
+- |CocAction('implementations')|
+- |CocAction('typeDefinitions')|
+- |CocAction('references')|
+
+Send custom locations request to languageserver:
+
+- |CocLocations()|
+- |CocLocationsAsync()|
+
+==============================================================================
+SIGNATURE HELP 						*coc-signature*
+
+Signature help of function is automatically triggered by default(when user
+type trigger characters defined by the provider), which will use float
+window/popup to show the signature messages when possible.
+
+Use |CocAction('showSignatureHelp')| to trigger signature help manually.
+
+Note error will not be thrown when provider not exists or nothing returned
+from languageserver, use `:CocCommand document.checkBuffer` to check provider
+state of current buffer.
+
+Use |coc-config-signature| to change default signature help behavior.
+
+==============================================================================
+FORMAT 							*coc-format*
+
+There're various ways to format document.
+
+Format full document:~
+
+Use |CocAction('format')|, you can create a command like: >
+
+	command! -nargs=0 Format :call CocActionAsync('format')
+<
+to format current buffer.
+
+Format on type:~
+
+Enable format when insert specific characters by configurations:
+
+- |coc-preferences-formatOnType|
+- |coc-preferences-formatOnTypeFiletypes|
+
+requires `onTypeEdit` provider |CocHasProvider|.
+
+Format selected code:~
+
+Use 'formatexpr' for specific filetypes: >
+
+  autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
+
+So that |gq| could works for format range of lines.
+>
+Setup visual mode and operator key-mappings: >
+
+  xmap <leader>f  <Plug>(coc-format-selected)
+  nmap <leader>f  <Plug>(coc-format-selected)
+<
+Format on save:~
+
+Use configuration |coc-preferences-formatOnSaveFiletypes|.
+
+Or create |BufWritePre| autocmd like: >
+
+	autocmd BufWritePre * call CocAction('format')
+<
+Note avoid use |CocActionAsync| with |BufWritePre|.
+
+Format on enter:~
+
+Use |coc#on_enter()| is required to notify coc.nvim the press on enter key.
+
+Configure |coc-preferences-bracketEnterImprove|
+
+==============================================================================
+CODE ACTION 						*coc-code-actions*
+
+Code actions are used for make some specific code changes.
+
+There're different kinds of code actions:
+
+- `quickfix` used for fix diagnostic(s).
+- `refactor` used for code refactor.
+- `source` code actions apply to the entire file.
+- `organizeImport` organize import statements of current document.
+
+Invoke code action~
+
+To fix diagnostic at current line, use |<plug>(coc-fix-current)|.
+
+Key-mappings for choose code action:~
+
+- |<plug>(coc-codeaction-cursor)|
+- |<plug>(coc-codeaction-line)|
+- |<plug>(coc-codeaction)|
+- |<plug>(coc-codeaction-selected)|
+
+|coc-dialog-menu| would be shown for pick specific code action.
+
+To invoke organize import action, use command like:
+>
+	command! -nargs=0 OR :call CocAction('runCommand',
+				\ 'editor.action.organizeImport')
+
+Related APIs~
+
+- |CocAction('codeActions')|
+- |CocAction('organizeImport')|
+- |CocAction('fixAll')|
+- |CocAction('quickfixes')|
+- |CocAction('doCodeAction')|
+- |CocAction('doQuickfix')|
+- |CocAction('codeActionRange')|
+
+==============================================================================
+DOCUMENT HIGHLIGHTS 					*coc-document-highlights*
+
+Document highlights is used for highlight same symbols of current document
+under cusor.
+
+To enable highlight on CursorHold, create an autocmd like this: >
+
+	autocmd CursorHold * silent call CocActionAsync('highlight')
+<
+Checkout |coc-highlights-document| for related highlight groups.
+
+Note error will not be thrown when provider not exists or nothing returned
+from languageserver with |CocAction('highlight')|
+
+Install `coc-highlight` extension if you want to highlight same words under
+cursor without languageserver support.
+
+To jump between previous/next symbol position, use
+`:CocCommand document.jumpToPrevSymbol` and
+`:CocCommand document.jumpToNextSymbol`
+
+==============================================================================
+DOCUMENT COLOR 						*coc-document-color*
+
+Document colors added color highlights to your documents.  To enable document
+color highlights, use ||coc-config-colors-filetypes||.
+
+Install `coc-highlights` to provide document color highlights for all
+filetypes.
+
+To pick a color from system color picker, use |CocAction('pickColor')| or
+choose `editor.action.pickColor` from |:CocCommand|.
+
+Note: may not work on your system.
+
+To change color presentation, use |CocAction('colorPresentation')| or choose
+`editor.action.colorPresentation` from |:CocCommand|.
+
+==============================================================================
+SNIPPETS SUPPORT 					*coc-snippets*
+
+Snippets engine of coc.nvim support both VSCode snippets and ultisnips
+snippets format.
+
+The complete item with snippet format has label ends with `~` by default.
+Select the complete item and confirm the completion by |coc#pum#confirm()| to
+expand the snippet.
+
+A snippet session would be deactivated under the following conditions:
+
+- |InsertEnter| triggered outside snippet.
+- Jump to final placeholder.
+- Content change detected after snippet.
+- Content changed in a snippet outside placeholder (except for deletion of
+  plain text).
+
+To load and expand custom snippets, install `coc-snippets` extension is
+recommended.
+
+Related configurations:~
+
+- |g:coc_snippet_prev|
+- |g:coc_snippet_next|
+- |coc-config-suggest-snippetIndicator|
+- |coc-config-suggest-preferCompleteThanJumpPlaceholder|
+- |coc-preferences-snippetStatusText|
+- |coc-preferences-snippetHighlight|
+
+Related functions:~
+
+- |coc#snippet#next()|
+- |coc#snippet#prev()|
+- |coc#expandable()|
+- |coc#jumpable()|
+- |coc#expandableOrJumpable()|
+
+Related variables, highlights and autocmds:~
+
+- |b:coc_snippet_active|
+- |CocSnippetVisual|
+- |CocJumpPlaceholder|
+
+==============================================================================
+WROKSPACE SUPPORT 					*coc-workspace*
+
+Workspace folders~
+
+Unlike VSCode, workspace folders are resolved from filepath after buffer
+creation.
+
+A list of file/folder names is used for resolve workspace folder, the patterns
+could comes from:
+
+- |b:coc_root_patterns|
+- `rootPatterns` field of configured language server.
+- `rootPatterns` contributions from coc extensions.
+- |coc-preferences-rootPatterns|
+
+Workspace folder is resolved from cwd of vim first and then from top directory
+to the parent directory of current filepath, when workspace folder not
+resolved, current working directory is used if it's parent folder of current
+buffer.  Configurations are provided to change the default behavior:
+
+- |coc-config-workspace-ignoredFiletypes|
+- |coc-config-workspace-ignoredFolders|
+- |coc-config-workspace-bottomUpFiletypes|
+- |coc-config-workspace-workspaceFolderCheckCwd|
+- |coc-config-workspace-workspaceFolderFallbackCwd|
+
+Note for performance reason, user's home directory would never considered as
+workspace folder, which also means the languageserver that requires workspace
+folder may not work when you start vim from home directory.
+
+To preserve workspace folders across vim session, |g:WorkspaceFolders| is
+provided.
+
+To manage current workspace folders, use |coc-list-folders|
+
+To get related root patterns of current buffer, use |coc#util#root_patterns()|
+
+Use `:CocCommand workspace.workspaceFolders` to echo current workspaceFolders.
+
+Workspace edit~
+
+Workspace edit is used to apply changes for multiple buffers(and files), the
+edit could includes document edits and file operations (including file create,
+file/directory delete and file/directory rename).
+
+When the edit failed to apply, coc.nvim will revert the changes (including
+document edits and file operations) that previous made.
+
+Files not loaded would be loaded by `tab drop` command, configured by
+|coc-config-workspace-openResourceCommand|.
+
+To undo and redo workspace edit just applied, use command
+`:CocCommand workspace.undo` and `:CocCommand workspace.redo`
+
+To inspect previous workspace edit, use command
+`:CocCommand workspace.inspectEdit`, in opened buffer, use <CR> for jump to
+change position under cursor.
+
+==============================================================================
+CURSORS SUPPORT						*coc-cursors*
+
+Multiple cursors supported is added to allow edit multiple locations at once.
+
+Cursors session could be started by following ways:
+
+- Use command `:CocCommand document.renameCurrentWord` to rename variable
+  under cursor.
+- Use |<plug>(coc-refactor)| to open refactor buffer.
+- Use |:CocSearch| to open searched locations.
+- Use cursors related key-mappings to add text range, including
+  |<plug>(coc-cursors-operator)|, |<Plug>(coc-cursors-word)|,
+  |<Plug>(coc-cursors-position)| and |<plug>(coc-cursors-range)|
+- Ranges added by command `editor.action.addRanges` from coc extensions.
+
+Default key-mappings when cursors activated:
+
+- <esc> cancel cursors session.
+- <C-n> jump to next cursors range.
+- <C-p> jump to previous cursors range.
+
+Use |coc-config-cursors| to change cursors related key-mappings.
+Use highlight group |CocCursorRange| to change default range highlight.
+Use |b:coc_cursors_activated| to check if cursors session is enabled.
+
+==============================================================================
+SYMBOLS OUTLINE						*coc-outline*
+
+Outline is a split window with current document symbols rendered as
+|coc-tree|.
+
+To show and hide outline of current window, use |CocAction('showOutline')| and
+|CocAction('hideOutline')|.
+
+Outline view has Window variable `cocViewId` set to `OUTLINE`.
+
+Following outline features are supported:
+- Start fuzzy filter by |coc-config-tree-key-activeFilter|.
+- Automatic update after document change.
+- Automatic reload when buffer in current window changed.
+- Automatic follow cursor position by default.
+- Different filter modes that can be changed on the fly
+  |coc-config-outline-switchSortKey|.
+
+Note: outline would try to reload document symbols after 500ms when provider
+not registered, which avoid the necessary to check provider existence.
+
+Checkout |coc-config-tree| and |coc-config-outline| for available
+configurations.
+
+Checkout |CocTree| and |CocSymbol| for customize highlights.
+
+Use configuration `"suggest.completionItemKindLabels"` for custom icons.
+
+To show outline for each tab automatically, use |autocmd|:
+>
+  autocmd VimEnter,Tabnew *
+	  \ if empty(&buftype) | call CocActionAsync('showOutline', 1) | endif
+<
+To close outline when it's the last window automatically, use
+|autocmd| like:
+>
+  autocmd BufEnter * call CheckOutline()
+  function! CheckOutline() abort
+    if &filetype ==# 'coctree' && winnr('$') == 1
+      if tabpagenr('$') != 1
+        close
+      else
+        bdelete
+      endif
+    endif
+  endfunction
+<
+Create a key-mapping to toggle outline, like:
+>
+  nnoremap <silent><nowait> <space>o  :call ToggleOutline()<CR>
+  function! ToggleOutline() abort
+    let winid = coc#window#find('cocViewId', 'OUTLINE')
+    if winid == -1
+      call CocActionAsync('showOutline', 1)
+    else
+      call coc#window#close(winid)
+    endif
+  endfunction
+<
+==============================================================================
+CALL HIERARCHY						*coc-callHierarchy*
+
+A call hierarchy is a splited |coc-tree| with locations for incoming or
+outgoing calls of current function.
+
+Call hierarchy window is opend by |CocAction('showIncomingCalls')| and
+|CocAction('showOutgoingCalls')|.
+
+Call hierarchy is configured by |CocSymbol|, |coc-config-callHierarchy| and
+|coc-config-tree|.
+
+Related ranges are highlighted with |CocSelectedRange| highlight group in
+opend buffer.
+
+|coc-dialog-menu| could be invoked by |coc-config-tree-key-actions|.
+Available actions:
+
+- Dismiss.
+- Open in new tab.
+- Show Incoming Calls.
+- Show Outgoing Calls.
+
+Use <CR> in call hierarchy tree to open location in original window.
+
+==============================================================================
+SEMANTIC HIGHLIGHTS					*coc-semantic-highlights*
+
+Semantic tokens are used to add additional color information to a file that
+depends on language specific symbol information.
+
+Use |coc-config-semanticTokens-filetypes| to enable semantic tokens highlights.
+
+Use `:CocCommand semanticTokens.checkCurrent` to check semantic highlight
+information with current buffer.
+
+To create custom highlights for symbol under cursor, follow these steps:
+
+- Inspect semantic token by
+>
+  :CocCommand semanticTokens.inspect
+<
+  to check token type and token modifiers with current symbol.
+
+- Create new highlight group by |highlight|, for example:
+>
+  :hi link CocSemDeclarationVariable MoreMsg
+<
+- Refresh semantic highlight of current buffer by:
+>
+  :CocCommand semanticTokens.refreshCurrent
+<
+See |CocSem| to customize semantic token highlight groups.
+
+See |coc-config-semanticTokens| for related configurations.
+
+==============================================================================
+INTERFACE						*coc-interface*
+
+------------------------------------------------------------------------------
+
+Key mappings						*coc-key-mappings*
+
+There're some cases that local key-mappings are enabled for current buffer.
+
+	Snippet jump key-mappings when snippet is activated:
+	|g:coc_snippet_prev| and |g:coc_snippet_next|.
+
+	Cursor jump and cancel key-mappings when cursors is activated
+	|coc-config-cursors|.
+
+	Dialog key-mappings for confirm and cancel dialog window
+	|coc-config-dialog|.
+
+	Key-mappings for |CocList| buffer: |coc-list-mappings|.
+
+Note: Use |:verbose| command to check key-mappings that taking effect.
+
+Note: Use 'noremap' with <Plug> will make the key-mapping not work at all.
+
+Note: <Plug> key-mappings are provided for convenient, use |CocActionAsync()| or
+|CocAction()| for more options.
+
+Normal mode key-mappings:~
+
+*<plug>(coc-diagnostic-info)* Show diagnostic message of current position by
+invoke |CocAction('diagnosticInfo')|
+
+*<plug>(coc-diagnostic-next)* Jump to next diagnostic position.
+
+*<plug>(coc-diagnostic-prev)* Jump to previous diagnostic position.
+
+*<plug>(coc-diagnostic-next-error)* Jump to next diagnostic error position.
+
+*<plug>(coc-diagnostic-prev-error)* Jump to previous diagnostic error position.
+
+*<plug>(coc-definition)* Jump to definition(s) of current symbol by invoke
+|CocAction('jumpDefinition')|
+
+*<plug>(coc-declaration)* Jump to declaration(s) of current symbol by invoke
+|CocAction('jumpDeclaration')|
+
+*<plug>(coc-implementation)* Jump to implementation(s) of current symbol by
+invoke |CocAction('jumpImplementation')|
+
+*<plug>(coc-type-definition)* Jump to type definition(s) of current symbol by
+invoke |CocAction('jumpTypeDefinition')|
+
+*<plug>(coc-references)* Jump to references of current symbol by invoke
+|CocAction('jumpReferences')|
+
+*<plug>(coc-references-used)* Jump to references of current symbol exclude
+declarations.
+
+*<plug>(coc-format-selected)*
+
+	Format selected range, works on both |visual-mode| and |normal-mode|,
+	when used in normal mode, the selection works on the motion object.
+
+	For example: >
+
+	vmap <leader>p  <Plug>(coc-format-selected)
+	nmap <leader>p  <Plug>(coc-format-selected)
+<
+	makes `<leader>p` format the visually selected range, and you can use
+	`<leader>pap` to format a paragraph.
+
+*<plug>(coc-format)* Format the whole buffer by invoke |CocAction('format')|
+*<plug>(coc-rename)* Rename symbol under cursor to a new word by invoke
+|CocAction('rename')|
+
+*<plug>(coc-refactor)* Open refactor window for refactor of current symbol by
+invoke |CocAction('refactor')|
+
+*<plug>(coc-command-repeat)* Repeat latest |CocCommand|.
+
+*<plug>(coc-codeaction)* Get and run code action(s) for current file, use
+|coc-codeaction-cursor| for same behavior as VSCode.
+
+*<plug>(coc-codeaction-line)* Get and run code action(s) for current line.
+
+*<plug>(coc-codeaction-cursor)* Get and run code action(s) using empty range
+at current cursor.
+
+*<plug>(coc-codeaction-selected)* Get and run code action(s) with the selected
+region.  Works on both |visual-mode| and |normal-mode|.
+
+*<plug>(coc-openlink)* Open link under cursor by use |CocAction('openlink')|.
+
+*<plug>(coc-codelens-action)* Do command from codeLens of current line.
+
+*<plug>(coc-fix-current)* Try first quickfix action for diagnostics of current
+line.
+
+*<plug>(coc-float-hide)* Hide all float windows/popups created by coc.nvim.
+
+*<plug>(coc-float-jump)* Jump to first float window (neovim only), use
+|CTRL-W_p| for jump to previous window.
+
+*<plug>(coc-range-select)*
+
+	Select next selection range.
+	Works on both |visual-mode| and |normal-mode|.
+
+	Note: requires selection ranges feature of language server.
+
+*<plug>(coc-funcobj-i)*
+
+	Select inside function. Recommend mapping:
+	Works on both |visual-mode| and |normal-mode|.
+  >
+	xmap if <Plug>(coc-funcobj-i)
+	omap if <Plug>(coc-funcobj-i)
+<
+	Note: Requires 'textDocument.documentSymbol' support from the language
+	server.
+
+*<Plug>(coc-funcobj-a)*
+
+	Select around function.  Works on both |visual-mode| and
+	|normal-mode|.  Recommended mapping:
+>
+	xmap af <Plug>(coc-funcobj-a)
+	omap af <Plug>(coc-funcobj-a)
+<
+	Note: Requires 'textDocument.documentSymbol' support from the language
+	server.
+
+*<Plug>(coc-classobj-i)*
+
+	Select inside class/struct/interface.  Works on both |visual-mode| and
+	|normal-mode|.  Recommended mapping:
+>
+	xmap ic <Plug>(coc-classobj-i)
+	omap ic <Plug>(coc-classobj-i)
+<
+	Note: Requires 'textDocument.documentSymbol' support from the language
+	server.
+
+*<plug>(coc-classobj-a)*
+
+	Select around class/struct/interface.  Works on both |visual-mode| and
+	|normal-mode|.  Recommended mapping:
+>
+	xmap ac <Plug>(coc-classobj-a)
+	omap ac <Plug>(coc-classobj-a)
+<
+	Note: Requires 'textDocument.documentSymbol' support from the language
+	server.
+
+
+*<plug>(coc-cursors-operator)* Add text to cursors session by motion object.
+
+*<Plug>(coc-cursors-word)* Add current word to cursors session.
+
+*<Plug>(coc-cursors-position)* Add current position as empty range to cursors
+session.
+
+Visual mode key-mappings:~
+
+*<plug>(coc-range-select-backward)*
+
+	Select previous selection range.
+
+	Note: requires selection ranges feature of language server, like:
+	coc-tsserver, coc-python
+
+*<plug>(coc-cursors-range)* Add selection to cursors session.
+
+------------------------------------------------------------------------------
+VARIABLES						*coc-variables*
+
+User defined variables:~
+
+------------------------------------------------------------------------------
+
+Buffer variables 					*coc-buffer-variables*
+
+b:coc_enabled						*b:coc_enabled*
+
+	Set to `0` on buffer create if you don't want coc.nvim receive content
+	from buffer. Normally used with |BufAdd| autocmd, example:
+>
+	" Disable file with size > 1MB
+	autocmd BufAdd * if getfsize(expand('<afile>')) > 1024*1024 |
+				\ let b:coc_enabled=0 |
+				\ endif
+<
+b:coc_root_patterns					*b:coc_root_patterns*
+
+	Root patterns used for resolving workspaceFolder for
+	the current file, will be used instead of
+	`"coc.preferences.rootPatterns"` setting. Example: >
+
+	autocmd FileType python let b:coc_root_patterns =
+				\ ['.git', '.env']
+<
+
+b:coc_suggest_disable					*b:coc_suggest_disable*
+
+	Disable completion support of current buffer. Example: >
+
+	" Disable completion for python
+	autocmd FileType python let b:coc_suggest_disable = 1
+
+b:coc_disabled_sources 					*b:coc_disabled_sources*
+
+	Disabled completion sources of current buffer. Example:
+>
+	let b:coc_disabled_sources = ['around', 'buffer', 'file']
+<
+b:coc_diagnostic_disable				*b:coc_diagnostic_disable*
+
+	Disable diagnostic support of current buffer.
+
+b:coc_suggest_blacklist                 	        *b:coc_suggest_blacklist*
+
+	List of input words for which completion should not be triggered.
+	Example: >
+
+	" Disable completion for 'end' in lua files
+	autocmd FileType lua let b:coc_suggest_blacklist = ["end"]
+
+b:coc_additional_keywords				*b:coc_additional_keywords*
+
+	Addition keyword characters for generate keywords. Example: >
+
+	" Add keyword characters for css
+	autocmd FileType css let b:coc_additional_keywords = ["-"]
+
+b:coc_trim_trailing_whitespace				*b:coc_trim_trailing_whitespace*
+
+	Trim trailing whitespace on a line, default `0`.
+	Use by "FormattingOptions" send to the server.
+
+b:coc_trim_final_newlines 				*b:coc_trim_final_newlines*
+
+	Trim all newlines after the final newline at the end of the file.
+	Use by "FormattingOptions" send to the server.
+
+	Other buffer options that affect document format: 'eol', 'shiftwidth'
+	and 'expandtab'.
+
+	Note: language server may not respect format options.
+
+------------------------------------------------------------------------------
+
+Global variables 					*coc-global-variables*
+
+g:coc_disable_startup_warning 				*g:coc_disable_startup_warning*
+
+	Disable possible warning on startup for old vim/node version.
+
+	Default: 0
+
+g:coc_disable_uncaught_error 				*g:coc_disable_uncaught_error*
+
+	Disable uncaught error messages from node process of coc.nvim.
+
+	Default: 0
+
+g:coc_text_prop_offset 					*g:coc_text_prop_offset*
+
+	Start |textprop| id offset of highlight namespaces on vim, change to
+	other value to avoid conflict.
+
+	Default: 1000
+
+g:coc_channel_timeout					*g:coc_channel_timeout*
+
+	Channel timeout in seconds for request to node client.
+
+	Default: 30
+
+g:coc_disable_transparent_cursor			*g:coc_disable_transparent_cursor*
+
+	Disable transparent cursor when CocList is activated.
+	Set it to `1` if you have issue with transparent
+	cursor.
+
+	Default: 0
+
+g:coc_start_at_startup					*g:coc_start_at_startup*
+
+	Start coc service on startup, use |CocStart| to start server when you
+	set it to 0.
+
+	Default: 1
+
+g:coc_global_extensions					*g:coc_global_extensions*
+
+	Global extension names to install when they aren't installed.
+>
+	let g:coc_global_extensions = ['coc-json', 'coc-git']
+<
+	Note: coc.nvim will try to install extensions that are not installed
+	in this list after initialization.
+
+g:coc_uri_prefix_replace_patterns			*g:coc_uri_prefix_replace_patterns*
+
+	This map defines URI prefix replacements. This is useful in the case
+	that an LSP requires code to adhere to a particular directory
+	structure. For example, `/Users/myUser/workspace` can be mapped to
+	`/home/myUser/workspace`.
+>
+	let g:coc_uri_prefix_replace_patterns = {'/Users': '/home'}
+<
+g:coc_enable_locationlist				*g:coc_enable_locationlist*
+
+	Use location list of |CocList| when jump to locations.
+
+	Set it to 0 when you need customize behavior of location jump by use
+	|CocLocationsChange| and |g:coc_jump_locations|
+
+	If you want use vim's quickfix list instead, add
+	`"coc.preferences.useQuickfixForLocations": true` in your
+	configuration file, this configuration would be ignored and no autocmd
+	triggered.
+
+	Default: 1
+
+g:coc_snippet_next					*g:coc_snippet_next*
+
+	Trigger key for going to the next snippet position, applied in insert
+	and select mode.
+
+	Only works when snippet session is activated.
+
+	Default: <C-j>
+
+g:coc_snippet_prev					*g:coc_snippet_prev*
+
+	Trigger key for going to the previous snippet position, applied in
+	insert and select mode.
+
+	Only works when snippet session is activated.
+
+	Default: <C-k>
+
+g:coc_filetype_map					*g:coc_filetype_map*
+
+	Map for document filetypes so the server could handle current document
+	as another filetype, example: >
+
+	let g:coc_filetype_map = {
+		\ 'html.swig': 'html',
+		\ 'wxss': 'css',
+		\ }
+<
+	Default: {}
+
+	See |coc-document-filetype| for details.
+
+g:coc_selectmode_mapping				*g:coc_selectmode_mapping*
+
+	Add key mappings for making snippet select mode easier. >
+
+	snoremap <silent> <BS> <c-g>c
+	snoremap <silent> <DEL> <c-g>c
+	snoremap <silent> <c-h> <c-g>c
+	snoremap <c-r> <c-g>"_c<c-r>
+<
+	Default: 1
+
+g:coc_node_path						*g:coc_node_path*
+
+	Path to node executable to start coc service, example: >
+
+	let g:coc_node_path = '/usr/local/opt/node@12/bin/node'
+<
+	Use this when coc has problems with your system node,
+
+	Note: you can use `~` as home directory.
+
+g:coc_node_args						*g:coc_node_args*
+
+	Arguments passed to node when starting coc service from source code.
+
+	Useful for starting coc in debug mode, example: >
+>
+	let g:coc_node_args = ['--nolazy', '--inspect-brk=6045']
+<
+	Default: []
+
+g:coc_status_error_sign					*g:coc_status_error_sign*
+
+	Error character used for statusline, default: `E`
+
+g:coc_status_warning_sign				*g:coc_status_warning_sign*
+
+	Warning character used for statusline, default: `W`
+
+g:coc_quickfix_open_command				*g:coc_quickfix_open_command*
+
+	Command used for open quickfix list.  To jump fist position after
+	quickfix list opend, you can use:
+>
+	let g:coc_quickfix_open_command = 'copen|cfirst'
+<
+	Default: |copen|
+
+g:node_client_debug					*g:node_client_debug*
+
+	Enable debug mode of node client for check rpc messages between vim
+	and coc.nvim.  Use environment variable $NODE_CLIENT_LOG_FILE to set
+	the log file or get the log file after coc.nvim started.
+	To open the log file, use command: >
+
+	:call coc#client#open_log()
+<
+	Default: `0`
+
+g:coc_config_home					*g:coc_config_home*
+
+	Configure the directory which will be used to look for
+	user's `coc-settings.json`, default:
+
+	Windows: `~/AppData/Local/nvim`
+	Other: `~/.config/nvim`
+
+g:coc_data_home						*g:coc_data_home*
+
+	Configure the directory which will be used to for data
+	files(extensions, mru and so on), default:
+
+	Windows: `~/AppData/Local/coc`
+	Other: `~/.config/coc`
+
+g:coc_terminal_height					*g:coc_terminal_height*
+
+	Height of terminal window, default `8`.
+
+g:coc_markdown_disabled_languages  			*g:coc_markdown_disabled_languages*
+
+	Filetype list that should be disabled for highlight in markdown block,
+	Example: >
+
+	let g:coc_markdown_disabled_languages = ['html']
+
+g:coc_highlight_maximum_count 				*g:coc_highlight_maximum_count*
+
+	When highlight items exceed maximum count, highlight items will be
+	grouped and added by using |timer_start| for better user experience.
+
+	Default `100`
+
+g:coc_default_semantic_highlight_groups 		*g:coc_default_semantic_highlight_groups*
+
+	Create default semantic highlight groups for |coc-semantic-highlights|
+
+	Default: `1`
+
+g:coc_max_treeview_width 				*g:coc_max_treeview_width*
+
+	Maximum width of tree view when adjusted by auto width.
+
+	Default: `40`
+
+g:coc_borderchars 					*g:coc_borderchars*
+
+	Border characters used by border window, default to:
+>
+	['─', '│', '─', '│', '┌', '┐', '┘', '└']
+<
+	Note: you may need special font like Nerd font to show them.
+
+g:coc_border_joinchars 					*g:coc_border_joinchars*
+
+	Border join characters used by float window/popup, default to:
+>
+	['┬', '┤', '┴', '├']
+<
+	Note: you may need special font like Nerd font to show them.
+
+g:coc_prompt_win_width 					*g:coc_prompt_win_width*
+
+	Width of input prompt window, default `32`.
+
+							*g:coc_notify*
+g:coc_notify_error_icon 				*g:coc_notify_error_icon*
+
+	Error icon for notification, default to: 
+
+g:coc_notify_warning_icon 				*g:coc_notify_warning_icon*
+
+	Warning icon for notification, default to: ⚠
+
+g:coc_notify_info_icon 					*g:coc_notify_info_icon*
+
+	Info icon for notification, default to: 
+
+------------------------------------------------------------------------------
+
+Some variables are provided by coc.nvim.
+
+
+g:WorkspaceFolders					*g:WorkspaceFolders*
+
+	Current workspace folders, used for restoring from a session file, add
+	`set sessionoptions+=globals` to vimrc for restoring globals on
+	session load.
+
+g:coc_jump_locations					*g:coc_jump_locations*
+
+	This variable would be set to jump locations when the
+	|CocLocationsChange| autocmd is fired.
+
+	Each location item contains:
+
+	'filename': full file path.
+	'lnum': line number (1 based).
+	'col': column number(1 based).
+	'text':  line content of location.
+
+g:coc_process_pid					*g:coc_process_pid*
+
+	Process pid of coc.nvim service. If your vim doesn't kill coc.nvim
+	process on exit, use:
+>
+	autocmd VimLeavePre * if get(g:, 'coc_process_pid', 0)
+		\	| call system('kill -9 '.g:coc_process_pid) | endif
+<
+	in your vimrc.
+
+g:coc_service_initialized	 			*g:coc_service_initialized*
+
+	Is `1` when coc.nvim initialized, used with autocmd |CocNvimInit|.
+
+g:coc_status						*g:coc_status*
+
+	Status string contributed by coc.nvim and extensions, used for status
+	line.
+
+g:coc_last_float_win					*g:coc_last_float_win*
+
+	Window id of latest created float/popup window.
+
+g:coc_last_hover_message				*g:coc_last_hover_message*
+
+	Last message echoed from `doHover`, can be used in statusline.
+
+	Note: not used when floating or preview window used for `doHover`.
+
+b:coc_snippet_active					*b:coc_snippet_active*
+
+	Is `1` when snippet session is activated, use |coc#jumpable| to check
+	if it's possible to jump placeholder.
+
+b:coc_diagnostic_info					*b:coc_diagnostic_info*
+
+	Diagnostic information of current buffer, the format would look like:
+
+	`{'error': 0, 'warning': 0, 'information': 0, 'hint':0}`
+
+	can be used to customize statusline. See |coc-status|.
+
+b:coc_current_function					*b:coc_current_function*
+
+	Function string that current cursor in.
+
+	Set `"coc.preferences.currentFunctionSymbolAutoUpdate": true`
+	in coc-settings.json to update it on CursorHold.
+
+b:coc_cursors_activated					*b:coc_cursors_activated*
+
+	Use expression `get(b:, 'coc_cursors_activated',0)` to check if
+	cursors session is activated for current buffer.
+
+------------------------------------------------------------------------------
+FUNCTIONS						*coc-functions*
+
+Coc functions are normally used by user defined command/keymap or other
+plugins.
+
+Note: some functions only work after the coc service has been initialized.
+
+To run a function on startup, use an autocmd like: >
+
+	autocmd User CocNvimInit call CocAction('runCommand',
+						\ 'tsserver.watchBuild')
+<
+coc#start([{option}]) 					*coc#start()*
+
+	Start completion with optional {option}.  Option could contains:
+
+		- `source` specific completion source name.
+
+	Example:  >
+
+	inoremap <silent> <C-w> <C-R>=coc#start({'source': 'word'})<CR>
+<
+	Use `:CocList sources` to get available sources.
+
+coc#refresh()						*coc#refresh()*
+
+	Start or refresh completion at current cursor position, bind this to
+	'imap' to trigger completion, example: >
+
+	inoremap <silent><expr> <c-space> coc#refresh()
+
+coc#_select_confirm()					*coc#_select_confirm()*
+
+	Select first completion item if no completion item is selected, then
+	confirm the completion.
+
+coc#config({section}, {value})				*coc#config()*
+
+	Change user configuration, overwrite configurations from
+	user config file and default values. Example: >
+
+	call coc#config('coc.preferences', {
+		\ 'timeout': 1000,
+		\})
+	call coc#config('languageserver', {
+		\ 'ccls': {
+		\   "command": "ccls",
+		\   "trace.server": "verbose",
+		\   "filetypes": ["c", "cpp", "objc", "objcpp"]
+		\ }
+		\})
+<
+
+	Note: this function can be called multiple times.
+	Note: this function can be called before coc.nvim started.
+	Note: this function can work alongside the user configuration file,
+	but it's not recommended to use both.
+
+coc#add_extension({name}, ...)				*coc#add_extension()*
+
+	Deprecated function for install extensions not exists.
+	Use |g:coc_global_extensions| variable instead.
+
+	Example: >
+
+	call coc#add_extension('coc-json', 'coc-tsserver', 'coc-rls')
+<
+	This function can be called before service initialized.
+	This function can be called multiple times.
+
+coc#add_command({id}, {command}, [{title}])		*coc#add_command()*
+
+	Add custom Vim command to commands list opened by
+	`:CocList commands` .
+
+	Example: >
+
+	call coc#add_command('mundoToggle', 'MundoToggle',
+		\ 'toggle mundo window')
+<
+coc#expandable()					*coc#expandable()*
+
+	Check if a snippet is expandable at the current position.
+	Requires `coc-snippets` extension installed.
+
+coc#jumpable()						*coc#jumpable()*
+
+	Check if a snippet is jumpable at the current position.
+
+coc#expandableOrJumpable()				*coc#expandableOrJumpable()*
+
+	Check if a snippet is expandable or jumpable at the current position.
+	Requires `coc-snippets` extension installed.
+
+coc#on_enter()						*coc#on_enter()*
+
+	Notify coc.nvim that `<enter>` has been pressed.
+
+	Used for the format on type and improvement of brackets, example: >
+
+	" Confirm the completion when popupmenu is visible, insert <CR> and
+	" notify coc.nvim otherwise.
+	inoremap <silent><expr> <CR> coc#pum#visible() ? coc#pum#confirm()
+                    	          \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
+<
+	Note:to enable format on type, add ` "coc.preferences.formatOnType": true`
+	in your settings file.
+
+coc#status()						*coc#status()*
+
+	Return a status string that can be used in the status line, the status
+	includes diagnostic information from `b:coc_diagnostic_info` and
+	extension contributed statuses from `g:coc_status`. For statusline
+	integration, see |coc-status|
+
+coc#util#api_version() 					*coc#util#api_version()*
+
+	Get coc.nvim's vim api version number, start from `1`.
+
+coc#util#job_command()					*coc#util#job_command()*
+
+	Get the job command used for starting the coc service.
+
+coc#util#get_config_home()				*coc#util#get_config_home()*
+
+	Get the config directory that contains the user's coc-settings.json.
+
+coc#util#get_data_home()				*coc#util#get_data_home()*
+
+	Get `coc` data directory.
+
+coc#util#extension_root()				*coc#util#extension_root()*
+
+	Return extensions root of coc.nvim.
+
+coc#util#rebuild()					*coc#util#rebuild()*
+
+	Run `npm rebuild` for all coc extensions.
+
+coc#util#root_patterns()				*coc#util#root_patterns()*
+
+	Get root patterns used for current document.
+
+	Result could be something like: >
+
+	{'global': ['.git', '.hg', '.projections.json'], 'buffer': [], 'server': v:null}
+<
+coc#util#get_config({key})				*coc#util#get_config()*
+
+	Get configuration (mostly defined in coc-settings.json)	by {key},
+	example: >
+
+	:echo coc#util#get_config('coc.preferences')
+
+coc#snippet#next() 					*coc#snippet#next()*
+
+	Jump to next placeholder, does nothing when |coc#jumpable| is 0.
+
+coc#snippet#prev() 					*coc#snippet#prev()*
+
+	Jump to previous placeholder, does nothing when |coc#jumpable| is 0.
+
+							*coc#pum*
+coc#pum#visible() 					*coc#pum#visible()*
+
+	Check if customized popupmenu is visible.
+
+coc#pum#next({insert}) 					*coc#pum#next()*
+
+	Select next item of customized popupmenu, insert word when {insert} is
+	truth value.
+
+coc#pum#prev({insert}) 					*coc#pum#prev()*
+
+	Select previous item of customized popupmenu, insert word when {insert}
+	is truth value.
+
+coc#pum#stop() 						*coc#pum#stop()*
+	
+	Close the customized popupmenu, works like <C-x><C-z> of vim.
+	Return <Ignore>
+
+coc#pum#cancel() 					*coc#pum#cancel()*
+
+	Cancel the customized popupmenu and revert trigger input, like <C-e>
+	of vim. Return empty string.
+
+coc#pum#confirm() 					*coc#pum#confirm()*
+
+	Confirm completion and close the customized pum, like <C-y> of vim.
+	Return empty string.
+
+coc#pum#info() 						*coc#pum#info()*
+
+	Return information of the customized popupmenu, should only be used
+	when |coc#pum#visible()| is 1.
+
+	Result contains:
+		index 		Current select item index, 0 based.
+		scrollbar 	Non-zero if a scrollbar is displayed.
+		row 		Screen row count, 0 based.
+		col 		Screen column count, 0 based.
+		width 		Width of pum, including padding and border.
+		height 		Height of pum, including padding and border.
+		size 		Count of displayed complete items.
+		inserted 	Is |v:true| when there is item inserted.
+
+coc#pum#select({index}, {insert}, {confirm}) 		*coc#pum#select()*
+
+	Selects an item in the completion popupmenu.
+	Return empty string.
+
+	Parameters:~
+		{index} 	Index (zero-based) of the item to select.
+		{insert} 	Whether the selection should be inserted
+				in the buffer.
+		{confirm} 	Confirm the completion and dismis the
+				popupmenu, implies `insert`.
+
+coc#pum#insert() 					*coc#pum#insert()*
+
+	Insert word of current selected item and finish completion.
+	Timer is used to make it works as rhs of key-mappings.
+
+coc#pum#scroll({forward}) 				*coc#pum#scroll()*
+
+	Scroll the popupmenu forward or backward by page.
+	Timer is used to make it works as rhs of key-mappings.
+	Return empty string.
+
+	Parameters:~
+		{forward} 	Scroll forward when none zero.
+
+							*coc#notify*
+coc#notify#close_all()					*coc#notify#close_all()*
+
+	Close all notification windows.
+
+coc#notify#do_action([{winid}]) 			*coc#notify#do_action()*
+
+	Invoke action for all notification windows, or particular window with
+	winid.
+
+coc#notify#copy() 					*coc#notify#copy()*
+
+	Copy all content from notifications to system clipboard.
+
+coc#notify#show_sources() 				*coc#notify#show_sources()*
+
+	Show source name (extension name) in notification windows.
+
+coc#notify#keep() 					*coc#notify#keep()*
+
+	Stop auto hide timer of notification windows.
+
+coc#float#has_float([{all}]) 				*coc#float#has_float()*
+
+	Check if float window/popup exists, check coc.nvim's float
+	window/popup by default.
+
+coc#float#close_all([{all}])				*coc#float#close_all()*
+
+	Close all float windows/popups created by coc.nvim, set {all} to `1`
+	for all float window/popups.
+
+coc#float#close({winid}) 				*coc#float#close()*
+
+	Close float window/popup with {winid}.
+
+coc#float#has_scroll() 					*coc#float#has_scroll()*
+
+	Return `1` when there is scrollable float window/popup created by
+	coc.nvim.
+
+	Example key-mappings:
+>
+	if has('nvim-0.4.0') || has('patch-8.2.0750')
+	  nnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
+	  nnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
+	  inoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(1)\<cr>" : "\<Right>"
+	  inoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(0)\<cr>" : "\<Left>"
+	  vnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
+	  vnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
+	endif
+<
+coc#float#scroll({forward}, [{amount}])			*coc#float#scroll()*
+
+	Scroll all scrollable float windows/popups, scroll backward when
+	{forward} is not `1`. {amount} could be number or full page when
+	omitted.
+
+	Note: this function requires nvim >= 0.4.0 or vim >= 8.2.750 to work.
+
+
+CocRequest({id}, {method}, [{params}])			*CocRequest()*
+
+	Send a request to language client of {id} with {method} and optional
+	{params}. Example: >
+
+	call CocRequest('tslint', 'textDocument/tslint/allFixes',
+		\  {'textDocument': {'uri': 'file:///tmp'}})
+<
+	Vim error will be raised if the response contains an error.
+
+							*CocRequestAsync()*
+
+CocRequestAsync({id}, {method}, [{params}, [{callback}]])
+
+	Send async request to remote language server.
+	{callback} function is called with error and response.
+
+CocNotify({id}, {method}, [{params}])			*CocNotify()*
+
+	Send notification to remote language server, example:
+>
+	call CocNotify('ccls', '$ccls/reload')
+<
+							*CocRegistNotification()*
+
+CocRegistNotification({id}, {method}, {callback})
+
+	Register notification callback for specified client {id} and {method},
+	example: >
+
+	autocmd User CocNvimInit call CocRegistNotification('ccls',
+		\ '$ccls/publishSemanticHighlight', function('s:Handler'))
+<
+	{callback} is called with single param as notification result.
+
+	Note: when register notification with same {id} and {method}, only the
+	later registered would work.
+
+							*CocLocations()*
+
+CocLocations({id}, {method}, [{params}, {openCommand}])
+
+	Send location request to language client of {id} with
+	{method} and optional {params}. eg: >
+
+	call CocLocations('ccls', '$ccls/call',  {'callee': v:true})
+
+	call CocLocations('ccls', '$ccls/call',  {}, 'vsplit')
+<
+	{openCommand}: optional command to open buffer, default to
+	`coc.preferences.jumpCommand` , |:edit| by default.  When it's
+	`v:false` locations list would always used.
+
+							*CocLocationsAsync()*
+
+CocLocationsAsync({id}, {method}, [{params}, {openCommand}])
+
+	Same as |CocLocations()|, but send notification to server instead
+	of request.
+
+
+CocAction({action}, [...{args}])			*CocAction()*
+
+	Run {action} of coc with optional extra {args}.
+
+	Checkout |coc-actions| for available actions.
+
+	Note: it's recommended to use |CocActionAsync()| unless you have to
+	block your vim.
+
+							*CocActionAsync()*
+
+CocActionAsync({action}, [...{args}, [{callback}]])
+
+	Call CocAction by send notification to server of coc.nvim.
+
+	Optional callback is called with `error` as the first argument and
+	`response` as the second argument.
+
+	Checkout |coc-actions| for available actions.
+
+CocHasProvider({feature})				*CocHasProvider()*
+
+	Check if provider exists for specified feature of current buffer.
+	Supported features:
+
+	`rename` `onTypeEdit` `documentLink` `documentColor` `foldingRange`
+	`format` `codeAction` `workspaceSymbols` `formatRange` `hover`
+	`signature` `documentSymbol` `documentHighlight` `definition`
+	`declaration` `typeDefinition` `reference` `implementation` `codeLens`
+	`selectionRange`
+
+CocTagFunc({pattern}, {flags}, {info})			*CocTagFunc()*
+
+	Used for vim's 'tagfunc' option, to make tag search by |CTRL-]| use
+	coc.nvim as provider, tag search would be performed when no result
+	from coc.nvim.
+
+	Make sure your vim support 'tagfunc' by
+>
+	:echo exists('&tagfunc')
+<
+------------------------------------------------------------------------------
+							*coc-actions*
+Available Actions ~
+
+Acceptable {action} names for |CocAction()| and |CocActionAsync()|.
+
+"ensureDocument" 					*CocAction('ensureDocument')*
+
+	Ensure current document is attached to coc.nvim
+	|coc-document-attached|, should be used when you need invoke action of
+	current document on buffer create.
+
+	Return |v:false| when document can't be attached.
+
+"diagnosticList"					*CocAction('diagnosticList')*
+
+	Get all diagnostic items of the current Neovim session.
+
+"diagnosticInfo"					*CocAction('diagnosticInfo')*
+
+	Show diagnostic message at the current position, do not truncate.
+
+"diagnosticToggle" [{enable}]	 			*CocAction('diagnosticToggle')*
+
+	Enable/disable diagnostics on the fly, not work when `displayByAle` is
+	enabled. You can toggle by specifying {enable}. {enable} can be 0 or 1
+
+"diagnosticPreview"					*CocAction('diagnosticPreview')*
+
+	Show diagnostics under current cursor in preview window.
+
+"diagnosticRefresh" [{bufnr}] 				*CocAction('diagnosticRefresh')*
+
+	Force refresh diagnostics for special buffer with {bufnr} or all buffers
+	when {bufnr} doesn't exist, returns `v:null` before diagnostics are shown.
+
+	NOTE: Will refresh in any mode.
+
+	Useful when `diagnostic.autoRefresh` is `false`.
+
+"refreshSource" [{source}]				*CocAction('refreshSource')*
+
+	refresh all sources or a source with a name of {source}.
+
+"sourceStat"						*CocAction('sourceStat')*
+
+	get the list of completion source stats for the current buffer.
+
+"toggleSource" {source}					*CocAction('toggleSource')*
+
+	enable/disable {source}.
+
+"definitions" 						*CocAction('definitions')*
+
+	Get definition locations of symbol under cursor.
+	Return LSP `Location[]`
+
+"declarations" 						*CocAction('declarations')*
+
+	Get declaration location(s) of symbol under cursor.
+	Return LSP `Location | Location[] | LocationLink[]`
+
+"implementations" 					*CocAction('implementations')*
+
+	Get implementation locations of symbol under cursor.
+	Return LSP `Location[]`
+
+"typeDefinitions" 					*CocAction('typeDefinitions')*
+
+	Get type definition locations of symbol under cursor.
+	Return LSP `Location[]`
+
+"references" [{excludeDeclaration}] 			*CocAction('references')*
+
+	Get references location list of symbol under cursor.
+
+	{excludeDeclaration}: exclude declaration locations when not zero.
+
+	Return LSP `Location[]`
+
+"jumpDefinition" [{openCommand}]			*CocAction('jumpDefinition')*
+
+	jump to definition locations of the current symbol.
+	Return `v:false` when location not found.
+
+	|coc-list-location| is used when more than one position is available,
+	for custom location list, use variable: |g:coc_enable_locationlist|.
+
+	To always use |coc-list-location|| for locations, use `v:false` for
+	{openCommand}.
+
+	{openCommand}: optional command to open buffer, default to
+	`coc.preferences.jumpCommand` in `coc-settings.json`
+
+"jumpDeclaration" [{openCommand}]			*CocAction('jumpDeclaration')*
+
+	jump to declaration locations of the current symbol.
+	Return `v:false` when location not found.
+
+	same behavior as "jumpDefinition".
+
+	When {openCommand} is `v:false`, location list would be always used.
+
+"jumpImplementation" [{openCommand}]			*CocAction('jumpImplementation')*
+
+	Jump to implementation locations of the current symbol.
+	Return `v:false` when location not found.
+
+	same behavior as "jumpDefinition"
+
+"jumpTypeDefinition" [{openCommand}]			*CocAction('jumpTypeDefinition')*
+
+	Jump to type definition locations of the current symbol.
+	Return `v:false` when location not found.
+
+	same behavior as "jumpDefinition"
+
+"jumpReferences" [{openCommand}]			*CocAction('jumpReferences')*
+
+	Jump to references locations of the current symbol, use
+	|CocAction('jumpUsed')| to exclude declaration locations.
+
+	Return `v:false` when location not found.
+
+	same behavior as "jumpDefinition"
+
+"jumpUsed" [{openCommand}] 				*CocAction('jumpUsed')*
+
+	Jump references locations withtout declarations.
+
+	same behavior as "jumpDefinition"
+
+"getHover"						*CocAction('getHover')*
+
+	Get documentation text array on current position, returns array of
+	string.
+
+"doHover" [{hoverTarget}]				*CocAction('doHover')*
+
+	Show documentation of  current symbol, return `v:false` when hover not
+	found.
+
+	{hoverTarget}: optional specification for where to show hover info,
+	defaults to `coc.preferences.hoverTarget` in `coc-settings.json`.
+	Valid options: ["preview", "echo", "float"]
+
+"definitionHover" [{hoverTarget}]			*CocAction('definitionHover')*
+
+	Same as |CocAction('doHover')|, but includes definition contents from
+	definition provider when possible.
+
+"showSignatureHelp"					*CocAction('showSignatureHelp')*
+
+	Echo signature help of current function, return `v:false` when
+	signature not found.  You may want to set up an autocmd like this: >
+
+	autocmd User CocJumpPlaceholder call
+				\ CocActionAsync('showSignatureHelp')
+<
+"getCurrentFunctionSymbol"				*CocAction('getCurrentFunctionSymbol')*
+
+	Return the function string that current cursor in.
+
+"documentSymbols" [{bufnr}]				*CocAction('documentSymbols')*
+
+	Get a list of symbols of current buffer or specific {bufnr}.
+
+"rename"						*CocAction('rename')*
+
+	Rename the symbol under the cursor position, user will be prompted for
+	a new name.
+
+	Note: coc.nvim supports rename for disk files, but your language server
+	may not.
+
+"refactor"						*CocAction('refactor')*
+
+	Open refactor windows with current symbol as activated cursor ranges.
+	Check |coc-config-cursors| and |coc-config-refactor| for related
+	configuration.
+
+	Use <CR> to open buffer at current position in split window.
+	Use <Tab> to show action menu which have tab open and remove actions.
+
+"format"						*CocAction('format')*
+
+	Format current buffer using the language server.
+	Return `v:false` when format failed.
+
+"formatSelected" [{mode}]				*CocAction('formatSelected')*
+
+	Format the selected range, {mode} should be one of visual mode: `v` ,
+	`V`, `char`, `line`.
+
+	When {mode} is omitted, it should be called using |formatexpr|.
+
+
+"selectionRanges"					*CocAction('selectionRanges')*
+
+	Get selection ranges of current position from language server.
+
+"services"						*CocAction('services')*
+
+	Get an information list for all services.
+
+"toggleService" {serviceId}				*CocAction('toggleService')*
+
+	Start or stop a service.
+
+"codeAction" [{mode}] [{only}]				*CocAction('codeAction')*
+
+	Prompt for a code action and do it.
+
+	{mode} could be `line` or `cursor` or result of |visualmode()|,
+	current buffer range is used when it's empty string.
+
+	{only} can be title of a codeAction or list of CodeActionKind.
+
+"codeActionRange" {start} {end} [{kind}]		*CocAction('codeActionRange')*
+
+	Run code action for range.
+
+	{start} 	Start line number of range.
+	{end} 		End line number of range.
+	{kind} 		Code action kind, see |CocAction('codeActions')| for available
+			action kind.
+
+	Can be used to create commands like: >
+
+	command! -nargs=* -range CocAction :call CocActionAsync('codeActionRange', <line1>, <line2>, <f-args>)
+	command! -nargs=* -range CocFix    :call CocActionAsync('codeActionRange', <line1>, <line2>, 'quickfix')
+<
+"codeLensAction"					*CocAction('codeLensAction')*
+
+	Invoke the command for codeLens of current line (or the line that
+	contains codeLens just above). Prompt would be shown when multiple
+	actions are available.
+
+"commands"						*CocAction('commands')*
+
+	Get a list of available service commands for the current buffer.
+
+"runCommand" [{name}] [...{args}]			*CocAction('runCommand')*
+
+	Run a global command provided by the language server. If {name} is not
+	provided, a prompt with a list of commands is shown to be selected.
+
+	{args} are passed as arguments of command.
+
+	You can bind your custom command like so: >
+
+	command! -nargs=0 OrganizeImport
+		\ :call CocActionAsync('runCommand', 'tsserver.organizeImports')
+
+"fold" {{kind}}						*CocAction('fold')*
+
+	Fold the current buffer, optionally use {kind} for filtering folds,
+	{kind} could be either 'comment', 'imports' or 'region'
+
+	Return `v:false` when failed.
+
+"highlight"						*CocAction('highlight')*
+
+	Highlight the symbols under the cursor.
+
+"openLink" [{command}]					*CocAction('openlink')*
+
+	Open a link under the cursor with {command}.
+	{command} default to `edit`.
+
+	File and URL links are supported, return `v:false` when failed.
+
+	Uri under cursor is searched when no link returned from documentLink
+	provider.
+
+"extensionStats"					*CocAction('extensionStats')*
+
+	Get all extension states as a list. Including `id`, `root` and
+	`state`.
+
+	State could be `disabled`, `activated` and `loaded`.
+
+"toggleExtension" {id}					*CocAction('toggleExtension')*
+
+	Enable/disable an extension.
+
+"uninstallExtension" {id}				*CocAction('uninstallExtension')*
+
+	Uninstall an extension.
+
+"reloadExtension" {id}					*CocAction('reloadExtension')*
+
+	Reload an activated extension.
+
+"activeExtension" {id}					*CocAction('activeExtension')*
+
+	Activate extension of {id}.
+
+"deactivateExtension" {id}				*CocAction('deactivateExtension')*
+
+	Deactivate extension of {id}.
+
+"pickColor"						*CocAction('pickColor')*
+
+	Change the color at the current cursor position, requires
+	`documentColor` provider |CocHasProvider|.
+
+	Note: only works on mac or when you have python support on Vim and
+	have the gtk module installed.
+
+"colorPresentation"					*CocAction('colorPresentation')*
+
+	Change the color presentation at the current color position, requires
+	`documentColor` provider |CocHasProvider|.
+
+"codeActions" [{mode}] [{only}]				*CocAction('codeActions')*
+
+	Get codeActions list of current document.
+
+	{mode} can be result of |visualmode()| for visual selected
+	range.  When it's falsy value, current file is used as range.
+
+	{only} can be array of codeActionKind, possible values including:
+	 - 'refactor': Base kind for refactoring actions
+	 - 'quickfix': base kind for quickfix actions
+	 - 'refactor.extract': Base kind for refactoring extraction actions
+	 - 'refactor.inline': Base kind for refactoring inline actions
+	 - 'refactor.rewrite': Base kind for refactoring rewrite actions
+	 - 'source': Base kind for source actions
+	 - 'source.organizeImports': Base kind for an organize imports source
+	   action
+	 - 'source.fixAll': Base kind for auto-fix source actions
+
+	{only} can also be string, which means filter by tilte of codeAction.
+
+"organizeImport" 					*CocAction('organizeImport')*
+
+	Run organize import codeAction for current buffer.
+	Show warning when codeAction not found.
+
+"fixAll" 						*CocAction('fixAll')*
+
+	Run fixAll codeAction for current buffer.
+	Show warning when codeAction not found.
+
+
+"quickfixes" [{visualmode}]				*CocAction('quickfixes')*
+
+	Get quickfix codeActions of current buffer.
+
+	Add {visualmode} as second argument get quickfix actions with range of
+	latest |visualmode()|
+
+"doCodeAction" {codeAction}				*CocAction('doCodeAction')*
+
+	Do a codeAction.
+
+"doQuickfix"						*CocAction('doQuickfix')*
+
+	Do the first preferred quickfix action on current line.
+
+	Throw error when no quickfix action found.
+
+"addRanges" {ranges}					*CocAction('addRanges')*
+
+	Ranges must be provided as array of range type: https://git.io/fjiEG
+
+"getWordEdit"						*CocAction('getWordEdit')*
+
+	Get workspaceEdit of current word, language server used when possible,
+	extract word from current buffer as fallback.
+
+"getWorkspaceSymbols" {input}				*CocAction('getWorkspaceSymbols')*
+
+	Get workspace symbols from {input}.
+
+"resolveWorkspaceSymbol" {symbol} 			*CocAction('resolveWorkspaceSymbol')*
+
+	Resolve location for workspace {symbol}.
+
+"diagnosticToggleBuffer" [{bufnr}] [{enable}] 		*CocAction('diagnosticToggleBuffer')*
+
+	Toggle diagnostics for specific buffer, current buffer is used when
+	{bufnr} not provided. 0 for current buffer
+	You can toggle by specifying {enable}. {enable} can be 0 or 1
+
+	Note: this will only affect diagnostics shown in the UI, list of all
+	diagnostics won't change.
+
+"showOutline" [{keep}]					*CocAction('showOutline')*
+
+	Show |coc-outline| for current buffer. Does nothing when outline
+	window already shown for current buffer.
+
+	{keep} override `"outline.keepWindow"` configuration when specified.
+	Could be 0 or 1.
+
+	Returns after window is shown (document symbol request is still in
+	progress).
+
+"hideOutline" 						*CocAction('hideOutline')*
+
+	Close |coc-outline| on current tab.  Throws vim error when it can't
+	be closed by vim.
+
+"incomingCalls" [{CallHierarchyItem}] 			*CocAction('incomingCalls')*
+
+	Retrieve incoming calls from {CallHierarchyItem} or current position
+	when not provided.
+
+"outgoingCalls" [{CallHierarchyItem}] 			*CocAction('outgoingCalls')*
+
+	Retrieve outgoing calls from {CallHierarchyItem} or current position
+	when not provided.
+
+"showIncomingCalls"  					*CocAction('showIncomingCalls')*
+
+	Show incoming calls of current function with |coc-tree|, see
+	|coc-callHierarchy|
+
+"showOutgoingCalls"  					*CocAction('showOutgoingCalls')*
+
+	Show outgoing calls of current function with |coc-tree|.
+
+"semanticHighlight" 					*CocAction('semanticHighlight')*
+
+	Request semantic tokens highlight for current buffer.
+
+"inspectSemanticToken" 					*CocAction('inspectSemanticToken')*
+
+	Inspect semantic token information at cursor position.
+
+"rangeSelect" {visualmode} {forward} 		 	*CocAction('rangeSelect')*
+
+	Visual select previous or next code range, requires `selectionRange`
+	provider.
+
+	{visualmode} should be result of {visualmode} or "" for current cursor
+	position.
+	{forward} select backward when it's falsy value.
+
+------------------------------------------------------------------------------
+COMMANDS						*coc-commands*
+
+:CocStart						*:CocStart*
+
+	Start the coc.nvim server, do nothing if it's already started.
+
+:CocRestart						*:CocRestart*
+
+	Restart coc.nvim service.
+
+	Use this command when you want coc to start all over again.
+
+:CocDisable						*:CocDisable*
+
+	Disable handling vim events.
+
+:CocEnable						*:CocEnable*
+
+	Enable handling vim events.
+
+:CocConfig						*:CocConfig*
+
+	Edit the user config file `.vim/coc-settings.json` in
+	|coc#util#get_config_home()|
+
+:CocLocalConfig						*:CocLocalConfig*
+
+	Edit or create `.vim/coc-settings.json` in current workspace folder.
+
+:CocInstall [{option}] {name} ...			*:CocInstall*
+
+	Install one or more coc extensions.
+
+	{option}: could be `-sync` for use blocked process to download instead
+	of terminal.
+
+	Examples: >
+
+	" Install latest coc-omni
+	:CocInstall coc-omni
+	" Install coc-omni 1.0.0
+	:CocInstall coc-omni@1.0.0
+	" Install snippet extension from github
+	:CocInstall https://github.com/dsznajder/vscode-es7-javascript-react-snippets
+>
+:CocUninstall {name}					*:CocUninstall*
+
+	Uninstall an extension, use <tab> to complete the extension
+	name.
+
+:CocUpdate						*:CocUpdate*
+
+	Update all coc extensions to the latest version.
+
+:CocUpdateSync						*:CocUpdateSync*
+
+	Block version of update coc extensions.
+
+:CocRebuild						*:CocRebuild*
+
+	Run `npm rebuild` for coc extensions.
+
+	May be required when environment nodejs get upgraded.
+
+:CocCommand {name} [{args}] ... 			*:CocCommand*
+
+	Run a command contributed by extensions, use `<tab>` for name
+	completion.
+
+:CocOpenLog						*:CocOpenLog*
+
+	Open log file of coc.nvim.
+
+	Use environmental variable `NVIM_COC_LOG_FILE` for fixed log file.
+	Note: the log would be cleared when coc.nvim started.
+
+	Use environment variable `NVIM_COC_LOG_LEVEL` to change log level
+	(default 'info', could be 'all', 'trace', 'debug', 'info',
+	'warn', 'error', 'off').
+	Use shell command: >
+
+	export NVIM_COC_LOG_LEVEL=debug
+<
+	or add: >
+
+	let $NVIM_COC_LOG_LEVEL='debug'
+<
+	to the beginning of your `.vimrc`
+
+:CocInfo						*:CocInfo*
+
+	Show version and log information in a split window, useful for
+	submitting a bug report.
+
+:CocDiagnostics	[height] 				*:CocDiagnostics*
+
+	Open vim's |location-list| with diagnostics of current buffer.
+
+:CocSearch 						*:CocSearch*
+
+	Perform search by ripgrep https://github.com/BurntSushi/ripgrep,
+	refactor window would be opened.
+
+	Note: the search is performed on your files, so normally you should
+	save your buffers before invoke this command.
+
+	Common arguments for ripgrep:~
+
+	`-e` `--regexp`: treat search pattern as regexp.
+	`-F` `--fixed-strings`: treat search pattern as fixed string.
+	`-L` `--follow`: follow symbolic links while traversing directories.
+	`-g` `--glob` {GLOB}: Include or exclude files and directories for
+	searching that match the given glob.
+	`--hidden`: Search hidden files and directories.
+	`--no-ignore-vcs`:  Don't respect version control ignore files
+	(.gitignore, etc.).
+	`--no-ignore`: Don't respect ignore files (.gitignore, .ignore, etc.).
+	`-w` `--word-regexp`: Only show matches surrounded by word boundaries.
+	`-S` `--smart-case`: Searches case insensitively if the pattern is all
+	lowercase. Search case sensitively otherwise.
+	`--no-config`: Never read configuration files.
+	`-x` `--line-regexp`: Only show matches surrounded by line boundaries.
+
+	Use `:man 1 rg` in your terminal for more details.
+
+	Note: By default, hidden files and directories are skipped.
+
+	Note: By default, vcs ignore files including `.gitignore` and
+	`.ignore` are respected
+
+	Escape arguments:~
+
+	|<f-args>| is used to convert command line arguments to arguments of
+	rg, which means you have to escape space for single argument. For
+	example, if you want to search `import { Neovim` , you have to use:
+>
+	:CocSearch import\ \{\ Neovim
+<
+	The escape for `{` is required because rg use regexp be default, or:
+>
+	:CocSearch -F import\ {\ Neovim
+<
+	for strict match.
+
+	Change and save:~
+
+	Refactor session is started with searched patterns highlighted, just
+	change the text and save refactor buffer to make changes across all
+	related files. You can make any kind of changes, including add lines
+	and remove lines.
+
+:CocWatch [extension] 					*:CocWatch*
+
+	Watch loaded [extension] for reload on file change, use <tab> for
+	complete extension id.
+
+:CocOutline 						*:CocOutline*
+
+	Invoke |CocAction('showOutline')| by notification.
+
+------------------------------------------------------------------------------
+AUTOCMD							*coc-autocmds*
+
+							*CocLocationsChange*
+
+:autocmd User CocLocationsChange {command}
+
+	For building a custom view of locations, set
+	|g:coc_enable_locationlist| to 0 and use this autocmd with with
+	|g:coc_jump_locations|
+
+	For example, to disable auto preview of location list, use:
+>
+	let g:coc_enable_locationlist = 0
+	autocmd User CocLocationsChange CocList --normal location
+<
+							*CocNvimInit*
+:autocmd User CocNvimInit {command}
+
+	Triggered after the coc services have started.
+
+	If you want to trigger an action of coc after Vim has started, this
+	autocmd should be used because coc is always started asynchronously.
+
+							*CocStatusChange*
+
+:autocmd User CocStatusChange {command}
+
+	Triggered after `g:coc_status` changed, can be used for refresh
+	stautsline.
+
+							*CocDiagnosticChange*
+
+:autocmd User CocDiagnosticChange {command}
+
+	Triggered after the diagnostic status has changed.
+
+	Could be used for updating the statusline.
+
+							*CocJumpPlaceholder*
+
+:autocmd User CocJumpPlaceholder {command}
+
+	Triggered after a jump to a placeholder. Can be used for
+	showing signature help like: >
+
+	autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
+<
+							*CocOpenFloat*
+
+:autocmd User CocOpenFloat {command}
+
+	Triggered when a floating window is opened.  The window is not
+	focused, use |g:coc_last_float_win| to get window id.
+
+							*CocOpenFloatPrompt*
+
+:autocmd User CocOpenFloatPrompt {command}
+
+	Triggered when a floating prompt window is opened (triggered after
+	CocOpenFloat).
+
+							*CocTerminalOpen*
+:autocmd User CocTerminalOpen {command}
+
+	Triggered when the terminal is shown, can be used for adjusting the
+	window height.
+
+------------------------------------------------------------------------------
+
+HIGHLIGHTS						*coc-highlights*
+
+To customize a highlight, simply use |:highlight| command in your vimrc, like:
+>
+	" make error texts have a red color
+	highlight CocErrorHighlight ctermfg=Red  guifg=#ff0000
+<
+Type |:highlight| command with group name to check current highlight.
+
+Note: don't use `:hi default` for overwriting the highlights.
+
+Note: user defined highlight commands should appear after the |:colorscheme|
+command and use |ColorScheme| autocmd to make sure customized highlights works
+after color scheme change.
+
+Markdown related~
+
+*CocBold* for bold text.
+*CocItalic* for italic text.
+*CocUnderline* for underlined text.
+*CocStrikeThrough* for strikethrough text, like usage of deprecated API.
+*CocMarkdownCode* for inline code in markdown content.
+*CocMarkdownHeader* for markdown header in floating window/popup.
+*CocMarkdownLink* for markdown link text in floating window/popup.
+
+Diagnostics related~
+							*coc-highlights-diagnostics*
+
+*CocFadeOut* for faded out text, such as for highlighting unnecessary code.
+*CocErrorSign* for error signs.
+*CocWarningSign* for warning signs.
+*CocInfoSign* for information signs.
+*CocHintSign* for hint signs.
+*CocErrorVirtualText* for error virtual text.
+*CocWarningVirtualText* for warning virtual text.
+*CocInfoVirtualText* for information virtual text.
+*CocHintVirtualText* for hint virtual text.
+*CocErrorHighlight* for error code range.
+*CocWarningHighlight* for warning code range.
+*CocInfoHighlight* for information code range.
+*CocHintHighlight* for hint code range.
+*CocDeprecatedHighlight* for deprecated code range, links to
+|CocStrikeThrough| by default.
+*CocUnusedHighlight* for unnecessary code range, links to |CocFadeOut| by
+default.
+*CocErrorLine* line highlight of sign which contains error.
+*CocWarningLine* line highlight of sign which contains warning.
+*CocInfoLine* line highlight of sign which information.
+*CocHintLine* line highlight of sign which contains hint.
+
+Highlight with higher priority would overwrite highlight with lower priority.
+The priority order:
+
+	|CocUnusedHighlight| > |CocDeprecatedHighlight| > |CocErrorHighlight|
+	> |CocWarningHighlight| > |CocInfoHighlight| > |CocHintHighlight|
+
+Document highlight related~
+							*coc-highlights-document*
+
+Highlights used for highlighting same symbols in the buffer at the current
+cursor position.
+
+*CocHighlightText* default symbol highlight.
+*CocHighlightRead* for `Read` kind of document symbol.
+*CocHighlightWrite* for `Write` kind of document symbol.
+
+Float window/popup related~
+
+*CocFloating* default highlight group of floating windows/popups.
+Default link to |NormalFloat| on neovim and|`Pmenu| on vim.
+*CocErrorFloat* for errors in floating windows/popups.
+*CocWarningFloat* for warnings in floating windows/popups.
+*CocInfoFloat* for infos in floating windows/popups.
+*CocHintFloat* for hints in floating windows/popups.
+
+Notification window/popup related~
+
+CocNotification 					*CocNotification*
+
+*CocNotificationProgress* for progress line in progress notification.
+*CocNotificationButton* for action buttons in notification window.
+*CocNotificationError* for highlight border of error notification.
+*CocNotificationWarning* for highlight border of warning notification.
+*CocNotificationInfo* for highlight border of info notification.
+
+List related~
+							*coc-highlights-list*
+
+*CocListLine* for current cursor line.
+*CocListSearch* for matched characters.
+*CocListMode* for mode text in the statusline.
+*CocListPath* for cwd text in the statusline.
+*CocSelectedText* for sign text of selected lines (multiple selection only).
+*CocSelectedLine* for line highlight of selected lines (multiple selection only).
+
+Tree view related~
+
+CocTree 						*CocTree*
+
+*CocTreeTitle* for title in tree view.
+*CocTreeDescription* for description beside label.
+*CocTreeOpenClose* for open and close icon in tree view.
+*CocTreeSelected* for highlight lines contains selected node.
+
+Popup menu related~
+							*CocPum*
+*CocPumSearch* for matched input characters, linked to |CocSearch| by default.
+*CocPumMenu* for menu of complete item.
+*CocPumShortcut* for shortcut text of source.
+*CocPumDeprecated* for deprecated label.
+*CocPumVirtualText* for virtual text which enabled by
+|coc-config-suggest-virtualText|
+
+Symbol icons~
+
+CocSymbol 						*CocSymbol*
+
+Highlight groups for symbol icons, including `CompletionItemKind` and
+`SymbolKind` of LSP.  The highlight groups link to related |nvim-treesitter|
+highlight groups when possible and fallback to builtin highlight groups.
+
+*CocSymbolDefault* linked to |hl-MoreMsg| by default.
+*CocSymbolText*
+*CocSymbolUnit*
+*CocSymbolValue*
+*CocSymbolKeyword*
+*CocSymbolSnippet*
+*CocSymbolColor*
+*CocSymbolReference*
+*CocSymbolFolder*
+*CocSymbolFile*
+*CocSymbolModule*
+*CocSymbolNamespace*
+*CocSymbolPackage*
+*CocSymbolClass*
+*CocSymbolMethod*
+*CocSymbolProperty*
+*CocSymbolField*
+*CocSymbolConstructor*
+*CocSymbolEnum*
+*CocSymbolInterface*
+*CocSymbolFunction*
+*CocSymbolVariable*
+*CocSymbolConstant*
+*CocSymbolString*
+*CocSymbolNumber*
+*CocSymbolBoolean*
+*CocSymbolArray*
+*CocSymbolObject*
+*CocSymbolKey*
+*CocSymbolNull*
+*CocSymbolEnumMember*
+*CocSymbolStruct*
+*CocSymbolEvent*
+*CocSymbolOperator*
+*CocSymbolTypeParameter*
+
+Note: Use configuration |coc-config-suggest-completionItemKindLabels| for customized icon
+characters.
+
+Semantic token highlight groups~
+								*CocSem*
+
+Semantic highlight groups are starts with `CocSem` which link to related
+|nvim-treesitter| highlight groups when possible and fallback to builtin
+highlight groups, use variable |g:coc_default_semantic_highlight_groups| to
+disable creation of these highlight groups.
+
+Only semantic tokens types and `deprecated` modifier have default
+highlight groups.
+
+You need create highlight groups for highlight other modifiers and/or specific
+modifier with type, for example:
+>
+	" Add highlights for defaultLibrary modifier
+	hi link CocSemDefaultLibrary TSOtherDefaultLibrary
+	hi link CocSemDefaultLibraryClass TSTypeDefaultLibrary
+	hi link CocSemDefaultLibraryInterface TSTypeDefaultLibrary
+	hi link CocSemDefaultLibraryEnum TSTypeDefaultLibrary
+	hi link CocSemDefaultLibraryType TSTypeDefaultLibrary
+	hi link CocSemDefaultLibraryNamespace TSTypeDefaultLibrary
+
+	" Add highlights for declaration modifier
+	hi link CocSemDeclaration TSOtherDeclaration
+	hi link CocSemDeclarationClass TSTypeDeclaration
+	hi link CocSemDeclarationInterface TSTypeDeclaration
+	hi link CocSemDeclarationEnum TSTypeDeclaration
+	hi link CocSemDeclarationType TSTypeDeclaration
+	hi link CocSemDeclarationNamespace TSTypeDeclaration
+<
+The modifier highlight groups have higher priority.
+
+Others~
+
+*CocSearch* highlight group for matched characters in list.
+*CocDisabled* highlight for disabled items, eg: menu item.
+*CocCodeLens* for virtual text of codeLens.
+*CocCursorRange* for highlight of activated cursors ranges.
+*CocLinkedEditing* for highlight of activated linked editing ranges.
+*CocHoverRange* for range of current hovered symbol.
+*CocMenuSel* for current menu item in menu dialog (should only provide
+background color).
+*CocSelectedRange* for highlight ranges of outgoing calls.
+*CocSnippetVisual* for highlight snippet placeholders.
+*CocInlayHint* for highlight inlay hint virtual text block, default linked to
+|CocHintSign|
+
+==============================================================================
+TREE SUPPORT 						*coc-tree*
+
+Tree view is used for render outline and call hierarchy, following features
+are supported:
+
+- Data update while keep tree node open/close state.
+- Auto refresh on load error.
+- Click open/close icon to toggle collapse state.
+- Click node to invoke default command.
+- Show tooltip in float window on |CursorHold| when possible.
+- Key-mappings support |coc-tree-mappings|
+- Optional multiple selection.
+- Optional node reveal support.
+- Optional fuzzy filter support.
+- Provide api `window.createTreeView` for extensions.
+
+Check |coc-config-tree| for related configurations.
+
+The filetype is `'coctree'`, which can be used to overwrite buffer and window
+options.
+
+Use variable |w:cocViewId| to detect the kind of tree.
+
+------------------------------------------------------------------------------
+
+TREE KEY MAPPINGS 					*coc-tree-mappings*
+
+Default key-mappings are provided for 'coctree' buffer, which can be changed
+by configuration |coc-config-tree|.
+
+<space> - Select/unselect item, configured by `"tree.key.toggleSelection"`.
+<tab> 	- Invoke actions of current item, configured by `"tree.key.actions"`.
+<esc>   - Close tree window, configured by `"tree.key.close"`.
+<cr>    - Invoke command of current item,  configured by `"tree.key.invoke"`.
+<C-o>   - Move cursor to original window.
+f 	- Activate filter, configured by `"tree.key.activeFilter"`.
+t 	- Trigger key to toggle expand state of tree node, configured by
+	`tree.key.toggle`.
+M 	- Collapse all tree node, configured by `"tree.key.collapseAll"`.
+
+------------------------------------------------------------------------------
+
+TREE FILTER 						*coc-tree-filter*
+
+Filter mode is used for search for specific node by fuzzy filter, invoke the
+key configured by `"tree.key.activeFilter"` to activate filter mode.
+
+Note: some tree views not have filter mode supported.
+
+When filter mode is activated, type normal character to insert filter input
+and following special keys are supported:
+
+<bs> 	- Delete last filter character when possible.
+<C-h> 	- Delete last filter character when possible.
+<C-u> 	- Clean up filter text.
+<C-p> 	- Navigate to previous filter text (stored on command invoke).
+<C-n> 	- Navigate to next filter text (stored on command invoke).
+<esc> 	- exit filter mode.
+<C-o> 	- exit filter mode.
+<up> or `"tree.key.selectPrevious"` 	- Select previous node.
+<down> or `"tree.key.selectNext"` 	- Select next node.
+<cr> or `"key.key.invoke"` 	- Invoke command of selected node.
+
+==============================================================================
+LIST SUPPORT						*coc-list*
+
+Built-in list support to make working with lists of items easier.
+
+The following features are supported:
+
+- Insert & normal mode.
+- Default key-mappings for insert & normal mode.
+- Customize key-mappings for insert & normal mode.
+- Commands for reopening & doing actions with a previous list.
+- Different match modes.
+- Interactive mode.
+- Auto preview on cursor move.
+- Number select support.
+- Built-in actions for locations.
+- Parse ANSI code.
+- Mouse support.
+- Select actions using <tab>.
+- Multiple selections using <space> in normal mode.
+- Select lines by visual selection.
+
+------------------------------------------------------------------------------
+
+LIST COMMAND						*coc-list-command*
+
+:CocList [{...options}] [{source}] [{...args}]		*:CocList*
+
+	Open coc list of {source}, example: >
+
+	:CocList --normal location
+<
+	For current jump locations.
+
+	See |coc-list-options| for available list options,
+
+	Also check |coc-config-list| for list configuration.
+
+	{args} are sent to source during the fetching of list.
+	Press `?` on normal mode to get supported {args} of current
+	list.
+
+	When {source} is empty, lists source is used.
+
+:CocListResume [{name}]					*:CocListResume*
+
+	Reopen last opened list, input and cursor position will be preserved.
+
+:CocListCancel						*:CocListCancel*
+
+	Close list, useful when the list is not the current window.
+
+:CocPrev [{name}]					*:CocPrev*
+
+	Invoke default action for the previous item in the last {name} list.
+
+	Doesn't open the list window if it's closed.
+
+:CocNext [{name}]					*:CocNext*
+
+	Invoke the default action for the next item in the last {name} list.
+
+	Doesn't open the list window if it's closed.
+
+:CocFirst [{name}]					*:CocFirst*
+
+	Invoke default action for first item in the last {name} list.
+
+:CocLast [{name}]					*:CocLast*
+
+	Invoke default action for last item in the last {name} list.
+
+							*coc-list-options*
+Options of CocList command~
+
+--top
+	Show list as top window.
+
+--tab
+	Open list in new tabpage.
+
+--normal
+
+	Start list in normal mode, recommended for short list.
+
+--no-sort
+	Disable sort made by fuzzy score or most recently used, use it when
+	it's already sorted.
+
+--input={input}
+
+	Specify the input on session start.
+
+--strict
+-S
+	Use strict matching instead of fuzzy matching.
+
+--regex
+-R
+	Use regex matching instead of fuzzy matching.
+
+--ignore-case
+
+	Ignore case when using strict matching or regex matching.
+
+--number-select
+-N
+	Type a line number to select an item and invoke the default action on
+	insert mode. Type `0` to select the 10th line.
+
+
+--interactive
+-I
+	Use interactive mode, list items would be reloaded on input
+	change, filter and sort would be done by list implementation.
+
+	Note: only works when the list support interactive mode.
+
+	Note: filtering and sorting would be done by underlying task, which
+	means options including `--strict`, `--no-sort`, `--regex`,
+	`--ignore-case` would not work at all.
+
+--auto-preview
+-A
+
+	Start a preview for the current item on the visible list.
+
+--no-quit
+
+	Not quit list session after do action.
+
+	Note: you may need to refresh the list for current state.
+
+--first
+
+	Invoke default action for first list item on list open.
+	Nothing happens when the list is empty.
+
+--reverse
+
+	Reverse lines order of list.
+
+------------------------------------------------------------------------------
+
+LIST CONFIGURATION					*coc-list-configuration*
+
+Use `coc-settings.json` for configuration of lists.
+
+Configuration of list starts with 'list.'.
+
+See |coc-config-list| or type `list.` in your settings file to get completion
+list (requires coc-json installed).
+
+For configuration of a specified list, use section that starts with:
+`list.source.{name}`, where `{name}` is the name of list.
+
+Change default action:~
+
+If you want to use `tabe` as default action of symbols list, you can use:
+>
+	// change default action of symbols
+	"list.source.symbols.defaultAction": "tabe"
+<
+in your coc-settings.json
+
+Change default options:~
+
+Use `list.source.{name}.defaultOptions` setting like: >
+
+	// make symbols list use normal mode and interactive by default
+	"list.source.symbols.defaultOptions": ["--interactive", "--number-select"],
+<
+Note: some list like symbols only work in interactive mode, you must
+include `--interactive` in `defaultOptions`.
+
+Note: default options will not be used when there're options passed
+with |:CocList| command.
+
+Change default arguments:~
+
+Use `list.source.{name}.defaultArgs` setting like: >
+
+	// use regex match for grep source
+	"list.source.grep.defaultArgs": ["-regex"],
+
+Note: default arguments used only when arguments from |:CocList| command is
+empty.
+
+Note: Type `?` on normal mode to get supported arguments of current list.
+
+------------------------------------------------------------------------------
+
+LIST MAPPINGS						*coc-list-mappings*
+
+Default mappings on insert mode:
+
+<Esc>       - Cancel list session.
+<CR>        - Do default action with selected items or current item.
+<C-c>       - Stop loading task.
+<C-v>       - Paste text from system clipboard.
+<C-l>       - Reload list.
+<C-o>       - Change to normal mode.
+<Down>      - Select next line.
+<Up>        - Select previous line.
+<Left>      - Move cursor left.
+<Right>     - Move cursor right.
+<End>       - Move cursor to end of prompt.
+<C-e>       - Same as <End>.
+<Home>      - Move cursor to start of prompt.
+<C-a>       - Same as <Home>.
+<C-f>       - Scroll window forward.
+<C-b>       - Scroll window backward.
+<Backspace> - Remove previous character of cursor.
+<C-h>       - Remove previous character of cursor.
+<C-w>       - Remove previous word of cursor.
+<C-u>       - Remove characters before cursor.
+<C-n>       - Navigate to next input in history.
+<C-p>       - Navigate to previous input in history.
+<C-s>       - Switch matcher for filter items.
+<C-r>       - Insert content from vim's register.
+<Tab>       - Select action.
+
+Default mappings on normal mode:
+
+<Esc>       - Cancel list session.
+<CR>        - Do default action with selected items or current item.
+<C-c>       - Stop source from fetching more items.
+<C-l>       - Reload list.
+<C-a>       - Mark all visible items selected.
+<C-o>       - Jump to original window on list create.
+<Tab>       - Select action.
+<C-e> 	    - Scroll preview window down.
+<C-y> 	    - Scroll preview window up.
+<Space>     - Toggle select of current item.
+i,I,o,O,a,A - Change to insert mode.
+p           - Preview action.
+:           - Cancel list session without closing window.
+?           - Show help of current list.
+t           - Do 'tabe' action.
+d           - Do 'drop' action.
+s           - Do 'split' action.
+
+Use |coc-list-mappings-custom| to override default mappings.
+
+							*coc-list-mappings-custom*
+
+Configurations `"list.normalMappings"` and `"list.insertMappings"` are used
+for customizing the list key-mappings, example: >
+
+	"list.insertMappings": {
+		"<C-r>": "do:refresh",
+		"<C-f>": "feedkeys:\\<C-f>",
+		"<C-b>": "feedkeys:\\<C-b>",
+		"<C-n>": "normal:j",
+		"<C-p>": "normal:k",
+		"<C-t>": "action:tabe",
+		"<C-x>": "call:MyFunc",
+		// paste yanked text to prompt
+		"<C-v>": "eval:@@"
+	}
+	"list.normalMappings": {
+		"c": "expr:MyExprFunc"
+		"d": "action:delete"
+	}
+<
+Note: you should only use mappings that start with `<C-` or `<A-` for insert
+mappings.
+
+Note: <Esc> can't be remapped for other actions.
+
+The mapping expression should be `command:arguments`, available commands:
+
+'do' - special actions provided by coc list, including:
+	'refresh'       - reload list.
+	'selectall'     - mark all visible items selected.
+	'switch'        - switch matcher used for filter items.
+	'exit'          - exit list session.
+	'stop'          - stop loading task.
+	'cancel'        - cancel list session but leave list window open.
+	'toggle'        - toggle selection of current item.
+	'togglemode'    - toggle between insert and normal mode.
+	'previous'      - move cursor to previous item.
+	'next'          - move cursor to next item.
+	'defaultaction' - do default action for selected item(s).
+	'chooseaction'  - choose action for selected item(s).
+	'jumpback'      - stop prompt and jump back to original window.
+	'previewtoggle' - toggle preview window, requires preview action exists.
+	'previewup'     - scroll preview window up.
+	'previewdown'   - scroll preview window down.
+	'help'          - show help.
+'prompt' - do prompt action, including:
+	'previous' - change to previous input in history.
+	'next'           - change to next input in history.
+	'start'          - move cursor to start.
+	'end'            - move cursor to end.
+	'left'           - move cursor left.
+	'right'          - move cursor right.
+	'deleteforward'  - remove previous character.
+	'deletebackward' - remove next character.
+	'removetail'     - remove characters afterwards.
+	'removeahead'    - remove character ahead.
+	'removeword'     - remove word before cursor.
+	'insertregister' - insert content from Vim register.
+	'paste'          - append text from system clipboard to prompt.
+'eval'     - append text to prompt from result of VimL expression.
+'action'   - execute action of list, use <tab> to find available actions.
+'feedkeys' - feedkeys to list window, use `\\` in JSON to escape special
+             characters.
+'normal'   - execute normal command in list window.
+'normal!'  - execute normal command without remap.
+'command'  - execute command.
+'call'     - call Vim function with |coc-list-context| as only argument.
+'expr'     - same as 'call' but expect the function return action name.
+
+							*coc-list-context*
+
+Context argument contains the following properties:
+
+'name'    - name of the list, example: `'location'`.
+'args'    - arguments of the list.
+'input'   - current input of prompt.
+'winid'   - window id on list activated.
+'bufnr'   - buffer number on list activated.
+'targets' - list of selected targets, checkout |coc-list-target| for properties.
+
+							*coc-list-target*
+
+Target contains the following properties:
+
+'label'      - mandatory property that is shown in the buffer.
+'filtertext' - optional filter text used for filtering items.
+'location'   - optional location of item, check out https://bit.ly/2Rtb6Bo
+'data'       - optional additional properties.
+
+------------------------------------------------------------------------------
+
+LIST SOURCES						*coc-list-sources*
+
+------------------------------------------------------------------------------
+
+location						*coc-list-location*
+
+	Last jump locations.
+
+	Actions:
+
+	- 'preview' : preview location in preview window.
+	- 'open': open location by use
+		`"coc.preferences.jumpCommand"`, default action
+	- 'tabe': Use |:tabe| to open location.
+	- 'drop': Use |:drop| to open location.
+	- 'vsplit': Use |:vsplit| to open location.
+	- 'split': Use |:split| to open location.
+	- 'quickfix': Add selected items to Vim's quickfix.
+
+extensions						*coc-list-extensions*
+
+	Manage coc.nvim extensions.
+
+	Actions:
+
+	- 'toggle' activate/deactivate extension, default action.
+	- 'disable' disable extension.
+	- 'enable' enable extension.
+	- 'lock' lock/unlock extension to current version.
+	- 'doc' view extension's README doc.
+	- 'fix' fix dependencies in terminal buffer.
+	- 'reload' reload extension.
+	- 'uninstall' uninstall extension.
+
+diagnostics						*coc-list-diagnostics*
+
+	All diagnostics for the workspace.
+
+	Actions:
+
+	- Same as |coc-list-location|
+
+folders 						*coc-list-folders*
+
+	Manage current workspace folders of coc.nvim.
+
+	Actions:
+
+	- 'edit' change the directory of workspace folder.
+	- 'delete' remove selected workspace folder.
+
+outline							*coc-list-outline*
+
+	Symbols in the current document.
+
+	Actions:
+
+	- Same as |coc-list-location|
+
+symbols							*coc-list-symbols*
+
+	Search workspace symbols.
+
+	Actions:
+
+	- Same as |coc-list-location|
+
+services						*coc-list-services*
+
+	Manage registered services.
+
+	Actions:
+
+	- 'toggle': toggle service state, default action.
+
+commands						*coc-list-commands*
+
+	Workspace commands.
+
+	Actions:
+
+	- 'run': run selected command, default action.
+
+links							*coc-list-links*
+
+	Links in the current document.
+
+	Actions:
+
+	- 'open': open the link, default action.
+	- 'jump': jump to link definition.
+
+sources							*coc-list-completion-sources*
+
+	Available completion sources.
+
+	Actions:
+
+	- 'toggle': activate/deactivate source, default action.
+	- 'refresh': refresh source.
+	- 'open': open the file where source defined.
+
+lists							*coc-list-lists*
+
+	Get available lists.
+
+	Actions:
+
+	- 'open': open selected list, default action.
+
+==============================================================================
+
+DIALOG SUPPORT						*coc-dialog*
+
+Dialog is special float window/popup that could response to user actions,
+dialog have close button, border, title (optional), bottom buttons(optional).
+
+Note bottom buttons work different on neovim and vim, on neovim you can
+click the button since neovim allows focus of window, on vim you have to type
+highlighted character to trigger button callback.
+
+Note dialog feature requires neovim >= 0.4.0 or vim >= 8.2.0750 to work.
+
+See |coc-config-dialog| for available configurations.
+
+------------------------------------------------------------------------------
+
+							*coc-dialog-basic*
+
+A basic dialog is create by javascript api `window.showDialog` , which is just
+some texts with optional buttons.
+
+------------------------------------------------------------------------------
+
+							*coc-dialog-confirm*
+
+A confirm dialog is used for user to confirm an action, normally created by
+`window.showPrompt()` Confirm dialog uses filter feature on vim8 and
+|getchar()| on neoivm.
+
+The difference is you can operate vim on vim8, but not on neovim.
+
+Supported key-mappings:
+
+<C-c>         - force cancel, return -1 for callback.
+<esc>, n, N   - reject the action, return 0 for callback.
+y,Y           - accept the action, return 1 for callback.
+
+------------------------------------------------------------------------------
+
+							*coc-dialog-input*
+
+An input dialog request user input with optional default value, normally
+created by `window.requestInput`, when `"coc.preferences.promptInput"` is
+false, vim's commandline input prompt is used instead.
+
+On neovim, it uses float window, on vim8, it opens terminal in popup.
+
+Supported key-mappings:
+
+<C-a>               - move cursor to first col.
+<C-e>               - move cursor to last col.
+<esc>               - cancel input, null is received by callback.
+<cr>                - accept current input selection of current item.
+
+QuickPick related (available when created by |coc-dialog-quickpick|).
+
+<C-f>               - scroll forward quickpick list.
+<C-b>               - scroll backward quickpick list.
+<C-j> <C-n> <down>  - move to next item in quickpick list.
+<C-k> <C-p> <up>    - move to previous item in quickpick list.
+<C-space>           - toggle selection of current item in quickpick list when
+canSelectMany is supported.
+
+Note on neovim, other insert mode key-mappings could work.
+
+Note not possible to configure key-mappings on vim8, to customize key-mappings
+on neovim, use |CocOpenFloatPrompt| with current buffer.
+
+------------------------------------------------------------------------------
+
+							*coc-dialog-quickpick*
+
+A quickpick is a input dialog in the middle with a float window/popup contains
+filtred list items.
+
+A simple fuzzy filter is used by default.
+
+See |coc-config-dialog| for available configurations.
+
+See |coc-dialog-input| for available key-mappings.
+
+------------------------------------------------------------------------------
+
+							*coc-dialog-menu*
+
+A menu dialog is shown aside current cursor position for pick a single item
+from list of items, extensions could use `window.showMenuPicker` to create menu
+dialog.
+
+Supported key-mappings:
+
+<Esc> <C-c>          - cancel selection.
+<cr>                 - confirm selection of current item, use
+|dialog.confirmKey| to override.
+1-9                  - select item with 1 based index.
+g                    - move to first item.
+G                    - move to last item.
+j <tab> <down> <C-n> - move to next item.
+k <s-tab> <up> <C-p> - move to previous item.
+<C-f>                - scroll forward.
+<C-b>                - scroll backward.
+
+------------------------------------------------------------------------------
+
+							*coc-dialog-picker*
+
+A picker dialog is used for multiple selection. On neovim, it's possible to
+toggle selection by mouse click inside the bracket. Extensions could use
+`window.showPickerDialog` to create picker dialog.
+
+Supported key-mappings:
+
+<Esc> <C-c>          - cancel selection.
+<cr>                 - confirm selection of current item, use
+|dialog.confirmKey| to override.
+<space>              - toggle selection of current item.
+g                    - move to first item.
+G                    - move to last item.
+j <tab> <down> <C-n> - move to next item.
+k <s-tab> <up> <C-p> - move to previous item.
+<C-f>                - scroll forward.
+<C-b>                - scroll backward.
+
+Note when close button is clicked, the selection is canceled with undefined
+result (same as <esc>).
+
+==============================================================================
+
+NOTIFICATION SUPPORT					*coc-notification*
+
+Notification windows are shown from bottom right of the screen. Notifications
+behavior like notifications on VSCode.
+
+Notifications are created by javascript APIs: `window.showErrorMessage()`,
+`window.showWarningMessage()`, `window.showInformationMessage()`,
+`window.showNotification()` and `window.withProgress()`.
+
+Possible kind of notifications: 'error', 'warning', 'info' and 'progress'.
+
+Message notifications (not progress) requires
+|coc-preferences-enableMessageDialog| to be `true`. Message notifications
+without actions would be automatically closed after milliseconds specified by
+|coc-config-notification-timeout|.
+
+Features:
+
+- Animated position and 'winblend' on show and hide.
+- Reposition current tab notification windows when notification dismissed.
+- Notification with same options will be replaced to avoid duplicated windows.
+- Percent and message update for progress notification.
+- Click the button (neovim only) or use |coc#notify#do_action()| to invoke
+  actions.
+- Click the window would cancel auto close (on neovim and focusable is true).
+- For customize icons, see |g:coc_notify|.
+- For customize highlights, see |CocNotification|.
+- For customize other behaviors, see |coc-config-notification|.
+- For available user actions (ex: "close_all", "do_action" "show_sources"), see
+  |coc#notify|.
+
+Note notification feature requires neovim >= 0.4.0 or vim >= 8.2.0750 to work.
+
+==============================================================================
+
+STATUSLINE SUPPORT					*coc-status*
+
+Diagnostics info and other status info contributed by extensions could be
+shown in statusline.
+
+The easiest way is add `%{coc#status()}` to your 'statusline' option. Example: >
+
+	set statusline^=%{coc#status()}
+>
+------------------------------------------------------------------------------
+
+							*coc-status-manual*
+
+Create function:
+>
+	function! StatusDiagnostic() abort
+	  let info = get(b:, 'coc_diagnostic_info', {})
+	  if empty(info) | return '' | endif
+	  let msgs = []
+	  if get(info, 'error', 0)
+	    call add(msgs, 'E' . info['error'])
+	  endif
+	  if get(info, 'warning', 0)
+	    call add(msgs, 'W' . info['warning'])
+	  endif
+	  return join(msgs, ' ') . ' ' . get(g:, 'coc_status', '')
+	endfunction
+<
+Add `%{StatusDiagnostic()}` to your 'statusline' option.
+
+------------------------------------------------------------------------------
+
+							*coc-status-airline*
+
+With vim-airline: https://github.com/vim-airline/vim-airline
+
+Error and warning display should work in vim-airline out of box.
+
+Disable vim-airline integration:
+>
+	let g:airline#extensions#coc#enabled = 0
+<
+Change error symbol:
+>
+	let airline#extensions#coc#error_symbol = 'Error:'
+<
+Change warning symbol:
+>
+	let airline#extensions#coc#warning_symbol = 'Warning:'
+<
+Change error format:
+>
+	let airline#extensions#coc#stl_format_err = '%E{[%e(#%fe)]}'
+<
+Change warning format:
+>
+	let airline#extensions#coc#stl_format_warn = '%W{[%w(#%fw)]}'
+<
+------------------------------------------------------------------------------
+							*coc-status-lightline*
+
+With lightline.vim: https://github.com/itchyny/lightline.vim
+
+Use configuration like: >
+
+  let g:lightline = {
+	\ 'colorscheme': 'wombat',
+	\ 'active': {
+	\   'left': [ [ 'mode', 'paste' ],
+	\             [ 'cocstatus', 'readonly', 'filename', 'modified' ] ]
+	\ },
+	\ 'component_function': {
+	\   'cocstatus': 'coc#status'
+	\ },
+	\ }
+
+  " Use autocmd to force lightline update.
+  autocmd User CocStatusChange,CocDiagnosticChange call lightline#update()
+<
+==============================================================================
+CUSTOM SOURCE						*coc-custom-source*
+
+Creating a custom source in VimL is supported.
+
+Check out https://github.com/neoclide/coc.nvim/wiki/Create-custom-source
+
+==============================================================================
+FAQ							*coc-faq*
+
+------------------------------------------------------------------------------
+
+Check out https://github.com/neoclide/coc.nvim/wiki/F.A.Q
+
+==============================================================================
+CHANGELOG						*coc-changelog*
+
+See history.md under project root.
+
+==============================================================================
+vim:tw=78:nosta:noet:ts=8:sts=0:ft=help:noet:fen:

+ 703 - 0
vimfiles/bundle/coc.nvim/plugin/coc.vim

@@ -0,0 +1,703 @@
+scriptencoding utf-8
+if exists('g:did_coc_loaded') || v:version < 800
+  finish
+endif
+
+function! s:checkVersion() abort
+  let l:unsupported = 0
+  if get(g:, 'coc_disable_startup_warning', 0) != 1
+    if has('nvim')
+      let l:unsupported = !has('nvim-0.4.0')
+    else
+      let l:unsupported = !has('patch-8.1.1719')
+    endif
+
+    if l:unsupported == 1
+      echohl Error
+      echom "coc.nvim requires at least Vim 8.1.1719 or Neovim 0.4.0, but you're using an older version."
+      echom "Please upgrade your (neo)vim."
+      echom "You can add this to your vimrc to avoid this message:"
+      echom "    let g:coc_disable_startup_warning = 1"
+      echom "Note that some features may error out or behave incorrectly."
+      echom "Please do not report bugs unless you're using at least Vim 8.1.1719 or Neovim 0.4.0."
+      echohl None
+      sleep 2
+    else
+      if !has('nvim-0.5.0') && !has('patch-8.2.0750')
+        echohl WarningMsg
+        echom "coc.nvim works best on vim >= 8.2.0750 and neovim >= 0.5.0, consider upgrade your vim."
+        echom "You can add this to your vimrc to avoid this message:"
+        echom "    let g:coc_disable_startup_warning = 1"
+        echom "Note that some features may behave incorrectly."
+        echohl None
+        sleep 2
+      endif
+    endif
+  endif
+endfunction
+
+call s:checkVersion()
+
+let g:did_coc_loaded = 1
+let g:coc_service_initialized = 0
+let s:is_win = has('win32') || has('win64')
+let s:root = expand('<sfile>:h:h')
+let s:is_vim = !has('nvim')
+let s:is_gvim = s:is_vim && has("gui_running")
+
+if get(g:, 'coc_start_at_startup', 1) && !s:is_gvim
+  call coc#rpc#start_server()
+endif
+
+function! CocTagFunc(pattern, flags, info) abort
+  if a:flags !=# 'c'
+    " use standard tag search
+    return v:null
+  endif
+  return coc#rpc#request('getTagList', [])
+endfunction
+
+function! CocPopupCallback(bufnr, arglist) abort
+  if len(a:arglist) == 2
+    if a:arglist[0] == 'confirm'
+      call coc#rpc#notify('PromptInsert', [a:arglist[1], a:bufnr])
+    elseif a:arglist[0] == 'exit'
+      execute 'silent! bd! '.a:bufnr
+      "call coc#rpc#notify('PromptUpdate', [a:arglist[1]])
+    elseif a:arglist[0] == 'change'
+      let text = a:arglist[1]
+      let current = getbufvar(a:bufnr, 'current', '')
+      if text !=# current
+        call setbufvar(a:bufnr, 'current', text)
+        let cursor = term_getcursor(a:bufnr)
+        let info = {
+              \ 'lnum': cursor[0],
+              \ 'col': cursor[1],
+              \ 'line': text,
+              \ 'changedtick': 0
+              \ }
+        call coc#rpc#notify('CocAutocmd', ['TextChangedI', a:bufnr, info])
+      endif
+    elseif a:arglist[0] == 'send'
+      let key = a:arglist[1]
+      let escaped = strcharpart(key, 1, strchars(key) - 2)
+      call coc#rpc#notify('PromptKeyPress', [a:bufnr, escaped])
+    endif
+  endif
+endfunction
+
+function! CocAction(name, ...) abort
+  if !get(g:, 'coc_service_initialized', 0)
+    throw 'coc.nvim not ready when invoke CocAction "'.a:name.'"'
+  endif
+  return coc#rpc#request(a:name, a:000)
+endfunction
+
+function! CocHasProvider(name) abort
+  return coc#rpc#request('hasProvider', [a:name])
+endfunction
+
+function! CocActionAsync(name, ...) abort
+  return s:AsyncRequest(a:name, a:000)
+endfunction
+
+function! CocRequest(...) abort
+  return coc#rpc#request('sendRequest', a:000)
+endfunction
+
+function! CocNotify(...) abort
+  return coc#rpc#request('sendNotification', a:000)
+endfunction
+
+function! CocRegistNotification(id, method, cb) abort
+  call coc#on_notify(a:id, a:method, a:cb)
+endfunction
+
+function! CocLocations(id, method, ...) abort
+  let args = [a:id, a:method] + copy(a:000)
+  return coc#rpc#request('findLocations', args)
+endfunction
+
+function! CocLocationsAsync(id, method, ...) abort
+  let args = [a:id, a:method] + copy(a:000)
+  return s:AsyncRequest('findLocations', args)
+endfunction
+
+function! CocRequestAsync(...)
+  return s:AsyncRequest('sendRequest', a:000)
+endfunction
+
+function! s:AsyncRequest(name, args) abort
+  let Cb = empty(a:args)? v:null : a:args[len(a:args) - 1]
+  if type(Cb) == 2
+    if !coc#rpc#ready()
+      call Cb('service not started', v:null)
+    else
+      call coc#rpc#request_async(a:name, a:args[0:-2], Cb)
+    endif
+    return ''
+  endif
+  call coc#rpc#notify(a:name, a:args)
+  return ''
+endfunction
+
+function! s:CommandList(...) abort
+  let list = coc#rpc#request('commandList', a:000)
+  return join(list, "\n")
+endfunction
+
+function! s:ExtensionList(...) abort
+  let stats = CocAction('extensionStats')
+  call filter(stats, 'v:val["isLocal"] == v:false')
+  let list = map(stats, 'v:val["id"]')
+  return join(list, "\n")
+endfunction
+
+function! s:SearchOptions(...) abort
+  let list = ['-e', '--regexp', '-F', '--fixed-strings', '-L', '--follow',
+        \ '-g', '--glob', '--hidden', '--no-hidden', '--no-ignore-vcs',
+        \ '--word-regexp', '-w', '--smart-case', '-S', '--no-config',
+        \ '--line-regexp', '--no-ignore', '-x']
+  return join(list, "\n")
+endfunction
+
+function! s:LoadedExtensions(...) abort
+  let list = CocAction('loadedExtensions')
+  return join(list, "\n")
+endfunction
+
+function! s:InstallOptions(...)abort
+  let list = ['-terminal', '-sync']
+  return join(list, "\n")
+endfunction
+
+function! s:OpenConfig()
+  let home = coc#util#get_config_home()
+  if !isdirectory(home)
+    echohl MoreMsg
+    echom 'Config directory "'.home.'" does not exist, create? (y/n)'
+    echohl None
+    let confirm = nr2char(getchar())
+    redraw!
+    if !(confirm ==? "y" || confirm ==? "\r")
+      return
+    else
+      call mkdir(home, 'p')
+    end
+  endif
+  execute 'edit '.home.'/coc-settings.json'
+  call coc#rpc#notify('checkJsonExtension', [])
+endfunction
+
+function! s:get_color(item, fallback) abort
+  let t = type(a:item)
+  if t == 1
+    return a:item
+  endif
+  if t == 4
+    let item = get(a:item, 'gui', {})
+    let color = get(item, &background, a:fallback)
+    return type(color) == 1 ? color : a:fallback
+  endif
+  return a:fallback
+endfunction
+
+function! s:AddAnsiGroups() abort
+  let color_map = {}
+  let colors = ['#282828', '#cc241d', '#98971a', '#d79921', '#458588', '#b16286', '#689d6a', '#a89984', '#928374']
+  let names = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'grey']
+  for i in range(0, len(names) - 1)
+    let name = names[i]
+    if exists('g:terminal_ansi_colors')
+      let color_map[name] = s:get_color(get(g:terminal_ansi_colors, i, colors[i]), colors[i])
+    else
+      let color_map[name] = get(g:, 'terminal_color_'.i, colors[i])
+    endif
+  endfor
+  try
+    for name in keys(color_map)
+      let foreground = toupper(name[0]).name[1:]
+      let foregroundColor = color_map[name]
+      for key in keys(color_map)
+        let background = toupper(key[0]).key[1:]
+        let backgroundColor = color_map[key]
+        exe 'hi default CocList'.foreground.background.' guifg='.foregroundColor.' guibg='.backgroundColor
+      endfor
+      exe 'hi default CocListFg'.foreground. ' guifg='.foregroundColor. ' ctermfg='.foreground
+      exe 'hi default CocListBg'.foreground. ' guibg='.foregroundColor. ' ctermbg='.foreground
+    endfor
+  catch /.*/
+    " ignore invalid color
+  endtry
+endfunction
+
+function! s:CursorRangeFromSelected(type, ...) abort
+  " add range by operator
+  call coc#rpc#request('cursorsSelect', [bufnr('%'), 'operator', a:type])
+endfunction
+
+function! s:OpenDiagnostics(...) abort
+  let height = get(a:, 1, 0)
+  call coc#rpc#request('fillDiagnostics', [bufnr('%')])
+  if height
+    execute ':lopen '.height
+   else
+    lopen
+  endif
+endfunction
+
+function! s:Disable() abort
+  if get(g:, 'coc_enabled', 0) == 0
+    return
+  endif
+  augroup coc_nvim
+    autocmd!
+  augroup end
+  call coc#rpc#request('detach', [])
+  echohl MoreMsg
+    echom '[coc.nvim] Event disabled'
+  echohl None
+  let g:coc_enabled = 0
+endfunction
+
+function! s:Autocmd(...) abort
+  if !get(g:, 'coc_workspace_initialized', 0)
+    return
+  endif
+  call coc#rpc#notify('CocAutocmd', a:000)
+endfunction
+
+function! s:HandleCharInsert(char, bufnr) abort
+  if get(g:, 'coc_disable_space_report', 0)
+    let g:coc_disable_space_report = 0
+    if a:char ==# ' '
+      return
+    endif
+  endif
+  call s:Autocmd('InsertCharPre', a:char, a:bufnr)
+endfunction
+
+function! s:HandleWinScrolled(winid) abort
+  if getwinvar(a:winid, 'float', 0)
+    call coc#float#nvim_scrollbar(a:winid)
+  endif
+  call s:Autocmd('WinScrolled', a:winid)
+endfunction
+
+function! s:SyncAutocmd(...)
+  if !get(g:, 'coc_workspace_initialized', 0)
+    return
+  endif
+  call coc#rpc#request('CocAutocmd', a:000)
+endfunction
+
+function! s:Enable(initialize)
+  if get(g:, 'coc_enabled', 0) == 1
+    return
+  endif
+  let g:coc_enabled = 1
+
+  augroup coc_nvim
+    autocmd!
+
+    if coc#rpc#started()
+      autocmd VimEnter            * call coc#rpc#notify('VimEnter', [])
+    elseif get(g:, 'coc_start_at_startup', 1)
+      autocmd VimEnter            * call coc#rpc#start_server()
+    endif
+    if s:is_vim
+      if exists('##DirChanged')
+        autocmd DirChanged        * call s:Autocmd('DirChanged', getcwd())
+      endif
+      if exists('##TerminalOpen')
+        autocmd TerminalOpen      * call s:Autocmd('TermOpen', +expand('<abuf>'))
+      endif
+    else
+      autocmd DirChanged        * call s:Autocmd('DirChanged', get(v:event, 'cwd', ''))
+      autocmd TermOpen          * call s:Autocmd('TermOpen', +expand('<abuf>'))
+      autocmd WinEnter          * call coc#float#nvim_win_enter(win_getid())
+    endif
+    autocmd CursorMoved         list:///* call coc#list#select(bufnr('%'), line('.'))
+    if exists('##WinClosed')
+      autocmd WinClosed         * call coc#float#on_close(+expand('<amatch>'))
+      autocmd WinClosed         * call coc#notify#on_close(+expand('<amatch>'))
+    elseif exists('##TabEnter')
+      autocmd TabEnter          * call coc#notify#reflow()
+    endif
+    if has('nvim-0.4.0') || has('patch-8.1.1719')
+      autocmd CursorHold        * call coc#float#check_related()
+    endif
+    if exists('##WinScrolled')
+      autocmd WinScrolled       * call s:HandleWinScrolled(+expand('<amatch>'))
+    endif
+    autocmd TabNew              * call s:Autocmd('TabNew', tabpagenr())
+    autocmd TabClosed           * call s:Autocmd('TabClosed', +expand('<afile>'))
+    autocmd WinLeave            * call s:Autocmd('WinLeave', win_getid())
+    autocmd WinEnter            * call s:Autocmd('WinEnter', win_getid())
+    autocmd BufWinLeave         * call s:Autocmd('BufWinLeave', +expand('<abuf>'), bufwinid(+expand('<abuf>')))
+    autocmd BufWinEnter         * call s:Autocmd('BufWinEnter', +expand('<abuf>'), win_getid())
+    autocmd FileType            * call s:Autocmd('FileType', expand('<amatch>'), +expand('<abuf>'))
+    autocmd InsertCharPre       * call s:HandleCharInsert(v:char, bufnr('%'))
+    if exists('##TextChangedP')
+      autocmd TextChangedP      * call s:Autocmd('TextChangedP', +expand('<abuf>'), coc#util#change_info())
+    endif
+    autocmd TextChangedI        * call s:Autocmd('TextChangedI', +expand('<abuf>'), coc#util#change_info())
+    autocmd InsertLeave         * call s:Autocmd('InsertLeave', +expand('<abuf>'))
+    autocmd InsertEnter         * call s:Autocmd('InsertEnter', +expand('<abuf>'))
+    autocmd BufHidden           * call s:Autocmd('BufHidden', +expand('<abuf>'))
+    autocmd BufEnter            * call s:Autocmd('BufEnter', +expand('<abuf>'))
+    autocmd TextChanged         * call s:Autocmd('TextChanged', +expand('<abuf>'), getbufvar(+expand('<abuf>'), 'changedtick'))
+    autocmd BufWritePost        * call s:Autocmd('BufWritePost', +expand('<abuf>'), getbufvar(+expand('<abuf>'), 'changedtick'))
+    autocmd CursorMoved         * call s:Autocmd('CursorMoved', +expand('<abuf>'), [line('.'), col('.')])
+    autocmd CursorMovedI        * call s:Autocmd('CursorMovedI', +expand('<abuf>'), [line('.'), col('.')])
+    autocmd CursorHold          * call s:Autocmd('CursorHold', +expand('<abuf>'), [line('.'), col('.')])
+    autocmd CursorHoldI         * call s:Autocmd('CursorHoldI', +expand('<abuf>'), [line('.'), col('.')])
+    autocmd BufNewFile,BufReadPost * call s:Autocmd('BufCreate', +expand('<abuf>'))
+    autocmd BufUnload           * call s:Autocmd('BufUnload', +expand('<abuf>'))
+    autocmd BufWritePre         * call s:SyncAutocmd('BufWritePre', +expand('<abuf>'), bufname(+expand('<abuf>')), getbufvar(+expand('<abuf>'), 'changedtick'))
+    autocmd FocusGained         * if mode() !~# '^c' | call s:Autocmd('FocusGained') | endif
+    autocmd FocusLost           * call s:Autocmd('FocusLost')
+    autocmd VimResized          * call s:Autocmd('VimResized', &columns, &lines)
+    autocmd VimLeavePre         * let g:coc_vim_leaving = 1
+    autocmd VimLeavePre         * call s:Autocmd('VimLeavePre')
+    autocmd BufReadCmd,FileReadCmd,SourceCmd list://* call coc#list#setup(expand('<amatch>'))
+    autocmd BufWriteCmd __coc_refactor__* :call coc#rpc#notify('saveRefactor', [+expand('<abuf>')])
+    autocmd ColorScheme * call s:Hi()
+  augroup end
+  if a:initialize == 0
+     call coc#rpc#request('attach', [])
+     echohl MoreMsg
+     echom '[coc.nvim] Event enabled'
+     echohl None
+  endif
+endfunction
+
+function! s:FgColor(hlGroup) abort
+  let fgId = synIDtrans(hlID(a:hlGroup))
+  let ctermfg = synIDattr(fgId, 'reverse', 'cterm') ==# '1' ? synIDattr(fgId, 'bg', 'cterm') : synIDattr(fgId, 'fg', 'cterm')
+  let guifg = synIDattr(fgId, 'reverse', 'gui') ==# '1'  ? synIDattr(fgId, 'bg', 'gui') : synIDattr(fgId, 'fg', 'gui')
+  let cmd = ' ctermfg=' . (empty(ctermfg) ? '223' : ctermfg)
+  let cmd .= ' guifg=' . (empty(guifg) ? '#ebdbb2' : guifg)
+  return cmd
+endfunction
+
+function! s:Hi() abort
+  hi default CocErrorSign     ctermfg=Red     guifg=#ff0000 guibg=NONE
+  hi default CocWarningSign   ctermfg=Brown   guifg=#ff922b guibg=NONE
+  hi default CocInfoSign      ctermfg=Yellow  guifg=#fab005 guibg=NONE
+  hi default CocHintSign      ctermfg=Blue    guifg=#15aabf guibg=NONE
+  hi default CocSelectedText  ctermfg=Red     guifg=#fb4934 guibg=NONE
+  hi default CocCodeLens      ctermfg=Gray    guifg=#999999 guibg=NONE
+  hi default CocUnderline     term=underline cterm=underline gui=underline
+  hi default CocBold          term=bold cterm=bold gui=bold
+  hi default CocItalic        term=italic cterm=italic gui=italic
+  if s:is_vim || has('nvim-0.4.0')
+    hi default CocStrikeThrough term=strikethrough cterm=strikethrough gui=strikethrough
+  else
+    hi default CocStrikeThrough guifg=#989898 ctermfg=gray
+  endif
+  hi default CocMarkdownLink  ctermfg=Blue    guifg=#15aabf guibg=NONE
+  hi default CocDisabled      guifg=#999999   ctermfg=gray
+  hi default CocSearch        ctermfg=Blue    guifg=#15aabf guibg=NONE
+  hi default link CocFadeOut             Conceal
+  hi default link CocMarkdownCode        markdownCode
+  hi default link CocMarkdownHeader      markdownH1
+  hi default link CocMenuSel             CursorLine
+  hi default link CocErrorFloat          CocErrorSign
+  hi default link CocWarningFloat        CocWarningSign
+  hi default link CocInfoFloat           CocInfoSign
+  hi default link CocHintFloat           CocHintSign
+  hi default link CocErrorHighlight      CocUnderline
+  hi default link CocWarningHighlight    CocUnderline
+  hi default link CocInfoHighlight       CocUnderline
+  hi default link CocHintHighlight       CocUnderline
+  hi default link CocDeprecatedHighlight CocStrikeThrough
+  hi default link CocUnusedHighlight     CocFadeOut
+  hi default link CocListLine            CursorLine
+  hi default link CocListSearch          CocSearch
+  hi default link CocListMode            ModeMsg
+  hi default link CocListPath            Comment
+  hi default link CocHighlightText       CursorColumn
+  hi default link CocHoverRange          Search
+  hi default link CocCursorRange         Search
+  hi default link CocLinkedEditing       CocCursorRange
+  hi default link CocHighlightRead       CocHighlightText
+  hi default link CocHighlightWrite      CocHighlightText
+  hi default link CocInlayHint           CocHintSign
+  " Notification
+  hi default CocNotificationProgress  ctermfg=Blue    guifg=#15aabf guibg=NONE
+  hi default link CocNotificationButton  CocUnderline
+  hi default link CocNotificationError   CocErrorFloat
+  hi default link CocNotificationWarning CocWarningFloat
+  hi default link CocNotificationInfo    CocInfoFloat
+  " Snippet
+  hi default link CocSnippetVisual       Visual
+  " Tree view highlights
+  hi default link CocTreeTitle       Title
+  hi default link CocTreeDescription Comment
+  hi default link CocTreeOpenClose   CocBold
+  hi default link CocTreeSelected    CursorLine
+  hi default link CocSelectedRange   CocHighlightText
+  " Symbol highlights
+  hi default link CocSymbolDefault       MoreMsg
+  "Pum
+  hi default link CocPumSearch           CocSearch
+  hi default link CocPumMenu             Normal
+  hi default link CocPumShortcut         Comment
+  hi default link CocPumDeprecated       CocStrikeThrough
+  hi default CocPumVirtualText      ctermfg=239 guifg=#504945
+
+  if has('nvim')
+    hi default link CocFloating NormalFloat
+  else
+    hi default link CocFloating Pmenu
+  endif
+  if !exists('*sign_getdefined') || empty(sign_getdefined('CocCurrentLine'))
+    sign define CocCurrentLine linehl=CocMenuSel
+  endif
+  if !exists('*sign_getdefined') || empty(sign_getdefined('CocListCurrent'))
+    sign define CocListCurrent linehl=CocListLine
+  endif
+  if !exists('*sign_getdefined') || empty(sign_getdefined('CocTreeSelected'))
+    sign define CocTreeSelected linehl=CocTreeSelected
+  endif
+  if has('nvim-0.5.0')
+    hi default CocCursorTransparent gui=strikethrough blend=100
+  endif
+
+  if has('nvim')
+    let names = ['Error', 'Warning', 'Info', 'Hint']
+    for name in names
+      if !hlexists('Coc'.name.'VirtualText')
+        let suffix = name ==# 'Warning' ? 'Warn' : name
+        if hlexists('DiagnosticVirtualText'.suffix)
+          exe 'hi default link Coc'.name.'VirtualText DiagnosticVirtualText'.suffix
+        else
+          exe 'hi default link Coc'.name.'VirtualText Coc'.name.'Sign'
+        endif
+      endif
+    endfor
+  endif
+  call s:AddAnsiGroups()
+
+  if get(g:, 'coc_default_semantic_highlight_groups', 1)
+    let hlMap = {
+        \ 'Namespace': ['TSNamespace', 'Include'],
+        \ 'Type': ['TSType', 'Type'],
+        \ 'Class': ['TSConstructor', 'Special'],
+        \ 'Enum': ['TSEnum', 'Type'],
+        \ 'Interface': ['TSInterface', 'Type'],
+        \ 'Struct': ['TSStruct', 'Identifier'],
+        \ 'TypeParameter': ['TSParameter', 'Identifier'],
+        \ 'Parameter': ['TSParameter', 'Identifier'],
+        \ 'Variable': ['TSSymbol', 'Identifier'],
+        \ 'Property': ['TSProperty', 'Identifier'],
+        \ 'EnumMember': ['TSEnumMember', 'Constant'],
+        \ 'Event': ['TSEvent', 'Keyword'],
+        \ 'Function': ['TSFunction', 'Function'],
+        \ 'Method': ['TSMethod', 'Function'],
+        \ 'Macro': ['TSConstMacro', 'Define'],
+        \ 'Keyword': ['TSKeyword', 'Keyword'],
+        \ 'Modifier': ['TSModifier', 'StorageClass'],
+        \ 'Comment': ['TSComment', 'Comment'],
+        \ 'String': ['TSString', 'String'],
+        \ 'Number': ['TSNumber', 'Number'],
+        \ 'Boolean': ['TSBoolean', 'Boolean'],
+        \ 'Regexp': ['TSStringRegex', 'String'],
+        \ 'Operator': ['TSOperator', 'Operator'],
+        \ 'Decorator': ['TSSymbol', 'Identifier'],
+        \ 'Deprecated': ['TSStrike', 'CocDeprecatedHighlight']
+        \ }
+    for [key, value] in items(hlMap)
+      let ts = get(value, 0, '')
+      let fallback = get(value, 1, '')
+      execute 'hi default link CocSem'.key.' '.(hlexists(ts) ? ts : fallback)
+    endfor
+  endif
+  let symbolMap = {
+      \ 'Keyword': ['TSKeyword', 'Keyword'],
+      \ 'Namespace': ['TSNamespace', 'Include'],
+      \ 'Class': ['TSConstructor', 'Special'],
+      \ 'Method': ['TSMethod', 'Function'],
+      \ 'Property': ['TSProperty', 'Identifier'],
+      \ 'Text': ['TSText', 'CocSymbolDefault'],
+      \ 'Unit': ['TSUnit', 'CocSymbolDefault'],
+      \ 'Value': ['TSValue', 'CocSymbolDefault'],
+      \ 'Snippet': ['TSSnippet', 'CocSymbolDefault'],
+      \ 'Color': ['TSColor', 'Float'],
+      \ 'Reference': ['TSTextReference', 'Constant'],
+      \ 'Folder': ['TSFolder', 'CocSymbolDefault'],
+      \ 'File': ['TSFile', 'Statement'],
+      \ 'Module': ['TSModule', 'Statement'],
+      \ 'Package': ['TSPackage', 'Statement'],
+      \ 'Field': ['TSField', 'Identifier'],
+      \ 'Constructor': ['TSConstructor', 'Special'],
+      \ 'Enum': ['TSEnum', 'CocSymbolDefault'],
+      \ 'Interface': ['TSInterface', 'CocSymbolDefault'],
+      \ 'Function': ['TSFunction', 'Function'],
+      \ 'Variable': ['TSVariableBuiltin', 'Special'],
+      \ 'Constant': ['TSConstant', 'Constant'],
+      \ 'String': ['TSString', 'String'],
+      \ 'Number': ['TSNumber', 'Number'],
+      \ 'Boolean': ['TSBoolean', 'Boolean'],
+      \ 'Array': ['TSArray', 'CocSymbolDefault'],
+      \ 'Object': ['TSObject', 'CocSymbolDefault'],
+      \ 'Key': ['TSKey', 'Identifier'],
+      \ 'Null': ['TSNull', 'Type'],
+      \ 'EnumMember': ['TSEnumMember', 'Identifier'],
+      \ 'Struct': ['TSStruct', 'Keyword'],
+      \ 'Event': ['TSEvent', 'Constant'],
+      \ 'Operator': ['TSOperator', 'Operator'],
+      \ 'TypeParameter': ['TSParameter', 'Identifier'],
+      \ }
+  for [key, value] in items(symbolMap)
+    let hlGroup = hlexists(value[0]) ? value[0] : get(value, 1, 'CocSymbolDefault')
+    if hlexists(hlGroup)
+      execute 'hi default CocSymbol'.key.' '.s:FgColor(hlGroup)
+    endif
+  endfor
+endfunction
+
+function! s:FormatFromSelected(type)
+  call CocActionAsync('formatSelected', a:type)
+endfunction
+
+function! s:CodeActionFromSelected(type)
+  call CocActionAsync('codeAction', a:type)
+endfunction
+
+function! s:ShowInfo()
+  if coc#rpc#ready()
+    call coc#rpc#notify('showInfo', [])
+  else
+    let lines = []
+    echomsg 'coc.nvim service not started, checking environment...'
+    let node = get(g:, 'coc_node_path', $COC_NODE_PATH == '' ? 'node' : $COC_NODE_PATH)
+    if !executable(node)
+      call add(lines, 'Error: '.node.' is not executable!')
+    else
+      let output = trim(system(node . ' --version'))
+      let ms = matchlist(output, 'v\(\d\+\).\(\d\+\).\(\d\+\)')
+      if empty(ms) || str2nr(ms[1]) < 12 || (str2nr(ms[1]) == 12 && str2nr(ms[2]) < 12)
+        call add(lines, 'Error: Node version '.output.' < 12.12.0, please upgrade node.js')
+      endif
+    endif
+    " check bundle
+    let file = s:root.'/build/index.js'
+    if !filereadable(file)
+      call add(lines, 'Error: javascript bundle not found, please compile code of coc.nvim by esbuild.')
+    endif
+    if !empty(lines)
+      botright vnew
+      setl filetype=nofile
+      call setline(1, lines)
+    else
+      if get(g:, 'coc_start_at_startup',1)
+        echohl MoreMsg | echon 'Service stopped for some unknown reason, try :CocStart' | echohl None
+      else
+        echohl MoreMsg | echon 'Start on startup is disabled, try :CocStart' | echohl None
+      endif
+    endif
+  endif
+endfunction
+
+command! -nargs=0 CocOutline      :call coc#rpc#notify('showOutline', [])
+command! -nargs=? CocDiagnostics  :call s:OpenDiagnostics(<f-args>)
+command! -nargs=0 CocInfo         :call s:ShowInfo()
+command! -nargs=0 CocOpenLog      :call coc#rpc#notify('openLog',  [])
+command! -nargs=0 CocDisable      :call s:Disable()
+command! -nargs=0 CocEnable       :call s:Enable(0)
+command! -nargs=0 CocConfig       :call s:OpenConfig()
+command! -nargs=0 CocLocalConfig  :call coc#rpc#notify('openLocalConfig', [])
+command! -nargs=0 CocRestart      :call coc#rpc#restart()
+command! -nargs=0 CocStart        :call coc#rpc#start_server()
+command! -nargs=0 CocRebuild      :call coc#util#rebuild()
+command! -nargs=1 -complete=custom,s:LoadedExtensions  CocWatch    :call coc#rpc#notify('watchExtension', [<f-args>])
+command! -nargs=+ -complete=custom,s:SearchOptions  CocSearch    :call coc#rpc#notify('search', [<f-args>])
+command! -nargs=+ -complete=custom,s:ExtensionList  CocUninstall :call CocActionAsync('uninstallExtension', <f-args>)
+command! -nargs=* -complete=custom,s:CommandList -range CocCommand :call coc#rpc#notify('runCommand', [<f-args>])
+command! -nargs=* -complete=custom,coc#list#options CocList      :call coc#rpc#notify('openList',  [<f-args>])
+command! -nargs=? -complete=custom,coc#list#names CocListResume   :call coc#rpc#notify('listResume', [<f-args>])
+command! -nargs=? -complete=custom,coc#list#names CocListCancel   :call coc#rpc#notify('listCancel', [])
+command! -nargs=? -complete=custom,coc#list#names CocPrev         :call coc#rpc#notify('listPrev', [<f-args>])
+command! -nargs=? -complete=custom,coc#list#names CocNext         :call coc#rpc#notify('listNext', [<f-args>])
+command! -nargs=? -complete=custom,coc#list#names CocFirst        :call coc#rpc#notify('listFirst', [<f-args>])
+command! -nargs=? -complete=custom,coc#list#names CocLast         :call coc#rpc#notify('listLast', [<f-args>])
+command! -nargs=0 CocUpdate       :call coc#util#update_extensions(1)
+command! -nargs=0 -bar CocUpdateSync   :call coc#util#update_extensions()
+command! -nargs=* -bar -complete=custom,s:InstallOptions CocInstall   :call coc#util#install_extension([<f-args>])
+
+call s:Enable(1)
+call s:Hi()
+
+" Default key-mappings for completion
+if empty(mapcheck("\<C-n>", 'i'))
+  inoremap <silent><expr> <C-n> coc#pum#visible() ? coc#pum#next(1) : "\<C-n>"
+endif
+if empty(mapcheck("\<C-p>", 'i'))
+  inoremap <silent><expr> <C-p> coc#pum#visible() ? coc#pum#prev(1) : "\<C-p>"
+endif
+if empty(mapcheck("\<down>", 'i'))
+  inoremap <silent><expr> <down> coc#pum#visible() ? coc#pum#next(0) : "\<down>"
+endif
+if empty(mapcheck("\<up>", 'i'))
+  inoremap <silent><expr> <up> coc#pum#visible() ? coc#pum#prev(0) : "\<up>"
+endif
+if empty(mapcheck("\<C-e>", 'i'))
+  inoremap <silent><expr> <C-e> coc#pum#visible() ? coc#pum#cancel() : "\<C-e>"
+endif
+if empty(mapcheck("\<C-y>", 'i'))
+  inoremap <silent><expr> <C-y> coc#pum#visible() ? coc#pum#confirm() : "\<C-y>"
+endif
+if empty(mapcheck("\<PageDown>", 'i'))
+  inoremap <silent><expr> <PageDown> coc#pum#visible() ? coc#pum#scroll(1) : "\<PageDown>"
+endif
+if empty(mapcheck("\<PageUp>", 'i'))
+  inoremap <silent><expr> <PageUp> coc#pum#visible() ? coc#pum#scroll(0) : "\<PageUp>"
+endif
+
+vnoremap <silent> <Plug>(coc-range-select)          :<C-u>call       CocActionAsync('rangeSelect',     visualmode(), v:true)<CR>
+vnoremap <silent> <Plug>(coc-range-select-backward) :<C-u>call       CocActionAsync('rangeSelect',     visualmode(), v:false)<CR>
+nnoremap <Plug>(coc-range-select)          :<C-u>call       CocActionAsync('rangeSelect',     '', v:true)<CR>
+nnoremap <Plug>(coc-codelens-action)       :<C-u>call       CocActionAsync('codeLensAction')<CR>
+vnoremap <silent> <Plug>(coc-format-selected)       :<C-u>call       CocActionAsync('formatSelected',     visualmode())<CR>
+vnoremap <silent> <Plug>(coc-codeaction-selected)   :<C-u>call       CocActionAsync('codeAction',         visualmode())<CR>
+nnoremap <Plug>(coc-codeaction-selected)   :<C-u>set        operatorfunc=<SID>CodeActionFromSelected<CR>g@
+nnoremap <Plug>(coc-codeaction)            :<C-u>call       CocActionAsync('codeAction',         '')<CR>
+nnoremap <Plug>(coc-codeaction-line)       :<C-u>call       CocActionAsync('codeAction',         'line')<CR>
+nnoremap <Plug>(coc-codeaction-cursor)     :<C-u>call       CocActionAsync('codeAction',         'cursor')<CR>
+nnoremap <silent> <Plug>(coc-rename)                :<C-u>call       CocActionAsync('rename')<CR>
+nnoremap <silent> <Plug>(coc-format-selected)       :<C-u>set        operatorfunc=<SID>FormatFromSelected<CR>g@
+nnoremap <silent> <Plug>(coc-format)                :<C-u>call       CocActionAsync('format')<CR>
+nnoremap <silent> <Plug>(coc-diagnostic-info)       :<C-u>call       CocActionAsync('diagnosticInfo')<CR>
+nnoremap <silent> <Plug>(coc-diagnostic-next)       :<C-u>call       CocActionAsync('diagnosticNext')<CR>
+nnoremap <silent> <Plug>(coc-diagnostic-prev)       :<C-u>call       CocActionAsync('diagnosticPrevious')<CR>
+nnoremap <silent> <Plug>(coc-diagnostic-next-error) :<C-u>call       CocActionAsync('diagnosticNext',     'error')<CR>
+nnoremap <silent> <Plug>(coc-diagnostic-prev-error) :<C-u>call       CocActionAsync('diagnosticPrevious', 'error')<CR>
+nnoremap <silent> <Plug>(coc-definition)            :<C-u>call       CocActionAsync('jumpDefinition')<CR>
+nnoremap <silent> <Plug>(coc-declaration)           :<C-u>call       CocActionAsync('jumpDeclaration')<CR>
+nnoremap <silent> <Plug>(coc-implementation)        :<C-u>call       CocActionAsync('jumpImplementation')<CR>
+nnoremap <silent> <Plug>(coc-type-definition)       :<C-u>call       CocActionAsync('jumpTypeDefinition')<CR>
+nnoremap <silent> <Plug>(coc-references)            :<C-u>call       CocActionAsync('jumpReferences')<CR>
+nnoremap <silent> <Plug>(coc-references-used)       :<C-u>call       CocActionAsync('jumpUsed')<CR>
+nnoremap <silent> <Plug>(coc-openlink)              :<C-u>call       CocActionAsync('openLink')<CR>
+nnoremap <silent> <Plug>(coc-fix-current)           :<C-u>call       CocActionAsync('doQuickfix')<CR>
+nnoremap <silent> <Plug>(coc-float-hide)            :<C-u>call       coc#float#close_all()<CR>
+nnoremap <silent> <Plug>(coc-float-jump)            :<c-u>call       coc#float#jump()<cr>
+nnoremap <silent> <Plug>(coc-command-repeat)        :<C-u>call       CocAction('repeatCommand')<CR>
+nnoremap <silent> <Plug>(coc-refactor)              :<C-u>call       CocActionAsync('refactor')<CR>
+
+nnoremap <silent> <Plug>(coc-cursors-operator) :<C-u>set operatorfunc=<SID>CursorRangeFromSelected<CR>g@
+vnoremap <silent> <Plug>(coc-cursors-range)    :<C-u>call CocAction('cursorsSelect', bufnr('%'), 'range', visualmode())<CR>
+nnoremap <silent> <Plug>(coc-cursors-word)     :<C-u>call CocAction('cursorsSelect', bufnr('%'), 'word', 'n')<CR>
+nnoremap <silent> <Plug>(coc-cursors-position) :<C-u>call CocAction('cursorsSelect', bufnr('%'), 'position', 'n')<CR>
+
+vnoremap <silent> <Plug>(coc-funcobj-i)        :<C-U>call CocAction('selectSymbolRange', v:true, visualmode(), ['Method', 'Function'])<CR>
+vnoremap <silent> <Plug>(coc-funcobj-a)        :<C-U>call CocAction('selectSymbolRange', v:false, visualmode(), ['Method', 'Function'])<CR>
+onoremap <silent> <Plug>(coc-funcobj-i)        :<C-U>call CocAction('selectSymbolRange', v:true, '', ['Method', 'Function'])<CR>
+onoremap <silent> <Plug>(coc-funcobj-a)        :<C-U>call CocAction('selectSymbolRange', v:false, '', ['Method', 'Function'])<CR>
+
+vnoremap <silent> <Plug>(coc-classobj-i)       :<C-U>call CocAction('selectSymbolRange', v:true, visualmode(), ['Interface', 'Struct', 'Class'])<CR>
+vnoremap <silent> <Plug>(coc-classobj-a)       :<C-U>call CocAction('selectSymbolRange', v:false, visualmode(), ['Interface', 'Struct', 'Class'])<CR>
+onoremap <silent> <Plug>(coc-classobj-i)       :<C-U>call CocAction('selectSymbolRange', v:true, '', ['Interface', 'Struct', 'Class'])<CR>
+onoremap <silent> <Plug>(coc-classobj-a)       :<C-U>call CocAction('selectSymbolRange', v:false, '', ['Interface', 'Struct', 'Class'])<CR>

+ 467 - 0
vimfiles/bundle/colorizer/autoload/colorizer.vim

@@ -0,0 +1,467 @@
+" colorizer.vim	Colorize all text in the form #rrggbb or #rgb; autoload functions
+" Maintainer:	lilydjwg <lilydjwg@gmail.com>
+" Version:	1.4.2
+" License:	Vim License  (see vim's :help license)
+"
+" See plugin/colorizer.vim for more info.
+
+let s:keepcpo = &cpo
+set cpo&vim
+
+function! s:FGforBG(bg) "{{{1
+  " takes a 6hex color code and returns a matching color that is visible
+  let pure = substitute(a:bg,'^#','','')
+  let r = str2nr(pure[0:1], 16)
+  let g = str2nr(pure[2:3], 16)
+  let b = str2nr(pure[4:5], 16)
+  let fgc = g:colorizer_fgcontrast
+  if r*30 + g*59 + b*11 > 12000
+    return s:predefined_fgcolors['dark'][fgc]
+  else
+    return s:predefined_fgcolors['light'][fgc]
+  end
+endfunction
+
+function! s:Rgb2xterm(color) "{{{1
+  " selects the nearest xterm color for a rgb value like #FF0000
+  let best_match=0
+  let smallest_distance = 10000000000
+  let r = str2nr(a:color[1:2], 16)
+  let g = str2nr(a:color[3:4], 16)
+  let b = str2nr(a:color[5:6], 16)
+  let colortable = s:GetXterm2rgbTable()
+  for c in range(0,254)
+    let d = pow(colortable[c][0]-r,2) + pow(colortable[c][1]-g,2) + pow(colortable[c][2]-b,2)
+    if d<smallest_distance
+      let smallest_distance = d
+      let best_match = c
+    endif
+  endfor
+  return best_match
+endfunction
+
+"" the 6 value iterations in the xterm color cube {{{1
+let s:valuerange = [0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF]
+
+"" 16 basic colors {{{1
+let s:basic16 = [
+      \ [0x00, 0x00, 0x00], [0xCD, 0x00, 0x00],
+      \ [0x00, 0xCD, 0x00], [0xCD, 0xCD, 0x00],
+      \ [0x00, 0x00, 0xEE], [0xCD, 0x00, 0xCD],
+      \ [0x00, 0xCD, 0xCD], [0xE5, 0xE5, 0xE5],
+      \ [0x7F, 0x7F, 0x7F], [0xFF, 0x00, 0x00],
+      \ [0x00, 0xFF, 0x00], [0xFF, 0xFF, 0x00],
+      \ [0x5C, 0x5C, 0xFF], [0xFF, 0x00, 0xFF],
+      \ [0x00, 0xFF, 0xFF], [0xFF, 0xFF, 0xFF]]
+
+function! s:Xterm2rgb(color) "{{{1
+  " 16 basic colors
+  let r = 0
+  let g = 0
+  let b = 0
+  if a:color<16
+    let r = s:basic16[a:color][0]
+    let g = s:basic16[a:color][1]
+    let b = s:basic16[a:color][2]
+  endif
+
+  " color cube color
+  if a:color>=16 && a:color<=232
+    let l:color=a:color-16
+    let r = s:valuerange[(l:color/36)%6]
+    let g = s:valuerange[(l:color/6)%6]
+    let b = s:valuerange[l:color%6]
+  endif
+
+  " gray tone
+  if a:color>=233 && a:color<=253
+    let r=8+(a:color-232)*0x0a
+    let g=r
+    let b=r
+  endif
+  let rgb=[r,g,b]
+  return rgb
+endfunction
+
+function! s:SetMatcher(color, pat) "{{{1
+  " "color" is the converted color and "pat" is what to highlight
+  let group = 'Color' . strpart(a:color, 1)
+  if !hlexists(group) || s:force_group_update
+    let fg = g:colorizer_fgcontrast < 0 ? a:color : s:FGforBG(a:color)
+    if &t_Co == 256 && !(has('termguicolors') && &termguicolors)
+      exe 'hi '.group.' ctermfg='.s:Rgb2xterm(fg).' ctermbg='.s:Rgb2xterm(a:color)
+    endif
+    " Always set gui* as user may switch to GUI version and it's cheap
+    exe 'hi '.group.' guifg='.fg.' guibg='.a:color
+  endif
+  if !exists("w:colormatches[a:pat]")
+    let w:colormatches[a:pat] = matchadd(group, a:pat)
+  endif
+endfunction
+
+" Color Converters {{{1
+function! s:RgbBgColor() "{{{2
+  let bg = synIDattr(synIDtrans(hlID("Normal")), "bg")
+  let r = str2nr(bg[1:2], 16)
+  let g = str2nr(bg[3:4], 16)
+  let b = str2nr(bg[5:6], 16)
+  return [r,g,b]
+endfunction
+
+function! s:Hexa2Rgba(hex,alpha) "{{{2
+  let r = str2nr(a:hex[1:2], 16)
+  let g = str2nr(a:hex[3:4], 16)
+  let b = str2nr(a:hex[5:6], 16)
+  let alpha = printf("%.2f", str2float(str2nr(a:alpha,16)) / 255.0)
+  return [r,g,b,alpha]
+endfunction
+
+function! s:Rgba2Rgb(r,g,b,alpha,percent,rgb_bg) "{{{2
+  " converts matched r,g,b values and percentages to [0:255]
+  " if possible, overlays r,g,b with alpha on given rgb_bg color
+  if a:percent
+    let r = a:r * 255 / 100
+    let g = a:g * 255 / 100
+    let b = a:b * 255 / 100
+  else
+    let r = a:r
+    let g = a:g
+    let b = a:b
+  endif
+  if r > 255 || g > 255 || b > 255
+    return []
+  endif
+  if empty(a:rgb_bg)
+    return [r,g,b]
+  endif
+  let alpha = str2float(a:alpha)
+  if alpha < 0
+    let alpha = 0.0
+  elseif alpha > 1
+    let alpha = 1.0
+  endif
+  if alpha == 1.0
+    return [r,g,b]
+  endif
+  let r = float2nr(ceil(r * alpha) + ceil(a:rgb_bg[0] * (1 - alpha)))
+  let g = float2nr(ceil(g * alpha) + ceil(a:rgb_bg[1] * (1 - alpha)))
+  let b = float2nr(ceil(b * alpha) + ceil(a:rgb_bg[2] * (1 - alpha)))
+  if r > 255
+    let r = 255
+  endif
+  if g > 255
+    let g = 255
+  endif
+  if b > 255
+    let b = 255
+  endif
+  return [r,g,b]
+endfunction
+
+"ColorFinders {{{1
+function! s:HexCode(str, lineno) "{{{2
+  " finds RGB: #00f #0000ff and RGBA: #00f8 #0000ff88 (or ARGB: #800f #880000ff)
+  if has("gui_running")
+    let rgb_bg = s:RgbBgColor()
+  else
+    " translucent colors would display incorrectly, so ignore the alpha value
+    let rgb_bg = []
+  endif
+  let ret = []
+  let place = 0
+  let colorpat = '#[0-9A-Fa-f]\{3\}\>\|#[0-9A-Fa-f]\{6\}\>\|#[0-9A-Fa-f]\{8\}\>\|#[0-9A-Fa-f]\{4\}\>'
+  while 1
+    let foundcolor = matchstr(a:str, colorpat, place)
+    if foundcolor == ''
+      break
+    endif
+    let place = matchend(a:str, colorpat, place)
+    let pat = foundcolor . '\>'
+    let colorlen = len(foundcolor)
+    if get(g:, 'colorizer_hex_alpha_first') == 1
+      if colorlen == 4 || colorlen == 5
+        let ha = tolower(foundcolor[1])
+        let hr = tolower(foundcolor[2])
+        let hg = tolower(foundcolor[3])
+        let hb = tolower(foundcolor[4])
+        let foundcolor = substitute(foundcolor, '[[:xdigit:]]', '&&', 'g')
+      else
+        let ha = tolower(foundcolor[1:2])
+        let hr = tolower(foundcolor[3:4])
+        let hg = tolower(foundcolor[5:6])
+        let hb = tolower(foundcolor[7:8])
+      endif
+      if len(foundcolor) == 9
+        let alpha      = foundcolor[1:2]
+        let foundcolor = '#'.foundcolor[3:8]
+      else
+        let alpha = 'ff'
+      endif
+      if empty(rgb_bg)
+        if colorlen == 5
+          let pat = printf('\c#\x\zs%s%s%s\ze\>', hr,hg,hb)
+        elseif colorlen == 9
+          let pat = printf('\c#\x\x\zs%s%s%s\ze\>', hr,hg,hb)
+        endif
+      endif
+    else
+      if colorlen == 4 || colorlen == 5
+        let hr = tolower(foundcolor[1])
+        let hg = tolower(foundcolor[2])
+        let hb = tolower(foundcolor[3])
+        let ha = tolower(foundcolor[4])
+        let foundcolor = substitute(foundcolor, '[[:xdigit:]]', '&&', 'g')
+      else
+        let hr = tolower(foundcolor[1:2])
+        let hg = tolower(foundcolor[3:4])
+        let hb = tolower(foundcolor[5:6])
+        let ha = tolower(foundcolor[7:8])
+      endif
+      if len(foundcolor) == 9
+        let alpha      = foundcolor[7:8]
+        let foundcolor = foundcolor[0:6]
+      else
+        let alpha = 'ff'
+      endif
+      if empty(rgb_bg)
+        if colorlen == 5
+          let pat = printf('\c#%s%s%s\ze\x\>', hr,hg,hb)
+        elseif colorlen == 9
+          let pat = printf('\c#%s%s%s\ze\x\x\>', hr,hg,hb)
+        endif
+      endif
+    endif
+    if empty(rgb_bg) || tolower(alpha) == 'ff'
+      call add(ret, [foundcolor, pat])
+    else
+      let rgba    = s:Hexa2Rgba(foundcolor, alpha)
+      let rgb     = s:Rgba2Rgb(rgba[0], rgba[1], rgba[2], rgba[3], 0, rgb_bg)
+      let l:color = printf('#%02x%02x%02x', rgb[0], rgb[1], rgb[2])
+      call add(ret, [l:color, pat])
+    endif
+  endwhile
+  return ret
+endfunction
+
+function! s:RgbColor(str, lineno) "{{{2
+  let ret = []
+  let place = 0
+  let colorpat = '\<rgb(\v\s*(\d+(\%)?)\s*,\s*(\d+%(\2))\s*,\s*(\d+%(\2))\s*\)'
+  while 1
+    let foundcolor = matchlist(a:str, colorpat, place)
+    if empty(foundcolor)
+      break
+    endif
+    let place = matchend(a:str, colorpat, place)
+    if foundcolor[2] == '%'
+      let r = foundcolor[1] * 255 / 100
+      let g = foundcolor[3] * 255 / 100
+      let b = foundcolor[4] * 255 / 100
+    else
+      let r = foundcolor[1]
+      let g = foundcolor[3]
+      let b = foundcolor[4]
+    endif
+    if r > 255 || g > 255 || b > 255
+      break
+    endif
+    let pat = printf('\<rgb(\v\s*%s\s*,\s*%s\s*,\s*%s\s*\)', foundcolor[1], foundcolor[3], foundcolor[4])
+    if foundcolor[2] == '%'
+      let pat = substitute(pat, '%', '\\%', 'g')
+    endif
+    let l:color = printf('#%02x%02x%02x', r, g, b)
+    call add(ret, [l:color, pat])
+  endwhile
+  return ret
+endfunction
+
+function! s:RgbaColor(str, lineno) "{{{2
+  if has("gui_running") || (has("termguicolors") && &termguicolors)
+    let rgb_bg = s:RgbBgColor()
+  else
+    " translucent colors would display incorrectly, so ignore the alpha value
+    let rgb_bg = []
+  endif
+  let ret = []
+  let place = 0
+  let percent = 0
+  let colorpat = '\<rgba(\v\s*(\d+(\%)?)\s*,\s*(\d+%(\2))\s*,\s*(\d+%(\2))\s*,\s*(-?[.[:digit:]]+)\s*\)'
+  while 1
+    let foundcolor = matchlist(a:str, colorpat, place)
+    if empty(foundcolor)
+      break
+    endif
+    if foundcolor[2] == '%'
+      let percent = 1
+    endif
+    let rgb = s:Rgba2Rgb(foundcolor[1], foundcolor[3], foundcolor[4], foundcolor[5], percent, rgb_bg)
+    if empty(rgb)
+      break
+    endif
+    let place = matchend(a:str, colorpat, place)
+    if empty(rgb_bg)
+      let pat = printf('\<rgba(\v\s*%s\s*,\s*%s\s*,\s*%s\s*,\ze\s*(-?[.[:digit:]]+)\s*\)', foundcolor[1], foundcolor[3], foundcolor[4])
+    else
+      let pat = printf('\<rgba(\v\s*%s\s*,\s*%s\s*,\s*%s\s*,\s*%s0*\s*\)', foundcolor[1], foundcolor[3], foundcolor[4], foundcolor[5])
+    endif
+    if percent
+      let pat = substitute(pat, '%', '\\%', 'g')
+    endif
+    let l:color = printf('#%02x%02x%02x', rgb[0], rgb[1], rgb[2])
+    call add(ret, [l:color, pat])
+  endwhile
+  return ret
+endfunction
+
+function! s:PreviewColorInLine(where) "{{{1
+  let line = getline(a:where)
+  for Func in s:ColorFinder
+    let ret = Func(line, a:where)
+    " returned a list of a list: color as #rrggbb, text pattern to highlight
+    for r in ret
+      call s:SetMatcher(r[0], r[1])
+    endfor
+  endfor
+endfunction
+
+function! s:CursorMoved() "{{{1
+  if !exists('w:colormatches')
+    return
+  endif
+  if exists('b:colorizer_last_update')
+    if b:colorizer_last_update == b:changedtick
+      " Nothing changed
+      return
+    endif
+  endif
+  call s:PreviewColorInLine('.')
+  let b:colorizer_last_update = b:changedtick
+endfunction
+
+function! s:TextChanged() "{{{1
+  if !exists('w:colormatches')
+    return
+  endif
+  echomsg "TextChanged"
+  call s:PreviewColorInLine('.')
+endfunction
+
+function! colorizer#ColorHighlight(update, ...) "{{{1
+  if exists('w:colormatches')
+    if !a:update
+      return
+    endif
+    call s:ClearMatches()
+  endif
+  if (g:colorizer_maxlines > 0) && (g:colorizer_maxlines <= line('$'))
+    return
+  end
+  let w:colormatches = {}
+  if g:colorizer_fgcontrast != s:saved_fgcontrast || (exists("a:1") && a:1 == '!')
+    let s:force_group_update = 1
+  endif
+  for i in range(1, line("$"))
+    call s:PreviewColorInLine(i)
+  endfor
+  let s:force_group_update = 0
+  let s:saved_fgcontrast = g:colorizer_fgcontrast
+  augroup Colorizer
+    au!
+    if exists('##TextChanged')
+      autocmd TextChanged * silent call s:TextChanged()
+      if v:version > 704 || v:version == 704 && has('patch143')
+        autocmd TextChangedI * silent call s:TextChanged()
+      else
+        " TextChangedI does not work as expected
+        autocmd CursorMovedI * silent call s:CursorMoved()
+      endif
+    else
+      autocmd CursorMoved,CursorMovedI * silent call s:CursorMoved()
+    endif
+    " rgba handles differently, so need updating
+    autocmd GUIEnter * silent call colorizer#ColorHighlight(1)
+    autocmd BufEnter * silent call colorizer#ColorHighlight(1)
+    autocmd WinEnter * silent call colorizer#ColorHighlight(1)
+    autocmd ColorScheme * let s:force_group_update=1 | silent call colorizer#ColorHighlight(1)
+  augroup END
+endfunction
+
+function! colorizer#ColorClear() "{{{1
+  augroup Colorizer
+    au!
+  augroup END
+  augroup! Colorizer
+  let save_tab = tabpagenr()
+  let save_win = winnr()
+  tabdo windo call s:ClearMatches()
+  exe 'tabn '.save_tab
+  exe save_win . 'wincmd w'
+endfunction
+
+function! s:ClearMatches() "{{{1
+  if !exists('w:colormatches')
+    return
+  endif
+  for i in values(w:colormatches)
+    try
+      call matchdelete(i)
+    catch /.*/
+      " matches have been cleared in other ways, e.g. user has called clearmatches()
+    endtry
+  endfor
+  unlet w:colormatches
+endfunction
+
+function! colorizer#ColorToggle() "{{{1
+  if exists('#Colorizer')
+    call colorizer#ColorClear()
+    echomsg 'Disabled color code highlighting.'
+  else
+    call colorizer#ColorHighlight(0)
+    echomsg 'Enabled color code highlighting.'
+  endif
+endfunction
+
+function! colorizer#AlphaPositionToggle() "{{{1
+  if exists('#Colorizer')
+    if get(g:, 'colorizer_hex_alpha_first') == 1
+      let g:colorizer_hex_alpha_first = 0
+    else
+      let g:colorizer_hex_alpha_first = 1
+    endif
+    call colorizer#ColorHighlight(1)
+  endif
+endfunction
+
+function! s:GetXterm2rgbTable() "{{{1
+  if !exists('s:table_xterm2rgb')
+    let s:table_xterm2rgb = []
+    for c in range(0, 254)
+      let s:color = s:Xterm2rgb(c)
+      call add(s:table_xterm2rgb, s:color)
+    endfor
+  endif
+  return s:table_xterm2rgb
+endfun
+
+" Setups {{{1
+let s:ColorFinder = [function('s:HexCode'), function('s:RgbColor'), function('s:RgbaColor')]
+let s:force_group_update = 0
+let s:predefined_fgcolors = {}
+let s:predefined_fgcolors['dark']  = ['#444444', '#222222', '#000000']
+let s:predefined_fgcolors['light'] = ['#bbbbbb', '#dddddd', '#ffffff']
+if !exists("g:colorizer_fgcontrast")
+  " Default to black / white
+  let g:colorizer_fgcontrast = len(s:predefined_fgcolors['dark']) - 1
+elseif g:colorizer_fgcontrast >= len(s:predefined_fgcolors['dark'])
+  echohl WarningMsg
+  echo "g:colorizer_fgcontrast value invalid, using default"
+  echohl None
+  let g:colorizer_fgcontrast = len(s:predefined_fgcolors['dark']) - 1
+endif
+let s:saved_fgcontrast = g:colorizer_fgcontrast
+
+" Restoration and modelines {{{1
+let &cpo = s:keepcpo
+unlet s:keepcpo
+" vim:ft=vim:fdm=marker:fmr={{{,}}}:ts=8:sw=2:sts=2:et

+ 36 - 0
vimfiles/bundle/colorizer/colortest.txt

@@ -0,0 +1,36 @@
+This file lists various colors, for testing the supported color syntax
+
+#000000   #333333   #666666   #999999   #cccccc   #ffffff
+#000000ff #333333ff #666666ff #999999ff #ccccccff #ffffffff
+#00000088 #33333388 #66666688 #99999988 #cccccc88 #ffffff88
+
+#000    #333    #666    #999    #ccc    #fff
+#000f   #333f   #666f   #999f   #cccf   #ffff
+#000c   #333c   #666c   #999c   #cccc   #fffc
+#0009   #3339   #6669   #9999   #ccc9   #fff9
+#0006   #3336   #6666   #9996   #ccc6   #fff6
+#0003   #3333   #6663   #9993   #ccc3   #fff3
+#0000   #3330   #6660   #9990   #ccc0   #fff0
+
+#00f#08f#0ff#0f8#0f0#8f0#ff0#f80#f00#f08#f0f#80f
+
+#f00f #f00c #f009 #f006 #f003 #f000
+
+rgba(255,0,0,1.0)  rgba(100%,0%,0%,1.0)  #f00f  #0f0f  #00ff #ff00  #f0f0  #f00f
+rgba(255,0,0,0.5)  rgba(100%,0%,0%,0.5)  #f008  #0f08  #00f8 #8f00  #80f0  #800f
+rgba(255,0,0,0.3)  rgba(100%,0%,0%,0.3)  #f004  #0f04  #00f4 #4f00  #40f0  #400f
+
+
+rgb(255,0,0) rgb(128,0,0)  rgb(64,0,0)
+rgb(0,255,0) rgb(0,128,0)  rgb(0,64,0)
+rgb(0,0,255) rgb(0,0,128)  rgb(0,0,64)
+
+#00f  #08f  #0ff  #0f8  #0f0  #8f0  #ff0  #f80  #f00  #f08  #f0f  #80f
+
+#00ff #08ff #0fff #0f8f #0f0f #8f0f #ff0f #f80f #f00f #f08f #f0ff #80ff
+#00fc #08fc #0ffc #0f8c #0f0c #8f0c #ff0c #f80c #f00c #f08c #f0fc #80fc
+#00f9 #08f9 #0ff9 #0f89 #0f09 #8f09 #ff09 #f809 #f009 #f089 #f0f9 #80f9
+#00f6 #08f6 #0ff6 #0f86 #0f06 #8f06 #ff06 #f806 #f006 #f086 #f0f6 #80f6
+#00f3 #08f3 #0ff3 #0f83 #0f03 #8f03 #ff03 #f803 #f003 #f083 #f0f3 #80f3
+#00f0 #08f0 #0ff0 #0f80 #0f00 #8f00 #ff00 #f800 #f000 #f080 #f0f0 #80f0
+

+ 76 - 0
vimfiles/bundle/colorizer/plugin/colorizer.vim

@@ -0,0 +1,76 @@
+" colorizer.vim	Colorize all text in the form #rrggbb or #rgb; entrance
+" Maintainer:	lilydjwg <lilydjwg@gmail.com>
+" Version:	1.4.2
+" Licence:	Vim license. See ':help license'
+" Derived From: css_color.vim
+" 		http://www.vim.org/scripts/script.php?script_id=2150
+" Thanks To:	Niklas Hofer (Author of css_color.vim), Ingo Karkat, rykka,
+"		KrzysztofUrban, blueyed, shanesmith, UncleBill
+" Usage:
+"
+" This plugin defines three commands:
+"
+" 	ColorHighlight	- start/update highlighting
+" 	ColorClear      - clear all highlights
+" 	ColorToggle     - toggle highlights
+"
+" By default, <leader>tc is mapped to ColorToggle. If you want to use another
+" key map, do like this:
+" 	nmap ,tc <Plug>Colorizer
+"
+" If you want completely not to map it, set the following in your vimrc:
+"	let g:colorizer_nomap = 1
+"
+" To use solid color highlight, set this in your vimrc (later change won't
+" probably take effect unless you use ':ColorHighlight!' to force update):
+"	let g:colorizer_fgcontrast = -1
+" set it to 0 or 1 to use a softened foregroud color.
+"
+" If you don't want to enable colorizer at startup, set the following:
+"	let g:colorizer_startup = 0
+"
+" You can disable it on long buffers, for example if more than 1000 lines:
+"	let g:colorizer_maxlines = 1000
+" -1 means unlimited number of lines
+"
+" There are color strings in the format #RRGGBBAA and #AARRGGBB. The former is
+" more common so it's the default. If you want the latter, set the following:
+"	let g:colorizer_hex_alpha_first = 1
+"
+" You can toggle the recognized alpha position by
+"       call colorizer#AlphaPositionToggle()
+"
+" Note: if you modify a color string in normal mode, if the cursor is still on
+" that line, it'll take 'updatetime' seconds to update. You can use
+" :ColorHighlight (or your key mapping) again to force update.
+"
+" Performance Notice: In terminal, it may take several seconds to highlight 240
+" different colors. GUI version is much quicker.
+
+" Reload guard and 'compatible' handling {{{1
+if exists("loaded_colorizer") || v:version < 700 || !(has("gui_running") || &t_Co == 256)
+  finish
+endif
+let loaded_colorizer = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+"Define commands {{{1
+if !exists('g:colorizer_maxlines')
+  let g:colorizer_maxlines = -1
+endif
+command! -bar -bang ColorHighlight call colorizer#ColorHighlight(1, "<bang>")
+command! -bar ColorClear call colorizer#ColorClear()
+command! -bar ColorToggle call colorizer#ColorToggle()
+nnoremap <silent> <Plug>Colorizer :ColorToggle<CR>
+if !hasmapto("<Plug>Colorizer") && (!exists("g:colorizer_nomap") || g:colorizer_nomap == 0)
+  nmap <unique> <Leader>tc <Plug>Colorizer
+endif
+if !exists('g:colorizer_startup') || g:colorizer_startup
+  call colorizer#ColorHighlight(0)
+endif
+
+" Cleanup and modelines {{{1
+let &cpo = s:save_cpo
+" vim:ft=vim:fdm=marker:fmr={{{,}}}:ts=8:sw=2:sts=2:

+ 485 - 0
vimfiles/bundle/lightline.vim/autoload/lightline.vim

@@ -0,0 +1,485 @@
+" =============================================================================
+" Filename: autoload/lightline.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2021/11/21 22:54:46.
+" =============================================================================
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+let s:_ = 1 " 1: uninitialized, 2: disabled
+
+function! lightline#update() abort
+  if s:skip() | return | endif
+  if s:_
+    if s:_ == 2 | return | endif
+    call lightline#init()
+    call lightline#colorscheme()
+  endif
+  if s:lightline.enable.statusline
+    let w = winnr()
+    let s = winnr('$') == 1 && w > 0 ? [lightline#statusline(0)] : [lightline#statusline(0), lightline#statusline(1)]
+    for n in range(1, winnr('$'))
+      call setwinvar(n, '&statusline', s[n!=w])
+    endfor
+  endif
+endfunction
+
+if exists('*win_gettype')
+  function! s:skip() abort " Vim 8.2.0257 (00f3b4e007), 8.2.0991 (0fe937fd86), 8.2.0996 (40a019f157)
+    return win_gettype() ==# 'popup' || win_gettype() ==# 'autocmd'
+  endfunction
+else
+  function! s:skip() abort
+    return &buftype ==# 'popup'
+  endfunction
+endif
+
+function! lightline#update_disable() abort
+  if s:lightline.enable.statusline
+    call setwinvar(0, '&statusline', '')
+  endif
+endfunction
+
+function! lightline#enable() abort
+  let s:_ = 1
+  call lightline#update()
+  augroup lightline
+    autocmd!
+    autocmd WinEnter,BufEnter,SessionLoadPost,FileChangedShellPost * call lightline#update()
+    if !has('patch-8.1.1715')
+      autocmd FileType qf call lightline#update()
+    endif
+    autocmd SessionLoadPost * call lightline#highlight()
+    autocmd ColorScheme * if !has('vim_starting') || expand('<amatch>') !=# 'macvim'
+          \ | call lightline#update() | call lightline#highlight() | endif
+  augroup END
+  augroup lightline-disable
+    autocmd!
+  augroup END
+  augroup! lightline-disable
+endfunction
+
+function! lightline#disable() abort
+  let [&statusline, &tabline] = [get(s:, '_statusline', ''), get(s:, '_tabline', '')]
+  for t in range(1, tabpagenr('$'))
+    for n in range(1, tabpagewinnr(t, '$'))
+      call settabwinvar(t, n, '&statusline', '')
+    endfor
+  endfor
+  augroup lightline
+    autocmd!
+  augroup END
+  augroup! lightline
+  augroup lightline-disable
+    autocmd!
+    autocmd WinEnter * call lightline#update_disable()
+  augroup END
+  let s:_ = 2
+endfunction
+
+function! lightline#toggle() abort
+  if exists('#lightline')
+    call lightline#disable()
+  else
+    call lightline#enable()
+  endif
+endfunction
+
+let s:_lightline = {
+      \   'active': {
+      \     'left': [['mode', 'paste'], ['readonly', 'filename', 'modified']],
+      \     'right': [['lineinfo'], ['percent'], ['fileformat', 'fileencoding', 'filetype']]
+      \   },
+      \   'inactive': {
+      \     'left': [['filename']],
+      \     'right': [['lineinfo'], ['percent']]
+      \   },
+      \   'tabline': {
+      \     'left': [['tabs']],
+      \     'right': [['close']]
+      \   },
+      \   'tab': {
+      \     'active': ['tabnum', 'filename', 'modified'],
+      \     'inactive': ['tabnum', 'filename', 'modified']
+      \   },
+      \   'component': {
+      \     'mode': '%{lightline#mode()}',
+      \     'absolutepath': '%F', 'relativepath': '%f', 'filename': '%t', 'modified': '%M', 'bufnum': '%n',
+      \     'paste': '%{&paste?"PASTE":""}', 'readonly': '%R', 'charvalue': '%b', 'charvaluehex': '%B',
+      \     'spell': '%{&spell?&spelllang:""}', 'fileencoding': '%{&fenc!=#""?&fenc:&enc}', 'fileformat': '%{&ff}',
+      \     'filetype': '%{&ft!=#""?&ft:"no ft"}', 'percent': '%3p%%', 'percentwin': '%P',
+      \     'lineinfo': '%3l:%-2c', 'line': '%l', 'column': '%c', 'close': '%999X X ', 'winnr': '%{winnr()}'
+      \   },
+      \   'component_visible_condition': {
+      \     'modified': '&modified||!&modifiable', 'readonly': '&readonly', 'paste': '&paste', 'spell': '&spell'
+      \   },
+      \   'component_function': {},
+      \   'component_function_visible_condition': {},
+      \   'component_expand': {
+      \     'tabs': 'lightline#tabs'
+      \   },
+      \   'component_type': {
+      \     'tabs': 'tabsel', 'close': 'raw'
+      \   },
+      \   'component_raw': {},
+      \   'tab_component': {},
+      \   'tab_component_function': {
+      \     'filename': 'lightline#tab#filename', 'modified': 'lightline#tab#modified',
+      \     'readonly': 'lightline#tab#readonly', 'tabnum': 'lightline#tab#tabnum'
+      \   },
+      \   'colorscheme': 'default',
+      \   'mode_map': {
+      \     'n': 'NORMAL', 'i': 'INSERT', 'R': 'REPLACE', 'v': 'VISUAL', 'V': 'V-LINE', "\<C-v>": 'V-BLOCK',
+      \     'c': 'COMMAND', 's': 'SELECT', 'S': 'S-LINE', "\<C-s>": 'S-BLOCK', 't': 'TERMINAL'
+      \   },
+      \   'separator': { 'left': '', 'right': '' },
+      \   'subseparator': { 'left': '|', 'right': '|' },
+      \   'tabline_separator': {},
+      \   'tabline_subseparator': {},
+      \   'enable': { 'statusline': 1, 'tabline': 1 },
+      \   '_mode_': {
+      \     'n': 'normal', 'i': 'insert', 'R': 'replace', 'v': 'visual', 'V': 'visual', "\<C-v>": 'visual',
+      \     'c': 'command', 's': 'select', 'S': 'select', "\<C-s>": 'select', 't': 'terminal'
+      \   },
+      \   'mode_fallback': { 'replace': 'insert', 'terminal': 'insert', 'select': 'visual' },
+      \   'palette': {},
+      \ }
+function! lightline#init() abort
+  let s:lightline = deepcopy(get(g:, 'lightline', {}))
+  for [key, value] in items(s:_lightline)
+    if type(value) == 4
+      if !has_key(s:lightline, key)
+        let s:lightline[key] = {}
+      endif
+      call extend(s:lightline[key], value, 'keep')
+    elseif !has_key(s:lightline, key)
+      let s:lightline[key] = value
+    endif
+    unlet value
+  endfor
+  call extend(s:lightline.tabline_separator, s:lightline.separator, 'keep')
+  call extend(s:lightline.tabline_subseparator, s:lightline.subseparator, 'keep')
+  let s:lightline.tabline_configured = has_key(get(get(g:, 'lightline', {}), 'component_expand', {}), 'tabs')
+  for components in deepcopy(s:lightline.tabline.left + s:lightline.tabline.right)
+    if len(filter(components, 'v:val !=# "tabs" && v:val !=# "close"')) > 0
+      let s:lightline.tabline_configured = 1
+      break
+    endif
+  endfor
+  if !exists('s:_statusline')
+    let s:_statusline = &statusline
+  endif
+  if !exists('s:_tabline')
+    let s:_tabline = &tabline
+  endif
+  if s:lightline.enable.tabline
+    set tabline=%!lightline#tabline()
+  else
+    let &tabline = get(s:, '_tabline', '')
+  endif
+  for f in values(s:lightline.component_function)
+    silent! call call(f, [])
+  endfor
+  for f in values(s:lightline.tab_component_function)
+    silent! call call(f, [1])
+  endfor
+  let s:mode = ''
+endfunction
+
+function! lightline#colorscheme() abort
+  try
+    let s:lightline.palette = g:lightline#colorscheme#{s:lightline.colorscheme}#palette
+  catch
+    call lightline#error('Could not load colorscheme ' . s:lightline.colorscheme . '.')
+    let s:lightline.colorscheme = 'default'
+    let s:lightline.palette = g:lightline#colorscheme#{s:lightline.colorscheme}#palette
+  finally
+    if has('win32') && !has('gui_running') && &t_Co < 256
+      call lightline#colortable#gui2cui_palette(s:lightline.palette)
+    endif
+    let s:highlight = {}
+    call lightline#highlight('normal')
+    call lightline#link()
+    let s:_ = 0
+  endtry
+endfunction
+
+function! lightline#palette() abort
+  return s:lightline.palette
+endfunction
+
+function! lightline#mode() abort
+  return get(s:lightline.mode_map, mode(), '')
+endfunction
+
+let s:mode = ''
+function! lightline#link(...) abort
+  let mode = get(s:lightline._mode_, a:0 ? a:1 : mode(), 'normal')
+  if s:mode ==# mode
+    return ''
+  endif
+  let s:mode = mode
+  if !has_key(s:highlight, mode)
+    call lightline#highlight(mode)
+  endif
+  let types = map(s:uniq(sort(filter(values(s:lightline.component_type), 'v:val !=# "raw"'))), '[v:val, 1]')
+  for [p, l] in [['Left', len(s:lightline.active.left)], ['Right', len(s:lightline.active.right)]]
+    for [i, t] in map(range(0, l), '[v:val, 0]') + types
+      if i != l
+        exec printf('hi link Lightline%s_active_%s Lightline%s_%s_%s', p, i, p, mode, i)
+      endif
+      for [j, s] in map(range(0, l), '[v:val, 0]') + types
+        if i + 1 == j || t || s && i != l
+          exec printf('hi link Lightline%s_active_%s_%s Lightline%s_%s_%s_%s', p, i, j, p, mode, i, j)
+        endif
+      endfor
+    endfor
+  endfor
+  exec printf('hi link LightlineMiddle_active LightlineMiddle_%s', mode)
+  return ''
+endfunction
+
+function! s:term(p) abort
+  return get(a:p, 4) !=# '' ? 'term='.a:p[4].' cterm='.a:p[4].' gui='.a:p[4] : ''
+endfunction
+
+if exists('*uniq')
+  let s:uniq = function('uniq')
+else
+  function! s:uniq(xs) abort
+    let i = len(a:xs) - 1
+    while i > 0
+      if a:xs[i] ==# a:xs[i - 1]
+        call remove(a:xs, i)
+      endif
+      let i -= 1
+    endwhile
+    return a:xs
+  endfunction
+endif
+
+function! lightline#highlight(...) abort
+  let [c, f] = [s:lightline.palette, s:lightline.mode_fallback]
+  let [s:lightline.llen, s:lightline.rlen] = [len(c.normal.left), len(c.normal.right)]
+  let [s:lightline.tab_llen, s:lightline.tab_rlen] = [len(has_key(get(c, 'tabline', {}), 'left') ? c.tabline.left : c.normal.left), len(has_key(get(c, 'tabline', {}), 'right') ? c.tabline.right : c.normal.right)]
+  let types = map(s:uniq(sort(filter(values(s:lightline.component_type), 'v:val !=# "raw"'))), '[v:val, 1]')
+  let modes = a:0 ? [a:1] : extend(['normal', 'insert', 'replace', 'visual', 'inactive', 'command', 'select', 'tabline'], exists(':terminal') == 2 ? ['terminal'] : [])
+  for mode in modes
+    let s:highlight[mode] = 1
+    let d = has_key(c, mode) ? mode : has_key(f, mode) && has_key(c, f[mode]) ? f[mode] : 'normal'
+    let left = d ==# 'tabline' ? s:lightline.tabline.left : d ==# 'inactive' ? s:lightline.inactive.left : s:lightline.active.left
+    let right = d ==# 'tabline' ? s:lightline.tabline.right : d ==# 'inactive' ? s:lightline.inactive.right : s:lightline.active.right
+    let ls = has_key(get(c, d, {}), 'left') ? c[d].left : has_key(f, d) && has_key(get(c, f[d], {}), 'left') ? c[f[d]].left : c.normal.left
+    let ms = has_key(get(c, d, {}), 'middle') ? c[d].middle[0] : has_key(f, d) && has_key(get(c, f[d], {}), 'middle') ? c[f[d]].middle[0] : c.normal.middle[0]
+    let rs = has_key(get(c, d, {}), 'right') ? c[d].right : has_key(f, d) && has_key(get(c, f[d], {}), 'right') ? c[f[d]].right : c.normal.right
+    for [p, l, zs] in [['Left', len(left), ls], ['Right', len(right), rs]]
+      for [i, t] in map(range(0, l), '[v:val, 0]') + types
+        if i < l || i < 1
+          let r = t ? (has_key(get(c, d, []), i) ? c[d][i][0] : has_key(get(c, 'tabline', {}), i) ? c.tabline[i][0] : get(c.normal, i, zs)[0]) : get(zs, i, ms)
+          exec printf('hi Lightline%s_%s_%s guifg=%s guibg=%s ctermfg=%s ctermbg=%s %s', p, mode, i, r[0], r[1], r[2], r[3], s:term(r))
+        endif
+        for [j, s] in map(range(0, l), '[v:val, 0]') + types
+          if i + 1 == j || t || s && i != l
+            let q = s ? (has_key(get(c, d, []), j) ? c[d][j][0] : has_key(get(c, 'tabline', {}), j) ? c.tabline[j][0] : get(c.normal, j, zs)[0]) : (j != l ? get(zs, j, ms) :ms)
+            exec printf('hi Lightline%s_%s_%s_%s guifg=%s guibg=%s ctermfg=%s ctermbg=%s', p, mode, i, j, r[1], q[1], r[3], q[3])
+          endif
+        endfor
+      endfor
+    endfor
+    exec printf('hi LightlineMiddle_%s guifg=%s guibg=%s ctermfg=%s ctermbg=%s %s', mode, ms[0], ms[1], ms[2], ms[3], s:term(ms))
+  endfor
+  if !a:0 | let s:mode = '' | endif
+endfunction
+
+function! s:subseparator(components, subseparator, expanded) abort
+  let [a, c, f, v, u] = [a:components, s:lightline.component, s:lightline.component_function, s:lightline.component_visible_condition, s:lightline.component_function_visible_condition]
+  let xs = map(range(len(a:components)), 'a:expanded[v:val] ? "1" :
+        \ has_key(f, a[v:val]) ? (has_key(u, a[v:val]) ? "(".u[a[v:val]].")" : (exists("*".f[a[v:val]]) ? "" : "exists(\"*".f[a[v:val]]."\")&&").f[a[v:val]]."()!=#\"\"") :
+        \ has_key(v, a[v:val]) ? "(".v[a[v:val]].")" : has_key(c, a[v:val]) ? "1" : "0"')
+  return '%{' . (xs[0] ==# '1' || xs[0] ==# '(1)' ? '' : xs[0] . '&&(') . join(xs[1:], '||') . (xs[0] ==# '1' || xs[0] ==# '(1)' ? '' : ')') . '?"' . a:subseparator . '":""}'
+endfunction
+
+function! lightline#concatenate(xs, right) abort
+  let separator = a:right ? s:lightline.subseparator.right : s:lightline.subseparator.left
+  return join(filter(copy(a:xs), 'v:val !=# ""'), ' ' . separator . ' ')
+endfunction
+
+function! lightline#statusline(inactive) abort
+  if a:inactive && !has_key(s:highlight, 'inactive')
+    call lightline#highlight('inactive')
+  endif
+  return s:line(0, a:inactive)
+endfunction
+
+function! s:normalize(result) abort
+  if type(a:result) == 3
+    return map(a:result, 'type(v:val) == 1 ? v:val : string(v:val)')
+  elseif type(a:result) == 1
+    return [a:result]
+  else
+    return [string(a:result)]
+  endif
+endfunction
+
+function! s:evaluate_expand(component) abort
+  try
+    let result = eval(a:component . '()')
+    if type(result) == 1 && result ==# ''
+      return []
+    endif
+  catch
+    return []
+  endtry
+  return map(type(result) == 3 ? (result + [[], [], []])[:2] : [[], [result], []], 'filter(s:normalize(v:val), "v:val !=# ''''")')
+endfunction
+
+function! s:convert(name, index) abort
+  if !has_key(s:lightline.component_expand, a:name)
+    return [[[a:name], 0, a:index, a:index]]
+  else
+    let type = get(s:lightline.component_type, a:name, a:index)
+    let is_raw = get(s:lightline.component_raw, a:name) || type ==# 'raw'
+    return filter(map(s:evaluate_expand(s:lightline.component_expand[a:name]),
+          \ '[v:val, 1 + ' . is_raw . ', v:key == 1 && ' . (type !=# 'raw') . ' ? "' . type . '" : "' . a:index . '", "' . a:index . '"]'), 'v:val[0] != []')
+  endif
+endfunction
+
+function! s:expand(components) abort
+  let components = []
+  let expanded = []
+  let indices = []
+  let prevtype = ''
+  let previndex = -1
+  let xs = []
+  call map(deepcopy(a:components), 'map(v:val, "extend(xs, s:convert(v:val, ''" . v:key . "''))")')
+  for [component, expand, type, index] in xs
+    if prevtype !=# type
+      for i in range(previndex + 1, max([previndex, index - 1]))
+        call add(indices, string(i))
+        call add(components, [])
+        call add(expanded, [])
+      endfor
+      call add(indices, type)
+      call add(components, [])
+      call add(expanded, [])
+    endif
+    call extend(components[-1], component)
+    call extend(expanded[-1], repeat([expand], len(component)))
+    let prevtype = type
+    let previndex = index
+  endfor
+  for i in range(previndex + 1, max([previndex, len(a:components) - 1]))
+    call add(indices, string(i))
+    call add(components, [])
+    call add(expanded, [])
+  endfor
+  call add(indices, string(len(a:components)))
+  return [components, expanded, indices]
+endfunction
+
+function! s:func(name) abort
+  return exists('*' . a:name) ? '%{' . a:name . '()}' : '%{exists("*' . a:name . '")?' . a:name . '():""}'
+endfunction
+
+function! s:line(tabline, inactive) abort
+  let _ = a:tabline ? '' : '%{lightline#link()}'
+  if s:lightline.palette == {}
+    call lightline#colorscheme()
+  endif
+  let [l, r] = a:tabline ? [s:lightline.tab_llen, s:lightline.tab_rlen] : [s:lightline.llen, s:lightline.rlen]
+  let [p, s] = a:tabline ? [s:lightline.tabline_separator, s:lightline.tabline_subseparator] : [s:lightline.separator, s:lightline.subseparator]
+  let [c, f, t, w] = [s:lightline.component, s:lightline.component_function, s:lightline.component_type, s:lightline.component_raw]
+  let mode = a:tabline ? 'tabline' : a:inactive ? 'inactive' : 'active'
+  let ls = has_key(s:lightline, mode) ? s:lightline[mode].left : s:lightline.active.left
+  let [lc, le, li] = s:expand(ls)
+  let rs = has_key(s:lightline, mode) ? s:lightline[mode].right : s:lightline.active.right
+  let [rc, re, ri] = s:expand(rs)
+  for i in range(len(lc))
+    let _ .= '%#LightlineLeft_' . mode . '_' . li[i] . '#'
+    for j in range(len(lc[i]))
+      let x = le[i][j] ? lc[i][j] : has_key(f, lc[i][j]) ? s:func(f[lc[i][j]]) : get(c, lc[i][j], '')
+      let _ .= has_key(t, lc[i][j]) && t[lc[i][j]] ==# 'raw' || get(w, lc[i][j]) || le[i][j] ==# 2 || x ==# '' ? x : '%( ' . x . ' %)'
+      if j < len(lc[i]) - 1 && s.left !=# ''
+        let _ .= s:subseparator(lc[i][(j):], s.left, le[i][(j):])
+      endif
+    endfor
+    let _ .= '%#LightlineLeft_' . mode . '_' . li[i] . '_' . li[i + 1] . '#'
+    let _ .= i < l + len(lc) - len(ls) && li[i] < l || li[i] != li[i + 1] ? p.left : len(lc[i]) ? s.left : ''
+  endfor
+  let _ .= '%#LightlineMiddle_' . mode . '#%='
+  for i in range(len(rc) - 1, 0, -1)
+    let _ .= '%#LightlineRight_' . mode . '_' . ri[i] . '_' . ri[i + 1] . '#'
+    let _ .= i < r + len(rc) - len(rs) && ri[i] < r || ri[i] != ri[i + 1] ? p.right : len(rc[i]) ? s.right : ''
+    let _ .= '%#LightlineRight_' . mode . '_' . ri[i] . '#'
+    for j in range(len(rc[i]))
+      let x = re[i][j] ? rc[i][j] : has_key(f, rc[i][j]) ? s:func(f[rc[i][j]]) : get(c, rc[i][j], '')
+      let _ .= has_key(t, rc[i][j]) && t[rc[i][j]] ==# 'raw' || get(w, rc[i][j]) || re[i][j] ==# 2 || x ==# '' ? x : '%( ' . x . ' %)'
+      if j < len(rc[i]) - 1 && s.right !=# ''
+        let _ .= s:subseparator(rc[i][(j):], s.right, re[i][(j):])
+      endif
+    endfor
+  endfor
+  return _
+endfunction
+
+let s:tabnr = -1
+let s:tabcnt = -1
+let s:columns = -1
+let s:tabline = ''
+function! lightline#tabline() abort
+  if !has_key(s:highlight, 'tabline')
+    call lightline#highlight('tabline')
+  endif
+  if s:lightline.tabline_configured || s:tabnr != tabpagenr() || s:tabcnt != tabpagenr('$') || s:columns != &columns
+    let s:tabnr = tabpagenr()
+    let s:tabcnt = tabpagenr('$')
+    let s:columns = &columns
+    let s:tabline = s:line(1, 0)
+  endif
+  return s:tabline
+endfunction
+
+function! lightline#tabs() abort
+  let [x, y, z] = [[], [], []]
+  let nr = tabpagenr()
+  let cnt = tabpagenr('$')
+  for i in range(1, cnt)
+    call add(i < nr ? x : i == nr ? y : z, (i > nr + 3 ? '%<' : '') . '%' . i . 'T%{lightline#onetab(' . i . ',' . (i == nr) . ')}' . (i == cnt ? '%T' : ''))
+  endfor
+  let abbr = '...'
+  let n = min([max([&columns / 40, 2]), 8])
+  if len(x) > n && len(z) > n
+    let x = extend(add(x[:n/2-1], abbr), x[-(n+1)/2:])
+    let z = extend(add(z[:(n+1)/2-1], abbr), z[-n/2:])
+  elseif len(x) + len(z) > 2 * n
+    if len(x) > n
+      let x = extend(add(x[:(2*n-len(z))/2-1], abbr), x[-(2*n-len(z)+1)/2:])
+    elseif len(z) > n
+      let z = extend(add(z[:(2*n-len(x)+1)/2-1], abbr), z[-(2*n-len(x))/2:])
+    endif
+  endif
+  return [x, y, z]
+endfunction
+
+function! lightline#onetab(n, active) abort
+  let _ = []
+  for name in a:active ? s:lightline.tab.active : s:lightline.tab.inactive
+    if has_key(s:lightline.tab_component_function, name)
+      call add(_, call(s:lightline.tab_component_function[name], [a:n]))
+    else
+      call add(_, get(s:lightline.tab_component, name, ''))
+    endif
+  endfor
+  return join(filter(_, 'v:val !=# ""'), ' ')
+endfunction
+
+function! lightline#error(msg) abort
+  echohl ErrorMsg
+  echomsg 'lightline.vim: '.a:msg
+  echohl None
+endfunction
+
+let &cpo = s:save_cpo
+unlet s:save_cpo

+ 257 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme.vim

@@ -0,0 +1,257 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2019/09/07 11:20:37.
+" =============================================================================
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+let s:cuicolor = {
+      \ 'black'          : 16,
+      \ 'white'          : 231,
+      \
+      \ 'darkestgreen'   : 22,
+      \ 'darkgreen'      : 28,
+      \ 'mediumgreen'    : 70,
+      \ 'brightgreen'    : 148,
+      \
+      \ 'darkestcyan'    : 23,
+      \ 'mediumcyan'     : 117,
+      \
+      \ 'darkestblue'    : 24,
+      \ 'darkblue'       : 31,
+      \
+      \ 'darkestred'     : 52,
+      \ 'darkred'        : 88,
+      \ 'mediumred'      : 124,
+      \ 'brightred'      : 160,
+      \ 'brightestred'   : 196,
+      \
+      \ 'darkestpurple'  : 55,
+      \ 'mediumpurple'   : 98,
+      \ 'brightpurple'   : 189,
+      \
+      \ 'brightorange'   : 208,
+      \ 'brightestorange': 214,
+      \
+      \ 'gray0'          : 233,
+      \ 'gray1'          : 235,
+      \ 'gray2'          : 236,
+      \ 'gray3'          : 239,
+      \ 'gray4'          : 240,
+      \ 'gray5'          : 241,
+      \ 'gray6'          : 244,
+      \ 'gray7'          : 245,
+      \ 'gray8'          : 247,
+      \ 'gray9'          : 250,
+      \ 'gray10'         : 252,
+      \
+      \ 'yellow'         : 136,
+      \ 'orange'         : 166,
+      \ 'red'            : 160,
+      \ 'magenta'        : 125,
+      \ 'violet'         : 61,
+      \ 'blue'           : 33,
+      \ 'cyan'           : 37,
+      \ 'green'          : 64,
+      \ }
+
+let s:guicolor = {
+      \ 'black'          : '#000000',
+      \ 'white'          : '#ffffff',
+      \
+      \ 'darkestgreen'   : '#005f00',
+      \ 'darkgreen'      : '#008700',
+      \ 'mediumgreen'    : '#5faf00',
+      \ 'brightgreen'    : '#afdf00',
+      \
+      \ 'darkestcyan'    : '#005f5f',
+      \ 'mediumcyan'     : '#87dfff',
+      \
+      \ 'darkestblue'    : '#005f87',
+      \ 'darkblue'       : '#0087af',
+      \
+      \ 'darkestred'     : '#5f0000',
+      \ 'darkred'        : '#870000',
+      \ 'mediumred'      : '#af0000',
+      \ 'brightred'      : '#df0000',
+      \ 'brightestred'   : '#ff0000',
+      \
+      \ 'darkestpurple'  : '#5f00af',
+      \ 'mediumpurple'   : '#875fdf',
+      \ 'brightpurple'   : '#dfdfff',
+      \
+      \ 'brightorange'   : '#ff8700',
+      \ 'brightestorange': '#ffaf00',
+      \
+      \ 'gray0'          : '#121212',
+      \ 'gray1'          : '#262626',
+      \ 'gray2'          : '#303030',
+      \ 'gray3'          : '#4e4e4e',
+      \ 'gray4'          : '#585858',
+      \ 'gray5'          : '#606060',
+      \ 'gray6'          : '#808080',
+      \ 'gray7'          : '#8a8a8a',
+      \ 'gray8'          : '#9e9e9e',
+      \ 'gray9'          : '#bcbcbc',
+      \ 'gray10'         : '#d0d0d0',
+      \
+      \ 'yellow'         : '#b58900',
+      \ 'orange'         : '#cb4b16',
+      \ 'red'            : '#dc322f',
+      \ 'magenta'        : '#d33682',
+      \ 'violet'         : '#6c71c4',
+      \ 'blue'           : '#268bd2',
+      \ 'cyan'           : '#2aa198',
+      \ 'green'          : '#859900',
+      \ }
+
+function! s:convert(rgb) abort
+  let rgb = map(matchlist(a:rgb, '#\(..\)\(..\)\(..\)')[1:3], '0 + ("0x".v:val)')
+  if len(rgb) == 0
+    return 0
+  endif
+  if rgb[0] == 0xc0 && rgb[1] == 0xc0 && rgb[2] == 0xc0
+    return 7
+  elseif rgb[0] == 0x80 && rgb[1] == 0x80 && rgb[2] == 0x80
+    return 8
+  elseif (rgb[0] == 0x80 || rgb[0] == 0x00) && (rgb[1] == 0x80 || rgb[1] == 0x00) && (rgb[2] == 0x80 || rgb[2] == 0x00)
+    return (rgb[0] / 0x80) + (rgb[1] / 0x80) * 2 + (rgb[1] / 0x80) * 4
+  elseif abs(rgb[0]-rgb[1]) < 3 && abs(rgb[1]-rgb[2]) < 3 && abs(rgb[2]-rgb[0]) < 3
+    return s:black((rgb[0] + rgb[1] + rgb[2]) / 3)
+  else
+    return 16 + ((s:nr(rgb[0]) * 6) + s:nr(rgb[1])) * 6 + s:nr(rgb[2])
+  endif
+endfunction
+
+function! s:black(x) abort
+  if a:x < 0x04
+    return 16
+  elseif a:x > 0xf4
+    return 231
+  elseif index([0x00, 0x5f, 0x87, 0xaf, 0xdf, 0xff], a:x) >= 0
+    let l = a:x / 0x30
+    return ((l * 6) + l) * 6 + l + 16
+  else
+    return 232 + (a:x < 8 ? 0 : a:x < 0x60 ? (a:x-8)/10 : a:x < 0x76 ? (a:x-0x60)/6+9 : (a:x-8)/10)
+  endif
+endfunction
+
+function! s:nr(x) abort
+  return a:x < 0x2f ? 0 : a:x < 0x73 ? 1 : a:x < 0x9b ? 2 : a:x < 0xc7 ? 3 : a:x < 0xef ? 4 : 5
+endfunction
+
+function! s:rgb(r, g, b) abort
+  return printf('#%02x%02x%02x', a:r, a:g, a:b)
+endfunction
+
+function! s:upconvert(nr) abort
+  let x = a:nr * 1
+  if x < 7
+    let [b, rg] = [x / 4, x % 4]
+    let [g, r] = [rg / 2, rg % 2]
+    return s:rgb(r * 0x80, g * 0x80, b * 0x80)
+  elseif x == 7
+    return s:rgb(0xc0, 0xc0, 0xc0)
+  elseif x == 8
+    return s:rgb(0x80, 0x80, 0x80)
+  elseif x < 16
+    let y = x - 8
+    let [b, rg] = [y / 4, y % 4]
+    let [g, r] = [rg / 2, rg % 2]
+    return s:rgb(r * 0xff, g * 0xff, b * 0xff)
+  elseif x < 232
+    let y = x - 16
+    let [rg, b] = [y / 6, y % 6]
+    let [r, g] = [rg / 6, rg % 6]
+    let l = [0x00, 0x5f, 0x87, 0xaf, 0xdf, 0xff]
+    return s:rgb(l[r], l[g], l[b])
+  elseif x < 241
+    let k = (x - 232) * 10 + 8
+    return s:rgb(k, k, k)
+  elseif x < 243
+    let k = (x - 241) * 6 + 0x60
+    return s:rgb(k, k, k)
+  else
+    let k = (x - 232) * 10 + 8
+    return s:rgb(k, k, k)
+  endif
+endfunction
+
+function! lightline#colorscheme#fill(p) abort
+  for k in values(a:p)
+    for l in values(k)
+      for m in l
+        if len(m) < 4
+          if type(m[0]) == 1 && type(m[1]) == 1
+            if m[0] =~# '^\d\+$' && m[1] =~# '^\d\+$'
+              call insert(m, s:upconvert(m[1]), 0)
+              call insert(m, s:upconvert(m[1]), 0)
+            else
+              call insert(m, get(s:cuicolor, m[0], s:convert(m[0])), 2)
+              call insert(m, get(s:cuicolor, m[1], s:convert(m[1])), 3)
+              let m[0] = get(s:guicolor, m[0], m[0])
+              let m[1] = get(s:guicolor, m[1], m[1])
+            endif
+          elseif type(m[0]) == 0 && type(m[1]) == 0
+              call insert(m, s:upconvert(m[1]), 0)
+              call insert(m, s:upconvert(m[1]), 0)
+          endif
+        endif
+      endfor
+    endfor
+  endfor
+  return a:p
+endfunction
+
+function! lightline#colorscheme#flatten(p) abort
+  for k in values(a:p)
+    for l in values(k)
+      for m in range(len(l))
+        let attr = ''
+        if len(l[m]) == 3 && type(l[m][2]) == 1
+          let attr = l[m][2]
+        endif
+        let l[m] = [l[m][0][0], l[m][1][0], l[m][0][1], l[m][1][1]]
+        if !empty(attr)
+          call add(l[m], attr)
+        endif
+      endfor
+    endfor
+  endfor
+  return a:p
+endfunction
+
+if has('gui_running') || (has('termguicolors') && &termguicolors)
+  function! lightline#colorscheme#background() abort
+    return &background
+  endfunction
+else
+  " &background is set inappropriately when the colorscheme sets ctermbg of the Normal group
+  function! lightline#colorscheme#background() abort
+    let bg_color = synIDattr(synIDtrans(hlID('Normal')), 'bg', 'cterm')
+    if bg_color !=# ''
+      if bg_color < 16
+        return &background
+      elseif 232 <= bg_color && bg_color < 244
+        return 'dark'
+      elseif 244 <= bg_color
+        return 'light'
+      endif
+    endif
+    let fg_color = synIDattr(synIDtrans(hlID('Normal')), 'fg', 'cterm')
+    if fg_color !=# ''
+      if fg_color < 7 || 232 <= fg_color && fg_color < 244
+        return 'light'
+      elseif 8 <= fg_color && fg_color < 16 || 244 <= fg_color
+        return 'dark'
+      endif
+    endif
+    return &background
+  endfunction
+endif
+
+let &cpo = s:save_cpo
+unlet s:save_cpo

+ 53 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/16color.vim

@@ -0,0 +1,53 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/16color.vim
+" Author: itchyny, jackno
+" License: MIT License
+" =============================================================================
+
+let s:black = [ '#000000', 0 ]
+let s:maroon = [ '#800000', 1 ]
+let s:green = [ '#008000', 2 ]
+let s:olive = [ '#808000', 3 ]
+let s:navy = [ '#000080', 4 ]
+let s:purple = [ '#800080', 5 ]
+let s:teal = [ '#008080', 6 ]
+let s:silver = [ '#c0c0c0', 7 ]
+let s:gray = [ '#808080', 8]
+let s:red = [ '#ff0000', 9 ]
+let s:lime = [ '#00ff00', 10 ]
+let s:yellow = [ '#ffff00', 11 ]
+let s:blue = [ '#0000ff', 12 ]
+let s:fuchsia = [ '#ff00ff', 13 ]
+let s:aqua = [ '#00ffff', 14 ]
+let s:white = [ '#ffffff', 15 ]
+
+if lightline#colorscheme#background() ==# 'light'
+  let [s:black, s:white] = [s:white, s:black]
+  let [s:silver, s:gray] = [s:gray, s:silver]
+  let [s:blue, s:aqua] = [s:aqua, s:blue]
+  let [s:purple, s:fuchsia] = [s:fuchsia, s:purple]
+  let [s:green, s:lime] = [s:lime, s:green]
+  let [s:red, s:yellow] = [s:yellow, s:red]
+endif
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:white, s:blue ], [ s:white, s:gray ] ]
+let s:p.normal.middle = [ [ s:silver, s:black ] ]
+let s:p.normal.right = [ [ s:white, s:blue ], [ s:white, s:gray ] ]
+let s:p.normal.error = [ [ s:black, s:red ] ]
+let s:p.normal.warning = [ [ s:black, s:yellow ] ]
+let s:p.inactive.left =  [ [ s:silver, s:gray ], [ s:gray, s:black ] ]
+let s:p.inactive.middle = [ [ s:silver, s:black ] ]
+let s:p.inactive.right = [ [ s:silver, s:gray ], [ s:gray, s:black ] ]
+let s:p.insert.left = [ [ s:white, s:green ], [ s:white, s:gray ] ]
+let s:p.insert.right = copy(s:p.insert.left)
+let s:p.replace.left = [ [ s:white, s:red ], [ s:white, s:gray ] ]
+let s:p.replace.right = copy(s:p.replace.left)
+let s:p.visual.left = [ [ s:white, s:purple ], [ s:white, s:gray ] ]
+let s:p.visual.right = copy(s:p.visual.left)
+let s:p.tabline.left = [ [ s:silver, s:black ] ]
+let s:p.tabline.tabsel = copy(s:p.normal.right)
+let s:p.tabline.middle = [ [ s:silver, s:black ] ]
+let s:p.tabline.right = copy(s:p.normal.right)
+
+let g:lightline#colorscheme#16color#palette = lightline#colorscheme#flatten(s:p)

+ 44 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/OldHope.vim

@@ -0,0 +1,44 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/OldHope.vim
+" Author: tomb0y
+" License: MIT License
+" Last Change: 2017/10/15 06:20:54.
+" =============================================================================
+
+let s:yellow = [ '#e5cd52' , 221 ]
+let s:blue = [ '#4fb4d8' , 39 ]
+let s:red = [ '#f92672' , 161 ]
+let s:green = [ '#78bd65' , 41 ]
+let s:orange = [ '#ef7c2a' , 202 ]
+let s:white = [ '#ffffff' , 15 ]
+let s:lightGray = [ '#848794' , 245 ]
+let s:gray = [ '#686b78' , 242 ]
+let s:darkGray = [ '#45474f' , 238 ]
+let s:veryDarkGray = [ '#1c1d21' , 234 ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+
+let s:p.normal.left = [ [ s:white, s:blue ], [ s:white, s:gray ] ]
+let s:p.insert.left = [ [ s:white, s:green ], [ s:white, s:gray ] ]
+let s:p.visual.left = [ [ s:white, s:orange ], [ s:white, s:gray ] ]
+let s:p.replace.left = [ [ s:white, s:red ], [ s:white, s:gray ] ]
+
+let s:p.inactive.right = [ [ s:darkGray, s:gray ], [ s:darkGray, s:gray ] ]
+let s:p.inactive.left = [ [ s:lightGray, s:darkGray ], [ s:white, s:darkGray ] ]
+let s:p.inactive.middle = [ [ s:white, s:darkGray ] ]
+
+let s:p.normal.middle = [ [ s:white, s:darkGray ] ]
+let s:p.normal.error = [ [ s:red, s:darkGray ] ]
+let s:p.normal.warning = [ [ s:orange, s:darkGray ] ]
+
+let s:p.tabline.left = [ [ s:lightGray, s:darkGray ] ]
+let s:p.tabline.tabsel = [ [ s:darkGray, s:yellow ] ]
+let s:p.tabline.middle = [ [ s:yellow, s:veryDarkGray ] ]
+
+let s:p.normal.right = copy(s:p.normal.left)
+let s:p.insert.right = copy(s:p.insert.left)
+let s:p.visual.right = copy(s:p.visual.left)
+let s:p.replace.right = copy(s:p.replace.left)
+let s:p.tabline.right = copy(s:p.tabline.left)
+
+let g:lightline#colorscheme#OldHope#palette = lightline#colorscheme#flatten(s:p)

+ 12 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/PaperColor.vim

@@ -0,0 +1,12 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/PaperColor.vim
+" Author: TKNGUE
+" License: MIT License
+" Last Change: 2017/11/25 11:13:35.
+" =============================================================================
+
+if lightline#colorscheme#background() ==# 'light'
+  let g:lightline#colorscheme#PaperColor#palette = g:lightline#colorscheme#PaperColor_light#palette
+else
+  let g:lightline#colorscheme#PaperColor#palette = g:lightline#colorscheme#PaperColor_dark#palette
+endif

+ 60 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/PaperColor_dark.vim

@@ -0,0 +1,60 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/PaperColor_dark.vim
+" Author: TKNGUE
+" License: MIT License
+" Last Change: 2015-07-27 06:01
+" =============================================================================
+
+let s:red = '#df0000'
+let s:green = '#008700'
+let s:blue = '#00afaf'
+
+let s:pink = '#afdf00'
+let s:olive = '#dfaf5f'
+let s:navy = '#df875f'
+
+let s:orange = '#d75f00'
+let s:purple = '#8959a8'
+let s:aqua = '#3e999f'
+
+" Basics:
+let s:foreground = '#d0d0d0'
+let s:background = '#444444'
+let s:window = '#efefef'
+let s:status = '#c6c6c6'
+let s:error = '#5f0000'
+
+" Tabline:
+let s:tabline_bg = '#3a3a3a'
+let s:tabline_active_fg = '#1c1c1c'
+let s:tabline_active_bg = '#00afaf'
+let s:tabline_inactive_fg = '#c6c6c6'
+let s:tabline_inactive_bg = '#585858'
+
+" Statusline:
+let s:statusline_active_fg = '#1c1c1c'
+let s:statusline_active_bg = '#5f8787'
+let s:statusline_inactive_fg = '#c6c6c6'
+let s:statusline_inactive_bg = '#444444'
+
+" Visual:
+let s:visual_fg = '#000000'
+let s:visual_bg = '#8787af'
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:foreground, s:background ], [ s:statusline_active_fg, s:status ], [ s:statusline_active_fg, s:statusline_active_bg ] ]
+let s:p.normal.right = [ [ s:foreground, s:background ], [ s:statusline_active_fg, s:status ], [ s:statusline_active_fg, s:statusline_active_bg ] ]
+let s:p.normal.middle = [ [ s:statusline_active_fg, s:statusline_active_bg ]]
+let s:p.inactive.right = [ [ s:foreground, s:background ], [ s:foreground, s:background ] ]
+let s:p.inactive.left = [ [ s:foreground, s:background ], [ s:foreground, s:background ] ]
+let s:p.inactive.middle = [ [ s:foreground, s:background ], ]
+let s:p.insert.left = [ [ s:background, s:blue], [ s:statusline_active_fg, s:status ], [ s:statusline_active_fg, s:statusline_active_bg ] ]
+let s:p.replace.left = [ [ s:background, s:pink ], [s:statusline_active_fg, s:status ], [ s:statusline_active_fg, s:statusline_active_bg ] ]
+let s:p.visual.left = [ [ s:visual_fg, s:visual_bg ], [s:statusline_active_fg, s:status ], [ s:statusline_active_fg, s:statusline_active_bg ] ]
+let s:p.tabline.left = [ [s:tabline_inactive_fg, s:tabline_inactive_bg ]]
+let s:p.tabline.tabsel = [ [s:tabline_active_fg, s:tabline_active_bg ] ]
+let s:p.tabline.middle = [ [s:tabline_bg, s:tabline_bg]]
+let s:p.tabline.right = copy(s:p.normal.right)
+let s:p.normal.error = [ [ s:background, s:error ] ]
+
+let g:lightline#colorscheme#PaperColor_dark#palette = lightline#colorscheme#fill(s:p)

+ 55 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/PaperColor_light.vim

@@ -0,0 +1,55 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/PaperColor_light.vim
+" Author: TKNGUE
+" License: MIT License
+" Last Change: 2015/07/28 07:46:40.
+" =============================================================================
+
+let s:red = '#df0000'
+let s:green = '#008700'
+let s:blue = '#4271ae'
+let s:pink = '#d7005f'
+let s:olive = '#718c00'
+let s:navy = '#005f87'
+let s:orange = '#d75f00'
+let s:purple = '#8959a8'
+let s:aqua = '#3e999f'
+
+" Basics:
+let s:foreground = '#4d4d4c'
+let s:background = '#F5F5F5'
+let s:window = '#efefef'
+let s:status = s:aqua
+let s:error = '#ffafdf'
+
+" Tabline:
+let s:tabline_bg = s:navy
+let s:tabline_active_fg = s:foreground
+let s:tabline_active_bg = s:window
+let s:tabline_inactive_fg = s:background
+let s:tabline_inactive_bg = s:aqua
+
+" Statusline:
+let s:statusline_active_fg = s:window
+let s:statusline_active_bg = s:navy
+let s:statusline_inactive_fg = s:foreground
+let s:statusline_inactive_bg = '#dadada'
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:foreground, s:background ], [ s:statusline_active_fg, s:status ], [ s:statusline_active_fg, s:statusline_active_bg ] ]
+let s:p.normal.right = [ [ s:foreground, s:background ], [ s:statusline_active_fg, s:status ], [ s:statusline_active_fg, s:statusline_active_bg ] ]
+let s:p.normal.middle = [ [ s:statusline_active_fg, s:statusline_active_bg ]]
+let s:p.inactive.right = [ [ s:foreground, s:background ], [ s:foreground, s:background ] ]
+let s:p.inactive.left = [ [ s:foreground, s:background ], [ s:foreground, s:background ] ]
+let s:p.inactive.middle = [ [ s:foreground, s:background ], ]
+let s:p.insert.left = [ [ s:blue, s:background ], [ s:statusline_active_fg, s:status ], [ s:statusline_active_fg, s:statusline_active_bg ] ]
+let s:p.replace.left = [ [ s:background, s:pink ], [s:statusline_active_fg, s:status ], [ s:statusline_active_fg, s:statusline_active_bg ] ]
+let s:p.visual.left = [ [ s:background, s:orange ], [s:statusline_active_fg, s:status ], [ s:statusline_active_fg, s:statusline_active_bg ] ]
+let s:p.tabline.left = [ [s:tabline_inactive_fg, s:tabline_inactive_bg ]]
+let s:p.tabline.tabsel = [ [s:tabline_active_fg, s:tabline_active_bg ] ]
+let s:p.tabline.middle = [ [s:tabline_bg, s:tabline_bg]]
+let s:p.tabline.right = copy(s:p.normal.right)
+let s:p.normal.error = [ [ s:background, s:error ] ]
+let s:p.normal.warning = [ [ s:background, s:olive ] ]
+
+let g:lightline#colorscheme#PaperColor_light#palette = lightline#colorscheme#fill(s:p)

+ 42 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/Tomorrow.vim

@@ -0,0 +1,42 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/Tomorrow.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2022/03/15 23:57:37.
+" =============================================================================
+
+let s:base03 = '#fafafa'
+let s:base023 = '#dfdfdf'
+let s:base02 = '#c8c8c8'
+let s:base01 = '#b4b4b4'
+let s:base00 = '#808080'
+let s:base0 = '#666666'
+let s:base1 = '#555555'
+let s:base2 = '#4f4f4f'
+let s:base3 = '#4d4d4c'
+let s:red = '#c82829'
+let s:orange = '#f5871f'
+let s:yellow = '#eab700'
+let s:green = '#718c00'
+let s:cyan = '#3e999f'
+let s:blue = '#4271ae'
+let s:magenta = '#8959a8'
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base02, s:blue ], [ s:base3, s:base01 ] ]
+let s:p.normal.right = [ [ s:base02, s:base0 ], [ s:base1, s:base01 ] ]
+let s:p.inactive.right = [ [ s:base02, s:base00 ], [ s:base00, s:base02 ] ]
+let s:p.inactive.left =  [ [ s:base0, s:base02 ], [ s:base00, s:base03 ] ]
+let s:p.insert.left = [ [ s:base02, s:green ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base02, s:orange ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base02, s:magenta ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base1, s:base02 ] ]
+let s:p.inactive.middle = [ [ s:base0, s:base02 ] ]
+let s:p.tabline.left = [ [ s:base2, s:base01 ] ]
+let s:p.tabline.tabsel = [ [ s:base2, s:base023 ] ]
+let s:p.tabline.middle = [ [ s:base01, s:base00 ] ]
+let s:p.tabline.right = copy(s:p.normal.right)
+let s:p.normal.error = [ [ s:red, s:base01 ] ]
+let s:p.normal.warning = [ [ s:yellow, s:base0 ] ]
+
+let g:lightline#colorscheme#Tomorrow#palette = lightline#colorscheme#fill(s:p)

+ 42 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/Tomorrow_Night.vim

@@ -0,0 +1,42 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/Tomorrow_Night.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2022/03/15 23:57:43.
+" =============================================================================
+
+let s:base3 = '#c5c8c6'
+let s:base2 = '#bababa'
+let s:base1 = '#a0a0a0'
+let s:base0 = '#909090'
+let s:base00 = '#666666'
+let s:base01 = '#555555'
+let s:base02 = '#434343'
+let s:base023 = '#303030'
+let s:base03 = '#1d1f21'
+let s:red = '#cc6666'
+let s:orange = '#de935f'
+let s:yellow = '#f0c674'
+let s:green = '#b5bd68'
+let s:cyan = '#8abeb7'
+let s:blue = '#81a2be'
+let s:magenta = '#b294bb'
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base02, s:blue ], [ s:base3, s:base01 ] ]
+let s:p.normal.right = [ [ s:base02, s:base0 ], [ s:base1, s:base01 ] ]
+let s:p.inactive.right = [ [ s:base02, s:base00 ], [ s:base00, s:base02 ] ]
+let s:p.inactive.left =  [ [ s:base0, s:base02 ], [ s:base00, s:base03 ] ]
+let s:p.insert.left = [ [ s:base02, s:green ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base02, s:orange ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base02, s:magenta ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base1, s:base02 ] ]
+let s:p.inactive.middle = [ [ s:base0, s:base02 ] ]
+let s:p.tabline.left = [ [ s:base2, s:base01 ] ]
+let s:p.tabline.tabsel = [ [ s:base2, s:base023 ] ]
+let s:p.tabline.middle = [ [ s:base01, s:base0 ] ]
+let s:p.tabline.right = copy(s:p.normal.right)
+let s:p.normal.error = [ [ s:red, s:base023 ] ]
+let s:p.normal.warning = [ [ s:yellow, s:base02 ] ]
+
+let g:lightline#colorscheme#Tomorrow_Night#palette = lightline#colorscheme#fill(s:p)

+ 43 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/Tomorrow_Night_Blue.vim

@@ -0,0 +1,43 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/Tomorrow_Night_Blue.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2022/03/15 23:57:49.
+" =============================================================================
+
+let s:base3 = '#ffffff'
+let s:base23 = '#ffffff'
+let s:base2 = '#ffffff'
+let s:base1 = '#ffffff'
+let s:base0 = '#ffffff'
+let s:base00 = '#6060df'
+let s:base01 = '#6060af'
+let s:base02 = '#606087'
+let s:base023 = '#202087'
+let s:base03 = '#002451'
+let s:red = '#ff9da4'
+let s:orange = '#ffc58f'
+let s:yellow = '#ffeead'
+let s:green = '#d1f1a9'
+let s:cyan = '#99ffff'
+let s:blue = '#bbdaff'
+let s:magenta = '#ebbbff'
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base023, s:blue ], [ s:base3, s:base01 ] ]
+let s:p.normal.right = [ [ s:base02, s:base1 ], [ s:base2, s:base01 ] ]
+let s:p.inactive.right = [ [ s:base02, s:base0 ], [ s:base1, s:base01 ] ]
+let s:p.inactive.left =  [ [ s:base02, s:base0 ], [ s:base00, s:base03 ] ]
+let s:p.insert.left = [ [ s:base023, s:green ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base023, s:orange ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base023, s:magenta ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base1, s:base02 ] ]
+let s:p.inactive.middle = [ [ s:base0, s:base02 ] ]
+let s:p.tabline.left = [ [ s:base2, s:base01 ] ]
+let s:p.tabline.tabsel = [ [ s:base2, s:base03 ] ]
+let s:p.tabline.middle = [ [ s:base01, s:base1 ] ]
+let s:p.tabline.right = copy(s:p.normal.right)
+let s:p.normal.error = [ [ s:base023, s:red ] ]
+let s:p.normal.warning = [ [ s:base023, s:yellow ] ]
+
+let g:lightline#colorscheme#Tomorrow_Night_Blue#palette = lightline#colorscheme#fill(s:p)

+ 43 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/Tomorrow_Night_Bright.vim

@@ -0,0 +1,43 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/Tomorrow_Night_Bright.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2022/03/15 23:57:52.
+" =============================================================================
+
+let s:base3 = '#eaeaea'
+let s:base23 = '#d0d0d0'
+let s:base2 = '#c6c6c6'
+let s:base1 = '#b2b2b2'
+let s:base0 = '#949494'
+let s:base00 = '#767676'
+let s:base01 = '#606060'
+let s:base02 = '#4e4e4e'
+let s:base023 = '#262626'
+let s:base03 = '#12124c'
+let s:red = '#d54e53'
+let s:orange = '#e78c45'
+let s:yellow = '#e7c547'
+let s:green = '#b9ca4a'
+let s:cyan = '#70c0b1'
+let s:blue = '#7aa6da'
+let s:magenta = '#c397d8'
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base023, s:blue ], [ s:base3, s:base01 ] ]
+let s:p.normal.right = [ [ s:base02, s:base1 ], [ s:base2, s:base01 ] ]
+let s:p.inactive.right = [ [ s:base02, s:base0 ], [ s:base1, s:base01 ] ]
+let s:p.inactive.left =  [ [ s:base02, s:base0 ], [ s:base00, s:base03 ] ]
+let s:p.insert.left = [ [ s:base023, s:green ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base023, s:orange ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base023, s:magenta ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base1, s:base02 ] ]
+let s:p.inactive.middle = [ [ s:base0, s:base02 ] ]
+let s:p.tabline.left = [ [ s:base2, s:base01 ] ]
+let s:p.tabline.tabsel = [ [ s:base2, s:base023 ] ]
+let s:p.tabline.middle = [ [ s:base01, s:base1 ] ]
+let s:p.tabline.right = copy(s:p.normal.right)
+let s:p.normal.error = [ [ s:red, s:base023 ] ]
+let s:p.normal.warning = [ [ s:yellow, s:base02 ] ]
+
+let g:lightline#colorscheme#Tomorrow_Night_Bright#palette = lightline#colorscheme#fill(s:p)

+ 43 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/Tomorrow_Night_Eighties.vim

@@ -0,0 +1,43 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/Tomorrow_Night_Eighties.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2022/03/15 23:57:56.
+" =============================================================================
+
+let s:base3 = '#cccccc'
+let s:base23 = '#bbbbbb'
+let s:base2 = '#aaaaaa'
+let s:base1 = '#999999'
+let s:base0 = '#777777'
+let s:base00 = '#666666'
+let s:base01 = '#555555'
+let s:base02 = '#444444'
+let s:base023 = '#333333'
+let s:base03 = '#2d2d2d'
+let s:red = '#f2777a'
+let s:orange = '#f99157'
+let s:yellow = '#ffcc66'
+let s:green = '#99cc99'
+let s:cyan = '#009999'
+let s:blue = '#99cccc'
+let s:magenta = '#cc99cc'
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base023, s:blue ], [ s:base3, s:base01 ] ]
+let s:p.normal.right = [ [ s:base02, s:base1 ], [ s:base2, s:base01 ] ]
+let s:p.inactive.right = [ [ s:base02, s:base0 ], [ s:base1, s:base01 ] ]
+let s:p.inactive.left =  [ [ s:base02, s:base0 ], [ s:base00, s:base03 ] ]
+let s:p.insert.left = [ [ s:base023, s:green ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base023, s:orange ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base023, s:magenta ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base1, s:base02 ] ]
+let s:p.inactive.middle = [ [ s:base0, s:base02 ] ]
+let s:p.tabline.left = [ [ s:base2, s:base01 ] ]
+let s:p.tabline.tabsel = [ [ s:base2, s:base03 ] ]
+let s:p.tabline.middle = [ [ s:base01, s:base1 ] ]
+let s:p.tabline.right = copy(s:p.normal.right)
+let s:p.normal.error = [ [ s:base023, s:red ] ]
+let s:p.normal.warning = [ [ s:base023, s:yellow ] ]
+
+let g:lightline#colorscheme#Tomorrow_Night_Eighties#palette = lightline#colorscheme#fill(s:p)

+ 46 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/apprentice.vim

@@ -0,0 +1,46 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/apprentice.vim
+" Author: pt307 (based on work by romainl)
+" License: MIT License
+" Last Change: 2021/03/02 18:25:22.
+" =============================================================================
+
+" For the Apprentice colorscheme <https://github.com/romainl/Apprentice>
+
+let s:almost_black = [ '#1c1c1c', 234 ]
+let s:darker_grey  = [ '#262626', 235 ]
+let s:medium_grey  = [ '#585858', 240 ]
+let s:lighter_grey = [ '#bcbcbc', 250 ]
+let s:green        = [ '#5f875f',  65 ]
+let s:red          = [ '#af5f5f', 131 ]
+let s:orange       = [ '#ff8700', 208 ]
+let s:ocre         = [ '#87875f', 101 ]
+let s:yellow       = [ '#ffffaf', 229 ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+
+let s:p.normal.left     = [ [ s:darker_grey, s:ocre ], [ s:darker_grey, s:medium_grey ] ]
+let s:p.normal.middle   = [ [ s:lighter_grey, s:darker_grey ] ]
+let s:p.normal.right    = [ [ s:darker_grey, s:ocre ], [ s:darker_grey, s:medium_grey ] ]
+let s:p.normal.warning  = [ [ s:almost_black, s:orange ] ]
+let s:p.normal.error    = [ [ s:almost_black, s:red ] ]
+
+let s:p.inactive.left   = [ [ s:darker_grey, s:medium_grey ] ]
+let s:p.inactive.middle = [ [ s:medium_grey, s:darker_grey ] ]
+let s:p.inactive.right  = [ [ s:darker_grey, s:medium_grey ] ]
+
+let s:p.insert.left     = [ [ s:darker_grey, s:green ], [ s:darker_grey, s:medium_grey ] ]
+let s:p.insert.right    = [ [ s:darker_grey, s:green ], [ s:darker_grey, s:medium_grey ] ]
+
+let s:p.replace.left    = [ [ s:darker_grey, s:red ], [ s:darker_grey, s:medium_grey ] ]
+let s:p.replace.right   = [ [ s:darker_grey, s:red ], [ s:darker_grey, s:medium_grey ] ]
+
+let s:p.visual.left     = [ [ s:darker_grey, s:yellow ], [ s:darker_grey, s:medium_grey ] ]
+let s:p.visual.right    = [ [ s:darker_grey, s:yellow ], [ s:darker_grey, s:medium_grey ] ]
+
+let s:p.tabline.left    = [ [ s:darker_grey, s:medium_grey ] ]
+let s:p.tabline.middle  = [ [ s:lighter_grey, s:darker_grey ] ]
+let s:p.tabline.right   = [ [ s:darker_grey, s:medium_grey ] ]
+let s:p.tabline.tabsel  = [ [ s:darker_grey, s:ocre ] ]
+
+let g:lightline#colorscheme#apprentice#palette = lightline#colorscheme#flatten(s:p)

+ 42 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/ayu_dark.vim

@@ -0,0 +1,42 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/ayu_dark.vim
+" Author: danielpeng2
+" License: MIT License
+" Last Change: 2020/05/01 19:37:33.
+" =============================================================================
+
+let s:base0 = '#e6e1cf'
+let s:base1 = '#e6e1cf'
+let s:base2 = '#3e4b59'
+let s:base3 = '#e6e1cf'
+let s:base00 = '#14191f'
+let s:base01 = '#14191f'
+let s:base02 = '#0f1419'
+let s:base023 = '#0f1419'
+let s:base03 = '#e6b673'
+let s:yellow = '#e6b673'
+let s:orange = '#ff7733'
+let s:red = '#f07178'
+let s:magenta = '#ffee99'
+let s:blue = '#36a3d9'
+let s:cyan = s:blue
+let s:green = '#b8cc52'
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base02, s:blue ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base2, s:base02 ] ]
+let s:p.normal.right = [ [ s:base02, s:base0 ], [ s:base1, s:base01 ] ]
+let s:p.inactive.left =  [ [ s:base1, s:base01 ], [ s:base3, s:base01 ] ]
+let s:p.inactive.middle = [ [ s:base1, s:base023 ] ]
+let s:p.inactive.right = [ [ s:base1, s:base01 ], [ s:base2, s:base02 ] ]
+let s:p.insert.left = [ [ s:base02, s:green ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base023, s:red ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base02, s:magenta ], [ s:base3, s:base01 ] ]
+let s:p.tabline.tabsel = [ [ s:base02, s:base03 ] ]
+let s:p.tabline.left = [ [ s:base3, s:base00 ] ]
+let s:p.tabline.middle = [ [ s:base2, s:base02 ] ]
+let s:p.tabline.right = [ [ s:base2, s:base00 ] ]
+let s:p.normal.error = [ [ s:base03, s:red ] ]
+let s:p.normal.warning = [ [ s:base023, s:yellow ] ]
+
+let g:lightline#colorscheme#ayu_dark#palette = lightline#colorscheme#fill(s:p)

+ 42 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/ayu_light.vim

@@ -0,0 +1,42 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/ayu_light.vim
+" Author: christalib
+" License: MIT License
+" Last Change: 2020/05/01 19:38:21.
+" =============================================================================
+
+let s:base0 = '#5C6773'
+let s:base1 = '#5C6773'
+let s:base2 = '#828C99'
+let s:base3 = '#5C6773'
+let s:base00 = '#FFFFFF'
+let s:base01 = '#FFFFFF'
+let s:base02 = '#FAFAFA'
+let s:base023 = '#FAFAFA'
+let s:base03 = '#E6B673'
+let s:yellow = '#E6B673'
+let s:orange = '#FF7733'
+let s:red = '#f07178'
+let s:magenta = '#A37ACC'
+let s:blue = '#59c2ff'
+let s:cyan = s:blue
+let s:green = '#86B300'
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base02, s:blue ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base2, s:base02 ] ]
+let s:p.normal.right = [ [ s:base02, s:base0 ], [ s:base1, s:base01 ] ]
+let s:p.inactive.left =  [ [ s:base1, s:base01 ], [ s:base3, s:base01 ] ]
+let s:p.inactive.middle = [ [ s:base1, s:base023 ] ]
+let s:p.inactive.right = [ [ s:base1, s:base01 ], [ s:base2, s:base02 ] ]
+let s:p.insert.left = [ [ s:base02, s:green ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base023, s:red ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base02, s:magenta ], [ s:base3, s:base01 ] ]
+let s:p.tabline.tabsel = [ [ s:base02, s:base03 ] ]
+let s:p.tabline.left = [ [ s:base3, s:base00 ] ]
+let s:p.tabline.middle = [ [ s:base2, s:base02 ] ]
+let s:p.tabline.right = [ [ s:base2, s:base00 ] ]
+let s:p.normal.error = [ [ s:base03, s:red ] ]
+let s:p.normal.warning = [ [ s:base023, s:yellow ] ]
+
+let g:lightline#colorscheme#ayu_light#palette = lightline#colorscheme#fill(s:p)

+ 42 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/ayu_mirage.vim

@@ -0,0 +1,42 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/ayu_mirage.vim
+" Author: impulse
+" License: MIT License
+" Last Change: 2020/05/01 19:37:21.
+" =============================================================================
+
+let s:base0 = '#d9d7ce'
+let s:base1 = '#d9d7ce'
+let s:base2 = '#607080'
+let s:base3 = '#d9d7ce'
+let s:base00 = '#272d38'
+let s:base01 = '#272d38'
+let s:base02 = '#212733'
+let s:base023 = '#212733'
+let s:base03 = '#ffc44c'
+let s:yellow = '#ffc44c'
+let s:orange = '#ffae57'
+let s:red = '#f07178'
+let s:magenta = '#d4bfff'
+let s:blue = '#59c2ff'
+let s:cyan = s:blue
+let s:green = '#bbe67e'
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base02, s:blue ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base2, s:base02 ] ]
+let s:p.normal.right = [ [ s:base02, s:base0 ], [ s:base1, s:base01 ] ]
+let s:p.inactive.left =  [ [ s:base1, s:base01 ], [ s:base3, s:base01 ] ]
+let s:p.inactive.middle = [ [ s:base1, s:base023 ] ]
+let s:p.inactive.right = [ [ s:base1, s:base01 ], [ s:base2, s:base02 ] ]
+let s:p.insert.left = [ [ s:base02, s:green ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base023, s:red ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base02, s:magenta ], [ s:base3, s:base01 ] ]
+let s:p.tabline.tabsel = [ [ s:base02, s:base03 ] ]
+let s:p.tabline.left = [ [ s:base3, s:base00 ] ]
+let s:p.tabline.middle = [ [ s:base2, s:base02 ] ]
+let s:p.tabline.right = [ [ s:base2, s:base00 ] ]
+let s:p.normal.error = [ [ s:base03, s:red ] ]
+let s:p.normal.warning = [ [ s:base023, s:yellow ] ]
+
+let g:lightline#colorscheme#ayu_mirage#palette = lightline#colorscheme#fill(s:p)

+ 37 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/darcula.vim

@@ -0,0 +1,37 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/darcula.vim
+" Author: kkopec
+" License: MIT License
+" Last Change: 2017/02/11 21:18:54.
+" =============================================================================
+
+let s:black = [ '#2b2b2b', 235 ]
+let s:gray = [ '#323232', 236 ]
+let s:white = [ '#a9b7c6', 250 ]
+let s:blue = [ '#6897bb' , 67 ] 
+let s:green = [ '#629755', 71 ] 
+let s:purple = [ '#9876aa', 104 ]
+let s:red = [ '#ff6b68', 204 ]
+let s:yellow = [ '#ffc66d', 222 ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:black, s:purple ], [ s:purple, s:gray ] ]
+let s:p.normal.right = [ [ s:black, s:purple ], [ s:purple, s:gray ] ]
+let s:p.inactive.left =  [ [ s:black, s:blue ], [ s:blue, s:gray ] ]
+let s:p.inactive.right = [ [ s:black, s:blue ], [ s:blue, s:gray ] ]
+let s:p.insert.left = [ [ s:black, s:green ], [ s:green, s:gray ] ] 
+let s:p.insert.right = [ [ s:black, s:green ], [ s:green, s:gray ] ]
+let s:p.replace.left = [ [ s:black, s:red ], [ s:red, s:gray ] ]
+let s:p.replace.right = [ [ s:black, s:red ], [ s:red, s:gray ] ]
+let s:p.visual.left = [ [ s:black, s:yellow ], [ s:yellow, s:gray ] ]
+let s:p.visual.right = [ [ s:black, s:yellow ], [ s:yellow, s:gray ] ]
+let s:p.normal.middle = [ [ s:white, s:gray ] ]
+let s:p.inactive.middle = [ [ s:white, s:gray ] ]
+let s:p.tabline.left = [ [ s:blue, s:gray ] ]
+let s:p.tabline.tabsel = [ [ s:black, s:blue ] ]
+let s:p.tabline.middle = [ [ s:blue, s:gray ] ]
+let s:p.tabline.right = [ [ s:black, s:blue ] ]
+let s:p.normal.error = [ [ s:red, s:black ] ]
+let s:p.normal.warning = [ [ s:yellow, s:black ] ]
+
+let g:lightline#colorscheme#darcula#palette = lightline#colorscheme#flatten(s:p)

+ 8 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/default.vim

@@ -0,0 +1,8 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/default.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2013/08/22 06:05:52.
+" =============================================================================
+
+let g:lightline#colorscheme#default#palette = g:lightline#colorscheme#powerline#palette

+ 39 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/deus.vim

@@ -0,0 +1,39 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/deus.vim
+" Author: nikersify
+" License: MIT License
+" Last Change: 2020/02/15 20:56:45.
+" =============================================================================
+
+let s:term_red = 204
+let s:term_green = 114
+let s:term_yellow = 180
+let s:term_blue = 39
+let s:term_purple = 170
+let s:term_white = 145
+let s:term_black = 235
+let s:term_grey = 236
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+
+let s:p.normal.left = [ [ '#292c33', '#98c379', s:term_black, s:term_green, 'bold' ], [ '#98c379', '#292c33', s:term_green, s:term_black ] ]
+let s:p.normal.right = [ [ '#292c33', '#98c379', s:term_black, s:term_green ], [ '#abb2bf', '#3e4452', s:term_white, s:term_grey ], [ '#98c379', '#292c33', s:term_green, s:term_black ] ]
+let s:p.inactive.right = [ [ '#292c33', '#61afef', s:term_black, s:term_blue], [ '#abb2bf', '#3e4452', s:term_white, s:term_grey ] ]
+let s:p.inactive.left = s:p.inactive.right[1:]
+let s:p.insert.left = [ [ '#292c33', '#61afef', s:term_black, s:term_blue, 'bold' ], [ '#61afef', '#292c33', s:term_blue, s:term_black ] ]
+let s:p.insert.right = [ [ '#292c33', '#61afef', s:term_black, s:term_blue ], [ '#ABB2BF', '#3E4452', s:term_white, s:term_grey ], [ '#61afef', '#292c33', s:term_blue, s:term_black ] ]
+let s:p.replace.left = [ [ '#292c33', '#e06c75', s:term_black, s:term_red, 'bold' ], [ '#e06c75', '#292c33', s:term_red, s:term_black ] ]
+let s:p.replace.right = [ [ '#292c33', '#e06c75', s:term_black, s:term_red ], s:p.normal.right[1], [ '#e06c75', '#292c33', s:term_red, s:term_black ] ]
+let s:p.visual.left = [ [ '#292c33', '#c678dd', s:term_black, s:term_purple, 'bold' ], [ '#c678dd', '#292c33', s:term_purple, s:term_black ] ]
+let s:p.visual.right = [ [ '#292c33', '#c678dd', s:term_black, s:term_purple ], s:p.normal.right[1], [ '#c678dd', '#292c33', s:term_purple, s:term_black ] ]
+let s:p.normal.middle = [ [ '#abb2bf', '#292c33', s:term_white, s:term_black ] ]
+let s:p.insert.middle = s:p.normal.middle
+let s:p.replace.middle = s:p.normal.middle
+let s:p.tabline.left = [ s:p.normal.left[1] ]
+let s:p.tabline.tabsel = [ s:p.normal.left[0] ]
+let s:p.tabline.middle = s:p.normal.middle
+let s:p.tabline.right = [ s:p.normal.left[1] ]
+let s:p.normal.error = [ [ '#292c33', '#e06c75', s:term_black, s:term_red ] ]
+let s:p.normal.warning = [ [ '#292c33', '#e5c07b', s:term_black, s:term_yellow ] ]
+
+let g:lightline#colorscheme#deus#palette = lightline#colorscheme#fill(s:p)

+ 41 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/jellybeans.vim

@@ -0,0 +1,41 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/jellybeans.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2022/03/15 23:59:15.
+" =============================================================================
+
+let s:base03 = [ '#151513', 233 ]
+let s:base02 = [ '#30302c', 236 ]
+let s:base01 = [ '#4e4e43', 239 ]
+let s:base00 = [ '#666656', 242  ]
+let s:base0 = [ '#808070', 244 ]
+let s:base1 = [ '#949484', 246 ]
+let s:base2 = [ '#a8a897', 248 ]
+let s:base3 = [ '#e8e8d3', 253 ]
+let s:yellow = [ '#ffb964', 215 ]
+let s:orange = [ '#fad07a', 222 ]
+let s:red = [ '#cf6a4c', 167 ]
+let s:magenta = [ '#f0a0c0', 217 ]
+let s:blue = [ '#8197bf', 103 ]
+let s:cyan = [ '#8fbfdc', 110 ]
+let s:green = [ '#99ad6a', 107 ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base02, s:blue ], [ s:base3, s:base01 ] ]
+let s:p.normal.right = [ [ s:base02, s:base1 ], [ s:base2, s:base01 ] ]
+let s:p.inactive.right = [ [ s:base02, s:base00 ], [ s:base0, s:base02 ] ]
+let s:p.inactive.left =  [ [ s:base0, s:base02 ], [ s:base00, s:base02 ] ]
+let s:p.insert.left = [ [ s:base02, s:green ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base02, s:red ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base02, s:magenta ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base0, s:base02 ] ]
+let s:p.inactive.middle = [ [ s:base00, s:base02 ] ]
+let s:p.tabline.left = copy(s:p.normal.middle)
+let s:p.tabline.tabsel = [ [ s:base3, s:base00 ] ]
+let s:p.tabline.middle = copy(s:p.normal.middle)
+let s:p.tabline.right = copy(s:p.tabline.middle)
+let s:p.normal.error = [ [ s:red, s:base02 ] ]
+let s:p.normal.warning = [ [ s:yellow, s:base01 ] ]
+
+let g:lightline#colorscheme#jellybeans#palette = lightline#colorscheme#flatten(s:p)

+ 25 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/landscape.vim

@@ -0,0 +1,25 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/landscape.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2015/11/26 21:49:44.
+" =============================================================================
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ ['#0000ff', '#ffffff', 21, 231, 'bold' ], [ '#ffffff', '#0000ff', 231, 21 ] ]
+let s:p.normal.right = [ [ '#303030', '#d0d0d0', 236, 252 ], [ '#303030', '#8a8a8a', 236, 245 ], [ '#bcbcbc', '#585858', 250, 240 ] ]
+let s:p.inactive.right = [ [ '#121212', '#606060', 233, 241 ], [ '#121212', '#3a3a3a', 233, 237 ], [ '#121212', '#262626', 233, 235 ] ]
+let s:p.inactive.left = s:p.inactive.right[1:]
+let s:p.insert.left =  [ ['#005f00', '#ffffff', 22, 231, 'bold' ], [ '#ffffff', '#005f00', 231, 22 ] ]
+let s:p.replace.left = [ [ '#af0000', '#ffffff', 124, 231, 'bold' ], [ '#ffffff', '#af0000', 231, 124 ] ]
+let s:p.visual.left = [ [ '#5f00ff', '#ffffff', 57, 231, 'bold' ], [ '#ffffff', '#5f00ff', 231, 57 ] ]
+let s:p.normal.middle = [ [ '#8a8a8a', '#303030', 245, 236 ] ]
+let s:p.inactive.middle = [ [ '#303030', '#121212', 236, 233 ] ]
+let s:p.tabline.left = [ [ '#d0d0d0', '#666666', 252, 242 ] ]
+let s:p.tabline.tabsel = [ [ '#dadada', '#121212', 253, 233 ] ]
+let s:p.tabline.middle = [ [ '#8a8a8a', '#3a3a3a', 245, 237 ] ]
+let s:p.tabline.right = [ [ '#d0d0d0', '#666666', 252, 242 ] ]
+let s:p.normal.error = [ [ '#d0d0d0', '#ff0000', 252, 196 ] ]
+let s:p.normal.warning = [ [ '#262626', '#ffff00', 235, 226 ] ]
+
+let g:lightline#colorscheme#landscape#palette = s:p

+ 63 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/materia.vim

@@ -0,0 +1,63 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/materia.vim
+" Author: Lokesh Krishna
+" License: MIT License
+" Last Change: 2017/11/25 11:13:40.
+" =============================================================================
+
+" Common colors
+let s:fg     = '#d5dbe5'
+let s:blue   = '#89ddff'
+let s:green  = '#8bd649'
+let s:purple = '#82aaff'
+let s:red1   = '#ec5f67'
+let s:red2   = '#ec5f67'
+let s:yellow = '#ffcc00'
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+
+if lightline#colorscheme#background() ==# 'light'
+  " Light variant
+  let s:bg     = '#ffffff'
+  let s:gray1  = '#2c393f'
+  let s:gray2  = '#d5dbe5'
+  let s:gray3  = '#707880'
+
+  let s:p.normal.left     = [ [ s:bg, s:green, 'bold' ], [ s:gray1, s:gray3 ] ]
+  let s:p.normal.middle   = [ [ s:gray1, s:gray2 ] ]
+  let s:p.inactive.left   = [ [ s:bg,  s:gray3 ], [ s:bg, s:gray3 ] ]
+  let s:p.inactive.middle = [ [ s:gray3, s:gray2 ] ]
+  let s:p.inactive.right  = [ [ s:bg, s:gray3 ], [ s:bg, s:gray3 ] ]
+  let s:p.insert.left     = [ [ s:bg, s:blue, 'bold' ], [ s:gray1, s:gray3 ] ]
+  let s:p.replace.left    = [ [ s:bg, s:red1, 'bold' ], [ s:gray1, s:gray3 ] ]
+  let s:p.visual.left     = [ [ s:bg, s:purple, 'bold' ], [ s:gray1, s:gray3 ] ]
+else
+  " Dark variant
+  let s:bg     = '#263238'
+  let s:gray1  = '#37474f'
+  let s:gray2  = '#2c393f'
+  let s:gray3  = '#37474f'
+
+  let s:p.normal.left     = [ [ s:bg, s:green, 'bold' ], [ s:fg, s:gray3 ] ]
+  let s:p.normal.middle   = [ [ s:fg, s:gray2 ] ]
+  let s:p.inactive.left   = [ [ s:gray1,  s:bg ], [ s:gray1, s:bg ] ]
+  let s:p.inactive.middle = [ [ s:gray1, s:gray2 ] ]
+  let s:p.inactive.right  = [ [ s:gray1, s:bg ], [ s:gray1, s:bg ] ]
+  let s:p.insert.left     = [ [ s:bg, s:blue, 'bold' ], [ s:fg, s:gray3 ] ]
+  let s:p.replace.left    = [ [ s:bg, s:red1, 'bold' ], [ s:fg, s:gray3 ] ]
+  let s:p.visual.left     = [ [ s:bg, s:purple, 'bold' ], [ s:fg, s:gray3 ] ]
+endif
+
+" Common
+let s:p.normal.right   = [ [ s:bg, s:green, 'bold' ], [ s:bg, s:green, 'bold' ] ]
+let s:p.normal.error   = [ [ s:red2,   s:bg ] ]
+let s:p.normal.warning = [ [ s:yellow, s:bg ] ]
+let s:p.insert.right   = [ [ s:bg, s:blue, 'bold' ], [ s:bg, s:blue, 'bold' ] ]
+let s:p.replace.right  = [ [ s:bg, s:red1, 'bold' ], [ s:bg, s:red1, 'bold' ] ]
+let s:p.visual.right   = [ [ s:bg, s:purple, 'bold' ], [ s:bg, s:purple, 'bold' ] ]
+let s:p.tabline.left   = [ [ s:bg, s:gray3 ] ]
+let s:p.tabline.tabsel = [ [ s:bg, s:purple, 'bold' ] ]
+let s:p.tabline.middle = [ [ s:gray3, s:gray2 ] ]
+let s:p.tabline.right  = copy(s:p.normal.right)
+
+let g:lightline#colorscheme#materia#palette = lightline#colorscheme#fill(s:p)

+ 63 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/material.vim

@@ -0,0 +1,63 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/material.vim
+" Author: Lokesh Krishna
+" License: MIT License
+" Last Change: 2017/11/25 11:13:42.
+" =============================================================================
+
+" Common colors
+let s:fg     = '#eeffff'
+let s:blue   = '#82aaff'
+let s:green  = '#c3e88d'
+let s:purple = '#c792ea'
+let s:red1   = '#f07178'
+let s:red2   = '#ff5370'
+let s:yellow = '#ffcb6b'
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+
+if lightline#colorscheme#background() ==# 'light'
+  " Light variant
+  let s:bg     = '#ffffff'
+  let s:gray1  = '#2e3c43'
+  let s:gray2  = '#eeffff'
+  let s:gray3  = '#546e7a'
+
+  let s:p.normal.left     = [ [ s:bg, s:blue, 'bold' ], [ s:gray1, s:gray3 ] ]
+  let s:p.normal.middle   = [ [ s:gray1, s:gray2 ] ]
+  let s:p.inactive.left   = [ [ s:bg,  s:gray3 ], [ s:bg, s:gray3 ] ]
+  let s:p.inactive.middle = [ [ s:gray3, s:gray2 ] ]
+  let s:p.inactive.right  = [ [ s:bg, s:gray3 ], [ s:bg, s:gray3 ] ]
+  let s:p.insert.left     = [ [ s:bg, s:green, 'bold' ], [ s:gray1, s:gray3 ] ]
+  let s:p.replace.left    = [ [ s:bg, s:red1, 'bold' ], [ s:gray1, s:gray3 ] ]
+  let s:p.visual.left     = [ [ s:bg, s:purple, 'bold' ], [ s:gray1, s:gray3 ] ]
+else
+  " Dark variant
+  let s:bg     = '#263238'
+  let s:gray1  = '#314549'
+  let s:gray2  = '#2E3C43'
+  let s:gray3  = '#314549'
+
+  let s:p.normal.left     = [ [ s:bg, s:blue, 'bold' ], [ s:fg, s:gray3 ] ]
+  let s:p.normal.middle   = [ [ s:fg, s:gray2 ] ]
+  let s:p.inactive.left   = [ [ s:gray1,  s:bg ], [ s:gray1, s:bg ] ]
+  let s:p.inactive.middle = [ [ s:gray1, s:gray2 ] ]
+  let s:p.inactive.right  = [ [ s:gray1, s:bg ], [ s:gray1, s:bg ] ]
+  let s:p.insert.left     = [ [ s:bg, s:green, 'bold' ], [ s:fg, s:gray3 ] ]
+  let s:p.replace.left    = [ [ s:bg, s:red1, 'bold' ], [ s:fg, s:gray3 ] ]
+  let s:p.visual.left     = [ [ s:bg, s:purple, 'bold' ], [ s:fg, s:gray3 ] ]
+endif
+
+" Common
+let s:p.normal.right   = [ [ s:bg, s:blue, 'bold' ], [ s:bg, s:blue, 'bold' ] ]
+let s:p.normal.error   = [ [ s:red2,   s:bg ] ]
+let s:p.normal.warning = [ [ s:yellow, s:bg ] ]
+let s:p.insert.right   = [ [ s:bg, s:green, 'bold' ], [ s:bg, s:green, 'bold' ] ]
+let s:p.replace.right  = [ [ s:bg, s:red1, 'bold' ], [ s:bg, s:red1, 'bold' ] ]
+let s:p.visual.right   = [ [ s:bg, s:purple, 'bold' ], [ s:bg, s:purple, 'bold' ] ]
+let s:p.tabline.left   = [ [ s:fg, s:gray3 ] ]
+let s:p.tabline.tabsel = [ [ s:bg, s:purple, 'bold' ] ]
+let s:p.tabline.middle = [ [ s:gray3, s:gray2 ] ]
+let s:p.tabline.right  = [ [ s:bg, s:red1, 'bold' ] ]
+
+let g:lightline#colorscheme#material#palette = lightline#colorscheme#fill(s:p)

+ 35 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/molokai.vim

@@ -0,0 +1,35 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/molokai.vim
+" Author: challsted
+" License: MIT License
+" Last Change: 2022/03/15 23:58:40.
+" =============================================================================
+
+let s:black = [ '#232526', 233 ]
+let s:gray = [ '#808080', 244 ]
+let s:white = [ '#f8f8f2', 234 ]
+let s:cyan = [ '#66d9ef', 81 ]
+let s:green = [ '#a6e22e', 118 ]
+let s:orange = [ '#ef5939', 166 ]
+let s:pink = [ '#f92672', 161 ]
+let s:red = [ '#ff0000', 160 ]
+let s:yellow = [ '#e6db74', 229 ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:black, s:cyan ], [ s:orange, s:black ] ]
+let s:p.normal.middle = [ [ s:orange, s:black ] ]
+let s:p.normal.right = [ [ s:pink, s:black ], [ s:black, s:pink ] ]
+let s:p.normal.error = [ [ s:pink, s:black ] ]
+let s:p.normal.warning = [ [ s:yellow, s:black ] ]
+let s:p.insert.left = [ [ s:black, s:green ], [ s:green, s:black ] ]
+let s:p.visual.left = [ [ s:black, s:yellow ], [ s:yellow, s:black ] ]
+let s:p.replace.left = [ [ s:black, s:red ], [ s:red, s:black ] ]
+let s:p.inactive.left =  [ [ s:pink, s:black ], [ s:white, s:black ] ]
+let s:p.inactive.middle = [ [ s:gray, s:black ] ]
+let s:p.inactive.right = [ [ s:white, s:pink ], [ s:pink, s:black ] ]
+let s:p.tabline.left = [ [ s:pink, s:black ] ]
+let s:p.tabline.middle = [ [ s:pink, s:black] ]
+let s:p.tabline.right = copy(s:p.normal.right)
+let s:p.tabline.tabsel = [ [ s:black, s:pink ] ]
+
+let g:lightline#colorscheme#molokai#palette = lightline#colorscheme#flatten(s:p)

+ 46 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/nord.vim

@@ -0,0 +1,46 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/nord.vim
+" Author: arcticicestudio
+" License: MIT
+" Last Change: 2017/11/12 20:27:51
+" =============================================================================
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+
+let s:nord0 = ["#2E3440", "NONE"]
+let s:nord1 = ["#3B4252", 0]
+let s:nord2 = ["#434C5E", "NONE"]
+let s:nord3 = ["#4C566A", 8]
+let s:nord4 = ["#D8DEE9", "NONE"]
+let s:nord5 = ["#E5E9F0", 7]
+let s:nord6 = ["#ECEFF4", 15]
+let s:nord7 = ["#8FBCBB", 14]
+let s:nord8 = ["#88C0D0", 6]
+let s:nord9 = ["#81A1C1", 4]
+let s:nord10 = ["#5E81AC", 12]
+let s:nord11 = ["#BF616A", 1]
+let s:nord12 = ["#D08770", 11]
+let s:nord13 = ["#EBCB8B", 3]
+let s:nord14 = ["#A3BE8C", 2]
+let s:nord15 = ["#B48EAD", 5]
+
+let s:p.normal.left = [ [ s:nord1, s:nord8 ], [ s:nord5, s:nord1 ] ]
+let s:p.normal.middle = [ [ s:nord5, s:nord3 ] ]
+let s:p.normal.right = [ [ s:nord5, s:nord1 ], [ s:nord5, s:nord1 ] ]
+let s:p.normal.warning = [ [ s:nord1, s:nord13 ] ]
+let s:p.normal.error = [ [ s:nord1, s:nord11 ] ]
+
+let s:p.inactive.left =  [ [ s:nord1, s:nord8 ], [ s:nord5, s:nord1 ] ]
+let s:p.inactive.middle = [ [ s:nord5, s:nord1 ] ]
+let s:p.inactive.right = [ [ s:nord5, s:nord1 ], [ s:nord5, s:nord1 ] ]
+
+let s:p.insert.left = [ [ s:nord1, s:nord6 ], [ s:nord5, s:nord1 ] ]
+let s:p.replace.left = [ [ s:nord1, s:nord13 ], [ s:nord5, s:nord1 ] ]
+let s:p.visual.left = [ [ s:nord1, s:nord7 ], [ s:nord5, s:nord1 ] ]
+
+let s:p.tabline.left = [ [ s:nord5, s:nord3 ] ]
+let s:p.tabline.middle = [ [ s:nord5, s:nord3 ] ]
+let s:p.tabline.right = [ [ s:nord5, s:nord3 ] ]
+let s:p.tabline.tabsel = [ [ s:nord1, s:nord8 ] ]
+
+let g:lightline#colorscheme#nord#palette = lightline#colorscheme#flatten(s:p)

+ 60 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/one.vim

@@ -0,0 +1,60 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/one.vim
+" Author: Zoltan Dalmadi
+" License: MIT License
+" Last Change: 2019/09/09 22:42:48.
+" =============================================================================
+
+" Common colors
+let s:blue   = [ '#61afef', 75 ]
+let s:green  = [ '#98c379', 76 ]
+let s:purple = [ '#c678dd', 176 ]
+let s:red1   = [ '#e06c75', 168 ]
+let s:red2   = [ '#be5046', 168 ]
+let s:yellow = [ '#e5c07b', 180 ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+
+if lightline#colorscheme#background() ==# 'light'
+  " Light variant
+  let s:fg    = [ '#494b53', 238 ]
+  let s:bg    = [ '#fafafa', 255 ]
+  let s:gray1 = [ '#494b53', 238 ]
+  let s:gray2 = [ '#f0f0f0', 255 ]
+  let s:gray3 = [ '#d0d0d0', 250 ]
+  let s:green = [ '#98c379', 35 ]
+
+  let s:p.inactive.left   = [ [ s:bg,  s:gray3 ], [ s:bg, s:gray3 ] ]
+  let s:p.inactive.middle = [ [ s:gray3, s:gray2 ] ]
+  let s:p.inactive.right  = [ [ s:bg, s:gray3 ] ]
+else
+  " Dark variant
+  let s:fg    = [ '#abb2bf', 145 ]
+  let s:bg    = [ '#282c34', 235 ]
+  let s:gray1 = [ '#5c6370', 241 ]
+  let s:gray2 = [ '#2c323d', 235 ]
+  let s:gray3 = [ '#3e4452', 240 ]
+
+  let s:p.inactive.left   = [ [ s:gray1,  s:bg ], [ s:gray1, s:bg ] ]
+  let s:p.inactive.middle = [ [ s:gray1, s:gray2 ] ]
+  let s:p.inactive.right  = [ [ s:gray1, s:bg ] ]
+endif
+
+" Common
+let s:p.normal.left    = [ [ s:bg, s:green, 'bold' ], [ s:fg, s:gray3 ] ]
+let s:p.normal.middle  = [ [ s:fg, s:gray2 ] ]
+let s:p.normal.right   = [ [ s:bg, s:green, 'bold' ], [ s:fg, s:gray3 ] ]
+let s:p.normal.error   = [ [ s:red2, s:bg ] ]
+let s:p.normal.warning = [ [ s:yellow, s:bg ] ]
+let s:p.insert.right   = [ [ s:bg, s:blue, 'bold' ], [ s:fg, s:gray3 ] ]
+let s:p.insert.left    = [ [ s:bg, s:blue, 'bold' ], [ s:fg, s:gray3 ] ]
+let s:p.replace.right  = [ [ s:bg, s:red1, 'bold' ], [ s:fg, s:gray3 ] ]
+let s:p.replace.left   = [ [ s:bg, s:red1, 'bold' ], [ s:fg, s:gray3 ] ]
+let s:p.visual.right   = [ [ s:bg, s:purple, 'bold' ], [ s:fg, s:gray3 ] ]
+let s:p.visual.left    = [ [ s:bg, s:purple, 'bold' ], [ s:fg, s:gray3 ] ]
+let s:p.tabline.left   = [ [ s:fg, s:gray3 ] ]
+let s:p.tabline.tabsel = [ [ s:bg, s:purple, 'bold' ] ]
+let s:p.tabline.middle = [ [ s:gray3, s:gray2 ] ]
+let s:p.tabline.right  = copy(s:p.normal.right)
+
+let g:lightline#colorscheme#one#palette = lightline#colorscheme#flatten(s:p)

+ 28 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/powerline.vim

@@ -0,0 +1,28 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/powerline.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2013/09/07 15:54:41.
+" =============================================================================
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ ['darkestgreen', 'brightgreen', 'bold'], ['white', 'gray4'] ]
+let s:p.normal.right = [ ['gray5', 'gray10'], ['gray9', 'gray4'], ['gray8', 'gray2'] ]
+let s:p.inactive.right = [ ['gray1', 'gray5'], ['gray4', 'gray1'], ['gray4', 'gray0'] ]
+let s:p.inactive.left = s:p.inactive.right[1:]
+let s:p.insert.left = [ ['darkestcyan', 'white', 'bold'], ['white', 'darkblue'] ]
+let s:p.insert.right = [ [ 'darkestcyan', 'mediumcyan' ], [ 'mediumcyan', 'darkblue' ], [ 'mediumcyan', 'darkestblue' ] ]
+let s:p.replace.left = [ ['white', 'brightred', 'bold'], ['white', 'gray4'] ]
+let s:p.visual.left = [ ['darkred', 'brightorange', 'bold'], ['white', 'gray4'] ]
+let s:p.normal.middle = [ [ 'gray7', 'gray2' ] ]
+let s:p.insert.middle = [ [ 'mediumcyan', 'darkestblue' ] ]
+let s:p.replace.middle = s:p.normal.middle
+let s:p.replace.right = s:p.normal.right
+let s:p.tabline.left = [ [ 'gray9', 'gray4' ] ]
+let s:p.tabline.tabsel = [ [ 'gray9', 'gray1' ] ]
+let s:p.tabline.middle = [ [ 'gray2', 'gray8' ] ]
+let s:p.tabline.right = [ [ 'gray9', 'gray3' ] ]
+let s:p.normal.error = [ [ 'gray9', 'brightestred' ] ]
+let s:p.normal.warning = [ [ 'gray1', 'yellow' ] ]
+
+let g:lightline#colorscheme#powerline#palette = lightline#colorscheme#fill(s:p)

+ 28 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/powerlineish.vim

@@ -0,0 +1,28 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/powerlineish.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2019/06/12 18:47:00.
+" =============================================================================
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ ['darkestgreen', 'brightgreen', 'bold'], ['white', 'gray0'] ]
+let s:p.normal.right = [ ['gray10', 'gray2'], ['white', 'gray1'], ['white', 'gray0'] ]
+let s:p.inactive.right = [ ['gray1', 'gray5'], ['gray4', 'gray1'], ['gray4', 'gray0'] ]
+let s:p.inactive.left = s:p.inactive.right[1:]
+let s:p.insert.left = [ ['darkestcyan', 'white', 'bold'], ['mediumcyan', 'darkestblue'] ]
+let s:p.insert.right = [ [ 'darkestblue', 'mediumcyan' ], [ 'mediumcyan', 'darkblue' ], [ 'mediumcyan', 'darkestblue' ] ]
+let s:p.replace.left = [ ['white', 'brightred', 'bold'], ['white', 'gray0'] ]
+let s:p.visual.left = [ ['black', 'brightestorange', 'bold'], ['white', 'gray0'] ]
+let s:p.normal.middle = [ [ 'white', 'gray0' ] ]
+let s:p.insert.middle = [ [ 'mediumcyan', 'darkestblue' ] ]
+let s:p.replace.middle = s:p.normal.middle
+let s:p.replace.right = s:p.normal.right
+let s:p.tabline.left = [ [ 'gray9', 'gray0' ] ]
+let s:p.tabline.tabsel = [ [ 'gray9', 'gray2' ] ]
+let s:p.tabline.middle = [ [ 'gray2', 'gray0' ] ]
+let s:p.tabline.right = [ [ 'gray9', 'gray1' ] ]
+let s:p.normal.error = [ [ 'gray9', 'brightestred' ] ]
+let s:p.normal.warning = [ [ 'gray1', 'yellow' ] ]
+
+let g:lightline#colorscheme#powerlineish#palette = lightline#colorscheme#fill(s:p)

+ 58 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/rosepine.vim

@@ -0,0 +1,58 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/rosepine.vim
+" Author: sheruost
+" License: MIT License
+" Last Change: 2022/05/09 23:27:50.
+" =============================================================================
+
+" Reference: https://rosepinetheme.com/palette
+if lightline#colorscheme#background() ==# 'light'
+  " Rosé Pine Dawn
+  let s:base = [ '#faf4ed', 255 ]
+  let s:surface = [ '#fffaf3', 255 ]
+
+  let s:overlay = [ '#f2e9e1', 254 ]
+  let s:highlight_m = [ '#dfdad9', 145 ]
+  let s:muted = [ '#9893a5', 103 ]
+  let s:subtle = [ '#797593', 102 ]
+
+  let s:iris = [ '#907aa9', 139 ]
+  let s:pine = [ '#286983', 24 ]
+  let s:foam = [ '#56949f', 67 ]
+  let s:rose = [ '#d7827e', 174 ]
+  let s:love = [ '#b4637a', 132 ]
+else
+  " Rosé Pine
+  let s:base = [ '#191724', 233 ]
+  let s:surface = [ '#1f1d2e', 234 ]
+
+  let s:overlay = [ '#26233a', 235 ]
+  let s:highlight_m = [ '#403d52', 59 ]
+  let s:muted = [ '#6e6a86', 60 ]
+  let s:subtle = [ '#908caa', 103 ]
+
+  let s:iris = [ '#c4a7e7', 182 ]
+  let s:pine = [ '#31748f', 30 ]
+  let s:foam = [ '#9ccfd8', 152 ]
+  let s:rose = [ '#ebbcba', 217 ]
+  let s:love = [ '#eb6f92', 204 ]
+endif
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base, s:pine ], [ s:subtle, s:surface ] ]
+let s:p.normal.right = [ [ s:overlay, s:subtle ], [ s:muted, s:overlay ], [ s:highlight_m, s:surface ] ]
+let s:p.inactive.right = [ [ s:base, s:surface ], [ s:overlay, s:base ] ]
+let s:p.inactive.left =  [ [ s:overlay, s:base ], [ s:surface, s:base ] ]
+let s:p.insert.left = [ [ s:base, s:foam ], [ s:subtle, s:surface ] ]
+let s:p.replace.left = [ [ s:base, s:love ], [ s:subtle, s:surface ] ]
+let s:p.visual.left = [ [ s:base, s:iris ], [ s:subtle, s:surface ] ]
+let s:p.normal.middle = [ [ s:overlay, s:base ] ]
+let s:p.inactive.middle = [ [ s:surface, s:base ] ]
+let s:p.tabline.left = [ [ s:subtle, s:base ] ]
+let s:p.tabline.tabsel = [ [ s:pine, s:base ] ]
+let s:p.tabline.middle = [ [ s:surface, s:base ] ]
+let s:p.tabline.right = copy(s:p.normal.right)
+let s:p.normal.error = [ [ s:love, s:base ] ]
+let s:p.normal.warning = [ [ s:rose, s:surface ] ]
+
+let g:lightline#colorscheme#rosepine#palette = lightline#colorscheme#flatten(s:p)

+ 49 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/selenized_black.vim

@@ -0,0 +1,49 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/selenized_black.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2020/05/02 16:56:50.
+" =============================================================================
+
+" https://github.com/jan-warchol/selenized/blob/master/the-values.md#selenized-black
+let s:bg_1      = ['#252525', 0]
+let s:bg_2      = ['#3b3b3b', 8]
+let s:dim_0     = ['#777777', 7]
+let s:red       = ['#ed4a46', 1]
+let s:green     = ['#70b433', 2]
+let s:yellow    = ['#dbb32d', 3]
+let s:blue      = ['#368aeb', 4]
+let s:magenta   = ['#eb6eb7', 5]
+let s:cyan      = ['#3fc5b7', 6]
+let s:brred     = ['#ff5e56', 9]
+let s:brgreen   = ['#83c746', 10]
+let s:bryellow  = ['#efc541', 11]
+let s:brblue    = ['#4f9cfe', 12]
+let s:brmagenta = ['#ff81ca', 13]
+let s:brcyan    = ['#56d8c9', 14]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+
+let s:p.normal.right = [[ s:bg_1, s:blue ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.normal.left = [[ s:bg_1, s:blue ], [ s:cyan, s:bg_2 ]]
+let s:p.normal.middle = [[ s:dim_0, s:bg_1 ]]
+let s:p.normal.error = [[ s:bg_1, s:red ]]
+let s:p.normal.warning = [[ s:bg_1, s:yellow ]]
+
+let s:p.insert.right = [[ s:bg_1, s:green ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.insert.left = [[ s:bg_1, s:green ], [ s:cyan, s:bg_2 ]]
+
+let s:p.visual.right = [[ s:bg_1, s:magenta ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.visual.left = [[ s:bg_1, s:magenta ], [ s:cyan, s:bg_2 ]]
+
+let s:p.inactive.left = [[ s:brblue, s:bg_2 ], [ s:cyan, s:bg_2 ]]
+let s:p.inactive.right = [[ s:brblue, s:bg_2 ], [ s:cyan, s:bg_2 ]]
+
+let s:p.replace.right = [[ s:bg_1, s:red ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.replace.left = [[ s:bg_1, s:red ], [ s:cyan, s:bg_2 ]]
+
+let s:p.tabline.right = [[ s:bg_1, s:red ]]
+let s:p.tabline.left = [[ s:cyan, s:bg_2 ]]
+let s:p.tabline.tabsel = [[ s:bg_1, s:blue ]]
+
+let g:lightline#colorscheme#selenized_black#palette = lightline#colorscheme#flatten(s:p)

+ 49 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/selenized_dark.vim

@@ -0,0 +1,49 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/selenized_dark.vim
+" Author: Charles Hall
+" License: MIT License
+" Last Change: 2020/05/02 16:53:17.
+" =============================================================================
+
+" https://github.com/jan-warchol/selenized/blob/master/the-values.md#selenized-dark
+let s:bg_1      = ['#184956', 0]
+let s:bg_2      = ['#2d5b69', 8]
+let s:dim_0     = ['#72898f', 7]
+let s:red       = ['#fa5750', 1]
+let s:green     = ['#75b938', 2]
+let s:yellow    = ['#dbb32d', 3]
+let s:blue      = ['#4695f7', 4]
+let s:magenta   = ['#f275be', 5]
+let s:cyan      = ['#41c7b9', 6]
+let s:brred     = ['#ff665c', 9]
+let s:brgreen   = ['#84c747', 10]
+let s:bryellow  = ['#ebc13d', 11]
+let s:brblue    = ['#58a3ff', 12]
+let s:brmagenta = ['#ff84cd', 13]
+let s:brcyan    = ['#53d6c7', 14]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+
+let s:p.normal.right = [[ s:bg_1, s:blue ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.normal.left = [[ s:bg_1, s:blue ], [ s:cyan, s:bg_2 ]]
+let s:p.normal.middle = [[ s:dim_0, s:bg_1 ]]
+let s:p.normal.error = [[ s:bg_1, s:red ]]
+let s:p.normal.warning = [[ s:bg_1, s:yellow ]]
+
+let s:p.insert.right = [[ s:bg_1, s:green ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.insert.left = [[ s:bg_1, s:green ], [ s:cyan, s:bg_2 ]]
+
+let s:p.visual.right = [[ s:bg_1, s:magenta ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.visual.left = [[ s:bg_1, s:magenta ], [ s:cyan, s:bg_2 ]]
+
+let s:p.inactive.left = [[ s:brblue, s:bg_2 ], [ s:cyan, s:bg_2 ]]
+let s:p.inactive.right = [[ s:brblue, s:bg_2 ], [ s:cyan, s:bg_2 ]]
+
+let s:p.replace.right = [[ s:bg_1, s:red ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.replace.left = [[ s:bg_1, s:red ], [ s:cyan, s:bg_2 ]]
+
+let s:p.tabline.right = [[ s:bg_1, s:red ]]
+let s:p.tabline.left = [[ s:cyan, s:bg_2 ]]
+let s:p.tabline.tabsel = [[ s:bg_1, s:blue ]]
+
+let g:lightline#colorscheme#selenized_dark#palette = lightline#colorscheme#flatten(s:p)

+ 49 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/selenized_light.vim

@@ -0,0 +1,49 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/selenized_light.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2020/05/02 16:58:00.
+" =============================================================================
+
+" https://github.com/jan-warchol/selenized/blob/master/the-values.md#selenized-light
+let s:bg_1      = ['#ece3cc', 0]
+let s:bg_2      = ['#d5cdb6', 8]
+let s:dim_0     = ['#909995', 7]
+let s:red       = ['#d2212d', 1]
+let s:green     = ['#489100', 2]
+let s:yellow    = ['#ad8900', 3]
+let s:blue      = ['#0072d4', 4]
+let s:magenta   = ['#ca4898', 5]
+let s:cyan      = ['#009c8f', 6]
+let s:brred     = ['#cc1729', 9]
+let s:brgreen   = ['#428b00', 10]
+let s:bryellow  = ['#a78300', 11]
+let s:brblue    = ['#006dce', 12]
+let s:brmagenta = ['#c44392', 13]
+let s:brcyan    = ['#00978a', 14]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+
+let s:p.normal.right = [[ s:bg_1, s:blue ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.normal.left = [[ s:bg_1, s:blue ], [ s:cyan, s:bg_2 ]]
+let s:p.normal.middle = [[ s:dim_0, s:bg_1 ]]
+let s:p.normal.error = [[ s:bg_1, s:red ]]
+let s:p.normal.warning = [[ s:bg_1, s:yellow ]]
+
+let s:p.insert.right = [[ s:bg_1, s:green ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.insert.left = [[ s:bg_1, s:green ], [ s:cyan, s:bg_2 ]]
+
+let s:p.visual.right = [[ s:bg_1, s:magenta ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.visual.left = [[ s:bg_1, s:magenta ], [ s:cyan, s:bg_2 ]]
+
+let s:p.inactive.left = [[ s:brblue, s:bg_2 ], [ s:cyan, s:bg_2 ]]
+let s:p.inactive.right = [[ s:brblue, s:bg_2 ], [ s:cyan, s:bg_2 ]]
+
+let s:p.replace.right = [[ s:bg_1, s:red ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.replace.left = [[ s:bg_1, s:red ], [ s:cyan, s:bg_2 ]]
+
+let s:p.tabline.right = [[ s:bg_1, s:red ]]
+let s:p.tabline.left = [[ s:cyan, s:bg_2 ]]
+let s:p.tabline.tabsel = [[ s:bg_1, s:blue ]]
+
+let g:lightline#colorscheme#selenized_light#palette = lightline#colorscheme#flatten(s:p)

+ 49 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/selenized_white.vim

@@ -0,0 +1,49 @@
+" =============================================================================
+" Filename: autoload/whiteline/colorscheme/selenized_white.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2020/05/03 19:34:07.
+" =============================================================================
+
+" https://github.com/jan-warchol/selenized/blob/master/the-values.md#selenized-white
+let s:bg_1      = ['#ebebeb', 0]
+let s:bg_2      = ['#cdcdcd', 8]
+let s:dim_0     = ['#878787', 7]
+let s:red       = ['#d6000c', 1]
+let s:green     = ['#1d9700', 2]
+let s:yellow    = ['#c49700', 3]
+let s:blue      = ['#0064e4', 4]
+let s:magenta   = ['#dd0f9d', 5]
+let s:cyan      = ['#00ad9c', 6]
+let s:brred     = ['#bf0000', 9]
+let s:brgreen   = ['#008400', 10]
+let s:bryellow  = ['#af8500', 11]
+let s:brblue    = ['#0054cf', 12]
+let s:brmagenta = ['#c7008b', 13]
+let s:brcyan    = ['#009a8a', 14]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+
+let s:p.normal.right = [[ s:bg_1, s:blue ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.normal.left = [[ s:bg_1, s:blue ], [ s:cyan, s:bg_2 ]]
+let s:p.normal.middle = [[ s:dim_0, s:bg_1 ]]
+let s:p.normal.error = [[ s:bg_1, s:red ]]
+let s:p.normal.warning = [[ s:bg_1, s:yellow ]]
+
+let s:p.insert.right = [[ s:bg_1, s:green ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.insert.left = [[ s:bg_1, s:green ], [ s:cyan, s:bg_2 ]]
+
+let s:p.visual.right = [[ s:bg_1, s:magenta ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.visual.left = [[ s:bg_1, s:magenta ], [ s:cyan, s:bg_2 ]]
+
+let s:p.inactive.left = [[ s:brblue, s:bg_2 ], [ s:cyan, s:bg_2 ]]
+let s:p.inactive.right = [[ s:brblue, s:bg_2 ], [ s:cyan, s:bg_2 ]]
+
+let s:p.replace.right = [[ s:bg_1, s:red ], [ s:cyan, s:bg_2 ], [ s:dim_0, s:bg_1 ]]
+let s:p.replace.left = [[ s:bg_1, s:red ], [ s:cyan, s:bg_2 ]]
+
+let s:p.tabline.right = [[ s:bg_1, s:red ]]
+let s:p.tabline.left = [[ s:cyan, s:bg_2 ]]
+let s:p.tabline.tabsel = [[ s:bg_1, s:blue ]]
+
+let g:lightline#colorscheme#selenized_white#palette = lightline#colorscheme#flatten(s:p)

+ 43 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/seoul256.vim

@@ -0,0 +1,43 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/seoul256.vim
+" Author: atweiden
+" License: MIT License
+" Last Change: 2022/03/15 23:58:59.
+" =============================================================================
+
+let s:base03 = [ '#151513', 233 ]
+let s:base02 = [ '#30302c', 236 ]
+let s:base01 = [ '#4e4e43', 239 ]
+let s:base00 = [ '#666656', 242  ]
+let s:base0 = [ '#808070', 244 ]
+let s:base1 = [ '#949484', 246 ]
+let s:base2 = [ '#a8a897', 248 ]
+let s:base3 = [ '#e8e8d3', 253 ]
+let s:yellow = [ '#d8af5f', 3 ]
+let s:orange = [ '#d7875f', 216 ]
+let s:red = [ '#d68787', 131 ]
+let s:magenta = [ '#df5f87', 168 ]
+let s:peach = [ '#d7afaf', 181 ]
+let s:blue = [ '#87afaf', 109 ]
+let s:cyan = [ '#87d7d7', 23 ]
+let s:green = [ '#87af87', 108 ]
+let s:white = [ '#d0d0d0', 252 ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base02, s:blue ], [ s:base3, s:base01 ] ]
+let s:p.normal.right = [ [ s:base02, s:base1 ], [ s:base2, s:base01 ] ]
+let s:p.inactive.right = [ [ s:base02, s:base00 ], [ s:base0, s:base02 ] ]
+let s:p.inactive.left =  [ [ s:base0, s:base02 ], [ s:base00, s:base02 ] ]
+let s:p.insert.left = [ [ s:base02, s:green ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base02, s:magenta ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base02, s:peach ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base0, s:base02 ] ]
+let s:p.inactive.middle = [ [ s:base00, s:base02 ] ]
+let s:p.tabline.left = [ [ s:base3, s:base00 ] ]
+let s:p.tabline.tabsel = [ [ s:base3, s:base02 ] ]
+let s:p.tabline.middle = [ [ s:base01, s:base1 ] ]
+let s:p.tabline.right = copy(s:p.normal.right)
+let s:p.normal.error = [ [ s:red, s:base02 ] ]
+let s:p.normal.warning = [ [ s:yellow, s:base01 ] ]
+
+let g:lightline#colorscheme#seoul256#palette = lightline#colorscheme#flatten(s:p)

+ 43 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/simpleblack.vim

@@ -0,0 +1,43 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/simpleblack.vim
+" Author: lucasprag
+" License: MIT License
+" Last Change: 2022/03/15 23:58:35.
+" =============================================================================
+
+let s:black = [ '#000000', '0' ]
+let s:black2 = [ '#121212', '233' ]
+
+let s:gray = [ '#262626', '235' ]
+let s:gray2 = [ '#3a3a3a', '237' ]
+let s:gray3 = [ '#4e4e4e', '239' ]
+let s:gray4 = [ '#626262', '241' ]
+
+let s:violet = [ '#cf73e6', '170' ]
+
+let s:blue = [ '#5f87af', '67' ]
+let s:blue2 = [ '#91aadf', '110' ]
+
+let s:green = [ '#57ba37', '71' ]
+let s:gold = [ '#f0d50c', '220' ]
+let s:red = [ '#d70000', '160' ]
+let s:none = [ 'NONE', 'NONE' ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:black, s:blue ], [ s:gray4, s:black2 ] ]
+let s:p.normal.right = [ [ s:gray, s:gray4 ], [ s:gray3, s:gray ], [ s:gray2, s:black2 ] ]
+let s:p.inactive.right = [ [ s:black, s:black2 ], [ s:gray, s:black ] ]
+let s:p.inactive.left =  [ [ s:gray, s:black ], [ s:black2, s:black ] ]
+let s:p.insert.left = [ [ s:black, s:green ], [ s:gray4, s:black2 ] ]
+let s:p.replace.left = [ [ s:black, s:red ], [ s:gray4, s:black2 ] ]
+let s:p.visual.left = [ [ s:black, s:violet ], [ s:gray4, s:black2 ] ]
+let s:p.normal.middle = [ [ s:gray, s:black ] ]
+let s:p.inactive.middle = [ [ s:black2, s:black ] ]
+let s:p.tabline.left = [ [ s:gray4, s:black ] ]
+let s:p.tabline.tabsel = [ [ s:blue, s:black ] ]
+let s:p.tabline.middle = [ [ s:black2, s:black ] ]
+let s:p.tabline.right = copy(s:p.normal.right)
+let s:p.normal.error = [ [ s:red, s:black ] ]
+let s:p.normal.warning = [ [ s:gold, s:black2 ] ]
+
+let g:lightline#colorscheme#simpleblack#palette = lightline#colorscheme#flatten(s:p)

+ 80 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/solarized.vim

@@ -0,0 +1,80 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/solarized.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2020/04/06 19:22:53.
+" =============================================================================
+
+let s:cuicolors = {
+      \ 'base03': [ '8', '234', 'DarkGray' ],
+      \ 'base02': [ '0', '235', 'Black' ],
+      \ 'base01': [ '10', '239', 'LightGreen' ],
+      \ 'base00': [ '11', '240', 'LightYellow' ],
+      \ 'base0':  [ '12', '244', 'LightBlue' ],
+      \ 'base1':  [ '14', '245', 'LightCyan' ],
+      \ 'base2': [ '7', '187', 'LightGray' ],
+      \ 'base3': [ '15', '230', 'White' ],
+      \ 'yellow': [ '3', '136', 'DarkYellow' ],
+      \ 'orange': [ '9', '166', 'LightRed' ],
+      \ 'red': [ '1', '124', 'DarkRed' ],
+      \ 'magenta': [ '5', '125', 'DarkMagenta' ],
+      \ 'violet': [ '13', '61', 'LightMagenta' ],
+      \ 'blue': [ '4', '33', 'DarkBlue' ],
+      \ 'cyan': [ '6', '37', 'DarkCyan' ],
+      \ 'green': [ '2', '64', 'DarkGreen' ],
+      \ }
+
+" The following condition only applies for the console and is the same
+" condition vim-colors-solarized uses to determine which set of colors
+" to use.
+let s:solarized_termcolors = get(g:, 'solarized_termcolors', 256)
+if s:solarized_termcolors != 256 && &t_Co >= 16
+  let s:cuiindex = 0
+elseif s:solarized_termcolors == 256
+  let s:cuiindex = 1
+else
+  let s:cuiindex = 2
+endif
+
+let s:base03 = [ '#002b36', s:cuicolors.base03[s:cuiindex] ]
+let s:base02 = [ '#073642', s:cuicolors.base02[s:cuiindex] ]
+let s:base01 = [ '#586e75', s:cuicolors.base01[s:cuiindex] ]
+let s:base00 = [ '#657b83', s:cuicolors.base00[s:cuiindex] ]
+let s:base0 = [ '#839496', s:cuicolors.base0[s:cuiindex] ]
+let s:base1 = [ '#93a1a1', s:cuicolors.base1[s:cuiindex] ]
+let s:base2 = [ '#eee8d5', s:cuicolors.base2[s:cuiindex] ]
+let s:base3 = [ '#fdf6e3', s:cuicolors.base3[s:cuiindex] ]
+let s:yellow = [ '#b58900', s:cuicolors.yellow[s:cuiindex] ]
+let s:orange = [ '#cb4b16', s:cuicolors.orange[s:cuiindex] ]
+let s:red = [ '#dc322f', s:cuicolors.red[s:cuiindex] ]
+let s:magenta = [ '#d33682', s:cuicolors.magenta[s:cuiindex] ]
+let s:violet = [ '#6c71c4', s:cuicolors.violet[s:cuiindex] ]
+let s:blue = [ '#268bd2', s:cuicolors.blue[s:cuiindex] ]
+let s:cyan = [ '#2aa198', s:cuicolors.cyan[s:cuiindex] ]
+let s:green = [ '#859900', s:cuicolors.green[s:cuiindex] ]
+
+if lightline#colorscheme#background() ==# 'light'
+  let [ s:base03, s:base3 ] = [ s:base3, s:base03 ]
+  let [ s:base02, s:base2 ] = [ s:base2, s:base02 ]
+  let [ s:base01, s:base1 ] = [ s:base1, s:base01 ]
+  let [ s:base00, s:base0 ] = [ s:base0, s:base00 ]
+endif
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base03, s:blue ], [ s:base03, s:base00 ] ]
+let s:p.normal.right = [ [ s:base03, s:base1 ], [ s:base03, s:base00 ] ]
+let s:p.inactive.right = [ [ s:base03, s:base00 ], [ s:base0, s:base02 ] ]
+let s:p.inactive.left =  [ [ s:base0, s:base02 ], [ s:base0, s:base02 ] ]
+let s:p.insert.left = [ [ s:base03, s:green ], [ s:base03, s:base00 ] ]
+let s:p.replace.left = [ [ s:base03, s:red ], [ s:base03, s:base00 ] ]
+let s:p.visual.left = [ [ s:base03, s:magenta ], [ s:base03, s:base00 ] ]
+let s:p.normal.middle = [ [ s:base1, s:base02 ] ]
+let s:p.inactive.middle = [ [ s:base01, s:base02 ] ]
+let s:p.tabline.left = [ [ s:base03, s:base00 ] ]
+let s:p.tabline.tabsel = [ [ s:base03, s:base1 ] ]
+let s:p.tabline.middle = [ [ s:base0, s:base02 ] ]
+let s:p.tabline.right = copy(s:p.tabline.left)
+let s:p.normal.error = [ [ s:base03, s:red ] ]
+let s:p.normal.warning = [ [ s:base03, s:yellow ] ]
+
+let g:lightline#colorscheme#solarized#palette = lightline#colorscheme#flatten(s:p)

+ 45 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/srcery_drk.vim

@@ -0,0 +1,45 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/srcery_drk.vim
+" Author: Christopher Vittal
+" License: MIT License
+" Last Change: 2018/05/19
+" =============================================================================
+
+let s:base03 = [ '#151513', 233 ]
+let s:base02 = [ '#30302c', 236 ]
+let s:base01 = [ '#4e4e43', 239 ]
+let s:base00 = [ '#666656', 242  ]
+let s:base0 = [ '#808070', 244 ]
+let s:base1 = [ '#949484', 246 ]
+let s:base2 = [ '#a8a897', 248 ]
+let s:base3 = [ '#e8e8d3', 253 ]
+let s:yellow = [ '#fbb829', 3 ]
+let s:orange = [ '#d75f00', 166 ]
+let s:red = [ '#ff3128', 1 ]
+let s:magenta = [ '#e02c6d', 5 ]
+let s:bright_magenta = [ '#e35682', 13 ]
+let s:blue = [ '#5573a3', 4 ]
+let s:bright_blue = [ '#8eb2f7', 12 ]
+let s:cyan = [ '#0aaeb3', 6 ]
+let s:green = [ '#519f50', 2 ]
+let s:bright_green = [ '#98bc37', 10 ]
+let s:white = [ '#fce8c3', 15 ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base02, s:bright_blue, 'bold' ], [ s:base3, s:base01 ] ]
+let s:p.normal.right = [ [ s:base02, s:base1 ], [ s:base2, s:base01 ] ]
+let s:p.inactive.right = [ [ s:base02, s:base00 ], [ s:base0, s:base02 ] ]
+let s:p.inactive.left =  [ [ s:base0, s:base02 ], [ s:base00, s:base02 ] ]
+let s:p.insert.left = [ [ s:base02, s:bright_green, 'bold' ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base3, s:red, 'bold' ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base3, s:bright_magenta, 'bold' ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base0, s:base02 ] ]
+let s:p.inactive.middle = [ [ s:base00, s:base02 ] ]
+let s:p.tabline.left = [ [ s:base3, s:base00, 'bold'] ]
+let s:p.tabline.tabsel = [ [ s:base3, s:base02 ] ]
+let s:p.tabline.middle = [ [ s:base01, s:base1 ] ]
+let s:p.tabline.right = copy(s:p.normal.right)
+let s:p.normal.error = [ [ s:red, s:base02 ] ]
+let s:p.normal.warning = [ [ s:yellow, s:base01 ] ]
+
+let g:lightline#colorscheme#srcery_drk#palette = lightline#colorscheme#flatten(s:p)

+ 42 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colorscheme/wombat.vim

@@ -0,0 +1,42 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/wombat.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2022/03/15 23:59:09.
+" =============================================================================
+
+let s:base03 = [ '#242424', 235 ]
+let s:base023 = [ '#353535', 236 ]
+let s:base02 = [ '#444444', 238 ]
+let s:base01 = [ '#585858', 240 ]
+let s:base00 = [ '#666666', 242  ]
+let s:base0 = [ '#808080', 244 ]
+let s:base1 = [ '#969696', 247 ]
+let s:base2 = [ '#a8a8a8', 248 ]
+let s:base3 = [ '#d0d0d0', 252 ]
+let s:yellow = [ '#cae682', 180 ]
+let s:orange = [ '#e5786d', 173 ]
+let s:red = [ '#e5786d', 203 ]
+let s:magenta = [ '#f2c68a', 216 ]
+let s:blue = [ '#8ac6f2', 117 ]
+let s:cyan = s:blue
+let s:green = [ '#95e454', 119 ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base02, s:blue ], [ s:base3, s:base01 ] ]
+let s:p.normal.right = [ [ s:base02, s:base0 ], [ s:base1, s:base01 ] ]
+let s:p.inactive.right = [ [ s:base023, s:base01 ], [ s:base00, s:base02 ] ]
+let s:p.inactive.left =  [ [ s:base1, s:base02 ], [ s:base00, s:base023 ] ]
+let s:p.insert.left = [ [ s:base02, s:green ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base023, s:red ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base02, s:magenta ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base2, s:base02 ] ]
+let s:p.inactive.middle = [ [ s:base1, s:base023 ] ]
+let s:p.tabline.left = [ [ s:base3, s:base00 ] ]
+let s:p.tabline.tabsel = [ [ s:base3, s:base03 ] ]
+let s:p.tabline.middle = [ [ s:base2, s:base02 ] ]
+let s:p.tabline.right = [ [ s:base2, s:base00 ] ]
+let s:p.normal.error = [ [ s:base03, s:red ] ]
+let s:p.normal.warning = [ [ s:base023, s:yellow ] ]
+
+let g:lightline#colorscheme#wombat#palette = lightline#colorscheme#flatten(s:p)

+ 52 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/colortable.vim

@@ -0,0 +1,52 @@
+" =============================================================================
+" Filename: autoload/lightline/colortable.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2020/06/19 11:07:13.
+" =============================================================================
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! s:load() abort
+  let rgbfile = $VIMRUNTIME . '/rgb.txt'
+  let table = {}
+  if filereadable(rgbfile)
+    for _ in map(filter(readfile(rgbfile), 'v:val !~# "^!"'), 'matchlist(v:val, "^\\s*\\(\\d\\+\\)\\s\\+\\(\\d\\+\\)\\s\\+\\(\\d\\+\\)\\s\\+\\(.*\\)")[1:4]')
+      let table[tolower(_[3])] = _[0:2]
+    endfor
+  endif
+  return table
+endfunction
+
+let s:table = s:load()
+
+function! lightline#colortable#name_to_rgb(name) abort
+  let name = tolower(a:name)
+  return has_key(s:table, name) ? s:table[name] : []
+endfunction
+
+function! lightline#colortable#gui2cui(rgb, fallback) abort
+  let rgb = map(matchlist(a:rgb, '#\(..\)\(..\)\(..\)')[1:3], '0 + ("0x".v:val)')
+  if len(rgb) == 0
+    let rgb = lightline#colortable#name_to_rgb(a:rgb)
+    if len(rgb) == 0
+      return a:fallback % 128
+    endif
+  endif
+  let rgb = [rgb[0] > 127 ? 4 : 0, rgb[1] > 127 ? 2 : 0, rgb[2] > 127 ? 1 : 0]
+  return rgb[0] + rgb[1] + rgb[2]
+endfunction
+
+function! lightline#colortable#gui2cui_palette(palette) abort
+  for u in values(a:palette)
+    for v in values(u)
+      for w in v
+        let [w[2], w[3]] = [lightline#colortable#gui2cui(w[0], w[2]), lightline#colortable#gui2cui(w[1], w[3])]
+      endfor
+    endfor
+  endfor
+endfunction
+
+let &cpo = s:save_cpo
+unlet s:save_cpo

+ 33 - 0
vimfiles/bundle/lightline.vim/autoload/lightline/tab.vim

@@ -0,0 +1,33 @@
+" =============================================================================
+" Filename: autoload/lightline/tab.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2016/05/07 22:31:02.
+" =============================================================================
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! lightline#tab#filename(n) abort
+  let buflist = tabpagebuflist(a:n)
+  let winnr = tabpagewinnr(a:n)
+  let _ = expand('#'.buflist[winnr - 1].':t')
+  return _ !=# '' ? _ : '[No Name]'
+endfunction
+
+function! lightline#tab#modified(n) abort
+  let winnr = tabpagewinnr(a:n)
+  return gettabwinvar(a:n, winnr, '&modified') ? '+' : gettabwinvar(a:n, winnr, '&modifiable') ? '' : '-'
+endfunction
+
+function! lightline#tab#readonly(n) abort
+  let winnr = tabpagewinnr(a:n)
+  return gettabwinvar(a:n, winnr, '&readonly') ? 'RO' : ''
+endfunction
+
+function! lightline#tab#tabnum(n) abort
+  return a:n
+endfunction
+
+let &cpo = s:save_cpo
+unlet s:save_cpo

+ 153 - 0
vimfiles/bundle/lightline.vim/colorscheme.md

@@ -0,0 +1,153 @@
+# Available Colorschemes
+
+### powerline (default)
+
+![lightline.vim - powerline](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/powerline.png)
+
+### powerlineish
+
+![lightline.vim - powerlineish](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/powerlineish.png)
+
+### wombat
+
+![lightline.vim - wombat](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/wombat.png)
+
+### OldHope
+
+![lightline.vim - OldHope](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/OldHope.png)
+
+### PaperColor (`background=dark`)
+
+![lightline.vim - PaperColor_dark](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/PaperColor_dark.png)
+
+### PaperColor (`background=light`)
+
+![lightline.vim - PaperColor_light](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/PaperColor_light.png)
+
+### Tomorrow
+
+![lightline.vim - Tomorrow](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/Tomorrow.png)
+
+### Tomorrow_Night
+
+![lightline.vim - Tomorrow_Night](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/Tomorrow_Night.png)
+
+### Tomorrow_Night_Blue
+
+![lightline.vim_- Tomorrow_Night_Blue](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/Tomorrow_Night_Blue.png)
+
+### Tomorrow_Night_Bright
+
+![lightline.vim - Tomorrow_Night_Bright](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/Tomorrow_Night_Bright.png)
+
+### Tomorrow_Night_Eighties
+
+![lightline.vim - Tomorrow_Night_Eighties](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/Tomorrow_Night_Eighties.png)
+
+### ayu_mirage
+
+![lightline.vim - ayu_mirage](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/ayu_mirage.png)
+
+### ayu_light
+
+![lightline.vim - ayu_light](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/ayu_light.png)
+
+### ayu_dark
+
+![lightline.vim - ayu_dark](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/ayu_dark.png)
+
+### darcula
+
+![lightline.vim - darcula](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/darcula.png)
+
+### deus
+
+![lightline.vim - deus](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/deus.png)
+
+### jellybeans
+
+![lightline.vim - jellybeans](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/jellybeans.png)
+
+### selenized_dark
+
+![lightline.vim - selenized_dark](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/selenized_dark.png)
+
+### selenized_black
+
+![lightline.vim - selenized_black](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/selenized_black.png)
+
+### selenized_light
+
+![lightline.vim - selenized_light](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/selenized_light.png)
+
+### selenized_white
+
+![lightline.vim - selenized_white](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/selenized_white.png)
+
+### solarized (`background=dark`)
+
+![lightline.vim - solarized_dark](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/solarized_dark.png)
+
+### solarized (`background=light`)
+
+![lightline.vim - solarized_light](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/solarized_light.png)
+
+### materia
+
+![lightline.vim - materia](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/materia.png)
+
+### material
+
+![lightline.vim - material](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/material.png)
+
+### molokai
+
+![lightline.vim - molokai](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/molokai.png)
+
+### nord
+
+![lightline.vim - nord](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/nord.png)
+
+### seoul256
+
+![lightline.vim - seoul256](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/seoul256.png)
+
+### one (`background=dark`)
+
+![lightline.vim - one_dark](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/one_dark.png)
+
+### one (`background=light`)
+
+![lightline.vim - one_light](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/one_light.png)
+
+### rosepine (`background=dark`)
+
+![lightline.vim - rosepine_dark](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/rosepine_dark.png)
+
+### rosepine (`background=light`)
+
+![lightline.vim - rosepine_light](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/rosepine_light.png)
+
+### srcery_drk
+
+![lightline.vim - srcery_drk](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/srcery_drk.png)
+
+### simpleblack
+
+![lightline.vim - simpleblack](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/simpleblack.png)
+
+### apprentice
+
+![lightline.vim - apprentice](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/apprentice.png)
+
+### landscape
+
+![lightline.vim - landscape](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/landscape.png)
+
+### 16color (`background=dark`)
+
+![lightline.vim - 16color_dark](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/16color_dark.png)
+
+### 16color (`background=light`)
+
+![lightline.vim - 16color_light](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/16color_light.png)

+ 1145 - 0
vimfiles/bundle/lightline.vim/doc/lightline.txt

@@ -0,0 +1,1145 @@
+*lightline.txt*	A light and configurable statusline/tabline for Vim
+
+Author: itchyny (https://github.com/itchyny)
+License: MIT License
+Repository: https://github.com/itchyny/lightline.vim
+Last Change: 2022/03/16 00:15:04.
+
+CONTENTS					*lightline-contents*
+
+Introduction				|lightline-introduction|
+Spirit					|lightline-spirit|
+Option					|lightline-option|
+Function				|lightline-function|
+Component Expansion			|lightline-component-expansion|
+Colorscheme				|lightline-colorscheme|
+Examples				|lightline-examples|
+Troubleshooting				|lightline-troubleshooting|
+
+==============================================================================
+INTRODUCTION					*lightline-introduction*
+
+The *lightline* plugin is a light and configurable statusline/tabline for Vim.
+
+------------------------------------------------------------------------------
+SPIRIT						*lightline-spirit*
+
+	Minimalism
+	    The core script is very small to achieve enough functions as a
+	    statusline plugin.
+
+	Configurability
+	    You can create your own component and easily add to the statusline
+	    and the tabline.
+
+	Orthogonality
+	    The plugin does not rely on the implementation of other plugins.
+	    Such plugin crossing settings should be configured by users.
+
+	You find this plugin does not integrate with other plugins by default.
+	This plugin does not provide branch information, which is a basic
+	component in existing statusline plugins. It is a design of
+	lightline.vim that such plugin crossing configuration should be
+	written by users. Once a plugin starts to integrate with some famous
+	plugins, it should be kept updated to follow the changes of the
+	plugins and should accept integration requests with new plugins.
+	Instead, lightline.vim is designed very carefully so that users can
+	easily integrate with other plugins. Good APIs keep a plugin clean.
+
+------------------------------------------------------------------------------
+OPTIONS						*lightline-option*
+
+	g:lightline				*g:lightline*
+		All the configurations are stored in this global variable.
+
+	g:lightline.active			*g:lightline.active*
+	g:lightline.inactive			*g:lightline.inactive*
+	g:lightline.tabline			*g:lightline.tabline*
+		Dictionaries to store the statusline/tabline components.
+		Note that right groups of components are stored from right to
+		left.
+		The default values are:
+>
+		let g:lightline.active = {
+		    \ 'left': [ [ 'mode', 'paste' ],
+		    \           [ 'readonly', 'filename', 'modified' ] ],
+		    \ 'right': [ [ 'lineinfo' ],
+		    \            [ 'percent' ],
+		    \            [ 'fileformat', 'fileencoding', 'filetype' ] ] }
+		let g:lightline.inactive = {
+		    \ 'left': [ [ 'filename' ] ],
+		    \ 'right': [ [ 'lineinfo' ],
+		    \            [ 'percent' ] ] }
+		let g:lightline.tabline = {
+		    \ 'left': [ [ 'tabs' ] ],
+		    \ 'right': [ [ 'close' ] ] }
+<
+	g:lightline.tab				*g:lightline.tab*
+		A dictionary to store the tab components in each tabs.
+		The default values are:
+>
+		let g:lightline.tab = {
+		    \ 'active': [ 'tabnum', 'filename', 'modified' ],
+		    \ 'inactive': [ 'tabnum', 'filename', 'modified' ] }
+<
+	g:lightline.component			*g:lightline.component*
+		A dictionary for statusline/tabline components.
+		The default value is:
+>
+		let g:lightline.component = {
+		    \ 'mode': '%{lightline#mode()}',
+		    \ 'absolutepath': '%F',
+		    \ 'relativepath': '%f',
+		    \ 'filename': '%t',
+		    \ 'modified': '%M',
+		    \ 'bufnum': '%n',
+		    \ 'paste': '%{&paste?"PASTE":""}',
+		    \ 'readonly': '%R',
+		    \ 'charvalue': '%b',
+		    \ 'charvaluehex': '%B',
+		    \ 'fileencoding': '%{&fenc!=#""?&fenc:&enc}',
+		    \ 'fileformat': '%{&ff}',
+		    \ 'filetype': '%{&ft!=#""?&ft:"no ft"}',
+		    \ 'percent': '%3p%%',
+		    \ 'percentwin': '%P',
+		    \ 'spell': '%{&spell?&spelllang:""}',
+		    \ 'lineinfo': '%3l:%-2c',
+		    \ 'line': '%l',
+		    \ 'column': '%c',
+		    \ 'close': '%999X X ',
+		    \ 'winnr': '%{winnr()}' }
+<
+	g:lightline.component_visible_condition
+						*g:lightline.component_visible_condition*
+		A dictionary to store the visible condition of the components.
+		Note that this configuration is used to control the visibility
+		of the subseparators, not to control the visibility of the
+		components themselves. Each expression should correspond to
+		the condition on which each component is not empty.
+		The default value is:
+>
+		let g:lightline.component_visible_condition = {
+		    \ 'modified': '&modified||!&modifiable',
+		    \ 'readonly': '&readonly',
+		    \ 'paste': '&paste',
+		    \ 'spell': '&spell' }
+<
+	g:lightline.component_function		*g:lightline.component_function*
+		A dictionary to store the function components.
+		This is useful to write a complex component configuration and
+		to integrate with other plugins. If a component set in both
+		component and component_function, the configuration of
+		component_function has priority.
+
+		The default value is:
+>
+		let g:lightline.component_function = {}
+<
+		For example, if you want to display the name of the git branch,
+		install |vim-fugitive| plugin and then configure as:
+>
+		let g:lightline = {
+			\ 'active': {
+			\   'left': [ [ 'mode', 'paste' ],
+			\             [ 'gitbranch', 'readonly', 'filename', 'modified' ] ]
+			\ },
+			\ 'component_function': {
+			\   'gitbranch': 'FugitiveHead'
+			\ },
+			\ }
+<
+		If you simply want to display the branch name instead of
+		installing a plugin for full git integration, you can use
+		vim-gitbranch (https://github.com/itchyny/vim-gitbranch).
+
+	g:lightline.component_function_visible_condition
+						*g:lightline.component_function_visible_condition*
+		A dictionary to store the visible conditions of the function
+		components. Each expression should correspond to the condition
+		each component is not empty. This configuration is used to
+		control the visibility of the sub-separators. You can use this
+		configuration to reduce the number of function calls for
+		performance improvement by setting the value 1 (to tell lightline
+		that the component is always visible).
+		The default value is:
+>
+		let g:lightline.component_function_visible_condition = {}
+<
+	g:lightline.component_expand		*g:lightline.component_expand*
+		A dictionary to store expanding components. You can create
+		warning and critical components. The values should be the name
+		of functions should return either one of:
+			+ a string
+			+ an array of three elements:
+				[[ left ], [ middle ], [ right ]]
+		The component in this dictionary has priority over
+		|g:lightline.component| and |g:lightline.component_function|.
+		Note that the return string is appended to the statusline
+		string without any conversion. So you should replace all the
+		% signs with %%. Otherwise, lightline will be disabled in case
+		the text has a % sign.
+		(example: return substitute(text, '%', '%%', 'g')).
+		See |lightline-component-expansion| for more detail.
+>
+		let g:lightline.component_expand = {
+		    \ 'tabs': 'lightline#tabs' }
+<
+	g:lightline.component_type		*g:lightline.component_type*
+		A dictionary to specify the types for components in
+		|g:lightline.component_expand|. The types are used to specify
+		the color. Specifically, the type raw is used to specify a
+		component which should not be wrapped by item group: %(...%).
+		If you want to specify the type of a raw component, please use
+		|g:lightline.component_raw|.
+		The default value is: >
+
+		let g:lightline.component_type = {
+		    \ 'tabs': 'tabsel',
+		    \ 'close': 'raw' }
+<
+	g:lightline.component_raw		*g:lightline.component_raw*
+		A dictionary to specify the raw type components. When you
+		register a component to this dictionary (like >
+		let g:lightline.component_raw = { 'example': 1 }
+<		), the example component is not wrapped by item group: %(...%).
+		The default value is: >
+
+		let g:lightline.component_raw = {}
+<
+	g:lightline.tab_component		*g:lightline.tab_component*
+		A dictionary for components in one tab.
+		The default value is: >
+
+		let g:lightline.tab_component = {}
+<
+	g:lightline.tab_component_function	*g:lightline.tab_component_function*
+		Another dictionary for components in one tab.
+		A function specified as a tab component takes one argument:
+		the tab [count].
+		The default value is:
+>
+		let g:lightline.tab_component_function = {
+		      \ 'filename': 'lightline#tab#filename',
+		      \ 'modified': 'lightline#tab#modified',
+		      \ 'readonly': 'lightline#tab#readonly',
+		      \ 'tabnum': 'lightline#tab#tabnum' }
+<
+	g:lightline.colorscheme			*g:lightline.colorscheme*
+		The colorscheme for lightline.vim.
+		Currently, wombat, solarized, powerline, powerlineish,
+		jellybeans, molokai, seoul256, darcula,
+		selenized_dark, selenized_black, selenized_light, selenized_white,
+		Tomorrow, Tomorrow_Night, Tomorrow_Night_Blue,
+		Tomorrow_Night_Bright, Tomorrow_Night_Eighties, PaperColor,
+		landscape, one, materia, material, OldHope, nord, deus,
+		simpleblack, srcery_drk, ayu_mirage, ayu_light, ayu_dark,
+		apprentice, rosepine, and 16color are available.
+		The default value is:
+>
+		let g:lightline.colorscheme = 'default'
+<
+		Note that the default colorscheme is exactly the same as the
+		powerline theme.
+
+	g:lightline.mode_map			*g:lightline.mode_map*
+		A dictionary of names for the modes. The keys are the return
+		values of |mode()|.
+		The default value is:
+>
+		let g:lightline.mode_map = {
+		    \ 'n' : 'NORMAL',
+		    \ 'i' : 'INSERT',
+		    \ 'R' : 'REPLACE',
+		    \ 'v' : 'VISUAL',
+		    \ 'V' : 'V-LINE',
+		    \ "\<C-v>": 'V-BLOCK',
+		    \ 'c' : 'COMMAND',
+		    \ 's' : 'SELECT',
+		    \ 'S' : 'S-LINE',
+		    \ "\<C-s>": 'S-BLOCK',
+		    \ 't': 'TERMINAL',
+		    \ }
+<
+		When you search a word, you get into the command mode. But if
+		you want to keep the mode indicator as 'NORMAL', add >
+		let g:lightline = { 'mode_map': { 'c': 'NORMAL' } }
+<		to your .vimrc.
+
+	g:lightline.separator			*g:lightline.separator*
+	g:lightline.subseparator		*g:lightline.subseparator*
+		Dictionaries to store separators.
+		The default value is
+>
+		let g:lightline.separator = { 'left': '', 'right': '' }
+		let g:lightline.subseparator = { 'left': '|', 'right': '|' }
+<
+	g:lightline.tabline_separator			*g:lightline.tabline_separator*
+	g:lightline.tabline_subseparator		*g:lightline.tabline_subseparator*
+		Dictionaries to store separators for the tabline.
+		The default value is
+>
+		let g:lightline.tabline_separator = g:lightline.separator
+		let g:lightline.tabline_subseparator = g:lightline.subseparator
+<
+	g:lightline.enable			*g:lightline.enable*
+		A dictionary to specify which feature is turned on.
+		The default value is
+>
+		let g:lightline.enable = {
+		    \ 'statusline': 1,
+		    \ 'tabline': 1
+		    \ }
+<
+==============================================================================
+FUNCTION					*lightline-function*
+Exposed functions for lightline.vim.
+
+	lightline#mode()			*lightline#mode()*
+		Returns the mode of the Vim using |g:lightline.mode_map|.
+
+	lightline#init()			*lightline#init()*
+		Initializes the internal state from |g:lightline|.
+
+	lightline#colorscheme()			*lightline#colorscheme()*
+		Initializes the colorscheme and the highlight groups.
+
+	lightline#update()			*lightline#update()*
+		Updates all the statuslines of existing windows.
+
+	lightline#enable()			*lightline#enable()*
+		Enables |lightline|.
+
+	lightline#disable()			*lightline#disable()*
+		Disables |lightline|.
+
+	lightline#toggle()			*lightline#toggle()*
+		Toggles |lightline|.
+
+	lightline#link([mode])			*lightline#link()*
+		Creates links of the highlight groups for the active window.
+		This function accepts an optional argument. It should be one
+		of the return value of |mode()|.
+
+	lightline#highlight()			*lightline#highlight()*
+		Set the highlight groups.
+
+	lightline#statusline({inactive})	*lightline#statusline()*
+		Returns |statusline| strings. If the argument is 0, it returns
+		the statusline for active window, and the statusline for
+		inactive window otherwise.
+
+	lightline#tabline()			*lightline#tabline()*
+		Returns the tabline string.
+
+	lightline#concatenate({list}, {num})	*lightline#concatenate()*
+		A string concatenation function. Concatenating all the strings
+		in {list} using the sub-separator of lightline. If {num} is 0,
+		then the left sub-separator is used. Otherwise, the right
+		sub-separator is used.
+
+	lightline#palette()			*lightline#palette()*
+		Returns the palette data.
+
+==============================================================================
+COMPONENT EXPANSION				*lightline-component-expansion*
+You can create components, which have specific colors. This section gives an
+example using |syntastic|.
+
+If you want to add the |syntastic| flag to the statusline, an easy example is:
+>
+	" Example A
+	let g:lightline = {
+	      \ 'active': {
+	      \   'right': [ [ 'lineinfo', 'syntastic' ],
+	      \              [ 'percent' ],
+	      \              [ 'fileformat', 'fileencoding', 'filetype' ] ]
+	      \ },
+	      \ 'component_function': {
+	      \   'syntastic': 'SyntasticStatuslineFlag',
+	      \ }
+	      \ }
+	let g:syntastic_mode_map = { 'mode': 'passive',
+	      \                      'active_filetypes': ['c', 'cpp'] }
+<
+However, the color of the syntastic component is the same as the lineinfo
+component.
+
+In order to change the syntastic component more outstanding, you have to use
+|g:lightline.component_expand|. See the following example:
+>
+	" Example B
+	let g:lightline = {
+	      \ 'active': {
+	      \   'right': [ [ 'syntastic', 'lineinfo' ],
+	      \              [ 'percent' ],
+	      \              [ 'fileformat', 'fileencoding', 'filetype' ] ]
+	      \ },
+	      \ 'component_expand': {
+	      \   'syntastic': 'SyntasticStatuslineFlag',
+	      \ },
+	      \ 'component_type': {
+	      \   'syntastic': 'error',
+	      \ }
+	      \ }
+	" Syntastic can call a post-check hook, let's update lightline there
+	" For more information: :help syntastic-loclist-callback
+	function! SyntasticCheckHook(errors)
+	  call lightline#update()
+	endfunction
+<
+In order to understand the above codes, you firstly should know how the
+colorschemes work in lightline.vim. Open the following file.
+		autoload/lightline/colorscheme/powerline.vim
+The colorscheme is created by one dictionary: s:p (abbreviation for palette).
+See the value of s:p.normal.right.
+>
+	let s:p.normal.right = [ ['gray5', 'gray10'],
+	      \                  ['gray9', 'gray4'],
+	      \                  ['gray8', 'gray2'] ]
+<
+This array corresponds to the structure of g:lightline.active.right. Recall
+the example A.
+>
+	" Example A
+	let g:lightline.active.right = [ [ 'lineinfo', 'syntastic' ],
+	      \                          [ 'percent' ],
+	      \                          [ 'fileformat', 'fileencoding', 'filetype' ] ]
+<
+The colors are ([fgcolor, bgcolor):
+>
+	(0) [ 'lineinfo', 'syntastic' ]                   ---  s:p.normal.right[0] = ['gray5', 'gray10']
+	(1) [ 'percent' ]                                 ---  s:p.normal.right[1] = ['gray9', 'gray4']
+	(2) [ 'fileformat', 'fileencoding', 'filetype' ]  ---  s:p.normal.right[2] = ['gray8', 'gray2']
+<
+Recall the example B.
+>
+	" Example B
+	let g:lightline.active.right = [ [ 'syntastic', 'lineinfo' ],
+	      \                          [ 'percent' ],
+	      \                          [ 'fileformat', 'fileencoding', 'filetype' ] ]
+<
+If a component is specified in |g:lightline.component_expand|, lightline.vim
+expands the components before setting to statusline/tabline. In this example,
+the syntastic component is expanded using the |SyntasticStatuslineFlag| function.
+This function returns a {string}. Let us call it `syntastic_flag`.
+>
+	let syntastic_flag = SyntasticStatuslineFlag()
+<
+The syntastic component is now expanded, so it go up to one component group.
+The type of the syntastic component is error, and the palette has error
+colors, the result is:
+>
+	" Expanded result of Example B
+	(error) [ syntastic_flag ]                            ---  s:p.normal.error[0] = ['gray9', 'brightestred']
+	(0)     [ 'lineinfo' ]                                ---  s:p.normal.right[0] = ['gray5', 'gray10']
+	(1)     [ 'percent' ]                                 ---  s:p.normal.right[1] = ['gray9', 'gray4']
+	(2)     [ 'fileformat', 'fileencoding', 'filetype' ]  ---  s:p.normal.right[2] = ['gray8', 'gray2']
+<
+Thus the syntastic component has the red color.
+
+
+Another example for |g:lightline.component_expand| is the tabs component.
+Actually, the expand feature is created for the tabs component.
+>
+	let g:lightline.tabline.left = [ [ 'tabs' ] ]
+	let g:lightline.component_expand = {
+	    \ 'tabs': 'lightline#tabs' }
+<
+Create three tabs and select the middle tab. Then execute
+>
+	echo lightline#tabs()
+	" [['%1T%{lightline#onetab(1,0)}'],
+	"  ['%2T%{lightline#onetab(2,1)}'],
+	"  ['%3T%{lightline#onetab(3,0)}%T']]
+<
+It returns an array of three elements. The expanded result is:
+>
+	" Expanded result of tabline
+	(0)      ['%1T%{lightline#onetab(1,0)}']    ---  s:p.tabline.left[0] = ['gray9', 'gray4']
+	(tabsel) ['%2T%{lightline#onetab(2,1)}']    ---  s:p.tabline.tabsel[0] = ['gray9', 'gray1']
+	(0)      ['%3T%{lightline#onetab(3,0)}%T']  ---  s:p.tabline.left[0] = ['gray9', 'gray4']
+<
+If the tabline components are
+>
+	let g:lightline.tabline.left = [ [ 'A', 'B', 'tabs', 'C', 'D' ] ]
+<
+then the expanded result is:
+>
+	(0)      ['A', 'B', '%1T%{lightline#onetab(1,0)}']    ---  s:p.tabline.left[0]
+	(tabsel) ['%2T%{lightline#onetab(2,1)}']              ---  s:p.tabline.tabsel[0]
+	(0)      ['%3T%{lightline#onetab(3,0)}%T', 'C', 'D']  ---  s:p.tabline.left[0]
+<
+In summary, when a function in |g:lightline.component_expand| returns an
+array of three elements, the first element and the last element remains as a
+part of existing component group. And the middle element goes up to new
+component group.
+------------------------------------------------------------------------------
+COLORSCHEME					*lightline-colorscheme*
+You can configure the colorscheme of lightline. For example,
+>
+	let g:lightline = {
+		\ 'colorscheme': 'wombat',
+		\ }
+<
+The colorscheme files are found in the directory
+
+	lightline.vim/autoload/lightline/colorscheme/
+
+In each file, one global variable is defined. For example, in the landscape.vim
+file, you see
+>
+	let g:lightline#colorscheme#landscape#palette = s:p
+<
+In the file, the colors for the landscape colorscheme are defined. For example,
+>
+	let s:p.normal.left = [ ['#0000ff', '#ffffff', 21, 231, 'bold' ], [ '#ffffff', '#0000ff', 231, 21 ] ]
+<
+defines the colors for the components on the left hand side, in normal mode.
+>
+	let s:p.tabline.tabsel = [ [ '#dadada', '#121212', 253, 233 ] ]
+<
+defines the colors for the selected tab in tabline. In general, each palette
+follows the following style:
+>
+	let s:p.{mode}.{where} = [ [ {guifg}, {guibg}, {ctermfg}, {ctermbg} ], ... ]
+<
+
+
+Now, you can create your own colorscheme for lightline. Create a
+yourcolorscheme.vim at
+
+	{one of the paths in &rtp}/autoload/lightline/colorscheme/yourcolorscheme.vim
+
+The following code gives the minimal palette definition for lightline.
+>
+	let s:p = {'normal': {}}
+	let s:p.normal.left = [ [ ... ] ]
+	let s:p.normal.right = [ [ ... ] ]
+	let s:p.normal.middle = [ [ ... ] ]
+	let g:lightline#colorscheme#yourcolorscheme#palette = s:p
+<
+And if you add the colorscheme configuration to your .vimrc(_vimrc),
+>
+	let g:lightline = {
+		\ 'colorscheme': 'yourcolorscheme',
+		\ }
+<
+you find it possible to change the lightline colors as you wish.
+
+Moreover, if you want to change the colors based on the mode of vim, write
+something like this:
+>
+	let s:p.insert.left = [ [ ... ] ]
+	let s:p.insert.right = [ [ ... ] ]
+	let s:p.replace.left = [ [ ... ] ]
+	let s:p.replace.right = [ [ ... ] ]
+	...
+	...
+<
+For expanded components, you are recommended to define the following two
+colors.
+>
+	let s:p.normal.error = [ [ ... ] ]
+	let s:p.normal.warning = [ [ ... ] ]
+<
+For the complete list of components the color of which you should define in
+your colorscheme, see the colorscheme files in lightline.
+
+It is sometimes painful to write all the colors for both gui and cterm.
+Actually, lightline has some useful functions for writing colorschemes. For
+example, see
+	lightline.vim/autoload/lightline/colorscheme/Tomorrow_Night.vim
+this colorscheme is defined using only gui color numbers. And convert to the
+normal colorscheme form using:
+>
+	let g:lightline#colorscheme#Tomorrow_Night#palette = lightline#colorscheme#fill(s:p)
+<
+This function fills the cterm colors for a palette which has only gui colors, or
+vice versa. However, note that using the convenient function sources an
+additional Vim script file (autoload/lightline/colorscheme.vim), which causes
+a little slow down. If you want to avoid this situation, write all the colors
+as done in autoload/lightline/colorscheme/landscape.vim; firstly create the
+colorscheme using the fill function, and see the result, in a sense, the
+compiled version of your colorscheme.
+>
+	echo g:lightline#colorscheme#yourcolorscheme#palette
+<
+Then copy and paste the result to the colorscheme file.
+
+If you want to contribute a new colorscheme that is not currently available
+please follow the following rules:
+    *) All hex codes should be lowercase only
+    *) Use 2 space soft tabs
+    *) If your colorscheme has both light and dark variants, use a single file
+    *) Normal Mode should default to Cyan
+    *) Insert Mode should default to Green
+    *) Visual Mode should default to Yellow
+    *) Replace Mode should default to Red
+
+==============================================================================
+EXAMPLES					*lightline-examples*
+You can configure the appearance of statusline.
+Write the following examples in you .vimrc(_vimrc).
+
+In order to change the colorscheme:
+>
+	let g:lightline = {
+		\ 'colorscheme': 'wombat',
+		\ }
+<
+In order to define your own component:
+>
+	let g:lightline = {
+		\ 'component_function': {
+		\   'filename': 'LightlineFilename',
+		\   'readonly': 'LightlineReadonly',
+		\   'modified': 'LightlineModified',
+		\ }
+		\ }
+	function! LightlineFilename()
+		return &ft ==# 'vimfiler' ? vimfiler#get_status_string() :
+		      \  &ft ==# 'unite' ? unite#get_status_string() :
+		      \ expand('%:t') !=# '' ? expand('%:t') : '[No Name]'
+	endfunction
+	function! LightlineReadonly()
+		return &ft !~? 'help\|vimfiler' && &readonly ? 'RO' : ''
+	endfunction
+	function! LightlineModified()
+		return &modifiable && &modified ? '+' : ''
+	endfunction
+<
+Separators settings:
+>
+	let g:lightline = {
+		\ 'separator': { 'left': '', 'right': '' },
+		\ 'subseparator': { 'left': '|', 'right': '|' }
+		\ }
+<
+An example for fugitive, vimfiler and unite users.
+>
+	let g:lightline = {
+		\ 'active': {
+		\   'left': [ [ 'mode', 'paste' ], [ 'fugitive', 'filename' ] ]
+		\ },
+		\ 'component_function': {
+		\   'fugitive': 'LightlineFugitive',
+		\   'filename': 'LightlineFilename'
+		\ }
+		\ }
+	function! LightlineModified()
+		return &ft =~# 'help\|vimfiler' ? '' : &modified ? '+' : &modifiable ? '' : '-'
+	endfunction
+	function! LightlineReadonly()
+		return &ft !~? 'help\|vimfiler' && &readonly ? 'RO' : ''
+	endfunction
+	function! LightlineFilename()
+		return (LightlineReadonly() !=# '' ? LightlineReadonly() . ' ' : '') .
+		\ (&ft ==# 'vimfiler' ? vimfiler#get_status_string() :
+		\  &ft ==# 'unite' ? unite#get_status_string() :
+		\ expand('%:t') !=# '' ? expand('%:t') : '[No Name]') .
+		\ (LightlineModified() !=# '' ? ' ' . LightlineModified() : '')
+	endfunction
+	function! LightlineFugitive()
+		if exists('*FugitiveHead')
+			return FugitiveHead()
+		endif
+		return ''
+	endfunction
+<
+For users of lots of plugins:
+>
+	let g:lightline = {
+	      \ 'active': {
+	      \   'left': [ [ 'mode', 'paste' ], [ 'fugitive', 'filename' ], ['ctrlpmark'] ],
+	      \   'right': [ [ 'syntastic', 'lineinfo' ], ['percent'], [ 'fileformat', 'fileencoding', 'filetype' ] ]
+	      \ },
+	      \ 'component_function': {
+	      \   'fugitive': 'LightlineFugitive',
+	      \   'filename': 'LightlineFilename',
+	      \   'fileformat': 'LightlineFileformat',
+	      \   'filetype': 'LightlineFiletype',
+	      \   'fileencoding': 'LightlineFileencoding',
+	      \   'mode': 'LightlineMode',
+	      \   'ctrlpmark': 'CtrlPMark',
+	      \ },
+	      \ 'component_expand': {
+	      \   'syntastic': 'SyntasticStatuslineFlag',
+	      \ },
+	      \ 'component_type': {
+	      \   'syntastic': 'error',
+	      \ },
+	      \ 'subseparator': { 'left': '|', 'right': '|' }
+	      \ }
+
+	function! LightlineModified()
+	  return &ft ==# 'help' ? '' : &modified ? '+' : &modifiable ? '' : '-'
+	endfunction
+
+	function! LightlineReadonly()
+	  return &ft !~? 'help' && &readonly ? 'RO' : ''
+	endfunction
+
+	function! LightlineFilename()
+	  let fname = expand('%:t')
+	  return fname ==# 'ControlP' && has_key(g:lightline, 'ctrlp_item') ? g:lightline.ctrlp_item :
+	        \ fname =~# '^__Tagbar__\|__Gundo\|NERD_tree' ? '' :
+	        \ &ft ==# 'vimfiler' ? vimfiler#get_status_string() :
+	        \ &ft ==# 'unite' ? unite#get_status_string() :
+	        \ &ft ==# 'vimshell' ? vimshell#get_status_string() :
+	        \ (LightlineReadonly() !=# '' ? LightlineReadonly() . ' ' : '') .
+	        \ (fname !=# '' ? fname : '[No Name]') .
+	        \ (LightlineModified() !=# '' ? ' ' . LightlineModified() : '')
+	endfunction
+
+	function! LightlineFugitive()
+	  try
+	    if expand('%:t') !~? 'Tagbar\|Gundo\|NERD' && &ft !~? 'vimfiler' && exists('*FugitiveHead')
+	      let mark = ''  " edit here for cool mark
+	      let branch = FugitiveHead()
+	      return branch !=# '' ? mark.branch : ''
+	    endif
+	  catch
+	  endtry
+	  return ''
+	endfunction
+
+	function! LightlineFileformat()
+	  return winwidth(0) > 70 ? &fileformat : ''
+	endfunction
+
+	function! LightlineFiletype()
+	  return winwidth(0) > 70 ? (&filetype !=# '' ? &filetype : 'no ft') : ''
+	endfunction
+
+	function! LightlineFileencoding()
+	  return winwidth(0) > 70 ? (&fenc !=# '' ? &fenc : &enc) : ''
+	endfunction
+
+	function! LightlineMode()
+	  let fname = expand('%:t')
+	  return fname =~# '^__Tagbar__' ? 'Tagbar' :
+	        \ fname ==# 'ControlP' ? 'CtrlP' :
+	        \ fname ==# '__Gundo__' ? 'Gundo' :
+	        \ fname ==# '__Gundo_Preview__' ? 'Gundo Preview' :
+	        \ fname =~# 'NERD_tree' ? 'NERDTree' :
+	        \ &ft ==# 'unite' ? 'Unite' :
+	        \ &ft ==# 'vimfiler' ? 'VimFiler' :
+	        \ &ft ==# 'vimshell' ? 'VimShell' :
+	        \ winwidth(0) > 60 ? lightline#mode() : ''
+	endfunction
+
+	function! CtrlPMark()
+	  if expand('%:t') ==# 'ControlP' && has_key(g:lightline, 'ctrlp_item')
+	    call lightline#link('iR'[g:lightline.ctrlp_regex])
+	    return lightline#concatenate([g:lightline.ctrlp_prev, g:lightline.ctrlp_item
+	          \ , g:lightline.ctrlp_next], 0)
+	  else
+	    return ''
+	  endif
+	endfunction
+
+	let g:ctrlp_status_func = {
+	  \ 'main': 'CtrlPStatusFunc_1',
+	  \ 'prog': 'CtrlPStatusFunc_2',
+	  \ }
+
+	function! CtrlPStatusFunc_1(focus, byfname, regex, prev, item, next, marked)
+	  let g:lightline.ctrlp_regex = a:regex
+	  let g:lightline.ctrlp_prev = a:prev
+	  let g:lightline.ctrlp_item = a:item
+	  let g:lightline.ctrlp_next = a:next
+	  return lightline#statusline(0)
+	endfunction
+
+	function! CtrlPStatusFunc_2(str)
+	  return lightline#statusline(0)
+	endfunction
+
+	let g:tagbar_status_func = 'TagbarStatusFunc'
+
+	function! TagbarStatusFunc(current, sort, fname, ...) abort
+	  return lightline#statusline(0)
+	endfunction
+
+	" Syntastic can call a post-check hook, let's update lightline there
+	" For more information: :help syntastic-loclist-callback
+	function! SyntasticCheckHook(errors)
+	  call lightline#update()
+	endfunction
+
+	let g:unite_force_overwrite_statusline = 0
+	let g:vimfiler_force_overwrite_statusline = 0
+	let g:vimshell_force_overwrite_statusline = 0
+<
+------------------------------------------------------------------------------
+TROUBLESHOOTING					*lightline-troubleshooting*
+
+Problem 1:				|lightline-problem-1|
+	How to install this plugin.
+
+Problem 2:				|lightline-problem-2|
+	How to update this plugin.
+
+Problem 3:				|lightline-problem-3|
+	How to uninstall this plugin.
+
+Problem 4:				|lightline-problem-4|
+	Cool statuslines appear only on |:vsp|.
+
+Problem 5:				|lightline-problem-5|
+	The statusline does not seem to be correctly colored.
+
+Problem 6:				|lightline-problem-6|
+	How to use a powerline font and the triangles for separators.
+
+Problem 10:				|lightline-problem-10|
+	Cool statusline disappears in |unite|, |vimfiler| and |vimshell|
+	buffers.
+
+Problem 11:				|lightline-problem-11|
+	Cool statusline disappears in |CtrlP|, |Tagbar| buffers.
+
+Problem 12:				|lightline-problem-12|
+	How to make the plus sign red like |powerline|?
+
+Problem 13:				|lightline-problem-13|
+	How to change the lightline colorscheme on the fly.
+
+Problem 14:				|lightline-problem-14|
+	The 'E541' warning appears on the right hand side.
+	Many components disable the statusline of lightline.
+
+Problem 15:				|lightline-problem-15|
+	Do not deal with the tabline.
+	Do not use the fancy separators in the tabline.
+
+Problem 16:				|lightline-problem-16|
+	When changed the component to a function component to an expanding
+	component, the statusline of lightline is sometimes disabled.
+
+Problem 17:				|lightline-problem-17|
+	Found a bug of this plugin.
+	Got many errors while using this plugin.
+	Vim hangs while using this plugin.
+	Want this plugin to be more configurable.
+	This troubleshooting is not helpful.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+Problem 1:					*lightline-problem-1*
+	How to install this plugin.
+
+		If you install this plugin using Vim packages:
+>
+			git clone https://github.com/itchyny/lightline.vim \
+			    ~/.vim/pack/plugins/start/lightline
+<
+		If you install this plugin using |vim-pathogen|:
+>
+			git clone https://github.com/itchyny/lightline.vim \
+			    ~/.vim/bundle/lightline.vim
+<
+		If you install this plugin using |Vundle|:
+
+			1. Add the following configuration to your
+			.vimrc(_vimrc).
+>
+			Plugin 'itchyny/lightline.vim'
+<
+			2. Install with |:PluginInstall|.
+
+		If you install this plugin using |NeoBundle|:
+
+			1. Add the following configuration to your
+			.vimrc(_vimrc).
+>
+			NeoBundle 'itchyny/lightline.vim'
+<
+			2. Install with |:NeoBundleInstall|.
+
+		If you install this plugin using |vim-plug|:
+
+			1. Add the following configuration to your
+			.vimrc(_vimrc).
+>
+			Plug 'itchyny/lightline.vim'
+<
+			2. Install with |:PlugInstall|.
+
+		If you install this plugin using |dein|:
+
+			1. Add the following configuration to your
+			.vimrc(_vimrc).
+>
+			call dein#add('itchyny/lightline.vim')
+<
+			2. Install with :call |dein#install()|.
+
+Problem 2:					*lightline-problem-2*
+	How to update this plugin.
+
+		If you installed this plugin using Vim packages:
+>
+			git -C ~/.vim/pack/plugins/start/lightline pull
+<
+		If you installed this plugin using |vim-pathogen|:
+>
+			git -C ~/.vim/bundle/lightline.vim pull
+<
+		If you installed this plugin using |Vundle|:
+
+			Execute |:PluginUpdate|.
+
+		If you installed this plugin using |NeoBundle|:
+
+			Execute |:NeoBundleUpdate|.
+
+		If you installed this plugin using |vim-plug|:
+
+			Execute |:PlugUpdate|.
+
+		If you installed this plugin using |dein|:
+
+			Execute :call |dein#update()|.
+
+Problem 3:					*lightline-problem-3*
+	How to uninstall this plugin.
+
+		If you installed this plugin using Vim packages:
+>
+			rm -rf ~/.vim/pack/plugins/start/lightline
+<
+		If you installed this plugin using |vim-pathogen|:
+>
+			rm -rf ~/.vim/bundle/lightline.vim
+<
+		If you have installed this plugin using |Vundle|:
+
+			1. Remove `Plugin 'itchyny/lightline.vim'`
+			from your .vimrc(_vimrc).
+			2. Execute |:PluginClean|.
+
+		If you installed this plugin using |NeoBundle|:
+
+			1. Remove `NeoBundle 'itchyny/lightline.vim'`
+			from your .vimrc(_vimrc).
+			2. Remove the plugin directory.
+
+		If you installed this plugin using |vim-plug|:
+
+			1. Remove `Plug 'itchyny/lightline.vim'`
+			from your .vimrc(_vimrc).
+			2. Execute |:PlugClean|.
+
+		If you installed this plugin using |dein|:
+
+			1. Remove `call dein#add('itchyny/lightline.vim')`
+			from your .vimrc(_vimrc).
+			2. Remove the plugin directory.
+
+Problem 4:					*lightline-problem-4*
+	Cool statuslines appear only on |:vsp|.
+
+		Add the following setting to your .vimrc(_vimrc).
+>
+			set laststatus=2
+<
+Problem 5:					*lightline-problem-5*
+	The statusline does not seem to be correctly colored.
+
+		Add
+>
+			export TERM=xterm-256color
+<
+		to your .*shrc and add
+>
+			if !has('gui_running')
+			  set t_Co=256
+			endif
+<
+		to your .vimrc(_vimrc).
+
+Problem 6:					*lightline-problem-6*
+	How to use a powerline font and the triangles for separators.
+
+		Using a patched font is not recommended due to less
+		portability. Also the powerline fonts project is not actively
+		maintained (https://github.com/powerline/fonts).
+
+		If you still want to use a patched font, you can configure
+>
+		\ 'separator': { 'left': "\ue0b0", 'right': "\ue0b2" },
+		\ 'subseparator': { 'left': "\ue0b1", 'right': "\ue0b3" },
+<
+		or
+>
+		\ 'separator': { 'left': "\u2b80", 'right': "\u2b82" },
+		\ 'subseparator': { 'left': "\u2b81", 'right': "\u2b83" },
+<
+Problem 10:					*lightline-problem-10*
+	Cool statusline disappears on |unite|, |vimfiler| and |vimshell|
+	buffers.
+
+		Add the following settings to your .vimrc(_vimrc).
+>
+		let g:unite_force_overwrite_statusline = 0
+		let g:vimfiler_force_overwrite_statusline = 0
+		let g:vimshell_force_overwrite_statusline = 0
+<
+Problem 11:					*lightline-problem-11*
+	Cool statusline disappears in |CtrlP|, |Tagbar| buffers.
+
+		Add the following settings to your .vimrc(_vimrc).
+>
+		let g:ctrlp_status_func = {
+		  \ 'main': 'CtrlPStatusFunc_1',
+		  \ 'prog': 'CtrlPStatusFunc_2',
+		  \ }
+		function! CtrlPStatusFunc_1(focus, byfname, regex, prev, item, next, marked)
+		  return lightline#statusline(0)
+		endfunction
+		function! CtrlPStatusFunc_2(str)
+		  return lightline#statusline(0)
+		endfunction
+
+		let g:tagbar_status_func = 'TagbarStatusFunc'
+		function! TagbarStatusFunc(current, sort, fname, ...) abort
+		  return lightline#statusline(0)
+		endfunction
+<
+		See |lightline-example| for more cool settings for
+		these plugins.
+
+Problem 12:					*lightline-problem-12*
+	How to make the plus sign red like |powerline|?
+
+		Use the following settings.
+>
+		let g:lightline = {
+		      \ 'component': {
+		      \   'modified': '%#ModifiedColor#%{LightlineModified()}',
+		      \ }
+		      \ }
+		function! LightlineModified()
+		  let map = { 'V': 'n', "\<C-v>": 'n', 's': 'n', 'v': 'n', "\<C-s>": 'n', 'c': 'n', 'R': 'n'}
+		  let mode = get(map, mode()[0], mode()[0])
+		  let bgcolor = {'n': [240, '#585858'], 'i': [31, '#0087af']}
+		  let color = get(bgcolor, mode, bgcolor.n)
+		  exe printf('hi ModifiedColor ctermfg=196 ctermbg=%d guifg=#ff0000 guibg=%s term=bold cterm=bold',
+			\ color[0], color[1])
+		  return &modified ? '+' : &modifiable ? '' : '-'
+		endfunction
+<
+		It's surely complicated. There's no easy API to do a thing
+		like this. But it means that your request does not match
+		the spirit of lightline.
+
+Problem 13:					*lightline-problem-13*
+	How to change the lightline colorscheme on the fly.
+
+		To update your lightline colorscheme in sync with your vim
+		colorscheme (only for select colorschemes which exist for
+		both), add the following settings to your .vimrc(_vimrc).
+>
+		augroup LightlineColorscheme
+		  autocmd!
+		  autocmd ColorScheme * call s:lightline_update()
+		augroup END
+		function! s:lightline_update()
+		  if !exists('g:loaded_lightline')
+		    return
+		  endif
+		  try
+		    if g:colors_name =~# 'wombat\|solarized\|landscape\|jellybeans\|seoul256\|Tomorrow'
+		      let g:lightline.colorscheme =
+		            \ substitute(substitute(g:colors_name, '-', '_', 'g'), '256.*', '', '')
+		      call lightline#init()
+		      call lightline#colorscheme()
+		      call lightline#update()
+		    endif
+		  catch
+		  endtry
+		endfunction
+<
+		If you have not settled on a single lightline colorscheme, you
+		can easily switch between lightline colorschemes by adding the
+		following LightlineColorscheme command to your .vimrc(_vimrc).
+>
+		function! s:set_lightline_colorscheme(name) abort
+		  let g:lightline.colorscheme = a:name
+		  call lightline#init()
+		  call lightline#colorscheme()
+		  call lightline#update()
+		endfunction
+
+		function! s:lightline_colorschemes(...) abort
+		  return join(map(
+		        \ globpath(&rtp,"autoload/lightline/colorscheme/*.vim",1,1),
+		        \ "fnamemodify(v:val,':t:r')"),
+		        \ "\n")
+		endfunction
+
+		command! -nargs=1 -complete=custom,s:lightline_colorschemes LightlineColorscheme
+		      \ call s:set_lightline_colorscheme(<q-args>)
+<
+Problem 14:					*lightline-problem-14*
+	The 'E541' warning appears on the right hand side.
+	Many components disable the statusline of lightline.
+
+		The number of items in statusline/tabline is limited to 80
+		(see |E541|). You cannot register too much components.
+
+Problem 15:					*lightline-problem-15*
+	Do not deal with the tabline.
+	Do not use the fancy separators in the tabline.
+
+		You can disable the tabline feature of lightline.vim using:
+>
+		let g:lightline = {
+			\ 'enable': { 'tabline': 0 },
+			\ }
+<
+		If you don't like the separators in the tabline, use:
+>
+		let g:lightline = {
+			\ 'tabline_separator': { 'left': '', 'right': '' },
+			\ 'tabline_subseparator': { 'left': '', 'right': '' },
+			\ }
+<
+Problem 16:					*lightline-problem-16*
+	When changed the component to a function component to an expanding
+	component, the statusline of lightline is sometimes disabled.
+
+		When you changed from
+>
+			\ 'component_function': {
+			\   'my': 'My',
+			\ }
+<
+		to
+>
+			\ 'component_expand': {
+			\   'my': 'My',
+			\ }
+<
+		the statusline of lightline is disabled unexpectedly.
+		In such a case, the text returned by 'My' function may include
+		the '%' character. Replace all the '%' signs with '%%'.
+>
+		function My()
+		  ...
+		  return substitute(text, '%', '%%', 'g')
+		endfunction
+<
+Problem 17:					*lightline-problem-17*
+	Found a bug of this plugin.
+	Got many errors while using this plugin.
+	Vim hangs while using this plugin.
+	Want this plugin to be more configurable.
+	This troubleshooting is not helpful.
+
+		Report/Request the issue/feature at
+		https://github.com/itchyny/lightline.vim/issues.
+
+==============================================================================
+vim:tw=78:sw=4:ts=8:ft=help:norl:noet:

+ 59 - 0
vimfiles/bundle/lightline.vim/doc/tags

@@ -0,0 +1,59 @@
+g:lightline	lightline.txt	/*g:lightline*
+g:lightline.active	lightline.txt	/*g:lightline.active*
+g:lightline.colorscheme	lightline.txt	/*g:lightline.colorscheme*
+g:lightline.component	lightline.txt	/*g:lightline.component*
+g:lightline.component_expand	lightline.txt	/*g:lightline.component_expand*
+g:lightline.component_function	lightline.txt	/*g:lightline.component_function*
+g:lightline.component_function_visible_condition	lightline.txt	/*g:lightline.component_function_visible_condition*
+g:lightline.component_raw	lightline.txt	/*g:lightline.component_raw*
+g:lightline.component_type	lightline.txt	/*g:lightline.component_type*
+g:lightline.component_visible_condition	lightline.txt	/*g:lightline.component_visible_condition*
+g:lightline.enable	lightline.txt	/*g:lightline.enable*
+g:lightline.inactive	lightline.txt	/*g:lightline.inactive*
+g:lightline.mode_map	lightline.txt	/*g:lightline.mode_map*
+g:lightline.separator	lightline.txt	/*g:lightline.separator*
+g:lightline.subseparator	lightline.txt	/*g:lightline.subseparator*
+g:lightline.tab	lightline.txt	/*g:lightline.tab*
+g:lightline.tab_component	lightline.txt	/*g:lightline.tab_component*
+g:lightline.tab_component_function	lightline.txt	/*g:lightline.tab_component_function*
+g:lightline.tabline	lightline.txt	/*g:lightline.tabline*
+g:lightline.tabline_separator	lightline.txt	/*g:lightline.tabline_separator*
+g:lightline.tabline_subseparator	lightline.txt	/*g:lightline.tabline_subseparator*
+lightline	lightline.txt	/*lightline*
+lightline#colorscheme()	lightline.txt	/*lightline#colorscheme()*
+lightline#concatenate()	lightline.txt	/*lightline#concatenate()*
+lightline#disable()	lightline.txt	/*lightline#disable()*
+lightline#enable()	lightline.txt	/*lightline#enable()*
+lightline#highlight()	lightline.txt	/*lightline#highlight()*
+lightline#init()	lightline.txt	/*lightline#init()*
+lightline#link()	lightline.txt	/*lightline#link()*
+lightline#mode()	lightline.txt	/*lightline#mode()*
+lightline#palette()	lightline.txt	/*lightline#palette()*
+lightline#statusline()	lightline.txt	/*lightline#statusline()*
+lightline#tabline()	lightline.txt	/*lightline#tabline()*
+lightline#toggle()	lightline.txt	/*lightline#toggle()*
+lightline#update()	lightline.txt	/*lightline#update()*
+lightline-colorscheme	lightline.txt	/*lightline-colorscheme*
+lightline-component-expansion	lightline.txt	/*lightline-component-expansion*
+lightline-contents	lightline.txt	/*lightline-contents*
+lightline-examples	lightline.txt	/*lightline-examples*
+lightline-function	lightline.txt	/*lightline-function*
+lightline-introduction	lightline.txt	/*lightline-introduction*
+lightline-option	lightline.txt	/*lightline-option*
+lightline-problem-1	lightline.txt	/*lightline-problem-1*
+lightline-problem-10	lightline.txt	/*lightline-problem-10*
+lightline-problem-11	lightline.txt	/*lightline-problem-11*
+lightline-problem-12	lightline.txt	/*lightline-problem-12*
+lightline-problem-13	lightline.txt	/*lightline-problem-13*
+lightline-problem-14	lightline.txt	/*lightline-problem-14*
+lightline-problem-15	lightline.txt	/*lightline-problem-15*
+lightline-problem-16	lightline.txt	/*lightline-problem-16*
+lightline-problem-17	lightline.txt	/*lightline-problem-17*
+lightline-problem-2	lightline.txt	/*lightline-problem-2*
+lightline-problem-3	lightline.txt	/*lightline-problem-3*
+lightline-problem-4	lightline.txt	/*lightline-problem-4*
+lightline-problem-5	lightline.txt	/*lightline-problem-5*
+lightline-problem-6	lightline.txt	/*lightline-problem-6*
+lightline-spirit	lightline.txt	/*lightline-spirit*
+lightline-troubleshooting	lightline.txt	/*lightline-troubleshooting*
+lightline.txt	lightline.txt	/*lightline.txt*

+ 33 - 0
vimfiles/bundle/lightline.vim/plugin/lightline.vim

@@ -0,0 +1,33 @@
+" =============================================================================
+" Filename: plugin/lightline.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2021/11/21 22:54:41.
+" =============================================================================
+
+if exists('g:loaded_lightline') || v:version < 703
+  finish
+endif
+let g:loaded_lightline = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+augroup lightline
+  autocmd!
+  autocmd WinEnter,BufEnter,SessionLoadPost,FileChangedShellPost * call lightline#update()
+  if !has('patch-8.1.1715')
+    autocmd FileType qf call lightline#update()
+  endif
+  autocmd SessionLoadPost * call lightline#highlight()
+  autocmd ColorScheme * if !has('vim_starting') || expand('<amatch>') !=# 'macvim'
+        \ | call lightline#update() | call lightline#highlight() | endif
+augroup END
+
+" This quickfix option was introduced at Vim 85850f3a5ef9, which is the commit
+" just before 8.1.1715. Before this patch, autocmd FileType is required to
+" overwrite the statusline of the quickfix and location windows.
+let g:qf_disable_statusline = 1
+
+let &cpo = s:save_cpo
+unlet s:save_cpo

+ 3021 - 0
vimfiles/bundle/nerdcommenter/autoload/nerdcommenter.vim

@@ -0,0 +1,3021 @@
+" Section: space string init
+" When putting spaces after the left delimiter and before the right we use
+" s:spaceStr for the space char. This way we can make it add anything after
+" the left and before the right by modifying this variable
+let s:spaceStr = ' '
+let s:lenSpaceStr = strlen(s:spaceStr)
+
+let s:NERDFileNameEscape="[]#*$%'\" ?`!&();<>\\"
+
+let s:delimiterMap = {
+    \ 'aap': { 'left': '#' },
+    \ 'abc': { 'left': '%' },
+    \ 'acedb': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'actionscript': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'ada': { 'left': '--', 'leftAlt': '--  ' },
+    \ 'ahdl': { 'left': '--' },
+    \ 'ahk': { 'left': ';', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'amiga': { 'left': ';' },
+    \ 'aml': { 'left': '/*' },
+    \ 'ampl': { 'left': '#' },
+    \ 'ansible': { 'left': '#' },
+    \ 'apache': { 'left': '#' },
+    \ 'apachestyle': { 'left': '#' },
+    \ 'apdl': { 'left': '!' },
+    \ 'applescript': { 'left': '--', 'leftAlt': '(*', 'rightAlt': '*)' },
+    \ 'armasm': { 'left': ';' },
+    \ 'asciidoc': { 'left': '//' },
+    \ 'asm': { 'left': ';', 'leftAlt': '#' },
+    \ 'asm68k': { 'left': ';' },
+    \ 'asn': { 'left': '--' },
+    \ 'asp': { 'left': '%', 'leftAlt': '%*', 'rightAlt': '*%' },
+    \ 'aspvbs': { 'left': '''', 'leftAlt': '<!--', 'rightAlt': '-->' },
+    \ 'asterisk': { 'left': ';' },
+    \ 'asy': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'atlas': { 'left': 'C', 'right': '$' },
+    \ 'ats': { 'left': '//', 'leftAlt': '(*', 'rightAlt': '*)' },
+    \ 'augeas': { 'left': '(*', 'right': '*)' },
+    \ 'autohotkey': { 'left': ';', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'autoit': { 'left': ';' },
+    \ 'ave': { 'left': "'" },
+    \ 'awk': { 'left': '#' },
+    \ 'basic': { 'left': "'", 'leftAlt': 'REM ' },
+    \ 'bbx': { 'left': '%' },
+    \ 'bc': { 'left': '#' },
+    \ 'bib': { 'left': '//' },
+    \ 'bindzone': { 'left': ';' },
+    \ 'bind-named': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'blade': { 'left': '{{--', 'right': '--}}' },
+    \ 'bst': { 'left': '%' },
+    \ 'btm': { 'left': '::' },
+    \ 'c': { 'left': '/*', 'right': '*/', 'leftAlt': '//' },
+    \ 'cabal': { 'left': '--' },
+    \ 'cairo': { 'left': '#' },
+    \ 'calibre': { 'left': '//' },
+    \ 'caos': { 'left': '*' },
+    \ 'catalog': { 'left': '--', 'right': '--' },
+    \ 'cf': { 'left': '<!---', 'right': '--->' },
+    \ 'cfg': { 'left': '#' },
+    \ 'cg': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'ch': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'cl': { 'left': '#' },
+    \ 'clean': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'clipper': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'clojure': { 'left': ';' },
+    \ 'cmake': { 'left': '#' },
+    \ 'cocci': { 'left': '//' },
+    \ 'coffee': { 'left': '#', 'leftAlt': '###', 'rightAlt': '###' },
+    \ 'conkyrc': { 'left': '#' },
+    \ 'context': { 'left': '%', 'leftAlt': '--' },
+    \ 'coq': { 'left': '(*', 'right': '*)' },
+    \ 'cpp': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'crontab': { 'left': '#' },
+    \ 'cs': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'csp': { 'left': '--' },
+    \ 'cterm': { 'left': '*' },
+    \ 'cucumber': { 'left': '#' },
+    \ 'cuda': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'cvs': { 'left': 'CVS:' },
+    \ 'cypher': { 'left': '//' },
+    \ 'cython': { 'left': '# ', 'leftAlt': '#' },
+    \ 'd': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'dakota': { 'left': '#' },
+    \ 'dcl': { 'left': '$!' },
+    \ 'debcontrol': { 'left': '#' },
+    \ 'debsources': { 'left': '#' },
+    \ 'def': { 'left': ';' },
+    \ 'desktop': { 'left': '#' },
+    \ 'dhcpd': { 'left': '#' },
+    \ 'diff': { 'left': '#' },
+    \ 'django': { 'left': '{% comment %}', 'right': '{% endcomment %}', 'leftAlt': '{#', 'rightAlt': '#}' },
+    \ 'dns': { 'left': ';' },
+    \ 'docbk': { 'left': '<!--', 'right': '-->' },
+    \ 'dockerfile': { 'left': '#' },
+    \ 'dosbatch': { 'left': 'REM ', 'leftAlt': '::' },
+    \ 'dosini': { 'left': ';' },
+    \ 'dot': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'dracula': { 'left': ';' },
+    \ 'dsl': { 'left': ';' },
+    \ 'dtml': { 'left': '<dtml-comment>', 'right': '</dtml-comment>' },
+    \ 'dylan': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'ebuild': { 'left': '#' },
+    \ 'ecd': { 'left': '#' },
+    \ 'eclass': { 'left': '#' },
+    \ 'eiffel': { 'left': '--' },
+    \ 'elf': { 'left': "'" },
+    \ 'elixir': { 'left': '#' },
+    \ 'elm': { 'left': '--', 'leftAlt': '{--', 'rightAlt': '--}' },
+    \ 'elmfilt': { 'left': '#' },
+    \ 'ember-script': { 'left': '#' },
+    \ 'emblem': { 'left': '/' },
+    \ 'erlang': { 'left': '%', 'leftAlt': '%%' },
+    \ 'eruby': { 'left': '<%#', 'right': '%>', 'leftAlt': '<!--', 'rightAlt': '-->' },
+    \ 'esmtprc': { 'left': '#' },
+    \ 'exim': { 'left': '#' },
+    \ 'expect': { 'left': '#' },
+    \ 'exports': { 'left': '#' },
+    \ 'factor': { 'left': '! ', 'leftAlt': '!# ' },
+    \ 'fancy': { 'left': '#' },
+    \ 'fasm': { 'left': ';' },
+    \ 'faust': { 'left': '//' },
+    \ 'fgl': { 'left': '#' },
+    \ 'fluent': { 'left': '#', 'leftAlt': '##' },
+    \ 'focexec': { 'left': '-*' },
+    \ 'form': { 'left': '*' },
+    \ 'fortran': { 'left': '!' },
+    \ 'foxpro': { 'left': '*' },
+    \ 'fsharp': { 'left': '(*', 'right': '*)', 'leftAlt': '//' },
+    \ 'fstab': { 'left': '#' },
+    \ 'fvwm': { 'left': '#' },
+    \ 'fx': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'gams': { 'left': '*' },
+    \ 'gdb': { 'left': '#' },
+    \ 'gdmo': { 'left': '--' },
+    \ 'gdscript3': { 'left': '# ', 'leftAlt': '#' },
+    \ 'geek': { 'left': 'GEEK_COMMENT:' },
+    \ 'genshi': { 'left': '<!--', 'right': '-->', 'leftAlt': '{#', 'rightAlt': '#}' },
+    \ 'gentoo-conf-d': { 'left': '#' },
+    \ 'gentoo-env-d': { 'left': '#' },
+    \ 'gentoo-init-d': { 'left': '#' },
+    \ 'gentoo-make-conf': { 'left': '#' },
+    \ 'gentoo-package-keywords': { 'left': '#' },
+    \ 'gentoo-package-mask': { 'left': '#' },
+    \ 'gentoo-package-use': { 'left': '#' },
+    \ 'gitcommit': { 'left': '#' },
+    \ 'gitconfig': { 'left': ';' },
+    \ 'gitignore': { 'left': '#' },
+    \ 'gitrebase': { 'left': '#' },
+    \ 'glsl': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'gnuplot': { 'left': '#' },
+    \ 'go': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'groff': { 'left': '\#' },
+    \ 'groovy': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'gsp': { 'left': '<%--', 'right': '--%>', 'leftAlt': '<!--', 'rightAlt': '-->' },
+    \ 'gtkrc': { 'left': '#' },
+    \ 'h': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'haml': { 'left': '-#', 'leftAlt': '/' },
+    \ 'handlebars': { 'left': '{{!-- ', 'right': ' --}}' },
+    \ 'haskell': { 'left': '--', 'nested': 0, 'leftAlt': '{-', 'rightAlt': '-}', 'nestedAlt': 1 },
+    \ 'haxe': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'hb': { 'left': '#' },
+    \ 'hbs': { 'left': '{{!-- ', 'right': ' --}}' },
+    \ 'hercules': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'hive': { 'left': '-- ' },
+    \ 'hocon': { 'left': '//', 'leftAlt': '#' },
+    \ 'hog': { 'left': '#' },
+    \ 'hostsaccess': { 'left': '#' },
+    \ 'htmlcheetah': { 'left': '##' },
+    \ 'htmldjango': { 'left': '{% comment %}', 'right': '{% endcomment %}', 'leftAlt': '{#', 'rightAlt': '#}' },
+    \ 'htmlos': { 'left': '#', 'right': '/#' },
+    \ 'hxml': { 'left': '#' },
+    \ 'hyphy': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'ia64': { 'left': '#' },
+    \ 'icon': { 'left': '#' },
+    \ 'idl': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'idlang': { 'left': ';' },
+    \ 'idris': { 'leftAlt': '--', 'left': '{-', 'right': '-}' },
+    \ 'incar': { 'left': '!' },
+    \ 'inform': { 'left': '!' },
+    \ 'inittab': { 'left': '#' },
+    \ 'ishd': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'iss': { 'left': ';' },
+    \ 'ist': { 'left': '%' },
+    \ 'jade': { 'left': '//-', 'leftAlt': '//' },
+    \ 'java': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'javacc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'javascript': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'javascriptreact': { 'left': '//', 'leftAlt': '{/*', 'rightAlt': '*/}' },
+    \ 'javascript.jquery': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'jess': { 'left': ';' },
+    \ 'jgraph': { 'left': '(*', 'right': '*)' },
+    \ 'jinja': { 'left': '{#', 'right': '#}', 'leftAlt': '<!--', 'rightAlt': '-->' },
+    \ 'jproperties': { 'left': '#' },
+    \ 'json5': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'jsonc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'jsonnet': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'jsp': { 'left': '<%--', 'right': '--%>' },
+    \ 'julia': { 'left': '# ', 'leftAlt': '#=', 'rightAlt': '=#' },
+    \ 'kivy': { 'left': '#' },
+    \ 'kix': { 'left': ';' },
+    \ 'kscript': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'lace': { 'left': '--' },
+    \ 'laravel': { 'left': '{{--', 'right': '--}}' },
+    \ 'ldif': { 'left': '#' },
+    \ 'lean': { 'left': '--', 'leftAlt': '/-', 'rightAlt': '-/' },
+    \ 'ledger': { 'left': '#', 'leftAlt': ';' },
+    \ 'less': { 'left': '/*', 'right': '*/' },
+    \ 'lhaskell': { 'left': '>{-', 'right': '-}', 'leftAlt': '>-- ' },
+    \ 'lilo': { 'left': '#' },
+    \ 'lilypond': { 'left': '%' },
+    \ 'liquid': { 'left': '{% comment %}', 'right': '{% endcomment %}' },
+    \ 'lisp': { 'left': ';', 'nested': 1, 'leftAlt': '#|', 'rightAlt': '|#', 'nestedAlt': 1 },
+    \ 'llvm': { 'left': ';' },
+    \ 'lotos': { 'left': '(*', 'right': '*)' },
+    \ 'lout': { 'left': '#' },
+    \ 'lpc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'lprolog': { 'left': '%' },
+    \ 'lscript': { 'left': "'" },
+    \ 'lss': { 'left': '#' },
+    \ 'lua': { 'left': '--', 'leftAlt': '--[[', 'rightAlt': ']]' },
+    \ 'lynx': { 'left': '#' },
+    \ 'lytex': { 'left': '%' },
+    \ 'm4': { 'left': 'dnl ' },
+    \ 'mail': { 'left': '> ' },
+    \ 'mako': { 'left': '##' },
+    \ 'man': { 'left': '."' },
+    \ 'mandoc': { 'left': '.\\"' },
+    \ 'map': { 'left': '%' },
+    \ 'maple': { 'left': '#' },
+    \ 'markdown': { 'left': '<!--', 'right': '-->' },
+    \ 'masm': { 'left': ';' },
+    \ 'mason': { 'left': '<% #', 'right': '%>' },
+    \ 'master': { 'left': '$' },
+    \ 'matlab': { 'left': '%', 'leftAlt': '%{', 'rightAlt': '%}' },
+    \ 'mel': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'meson': { 'left': '#' },
+    \ 'mib': { 'left': '--' },
+    \ 'minizinc': { 'left': '% ', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'mips': { 'left': '#' },
+    \ 'mirah': {'left': '#' },
+    \ 'mkd': { 'left': '<!---', 'right': '-->' },
+    \ 'mma': { 'left': '(*', 'right': '*)' },
+    \ 'model': { 'left': '$', 'right': '$' },
+    \ 'modula2': { 'left': '(*', 'right': '*)' },
+    \ 'modula3': { 'left': '(*', 'right': '*)' },
+    \ 'molpro': { 'left': '!' },
+    \ 'monk': { 'left': ';' },
+    \ 'mush': { 'left': '#' },
+    \ 'mustache': { 'left': '{{!', 'right': '}}' },
+    \ 'nagios': { 'left': ';' },
+    \ 'named': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'nasm': { 'left': ';' },
+    \ 'nastran': { 'left': '$' },
+    \ 'natural': { 'left': '/*' },
+    \ 'ncf': { 'left': ';' },
+    \ 'newlisp': { 'left': ';' },
+    \ 'nginx': { 'left': '#' },
+    \ 'nimrod': { 'left': '#' },
+    \ 'nix': { 'left': '#' },
+    \ 'nroff': { 'left': '\"' },
+    \ 'nsis': { 'left': '#' },
+    \ 'ntp': { 'left': '#' },
+    \ 'objc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'objcpp': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'objj': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'ocaml': { 'left': '(*', 'right': '*)', 'nested': 1 },
+    \ 'occam': { 'left': '--' },
+    \ 'octave': { 'left': '%', 'leftAlt': '#' },
+    \ 'omlet': { 'left': '(*', 'right': '*)' },
+    \ 'omnimark': { 'left': ';' },
+    \ 'ooc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'openroad': { 'left': '//' },
+    \ 'opl': { 'left': 'REM' },
+    \ 'ora': { 'left': '#' },
+    \ 'ox': { 'left': '//' },
+    \ 'paludis-use-conf': { 'left': '#' },
+    \ 'pandoc': { 'left': '<!--', 'right': '-->' },
+    \ 'pascal': { 'left': '{', 'right': '}', 'leftAlt': '(*', 'rightAlt': '*)' },
+    \ 'patran': { 'left': '$', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'pcap': { 'left': '#' },
+    \ 'pccts': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'pdf': { 'left': '%' },
+    \ 'perl': { 'left': '#' },
+    \ 'pfmain': { 'left': '//' },
+    \ 'php': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'pic': { 'left': ';' },
+    \ 'pike': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'pilrc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'pine': { 'left': '#' },
+    \ 'plm': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'plsql': { 'left': '-- ', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'po': { 'left': '#' },
+    \ 'poscar': { 'left': '!' },
+    \ 'postscr': { 'left': '%' },
+    \ 'pov': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'povini': { 'left': ';' },
+    \ 'ppd': { 'left': '%' },
+    \ 'ppwiz': { 'left': ';;' },
+    \ 'praat': { 'left': '#' },
+    \ 'privoxy': { 'left': '#' },
+    \ 'processing': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'prolog': { 'left': '%', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'proto': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'ps1': { 'left': '#' },
+    \ 'psf': { 'left': '#' },
+    \ 'ptcap': { 'left': '#' },
+    \ 'pug': { 'left': '//-', 'leftAlt': '//' },
+    \ 'puppet': { 'left': '#' },
+    \ 'pyrex': { 'left': '# ', 'leftAlt': '#' },
+    \ 'python': { 'left': '# ', 'leftAlt': '#' },
+    \ 'r': { 'left': '#', 'leftAlt': '#''' },
+    \ 'racket': { 'left': ';', 'nested': 1, 'leftAlt': '#|', 'rightAlt': '|#', 'nestedAlt': 1 },
+    \ 'radiance': { 'left': '#' },
+    \ 'ratpoison': { 'left': '#' },
+    \ 'rc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'rebol': { 'left': ';' },
+    \ 'registry': { 'left': ';' },
+    \ 'rego': { 'left': '#' },
+    \ 'remind': { 'left': '#' },
+    \ 'renpy': { 'left': '# ' },
+    \ 'resolv': { 'left': '#' },
+    \ 'rgb': { 'left': '!' },
+    \ 'rib': { 'left': '#' },
+    \ 'rmd': { 'left': '<!--', 'right': '-->', 'leftAlt': '#' },
+    \ 'robot': { 'left': '#' },
+    \ 'robots': { 'left': '#' },
+    \ 'rspec': { 'left': '#' },
+    \ 'ruby': { 'left': '#' },
+    \ 'rust': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'sa': { 'left': '--' },
+    \ 'samba': { 'left': ';', 'leftAlt': '#' },
+    \ 'sass': { 'left': '//', 'leftAlt': '/*' },
+    \ 'sather': { 'left': '--' },
+    \ 'scala': { 'left': '//', 'nested': 1, 'leftAlt': '/*', 'rightAlt': '*/', 'nestedAlt': 1 },
+    \ 'scheme': { 'left': ';', 'nested': 1, 'leftAlt': '#|', 'rightAlt': '|#', 'nestedAlt': 1 },
+    \ 'scilab': { 'left': '//' },
+    \ 'scilla': { 'left': '(*', 'right': '*)', 'nested': 1 },
+    \ 'scons': { 'left': '#' },
+    \ 'scsh': { 'left': ';' },
+    \ 'scss': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'sdc': { 'left': '#' },
+    \ 'sed': { 'left': '#' },
+    \ 'sentinel': { 'left': '#', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'sgmldecl': { 'left': '--', 'right': '--' },
+    \ 'sgmllnx': { 'left': '<!--', 'right': '-->' },
+    \ 'sh': { 'left': '#' },
+    \ 'shader_test': { 'left': '#' },
+    \ 'sicad': { 'left': '*' },
+    \ 'sile': { 'left': '%', 'leftAlt': '--' },
+    \ 'simula': { 'left': '%', 'leftAlt': '--' },
+    \ 'sinda': { 'left': '$' },
+    \ 'skill': { 'left': ';' },
+    \ 'slang': { 'left': '%' },
+    \ 'slice': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'slim': { 'left': '/', 'leftAlt': '/!' },
+    \ 'slrnrc': { 'left': '%' },
+    \ 'sls': { 'left': '#' },
+    \ 'sm': { 'left': '#' },
+    \ 'smarty': { 'left': '{*', 'right': '*}' },
+    \ 'smil': { 'left': '<!', 'right': '>' },
+    \ 'smith': { 'left': ';' },
+    \ 'sml': { 'left': '(*', 'right': '*)', 'nested': 1 },
+    \ 'snakemake': { 'left': '#' },
+    \ 'snippets': { 'left': '#' },
+    \ 'snnsnet': { 'left': '#' },
+    \ 'snnspat': { 'left': '#' },
+    \ 'snnsres': { 'left': '#' },
+    \ 'snobol4': { 'left': '*' },
+    \ 'spec': { 'left': '#' },
+    \ 'specman': { 'left': '//' },
+    \ 'spectre': { 'left': '//', 'leftAlt': '*' },
+    \ 'spice': { 'left': '$' },
+    \ 'spin': { 'left': '''', 'leftAlt': '{', 'rightAlt': '}' },
+    \ 'sql': { 'left': '-- ', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'sqlforms': { 'left': '-- ' },
+    \ 'sqlj': { 'left': '-- ' },
+    \ 'sqr': { 'left': '!' },
+    \ 'squid': { 'left': '#' },
+    \ 'ss': { 'left': ';', 'leftAlt': '#|', 'rightAlt': '|#' },
+    \ 'sshconfig': { 'left': '#' },
+    \ 'sshdconfig': { 'left': '#' },
+    \ 'st': { 'left': '"' },
+    \ 'stan': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'stp': { 'left': '/*', 'right': '*/', 'leftAlt': '//' },
+    \ 'supercollider': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'swift': { 'left': '/*', 'right': '*/', 'leftAlt': '//' },
+    \ 'systemverilog': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'tads': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'tags': { 'left': ';' },
+    \ 'tak': { 'left': '$' },
+    \ 'tasm': { 'left': ';' },
+    \ 'tcl': { 'left': '#' },
+    \ 'teak': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'terraform': { 'left': '#', 'leftAlt': '/*', 'rightAlt': '*/'  },
+    \ 'tex': { 'left': '%' },
+    \ 'texinfo': { 'left': '@c ' },
+    \ 'texmf': { 'left': '%' },
+    \ 'tf': { 'left': '#' },
+    \ 'tidy': { 'left': '#' },
+    \ 'tla': { 'left': '\\*', 'leftAlt': '(*', 'rightAlt': '*)' },
+    \ 'tli': { 'left': '#' },
+    \ 'tmux': { 'left': '#' },
+    \ 'toml': { 'left': '#' },
+    \ 'trasys': { 'left': '$' },
+    \ 'troff': { 'left': '.\\"' },
+    \ 'tsalt': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'tsscl': { 'left': '#' },
+    \ 'tssgm': { 'left': "comment = '", 'right': "'" },
+    \ 'ttl': { 'left': '#' },
+    \ 'tup': { 'left': '#' },
+    \ 'twig': { 'left': '{#', 'right': '#}' },
+    \ 'txt2tags': { 'left': '%' },
+    \ 'typescript': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'typescriptreact': { 'left': '//', 'leftAlt': '{/*', 'rightAlt': '*/}' },
+    \ 'uc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'uc4': { 'left': '!' },
+    \ 'uil': { 'left': '!' },
+    \ 'upstart': { 'left': '#' },
+    \ 'vala': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'vasp': { 'left': '!' },
+    \ 'vb': { 'left': "'" },
+    \ 'velocity': { 'left': '##', 'right': '', 'leftAlt': '#*', 'rightAlt': '*#' },
+    \ 'vera': { 'left': '/*', 'right': '*/', 'leftAlt': '//' },
+    \ 'verilog': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'verilog_systemverilog': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+    \ 'vgrindefs': { 'left': '#' },
+    \ 'vhdl': { 'left': '--' },
+    \ 'vimperator': { 'left': '"' },
+    \ 'virata': { 'left': '%' },
+    \ 'vrml': { 'left': '#' },
+    \ 'vsejcl': { 'left': '/*' },
+    \ 'webmacro': { 'left': '##' },
+    \ 'wget': { 'left': '#' },
+    \ 'wikipedia': { 'left': '<!--', 'right': '-->' },
+    \ 'winbatch': { 'left': ';' },
+    \ 'wml': { 'left': '#' },
+    \ 'wvdial': { 'left': ';' },
+    \ 'xdefaults': { 'left': '!' },
+    \ 'xkb': { 'left': '//' },
+    \ 'xmath': { 'left': '#' },
+    \ 'xpm2': { 'left': '!' },
+    \ 'xquery': { 'left': '(:', 'right': ':)' },
+    \ 'yaml': { 'left': '#' },
+    \ 'z8a': { 'left': ';' },
+    \ 'zig': { 'left': '//' }
+    \ }
+
+let g:NERDDelimiterMap = s:delimiterMap
+let nerdcommenter#delimiterMap = s:delimiterMap
+
+if exists('g:NERDCustomDelimiters')
+    call extend(s:delimiterMap, g:NERDCustomDelimiters)
+endif
+
+" Section: Comment mapping functions, autocommands and commands
+" ============================================================================
+
+" Function: nerdcommenter#SetUp() function
+" This function is responsible for setting up buffer scoped variables for the
+" current buffer.
+function! nerdcommenter#SetUp() abort
+    if exists('b:NERDCommenterDelims')
+        return
+    endif
+
+    let filetype = &filetype
+
+    "for compound filetypes, if we don't know how to handle the full filetype
+    "then break it down and use the first part that we know how to handle
+    if filetype =~# '\.' && !has_key(s:delimiterMap, filetype)
+        let filetypes = split(filetype, '\.')
+        for i in filetypes
+            if has_key(s:delimiterMap, i)
+                let filetype = i
+                break
+            endif
+        endfor
+    endif
+
+    let b:NERDSexyComMarker = ''
+
+    if has_key(s:delimiterMap, filetype)
+        let b:NERDCommenterDelims = s:delimiterMap[filetype]
+        for i in ['left', 'leftAlt', 'right', 'rightAlt']
+            if !has_key(b:NERDCommenterDelims, i)
+                let b:NERDCommenterDelims[i] = ''
+            endif
+        endfor
+        for i in ['nested', 'nestedAlt']
+            if !has_key(b:NERDCommenterDelims, i)
+                let b:NERDCommenterDelims[i] = 0
+            endif
+        endfor
+        " if g:NERD_<filetype>_alt_style is defined, use the alternate style
+        let b:NERDCommenterFirstInit = getbufvar(1,'NERDCommenterFirstInit')
+        if exists('g:NERDAltDelims_'.filetype) && eval('g:NERDAltDelims_'.filetype) && !b:NERDCommenterFirstInit
+            call nerdcommenter#SwitchToAlternativeDelimiters(0)
+            let b:NERDCommenterFirstInit = 1
+        endif
+    else
+        let b:NERDCommenterDelims = s:CreateDelimMapFromCms()
+    endif
+
+endfunction
+
+function! s:CreateDelimMapFromCms() abort
+    if &filetype ==# '' && exists('g:NERDDefaultDelims')
+        let delims = g:NERDDefaultDelims
+        for i in ['left', 'leftAlt', 'right', 'rightAlt']
+            if !has_key(delims, i)
+                let delims[i] = ''
+            endif
+        endfor
+        return delims
+    endif
+    return {
+        \ 'left': matchstr(&commentstring, '^\S*\ze\s*%s'),
+        \ 'right': matchstr(&commentstring, '%s\s*\zs.*$'),
+        \ 'nested': 0,
+        \ 'leftAlt': '',
+        \ 'rightAlt': '',
+        \ 'nestedAlt': 0}
+endfunction
+
+" Function: nerdcommenter#SwitchToAlternativeDelimiters(printMsgs) function
+" This function is used to swap the delimiters that are being used to the
+" alternative delimiters for that filetype. For example, if a c++ file is
+" being edited and // comments are being used, after this function is called
+" /**/ comments will be used.
+"
+" Args:
+"   -printMsgs: if this is 1 then a message is echoed to the user telling them
+"    if this function changed the delimiters or not
+" function nerdcommenter#SwitchToAlternativeDelimiters(printMsgs)
+function! nerdcommenter#SwitchToAlternativeDelimiters(printMsgs) abort
+    call nerdcommenter#SetUp()
+    if exists('*NERDCommenter_before')
+        exe 'call NERDCommenter_before()'
+    endif
+    "if both of the alternative delimiters are empty then there is no
+    "alternative comment style so bail out
+    if b:NERDCommenterDelims['leftAlt'] ==# '' && b:NERDCommenterDelims['rightAlt'] ==# ''
+        if a:printMsgs
+            call s:NerdEcho('Cannot use alternative delimiters, none are specified', 0)
+        endif
+        return 0
+    endif
+
+    "save the current delimiters
+    let tempLeft = s:Left()
+    let tempRight = s:Right()
+    let tempNested = s:Nested()
+
+    "swap current delimiters for alternative
+    let b:NERDCommenterDelims['left'] = b:NERDCommenterDelims['leftAlt']
+    let b:NERDCommenterDelims['right'] = b:NERDCommenterDelims['rightAlt']
+    "set information on whether these are nested
+    let b:NERDCommenterDelims['nested'] = b:NERDCommenterDelims['nestedAlt']
+
+    "set the previously current delimiters to be the new alternative ones
+    let b:NERDCommenterDelims['leftAlt'] = tempLeft
+    let b:NERDCommenterDelims['rightAlt'] = tempRight
+    let b:NERDCommenterDelims['nestedAlt'] = tempNested
+
+    "tell the user what comment delimiters they are now using
+    if a:printMsgs
+        call s:NerdEcho('Now using ' . s:Left() . ' ' . s:Right() . ' to delimit comments', 1)
+    endif
+
+    if exists('*NERDCommenter_after')
+        exe 'call NERDCommenter_after()'
+    endif
+
+    return 1
+endfunction
+
+" Section: Comment delimiter add/removal functions
+" ============================================================================
+" Function: s:AppendCommentToLine()
+" This function appends comment delimiters at the EOL and places the cursor in
+" position to start typing the comment
+function! s:AppendCommentToLine() abort
+    let left = s:Left({'space': 1})
+    let right = s:Right({'space': 1})
+
+    " get the length of the right delimiter
+    let lenRight = strlen(right)
+
+    let isLineEmpty = strlen(getline('.')) ==# 0
+    let insOrApp = (isLineEmpty==#1 ? 'i' : 'A')
+
+    "stick the delimiters down at the end of the line. We have to format the
+    "comment with spaces as appropriate
+    execute ':normal! ' . insOrApp . (isLineEmpty ? '' : ' ') . left . right
+
+    " if there is a right delimiter then we gotta move the cursor left
+    " by the length of the right delimiter so we insert between the delimiters
+    if lenRight > 0
+        let leftMoveAmount = lenRight - 1
+        execute ':normal! ' . leftMoveAmount . 'h'
+        startinsert
+    else
+        startinsert!
+    endif
+endfunction
+
+" Function: s:CommentBlock(top, bottom, lSide, rSide, forceNested )
+" This function is used to comment out a region of code. This region is
+" specified as a bounding box by arguments to the function.
+"
+" Args:
+"   -top: the line number for the top line of code in the region
+"   -bottom: the line number for the bottom line of code in the region
+"   -lSide: the column number for the left most column in the region
+"   -rSide: the column number for the right most column in the region
+"   -forceNested: a flag indicating whether comments should be nested
+function! s:CommentBlock(top, bottom, lSide, rSide, forceNested) abort
+    " we need to create local copies of these arguments so we can modify them
+    let top = a:top
+    let bottom = a:bottom
+    let lSide = a:lSide
+    let rSide = a:rSide
+
+    "if the top or bottom line starts with tabs we have to adjust the left and
+    "right boundaries so that they are set as though the tabs were spaces
+    let topline = getline(top)
+    let bottomline = getline(bottom)
+    if s:HasLeadingTabs(topline, bottomline)
+
+        "find out how many tabs are in the top line and adjust the left
+        "boundary accordingly
+        let numTabs = s:NumberOfLeadingTabs(topline)
+        if lSide < numTabs
+            let lSide = &tabstop * lSide
+        else
+            let lSide = (lSide - numTabs) + (&tabstop * numTabs)
+        endif
+
+        "find out how many tabs are in the bottom line and adjust the right
+        "boundary accordingly
+        let numTabs = s:NumberOfLeadingTabs(bottomline)
+        let rSide = (rSide - numTabs) + (&tabstop * numTabs)
+    endif
+
+    "we must check that bottom IS actually below top, if it is not then we
+    "swap top and bottom. Similarly for left and right.
+    if bottom < top
+        let temp = top
+        let top = bottom
+        let bottom = top
+    endif
+    if rSide < lSide
+        let temp = lSide
+        let lSide = rSide
+        let rSide = temp
+    endif
+
+    "if the current delimiters aren't multipart then we will switch to the
+    "alternative delimiters (if THEY are) as the comment will be better and more
+    "accurate with multipart delimiters
+    let switchedDelims = 0
+    if !s:Multipart() && g:NERDAllowAnyVisualDelims && s:AltMultipart()
+        let switchedDelims = 1
+        call nerdcommenter#SwitchToAlternativeDelimiters(0)
+    endif
+
+    "start the commenting from the top and keep commenting till we reach the
+    "bottom
+    let currentLine=top
+    while currentLine <= bottom
+
+        "check if we are allowed to comment this line
+        if s:CanCommentLine(a:forceNested, currentLine)
+
+            "convert the leading tabs into spaces
+            let theLine = getline(currentLine)
+            let lineHasLeadTabs = s:HasLeadingTabs(theLine)
+            if lineHasLeadTabs
+                let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+            endif
+
+            "don't comment lines that begin after the right boundary of the
+            "block unless the user has specified to do so
+            if theLine !~# '^ \{' . rSide . '\}' || !g:NERDBlockComIgnoreEmpty
+
+                "attempt to place the cursor in on the left of the boundary box,
+                "then check if we were successful, if not then we cant comment this
+                "line
+                call setline(currentLine, theLine)
+                if s:CanPlaceCursor(currentLine, lSide)
+
+                    let leftSpaced = s:Left({'space': 1})
+                    let rightSpaced = s:Right({'space': 1})
+
+                    "stick the left delimiter down
+                    let theLine = strpart(theLine, 0, lSide-1) . leftSpaced . strpart(theLine, lSide-1)
+
+                    if s:Multipart()
+                        "stick the right delimiter down
+                        "byte idx of the char next to the last char = (byte idx of last char + 1) + (last char byte len) - 1
+                        let rIndex = (rSide+strlen(leftSpaced)) + strlen(strcharpart(strpart(theLine, rSide+strlen(leftSpaced)-1), 0, 1)) - 1
+                        let theLine = strpart(theLine, 0, rIndex) . rightSpaced . strpart(theLine, rIndex)
+
+                        let firstLeftDelim = s:FindDelimiterIndex(s:Left(), theLine)
+                        let lastRightDelim = s:LastIndexOfDelim(s:Right(), theLine)
+
+                        if firstLeftDelim !=# -1 && lastRightDelim !=# -1
+                            let searchStr = strpart(theLine, 0, lastRightDelim)
+                            let searchStr = strpart(searchStr, firstLeftDelim+strlen(s:Left()))
+
+                            "replace the outer most delimiters in searchStr with
+                            "place-holders
+                            let theLineWithPlaceHolders = s:ReplaceDelims(s:Left(), s:Right(), g:NERDLPlace, g:NERDRPlace, searchStr)
+
+                            "add the right delimiter onto the line
+                            let theLine = strpart(theLine, 0, firstLeftDelim+strlen(s:Left())) . theLineWithPlaceHolders . strpart(theLine, lastRightDelim)
+                        endif
+                    endif
+                endif
+            endif
+
+            "restore tabs if needed
+            if lineHasLeadTabs
+                let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+            endif
+
+            if g:NERDTrimTrailingWhitespace ==# 1
+              let theLine = s:TrimTrailingWhitespace(theLine)
+            endif
+
+            call setline(currentLine, theLine)
+        endif
+
+        let currentLine = currentLine + 1
+    endwhile
+
+    "if we switched delimiterss then we gotta go back to what they were before
+    if switchedDelims ==# 1
+        call nerdcommenter#SwitchToAlternativeDelimiters(0)
+    endif
+endfunction
+
+" Function: s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine)
+" This function comments a range of lines.
+"
+" Args:
+"   -forceNested: a flag indicating whether the called is requesting the comment
+"    to be nested if need be
+"   -align: should be "left", "start", "both" or "none"
+"   -firstLine/lastLine: the top and bottom lines to comment
+function! s:CommentLines(forceNested, align, firstLine, lastLine) abort
+    " we need to get the left and right indexes of the leftmost char in the
+    " block of of lines and the right most char so that we can do alignment of
+    " the delimiters if the user has specified
+    let leftAlignIndx = a:align ==# 'start' ? 0 : s:LeftMostIndx(a:forceNested, 0, a:firstLine, a:lastLine)
+    let rightAlignIndx = s:RightMostIndx(a:forceNested, 0, a:firstLine, a:lastLine)
+
+    " gotta add the length of the left delimiter onto the rightAlignIndx cos
+    " we'll be adding a left delimiter to the line
+    let rightAlignIndx = rightAlignIndx + strlen(s:Left({'space': 1}))
+
+    " now we actually comment the lines. Do it line by line
+    let currentLine = a:firstLine
+    while currentLine <= a:lastLine
+
+        " get the next line, check commentability and convert spaces to tabs
+        let theLine = getline(currentLine)
+        let lineHasLeadingTabs = s:HasLeadingTabs(theLine)
+        let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+        if s:CanCommentLine(a:forceNested, currentLine)
+            "if the user has specified forceNesting then we check to see if we
+            "need to switch delimiters for place-holders
+            if a:forceNested && g:NERDUsePlaceHolders && !s:Nested()
+                let theLine = s:SwapOuterMultiPartDelimsForPlaceHolders(theLine)
+            endif
+
+            " find out if the line is commented using normal delimiters and/or
+            " alternate ones
+            let isCommented = s:IsCommented(s:Left(), s:Right(), theLine) || s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), theLine)
+
+            " check if we can comment this line
+            if !isCommented || g:NERDUsePlaceHolders || s:Multipart()
+                if a:align ==# 'left' || a:align ==# 'start' || a:align ==# 'both'
+                    let theLine = s:AddLeftDelimAligned(s:Left({'space': 1}), theLine, leftAlignIndx)
+                else
+                    let theLine = s:AddLeftDelim(s:Left({'space': 1}), theLine)
+                endif
+                if a:align ==# 'both'
+                    let theLine = s:AddRightDelimAligned(s:Right({'space': 1}), theLine, rightAlignIndx)
+                else
+                    let theLine = s:AddRightDelim(s:Right({'space': 1}), theLine)
+                endif
+            endif
+        endif
+
+        " restore leading tabs if appropriate
+        if lineHasLeadingTabs
+            let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+        endif
+
+        if g:NERDTrimTrailingWhitespace ==# 1
+            let theLine = s:TrimTrailingWhitespace(theLine)
+        endif
+
+        " we are done with this line
+        call setline(currentLine, theLine)
+        let currentLine = currentLine + 1
+    endwhile
+
+endfunction
+
+" Function: s:CommentLinesMinimal(firstLine, lastLine)
+" This function comments a range of lines in a minimal style. I
+"
+" Args:
+"   -firstLine/lastLine: the top and bottom lines to comment
+function! s:CommentLinesMinimal(firstLine, lastLine) abort
+    "check that minimal comments can be done on this filetype
+    if !s:HasMultipartDelims()
+        throw 'NERDCommenter.Delimiters exception: Minimal comments can only be used for filetypes that have multipart delimiters'
+    endif
+
+    let sexyNested = s:SexyNested()
+
+    "if we need to use place holders for the comment, make sure they are
+    "enabled for this filetype, or the delimiterss allow nesting
+    if !g:NERDUsePlaceHolders && !sexyNested && s:DoesBlockHaveMultipartDelim(a:firstLine, a:lastLine)
+        throw 'NERDCommenter.Settings exception: Place holders are required but disabled.'
+    endif
+
+    "get the left and right delimiters to smack on
+    let left = s:GetSexyComLeft(g:NERDSpaceDelims,0)
+    let right = s:GetSexyComRight(g:NERDSpaceDelims,0)
+
+    "make sure all multipart delimiters on the lines are replaced with
+    "placeholders to prevent illegal syntax
+    if !sexyNested
+        let currentLine = a:firstLine
+        while(currentLine <= a:lastLine)
+            let theLine = getline(currentLine)
+            let theLine = s:ReplaceDelims(left, right, g:NERDLPlace, g:NERDRPlace, theLine)
+            call setline(currentLine, theLine)
+            let currentLine = currentLine + 1
+        endwhile
+    endif
+
+    "add the delimiter to the top line
+    let theLine = getline(a:firstLine)
+    let lineHasLeadingTabs = s:HasLeadingTabs(theLine)
+    let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+    let theLine = s:AddLeftDelim(left, theLine)
+    if lineHasLeadingTabs
+        let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+    endif
+    call setline(a:firstLine, theLine)
+
+    "add the delimiter to the bottom line
+    let theLine = getline(a:lastLine)
+    let lineHasLeadingTabs = s:HasLeadingTabs(theLine)
+    let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+    let theLine = s:AddRightDelim(right, theLine)
+    if lineHasLeadingTabs
+        let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+    endif
+
+    if g:NERDTrimTrailingWhitespace ==# 1
+        let theLine = s:TrimTrailingWhitespace(theLine)
+    endif
+
+    call setline(a:lastLine, theLine)
+endfunction
+
+" Function: s:CommentLinesSexy(topline, bottomline) function
+" This function is used to comment lines in the 'Sexy' style. E.g., in c:
+" /*
+"  * This is a sexy comment
+"  */
+" Args:
+"   -topline: the line number of the top line in the sexy comment
+"   -bottomline: the line number of the bottom line in the sexy comment
+function! s:CommentLinesSexy(topline, bottomline) abort
+    let left = s:GetSexyComLeft(0, 0)
+    let right = s:GetSexyComRight(0, 0)
+
+    "check if we can do a sexy comment with the available delimiters
+    if left ==# -1 || right ==# -1
+        throw 'NERDCommenter.Delimiters exception: cannot perform sexy comments with available delimiters.'
+    endif
+
+    "make sure the lines aren't already commented sexually or we can nest
+    if !s:CanSexyCommentLines(a:topline, a:bottomline)
+        throw 'NERDCommenter.Nesting exception: cannot nest sexy comments'
+    endif
+
+
+    let sexyComMarker = s:GetSexyComMarker(0,0)
+    let sexyComMarkerSpaced = s:GetSexyComMarker(1,0)
+
+
+    " we jam the comment as far to the right as possible
+    let leftAlignIndx = s:LeftMostIndx(1, 1, a:topline, a:bottomline)
+
+    "check if we should use the compact style i.e that the left/right
+    "delimiters should appear on the first and last lines of the code and not
+    "on separate lines above/below the first/last lines of code
+    if g:NERDCompactSexyComs
+        let spaceString = (g:NERDSpaceDelims ? s:spaceStr : '')
+
+        "comment the top line
+        let theLine = getline(a:topline)
+        let lineHasTabs = s:HasLeadingTabs(theLine)
+        if lineHasTabs
+            let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+        endif
+        if !s:SexyNested()
+            let theLine = s:SwapOuterMultiPartDelimsForPlaceHolders(theLine)
+        endif
+        let theLine = s:AddLeftDelimAligned(left . spaceString, theLine, leftAlignIndx)
+        if lineHasTabs
+            let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+        endif
+        call setline(a:topline, theLine)
+
+        "comment the bottom line
+        if a:bottomline !=# a:topline
+            let theLine = getline(a:bottomline)
+            let lineHasTabs = s:HasLeadingTabs(theLine)
+            if lineHasTabs
+                let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+            endif
+            if !s:SexyNested()
+                let theLine = s:SwapOuterMultiPartDelimsForPlaceHolders(theLine)
+            endif
+        endif
+        let theLine = s:AddRightDelim(spaceString . right, theLine)
+        if lineHasTabs
+            let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+        endif
+        call setline(a:bottomline, theLine)
+    else
+
+        " add the left delimiter one line above the lines that are to be commented
+        call cursor(a:topline, 1)
+        execute 'normal! O'
+        let theLine = repeat(' ', leftAlignIndx) . left
+
+        " Make sure tabs are respected
+        if !&expandtab
+           let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+        endif
+        call setline(a:topline, theLine)
+
+        " add the right delimiter after bottom line (we have to add 1 cos we moved
+        " the lines down when we added the left delimiter
+        call cursor(a:bottomline+1, 1)
+        execute 'normal! o'
+        if g:NERDDisableTabsInBlockComm
+          let theLine = repeat(' ', leftAlignIndx) . right
+        else
+          let theLine = repeat(' ', leftAlignIndx) . repeat(' ', strlen(left)-strlen(sexyComMarker)) . right
+        endif
+
+        " Make sure tabs are respected
+        if !&expandtab
+           let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+        endif
+        call setline(a:bottomline+2, theLine)
+
+    endif
+
+    " go thru each line adding the sexyComMarker marker to the start of each
+    " line in the appropriate place to align them with the comment delimiters
+    let currentLine = a:topline+1
+    while currentLine <= a:bottomline + !g:NERDCompactSexyComs
+        " get the line and convert the tabs to spaces
+        let theLine = getline(currentLine)
+        let lineHasTabs = s:HasLeadingTabs(theLine)
+        if lineHasTabs
+            let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+        endif
+
+        if !s:SexyNested()
+            let theLine = s:SwapOuterMultiPartDelimsForPlaceHolders(theLine)
+        endif
+
+        " add the sexyComMarker
+        if g:NERDDisableTabsInBlockComm
+          let theLine = repeat(' ', leftAlignIndx) . sexyComMarkerSpaced . strpart(theLine, leftAlignIndx)
+        else
+          let theLine = repeat(' ', leftAlignIndx) . repeat(' ', strlen(left)-strlen(sexyComMarker)) . sexyComMarkerSpaced . strpart(theLine, leftAlignIndx)
+        endif
+
+        if lineHasTabs
+            let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+        endif
+
+        if g:NERDTrimTrailingWhitespace ==# 1
+            let theLine = s:TrimTrailingWhitespace(theLine)
+        endif
+
+        " set the line and move onto the next one
+        call setline(currentLine, theLine)
+        let currentLine = currentLine + 1
+    endwhile
+
+endfunction
+
+" Function: s:CommentLinesToggle(forceNested, firstLine, lastLine)
+" Applies "toggle" commenting to the given range of lines
+"
+" Args:
+"   -forceNested: a flag indicating whether the called is requesting the comment
+"    to be nested if need be
+"   -firstLine/lastLine: the top and bottom lines to comment
+function! s:CommentLinesToggle(forceNested, firstLine, lastLine) abort
+    let currentLine = a:firstLine
+
+    let align = g:NERDDefaultAlign
+    let leftAlignIndx = align ==# 'start' ? 0 : s:LeftMostIndx(a:forceNested, 0, a:firstLine, a:lastLine)
+    let rightAlignIndx = s:RightMostIndx(a:forceNested, 0, a:firstLine, a:lastLine)
+    let rightAlignIndx = rightAlignIndx + strlen(s:Left({'space': 1}))
+
+    while currentLine <= a:lastLine
+
+        " get the next line, check commentability and convert spaces to tabs
+        let theLine = getline(currentLine)
+        let lineHasLeadingTabs = s:HasLeadingTabs(theLine)
+        let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+        if s:CanToggleCommentLine(a:forceNested, currentLine)
+
+            "if the user has specified forceNesting then we check to see if we
+            "need to switch delimiters for place-holders
+            if g:NERDUsePlaceHolders && !s:Nested()
+                let theLine = s:SwapOuterMultiPartDelimsForPlaceHolders(theLine)
+            endif
+
+            if align ==# 'left' || align ==# 'start' || align ==# 'both'
+                let theLine = s:AddLeftDelimAligned(s:Left({'space': 1}), theLine, leftAlignIndx)
+            else
+                let theLine = s:AddLeftDelim(s:Left({'space': 1}), theLine)
+            endif
+            if align ==# 'both'
+                let theLine = s:AddRightDelimAligned(s:Right({'space': 1}), theLine, rightAlignIndx)
+            else
+                let theLine = s:AddRightDelim(s:Right({'space': 1}), theLine)
+            endif
+        endif
+
+        " restore leading tabs if appropriate
+        if lineHasLeadingTabs
+            let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+        endif
+
+        if g:NERDTrimTrailingWhitespace ==# 1
+            let theLine = s:TrimTrailingWhitespace(theLine)
+        endif
+
+        " we are done with this line
+        call setline(currentLine, theLine)
+        let currentLine = currentLine + 1
+    endwhile
+
+endfunction
+
+" Function: s:CommentRegion(topline, topCol, bottomLine, bottomCol) function
+" This function comments chunks of text selected in visual mode.
+" It will comment exactly the text that they have selected.
+" Args:
+"   -topLine: the line number of the top line in the sexy comment
+"   -topCol: top left column for this comment
+"   -bottomline: the line number of the bottom line in the sexy comment
+"   -bottomCol: the bottom right column for this comment
+"   -forceNested: whether the caller wants comments to be nested if the
+"    line(s) are already commented
+function! s:CommentRegion(topLine, topCol, bottomLine, bottomCol, forceNested) abort
+
+    "switch delimiters (if we can) if the current set isn't multipart
+    let switchedDelims = 0
+    if !s:Multipart() && s:AltMultipart() && g:NERDAllowAnyVisualDelims
+        let switchedDelims = 1
+        call nerdcommenter#SwitchToAlternativeDelimiters(0)
+    endif
+
+    "if there is only one line in the comment then just do it
+    if a:topLine ==# a:bottomLine
+        call s:CommentBlock(a:topLine, a:bottomLine, a:topCol, a:bottomCol, a:forceNested)
+
+    "there are multiple lines in the comment
+    else
+        "comment the top line
+        call s:CommentBlock(a:topLine, a:topLine, a:topCol, strlen(getline(a:topLine)), a:forceNested)
+
+        "comment out all the lines in the middle of the comment
+        let topOfRange = a:topLine+1
+        let bottomOfRange = a:bottomLine-1
+        if topOfRange <= bottomOfRange
+            call s:CommentLines(a:forceNested, g:NERDDefaultAlign, topOfRange, bottomOfRange)
+        endif
+
+        "comment the bottom line
+        let bottom = getline(a:bottomLine)
+        let numLeadingSpacesTabs = strlen(matchstr(bottom, '^\s*'))
+        call s:CommentBlock(a:bottomLine, a:bottomLine, numLeadingSpacesTabs+1, a:bottomCol, a:forceNested)
+
+    endif
+
+    "stick the cursor back on the char it was on before the comment
+    call cursor(a:topLine, a:topCol + strlen(s:Left()) + g:NERDSpaceDelims)
+
+    "if we switched delimiters then we gotta go back to what they were before
+    if switchedDelims ==# 1
+        call nerdcommenter#SwitchToAlternativeDelimiters(0)
+    endif
+
+endfunction
+
+" Function: s:InvertComment(firstLine, lastLine) function
+" Inverts the comments on the lines between and including the given line
+" numbers i.e all commented lines are uncommented and vice versa
+" Args:
+"   -firstLine: the top of the range of lines to be inverted
+"   -lastLine: the bottom of the range of lines to be inverted
+function! s:InvertComment(firstLine, lastLine) abort
+
+    " go thru all lines in the given range
+    let currentLine = a:firstLine
+    while currentLine <= a:lastLine
+        let theLine = getline(currentLine)
+
+        let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine)
+
+        " if the line is commented normally, uncomment it
+        if s:IsCommentedFromStartOfLine(s:Left(), theLine) || s:IsCommentedFromStartOfLine(s:Left({'alt': 1}), theLine)
+            call s:UncommentLines(currentLine, currentLine)
+            let currentLine = currentLine + 1
+
+        " check if the line is commented sexually
+        elseif !empty(sexyComBounds)
+            let numLinesBeforeSexyComRemoved = s:NumLinesInBuf()
+            call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1])
+
+            "move to the line after last line of the sexy comment
+            let numLinesAfterSexyComRemoved = s:NumLinesInBuf()
+            let currentLine = sexyComBounds[1] - (numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved) + 1
+
+        " the line isn't commented
+        else
+            call s:CommentLinesToggle(1, currentLine, currentLine)
+            let currentLine = currentLine + 1
+        endif
+
+    endwhile
+endfunction
+
+" Function: nerdcommenter#IsLineCommented(lineNo)
+" Check if the line is a comment
+" Note this function checks if the line is **completely** a comment
+" Args:
+"   -lineNo:    the line number of the line to check
+" Return: Number, 1 if the line is a comment, 0 else
+function! nerdcommenter#IsLineCommented(lineNo) abort
+    call nerdcommenter#SetUp()
+    let theLine = getline(a:lineNo)
+    return s:IsInSexyComment(a:lineNo) || s:IsCommentedFromStartOfLine(s:Left(), theLine) || s:IsCommentedFromStartOfLine(s:Left({'alt': 1}), theLine)
+endfunction
+
+" Function: nerdcommenter#Comment(mode, type) function
+" This function is a Wrapper for the main commenting functions
+"
+" Args:
+"   -mode: a character indicating the mode in which the comment is requested:
+"   'n' for Normal mode, 'x' for Visual mode
+"   -type: the type of commenting requested. Can be 'Sexy', 'Invert',
+"    'Minimal', 'Toggle', 'AlignLeft', 'AlignBoth', 'Comment',
+"    'Nested', 'ToEOL', 'Append', 'Insert', 'Uncomment', 'Yank'
+function! nerdcommenter#Comment(mode, type) range abort
+    call nerdcommenter#SetUp()
+    if exists('*NERDCommenter_before')
+        exe 'call NERDCommenter_before()'
+    endif
+
+    let isVisual = a:mode =~# '[vsx]'
+
+    if !exists('g:did_load_ftplugin') || g:did_load_ftplugin !=# 1
+        call s:NerdEcho('filetype plugins should be enabled. See :help NERDComInstallation and :help :filetype-plugin-on', 0)
+    endif
+
+    if isVisual
+        let firstLine = line("'<")
+        let lastLine = line("'>")
+        let firstCol = col("'<")
+        let lastCol = col("'>") - (&selection ==# 'exclusive' ? 1 : 0)
+    else
+        let firstLine = a:firstline
+        let lastLine = a:lastline
+    endif
+    "
+    " Save options we need to change so we can recover them later
+    let state = s:SetupStateBeforeLineComment(firstLine, lastLine)
+
+    let countWasGiven = (!isVisual && firstLine !=# lastLine)
+
+    let forceNested = (a:type ==? 'Nested' || g:NERDDefaultNesting)
+
+    if a:type ==? 'Comment' || a:type ==? 'Nested'
+        if isVisual && visualmode() ==# "\<C-V>"
+            call s:CommentBlock(firstLine, lastLine, firstCol, lastCol, forceNested)
+        elseif isVisual && visualmode() ==# 'v' && (g:NERDCommentWholeLinesInVMode==#0 || (g:NERDCommentWholeLinesInVMode==#2 && s:HasMultipartDelims()))
+            call s:CommentRegion(firstLine, firstCol, lastLine, lastCol, forceNested)
+        else
+            call s:CommentLines(forceNested, g:NERDDefaultAlign, firstLine, lastLine)
+        endif
+
+    elseif a:type ==? 'AlignLeft' || a:type ==? 'AlignBoth'
+        let align = 'none'
+        if a:type ==? 'AlignLeft'
+            let align = 'left'
+        elseif a:type ==? 'AlignBoth'
+            let align = 'both'
+        endif
+        call s:CommentLines(forceNested, align, firstLine, lastLine)
+
+    elseif a:type ==? 'Invert'
+        call s:InvertComment(firstLine, lastLine)
+
+    elseif a:type ==? 'Sexy'
+        try
+            call s:CommentLinesSexy(firstLine, lastLine)
+        catch /NERDCommenter.Delimiters/
+            call s:CommentLines(forceNested, g:NERDDefaultAlign, firstLine, lastLine)
+        catch /NERDCommenter.Nesting/
+            call s:NerdEcho('Sexy comment aborted. Nested sexy cannot be nested', 0)
+        endtry
+
+    elseif a:type ==? 'Toggle'
+        if g:NERDToggleCheckAllLines ==# 0
+          let theLine = getline(firstLine)
+          if s:IsInSexyComment(firstLine) || s:IsCommentedFromStartOfLine(s:Left(), theLine) || s:IsCommentedFromStartOfLine(s:Left({'alt': 1}), theLine)
+              call s:UncommentLines(firstLine, lastLine)
+          else
+              call s:CommentLinesToggle(forceNested, firstLine, lastLine)
+          endif
+        else
+          let l:commentAllLines = 0
+          for i in range(firstLine, lastLine)
+            let theLine = getline(i)
+            " if have one line no comment(not include blank/whitespace-only lines), then comment all lines
+            if theLine =~# '\S\+' && !s:IsInSexyComment(firstLine) && !s:IsCommentedFromStartOfLine(s:Left(), theLine) && !s:IsCommentedFromStartOfLine(s:Left({'alt': 1}), theLine)
+              let l:commentAllLines = 1
+              break
+            else
+          endif
+          endfor
+          if l:commentAllLines ==# 1
+            call s:CommentLinesToggle(forceNested, firstLine, lastLine)
+          else
+            call s:UncommentLines(firstLine, lastLine)
+          endif
+        endif
+
+    elseif a:type ==? 'Minimal'
+        try
+            call s:CommentLinesMinimal(firstLine, lastLine)
+        catch /NERDCommenter.Delimiters/
+            call s:NerdEcho('Minimal comments can only be used for filetypes that have multipart delimiters.', 0)
+        catch /NERDCommenter.Settings/
+            call s:NerdEcho('Place holders are required but disabled.', 0)
+        endtry
+
+    elseif a:type ==? 'ToEOL'
+        let view = winsaveview()
+        call s:CommentBlock(firstLine, firstLine, col('.'), col('$')-1, 1)
+        call winrestview(view)
+
+    elseif a:type ==? 'Append'
+        call s:AppendCommentToLine()
+
+    elseif a:type ==? 'Insert'
+        call s:PlaceDelimitersAndInsBetween()
+
+    elseif a:type ==? 'Uncomment'
+        call s:UncommentLines(firstLine, lastLine)
+
+    elseif a:type ==? 'Yank'
+        if isVisual
+            normal! gvy
+        elseif countWasGiven
+            execute firstLine .','. lastLine .'yank'
+        else
+            normal! yy
+        endif
+        execute firstLine .','. lastLine .'call nerdcommenter#Comment("'. a:mode .'", "Comment")'
+    endif
+
+    call s:RecoverStateAfterLineComment(state)
+
+    if isVisual
+        let nlines = lastLine - firstLine
+        silent! call repeat#set('V' . nlines . 'jo' . "\<Plug>NERDCommenter". a:type)
+    else
+        silent! call repeat#set("\<Plug>NERDCommenter". a:type)
+    endif
+
+    if exists('*NERDCommenter_after')
+        exe 'call NERDCommenter_after()'
+    endif
+
+endfunction
+
+" Function: nerdcommenter#IsCharCommented(line, col) abort
+" Check if the character at [line, col] is inside a comment
+" Note the Comment delimeter it self is considered as part of the comment
+" 
+" Args:
+"   -line       the line number of the character
+"   -col        the column number of the character
+" Return: Number, 1 if the character is inside a comment, 0 if is not
+function! nerdcommenter#IsCharCommented(line, col) abort
+  " Function: s:searchfor(str, line, col, direction, [maxline])
+  " search str in the buffer, including the character at [line, col]
+  " Args: 
+  "   -str:       the string for search
+  "   -line:      the line number where search begins
+  "   -col:       the column number where search begins
+  "   -direction: 0 if forward, and 1 if backward
+  "   -maxline:   the max lines the search would look up
+  "               1 if search only one line
+  "               if not given, search until reaches the begining or end of file
+  " Return: List, in the format of [line, col], where line and col is the
+  "         position of first found result; If str cannot be found, returns
+  "         [0, 0]
+  function! s:searchfor(str, line, col, direction, ...) abort
+    let l:curlinenr = a:line
+    let l:maxline = (a:0 > 0) ? a:1 : (a:direction ? a:line : line('$') - a:line + 1)
+    while abs(curlinenr - a:line) < maxline
+      let linestr = getline(curlinenr)
+      if curlinenr == a:line
+        if !a:direction
+          let l:partstr = strpart(linestr, a:col - strlen(a:str))
+        else
+          let l:partstr = strpart(linestr, 0, a:col + strlen(a:str) - 1)
+        endif
+      else
+        let l:partstr = linestr
+      endif
+      if !a:direction
+        " forward
+        let idx = stridx(partstr, a:str)
+        if idx != -1
+          if curlinenr == a:line
+            let idx += a:col - strlen(a:str)
+          else
+          endif
+          return [curlinenr, idx + 1]
+        endif
+      else
+        " backward
+        let idx = strridx(partstr, a:str)
+        if idx != -1
+          return [curlinenr, idx + 1]
+        endif
+      endif
+      let curlinenr += a:direction ? -1 : 1
+    endwhile
+    return [0, 0]
+  endfunction
+  " Function: s:checkwith(left, right, line, col) abort
+  " check if the char at [line, col] is commented using [left, right] pair
+  " Args:
+  "   -left:      the string begins a comment
+  "   -right:     the string ends a comment
+  "   -line:      the line position of the character
+  "   -col:       the column position of the character
+  " Return: Number, 1 if is in a comment, 0 else
+  function! s:checkwith(left, right, line, col) abort
+    let linecommented  = 0
+    let blockcommented = 0
+    if a:right ==# ''
+      let leftpos = s:searchfor(a:left, a:line, a:col, 1, 1)
+      if leftpos == [0, 0]
+        if !linecommented | let linecommented = 0 | endif
+      else
+        if !linecommented | let linecommented = 1 | endif
+      endif
+    else
+      let leftpos = s:searchfor(a:left, a:line, a:col, 1)
+      if leftpos == [0, 0]
+        if !blockcommented | let blockcommented = 0 | endif
+      else 
+        " call s:searchfor(a:right, a:line, a:col, 0)
+        let rightpos = s:searchfor(a:right, leftpos[0], leftpos[1] + strlen(a:right) + 1, 0)
+        if rightpos != [0, 0]
+          if rightpos[0] < a:line
+            if !blockcommented | let blockcommented = 0 | endif
+          elseif rightpos[0] == a:line
+            if !blockcommented 
+              let blockcommented = (rightpos[1] + strlen(a:right) > a:col) ? 1 : 0
+            endif
+          else " rightpos > a:line
+            if !blockcommented | let blockcommented = 1 | endif
+          endif
+        else
+          if !blockcommented | let blockcommented = 1 | endif
+        endif
+      endif
+    endif
+    return linecommented || blockcommented
+  endfunction
+  return s:checkwith(
+          \ b:NERDCommenterDelims['left'], 
+          \ b:NERDCommenterDelims['right'], 
+          \ a:line, 
+          \ a:col) || 
+        \ s:checkwith(
+          \ b:NERDCommenterDelims['leftAlt'], 
+          \ b:NERDCommenterDelims['rightAlt'], 
+          \ a:line, 
+          \ a:col)
+endfunction
+
+" Function: s:PlaceDelimitersAndInsBetween() function
+" This is function is called to place comment delimiters down and place the
+" cursor between them
+function! s:PlaceDelimitersAndInsBetween() abort
+    " get the left and right delimiters without any escape chars in them
+    let left = s:Left({'space': 1})
+    let right = s:Right({'space': 1})
+
+    " 0. Entered insert normal mode using <C-\><C-O> (:h i_CTRL-\_CTRL-O) to
+    "    maintain the cursor position (from <Plug>NERDCommenterInsert).
+    " 1. Enter insert mode without changing the cursor position.
+    "    If the cursor is on EOL (right of the last char), use 'a'.
+    "    Otherwise, use 'i'.
+    let insert = col('.') > strlen(getline('.')) ? 'a' : 'i'
+    " 2. Insert comment delimiters.
+    " 3. Move the cursor to the left of the closing delimiter, without
+    "    breaking undo sequence.
+    " 4. Enter insert normal mode again without changing the cursor position.
+    "    This ensures that returning to the insert mode after finishing the
+    "    script execution does not move the cursor.
+    "                 ( 1  )   (    2     )   (                   3                   )   (      4     )
+    execute 'normal!' insert . left . right . repeat("\<C-G>U\<Left>", strchars(right)) . "\<C-\>\<C-O>"
+endfunction
+
+" Function: s:RemoveDelimiters(left, right, line)
+" this function is called to remove the first left comment delimiter and the
+" last right delimiter of the given line.
+"
+" The arguments left and right must be strings. If there is no right delimiter (as
+" is the case for e.g vim file comments) them the argument right should be ''
+"
+" Args:
+"   -left: the left comment delimiter
+"   -right: the right comment delimiter
+"   -line: the line to remove the delimiters from
+function! s:RemoveDelimiters(left, right, line) abort
+
+    let l:left = a:left
+    let l:right = a:right
+    let lenLeft = strlen(left)
+    let lenRight = strlen(right)
+
+    let delimsSpaced = (g:NERDSpaceDelims || g:NERDRemoveExtraSpaces)
+
+    let line = a:line
+
+    "look for the left delimiter, if we find it, remove it.
+    let leftIndx = s:FindDelimiterIndex(a:left, line)
+    if leftIndx !=# -1
+        let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+lenLeft)
+
+        "if the user has specified that there is a space after the left delimiter
+        "then check for the space and remove it if it is there
+        if delimsSpaced && strpart(line, leftIndx, s:lenSpaceStr) ==# s:spaceStr
+            let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+s:lenSpaceStr)
+        endif
+    endif
+
+    "look for the right delimiter, if we find it, remove it
+    let rightIndx = s:LastIndexOfDelim(a:right, line)
+    if rightIndx !=# -1
+        let line = strpart(line, 0, rightIndx) . strpart(line, rightIndx+lenRight)
+
+        "if the user has specified that there is a space before the right delimiter
+        "then check for the space and remove it if it is there
+        if delimsSpaced && strpart(line, rightIndx-s:lenSpaceStr, s:lenSpaceStr) ==# s:spaceStr && (s:Multipart() || s:AltMultipart())
+            let line = strpart(line, 0, rightIndx-s:lenSpaceStr) . strpart(line, rightIndx)
+        endif
+    endif
+
+    return line
+endfunction
+
+" Function: s:SetupStateBeforeLineComment(topLine, bottomLine)
+" Changes ignorecase and foldmethod options before commenting lines and saves
+" their original values in a dict, which is returned as a result
+"
+" Args:
+" topLine: the top line of the visual selection to uncomment
+" bottomLine: the bottom line of the visual selection to uncomment
+"
+" Return: a dict with the state prior to configuration changes
+"
+function! s:SetupStateBeforeLineComment(topLine, bottomLine) abort
+    let state = {'foldmethod' : &foldmethod,
+                \'ignorecase' : &ignorecase}
+
+    " Vim's foldmethods are evaluated every time we use 'setline', which can
+    " make commenting wide ranges of lines VERY slow. We'll change it to
+    " manual, do the commenting stuff and recover it later. To avoid slowing
+    " down commenting few lines, we avoid doing this for ranges smaller than
+    " 10 lines
+    if a:bottomLine - a:topLine >= 10 && &foldmethod !=# 'manual'
+        set foldmethod=manual
+    endif
+
+    " we want case sensitivity when commenting
+    set noignorecase
+
+    return state
+endfunction
+
+" Function: s:RecoverStateAfterLineComment(state)
+" Receives the state returned by s:SetupStateBeforeLineComment and restores
+" the state accordingly
+"
+" Args:
+" state: the top line of the visual selection to uncomment
+" bottomLine: the bottom line of the visual selection to uncomment
+function! s:RecoverStateAfterLineComment(state) abort
+    if a:state['foldmethod'] !=# &foldmethod
+        let &foldmethod = a:state['foldmethod']
+    endif
+    if a:state['ignorecase'] !=# &ignorecase
+        let &ignorecase = a:state['ignorecase']
+    endif
+endfunction
+
+" Function: s:TrimTrailingWhitespace(line)
+" This function removes all the trailing whitespace
+" Args:
+"   -line: the target line
+function! s:TrimTrailingWhitespace(line) abort
+    let toReturn = substitute(a:line, '\s\+$', '', 'g')
+    return toReturn
+endfunction
+
+" Function: s:UncommentLines(topLine, bottomLine)
+" This function uncomments the given lines
+"
+" Args:
+" topLine: the top line of the visual selection to uncomment
+" bottomLine: the bottom line of the visual selection to uncomment
+function! s:UncommentLines(topLine, bottomLine) abort
+    "make local copies of a:firstline and a:lastline and, if need be, swap
+    "them around if the top line is below the bottom
+    let l:firstline = a:topLine
+    let l:lastline = a:bottomLine
+    if firstline > lastline
+        let firstline = lastline
+        let lastline = a:topLine
+    endif
+
+    "go thru each line uncommenting each line removing sexy comments
+    let currentLine = firstline
+    while currentLine <= lastline
+
+        "check the current line to see if it is part of a sexy comment
+        let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine)
+        if !empty(sexyComBounds)
+
+            "we need to store the number of lines in the buffer before the comment is
+            "removed so we know how many lines were removed when the sexy comment
+            "was removed
+            let numLinesBeforeSexyComRemoved = s:NumLinesInBuf()
+
+            call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1])
+
+            "move to the line after last line of the sexy comment
+            let numLinesAfterSexyComRemoved = s:NumLinesInBuf()
+            let numLinesRemoved = numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved
+            let currentLine = sexyComBounds[1] - numLinesRemoved + 1
+            let lastline = lastline - numLinesRemoved
+
+        "no sexy com was detected so uncomment the line as normal
+        else
+            call s:UncommentLinesNormal(currentLine, currentLine)
+            let currentLine = currentLine + 1
+        endif
+    endwhile
+
+endfunction
+
+" Function: s:UncommentLinesSexy(topline, bottomline)
+" This function removes all the comment characters associated with the sexy
+" comment spanning the given lines
+" Args:
+"   -topline/bottomline: the top/bottom lines of the sexy comment
+function! s:UncommentLinesSexy(topline, bottomline) abort
+    let left = s:GetSexyComLeft(0,1)
+    let right = s:GetSexyComRight(0,1)
+
+
+    "check if it is even possible for sexy comments to exist with the
+    "available delimiters
+    if left ==# -1 || right ==# -1
+        throw 'NERDCommenter.Delimiters exception: cannot uncomment sexy comments with available delimiters.'
+    endif
+
+    let leftUnEsc = s:GetSexyComLeft(0,0)
+    let rightUnEsc = s:GetSexyComRight(0,0)
+
+    let sexyComMarker = s:GetSexyComMarker(0, 1)
+    let sexyComMarkerUnEsc = s:GetSexyComMarker(0, 0)
+
+    "the markerOffset is how far right we need to move the sexyComMarker to
+    "line it up with the end of the left delimiter
+    let markerOffset = strlen(leftUnEsc)-strlen(sexyComMarkerUnEsc)
+
+    " go thru the intermediate lines of the sexy comment and remove the
+    " sexy comment markers (e.g., the '*'s on the start of line in a c sexy
+    " comment)
+    let currentLine = a:topline+1
+    while currentLine < a:bottomline
+        let theLine = getline(currentLine)
+
+        " remove the sexy comment marker from the line. We also remove the
+        " space after it if there is one and if appropriate options are set
+        let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc)
+        if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) ==# s:spaceStr  && g:NERDSpaceDelims
+            let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr)
+        else
+            let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc))
+        endif
+
+        let theLine = s:SwapOuterPlaceHoldersForMultiPartDelims(theLine)
+
+        let theLine = s:ConvertLeadingWhiteSpace(theLine)
+
+        if g:NERDTrimTrailingWhitespace ==# 1
+            let theLine = s:TrimTrailingWhitespace(theLine)
+        endif
+
+        " move onto the next line
+        call setline(currentLine, theLine)
+        let currentLine = currentLine + 1
+    endwhile
+
+    " gotta make a copy of a:bottomline cos we modify the position of the
+    " last line  it if we remove the topline
+    let bottomline = a:bottomline
+
+    " get the first line so we can remove the left delimiter from it
+    let theLine = getline(a:topline)
+
+    " if the first line contains only the left delimiter then just delete it
+    if theLine =~# '^\s*' . left . '\s*$' && !g:NERDCompactSexyComs
+        call cursor(a:topline, 1)
+        normal! dd
+        let bottomline = bottomline - 1
+
+    " topline contains more than just the left delimiter
+    else
+
+        " remove the delimiter. If there is a space after it
+        " then remove this too if appropriate
+        let delimIndx = stridx(theLine, leftUnEsc)
+        if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) ==# s:spaceStr && g:NERDSpaceDelims
+            let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc)+s:lenSpaceStr)
+        else
+            let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc))
+        endif
+        let theLine = s:SwapOuterPlaceHoldersForMultiPartDelims(theLine)
+        call setline(a:topline, theLine)
+    endif
+
+    " get the last line so we can remove the right delimiter
+    let theLine = getline(bottomline)
+
+    " if the bottomline contains only the right delimiter then just delete it
+    if theLine =~# '^\s*' . right . '\s*$'
+        call cursor(bottomline, 1)
+        normal! dd
+
+    " the last line contains more than the right delimiter
+    else
+        " remove the right delimiter. If there is a space after it and
+        " if the appropriate options are set then remove this too.
+        let delimIndx = s:LastIndexOfDelim(rightUnEsc, theLine)
+        if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) ==# s:spaceStr  && g:NERDSpaceDelims
+            let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc)+s:lenSpaceStr)
+        else
+            let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc))
+        endif
+
+        " if the last line also starts with a sexy comment marker then we
+        " remove this as well
+        if theLine =~# '^\s*' . sexyComMarker
+
+            " remove the sexyComMarker. If there is a space after it then
+            " remove that too
+            let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc)
+            if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) ==# s:spaceStr  && g:NERDSpaceDelims
+                let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr)
+            else
+                let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc))
+            endif
+        endif
+
+        let theLine = s:SwapOuterPlaceHoldersForMultiPartDelims(theLine)
+        call setline(bottomline, theLine)
+    endif
+
+    " remove trailing whitespaces for first and last line
+    if g:NERDTrimTrailingWhitespace ==# 1
+        let theLine = getline(a:bottomline)
+        let theLine = s:TrimTrailingWhitespace(theLine)
+        call setline(a:bottomline, theLine)
+        let theLine = getline(a:topline)
+        let theLine = s:TrimTrailingWhitespace(theLine)
+        call setline(a:topline, theLine)
+    endif
+endfunction
+
+" Function: s:UncommentLineNormal(line)
+" uncomments the given line and returns the result
+" Args:
+"   -line: the line to uncomment
+function! s:UncommentLineNormal(line) abort
+    let line = a:line
+
+    "get the positions of all delimiter types on the line
+    let indxLeft = s:FindDelimiterIndex(s:Left(), line)
+    let indxLeftAlt = s:FindDelimiterIndex(s:Left({'alt': 1}), line)
+    let indxRight = s:LastIndexOfDelim(s:Right(), line)
+    let indxRightAlt = s:LastIndexOfDelim(s:Right({'alt': 1}), line)
+
+    "get the comment status on the line so we know how it is commented
+    let lineCommentStatus =  s:IsCommentedOutermost(s:Left(), s:Right(), s:Left({'alt': 1}), s:Right({'alt': 1}), line)
+
+    "it is commented with s:Left() and s:Right() so remove these delimiters
+    if lineCommentStatus ==# 1
+        let line = s:RemoveDelimiters(s:Left(), s:Right(), line)
+
+    "it is commented with s:Left({'alt': 1}) and s:Right({'alt': 1}) so remove these delimiters
+    elseif lineCommentStatus ==# 2 && g:NERDRemoveAltComs
+        let line = s:RemoveDelimiters(s:Left({'alt': 1}), s:Right({'alt': 1}), line)
+
+    "it is not properly commented with any delimiters so we check if it has
+    "any random left or right delimiters on it and remove the outermost ones
+    else
+        "remove the outer most left comment delimiter
+        if indxLeft !=# -1 && (indxLeft < indxLeftAlt || indxLeftAlt ==# -1)
+            let line = s:RemoveDelimiters(s:Left(), '', line)
+        elseif indxLeftAlt !=# -1 && g:NERDRemoveAltComs
+            let line = s:RemoveDelimiters(s:Left({'alt': 1}), '', line)
+        endif
+
+        "remove the outer most right comment delimiter
+        if indxRight !=# -1 && (indxRight < indxRightAlt || indxRightAlt ==# -1)
+            let line = s:RemoveDelimiters('', s:Right(), line)
+        elseif indxRightAlt !=# -1 && g:NERDRemoveAltComs
+            let line = s:RemoveDelimiters('', s:Right({'alt': 1}), line)
+        endif
+    endif
+
+
+    let indxLeftPlace = s:FindDelimiterIndex(g:NERDLPlace, line)
+    let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line)
+
+    let right = s:Right()
+    let left = s:Left()
+    if !s:Multipart()
+        let right = s:Right({'alt': 1})
+        let left = s:Left({'alt': 1})
+    endif
+
+
+    "if there are place-holders on the line then we check to see if they are
+    "the outermost delimiters on the line. If so then we replace them with
+    "real delimiters
+    if indxLeftPlace !=# -1
+        if (indxLeftPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
+            let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
+        endif
+    elseif indxRightPlace !=# -1
+        if (indxRightPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
+            let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
+        endif
+
+    endif
+
+    let line = s:ConvertLeadingWhiteSpace(line)
+
+    if g:NERDTrimTrailingWhitespace ==# 1
+        let line = s:TrimTrailingWhitespace(line)
+    endif
+
+    return line
+endfunction
+
+" Function: s:UncommentLinesNormal(topline, bottomline)
+" This function is called to uncomment lines that aren't a sexy comment
+" Args:
+"   -topline/bottomline: the top/bottom line numbers of the comment
+function! s:UncommentLinesNormal(topline, bottomline) abort
+    let currentLine = a:topline
+    while currentLine <= a:bottomline
+        let line = getline(currentLine)
+        call setline(currentLine, s:UncommentLineNormal(line))
+        let currentLine = currentLine + 1
+    endwhile
+endfunction
+
+
+" Section: Other helper functions
+" ============================================================================
+
+" Function: s:AddLeftDelim(delim, theLine)
+" Args:
+function! s:AddLeftDelim(delim, theLine) abort
+    return substitute(a:theLine, '^\(\s*\)', '\1' . a:delim, '')
+endfunction
+
+" Function: s:AddLeftDelimAligned(delim, theLine)
+" Args:
+function! s:AddLeftDelimAligned(delim, theLine, alignIndx) abort
+
+    "if the line is not long enough then bung some extra spaces on the front
+    "so we can align the delimiter properly
+    let theLine = a:theLine
+    if strlen(theLine) < a:alignIndx
+        let theLine = repeat(' ', a:alignIndx - strlen(theLine))
+    endif
+
+    return strpart(theLine, 0, a:alignIndx) . a:delim . strpart(theLine, a:alignIndx)
+endfunction
+
+" Function: s:AddRightDelim(delim, theLine)
+" Args:
+function! s:AddRightDelim(delim, theLine) abort
+    if a:delim ==# ''
+        return a:theLine
+    else
+        return substitute(a:theLine, '$', a:delim, '')
+    endif
+endfunction
+
+" Function: s:AddRightDelimAligned(delim, theLine, alignIndx)
+" Args:
+function! s:AddRightDelimAligned(delim, theLine, alignIndx) abort
+    if a:delim ==# ''
+        return a:theLine
+    else
+
+        " when we align the right delimiter we are just adding spaces
+        " so we get a string containing the needed spaces (it
+        " could be empty)
+        let extraSpaces = ''
+        let extraSpaces = repeat(' ', a:alignIndx-strlen(a:theLine))
+
+        " add the right delimiter
+        return substitute(a:theLine, '$', extraSpaces . a:delim, '')
+    endif
+endfunction
+
+" Function: s:AltMultipart()
+" returns 1 if the alternative delimiters are multipart
+function! s:AltMultipart() abort
+    return b:NERDCommenterDelims['rightAlt'] !=# ''
+endfunction
+
+" Function: s:AltNested()
+" returns 1 if the alternate multipart (if any) delimiters allow nesting
+function! s:AltNested() abort
+    return b:NERDCommenterDelims['nestedAlt']
+endfunction
+
+" Function: s:CanCommentLine(forceNested, line)
+"This function is used to determine whether the given line can be commented.
+"It returns 1 if it can be and 0 otherwise
+"
+" Args:
+"   -forceNested: a flag indicating whether the caller wants comments to be nested
+"    if the current line is already commented
+"   -lineNum: the line number of the line to check for commentability
+function! s:CanCommentLine(forceNested, lineNum) abort
+    let theLine = getline(a:lineNum)
+
+    " make sure we don't comment lines that are just spaces or tabs or empty,
+    " unless configured otherwise
+    if g:NERDCommentEmptyLines ==# 0 && theLine =~# '^\s*$'
+        return 0
+    endif
+
+    "if the line is part of a sexy comment then just flag it...
+    if s:IsInSexyComment(a:lineNum)
+        return 0
+    endif
+
+    let isCommented = s:IsCommentedNormOrSexy(a:lineNum)
+
+    "if the line isn't commented return true
+    if !isCommented
+        return 1
+    endif
+
+    "if the line is commented but nesting is allowed then return true
+    if s:Nested() || (a:forceNested && (!s:Multipart() || g:NERDUsePlaceHolders))
+        return 1
+    endif
+
+    return 0
+endfunction
+
+" Function: s:CanPlaceCursor(line, col)
+" returns 1 if the cursor can be placed exactly in the given position
+function! s:CanPlaceCursor(line, col) abort
+    let c = col('.')
+    let l = line('.')
+    call cursor(a:line, a:col)
+    let success = (line('.') ==# a:line && col('.') ==# a:col)
+    call cursor(l,c)
+    return success
+endfunction
+
+" Function: s:CanSexyCommentLines(topline, bottomline)
+" Return: 1 if the given lines can be commented sexually, 0 otherwise
+function! s:CanSexyCommentLines(topline, bottomline) abort
+    " see if the selected regions have any sexy comments
+    " however, if the language allows nested comments,
+    " we allow nested sexy comments
+    if s:SexyNested()
+        return 1
+    endif
+    let currentLine = a:topline
+    while(currentLine <= a:bottomline)
+        if s:IsInSexyComment(currentLine)
+            return 0
+        endif
+        let currentLine = currentLine + 1
+    endwhile
+    return 1
+endfunction
+" Function: s:CanToggleCommentLine(forceNested, line)
+"This function is used to determine whether the given line can be toggle commented.
+"It returns 1 if it can be and 0 otherwise
+"
+" Args:
+"   -lineNum: the line number of the line to check for commentability
+function! s:CanToggleCommentLine(forceNested, lineNum) abort
+    let theLine = getline(a:lineNum)
+    if (s:IsCommentedFromStartOfLine(s:Left(), theLine) || s:IsCommentedFromStartOfLine(s:Left({'alt': 1}), theLine)) && !a:forceNested
+        return 0
+    endif
+
+    " make sure we don't comment lines that are just spaces or tabs or empty,
+    " unless configured otherwise
+    if g:NERDCommentEmptyLines ==# 0 && theLine =~# '^\s*$'
+        return 0
+    endif
+
+    "if the line is part of a sexy comment then just flag it...
+    if s:IsInSexyComment(a:lineNum)
+        return 0
+    endif
+
+    return 1
+endfunction
+
+" Function: s:ConvertLeadingSpacesToTabs(line)
+" This function takes a line and converts all leading tabs on that line into
+" spaces
+"
+" Args:
+"   -line: the line whose leading tabs will be converted
+function! s:ConvertLeadingSpacesToTabs(line) abort
+    let toReturn  = a:line
+    while toReturn =~# '^\t*' . s:TabSpace() . '\(.*\)$'
+        let toReturn = substitute(toReturn, '^\(\t*\)' . s:TabSpace() . '\(.*\)$'  ,  '\1\t\2' , '')
+    endwhile
+
+    return toReturn
+endfunction
+
+
+" Function: s:ConvertLeadingTabsToSpaces(line)
+" This function takes a line and converts all leading spaces on that line into
+" tabs
+"
+" Args:
+"   -line: the line whose leading spaces will be converted
+function! s:ConvertLeadingTabsToSpaces(line) abort
+    let toReturn  = a:line
+    while toReturn =~# '^\( *\)\t'
+        let toReturn = substitute(toReturn, '^\( *\)\t',  '\1' . s:TabSpace() , '')
+    endwhile
+
+    return toReturn
+endfunction
+
+" Function: s:ConvertLeadingWhiteSpace(line)
+" Converts the leading white space to tabs/spaces depending on &tabstop
+"
+" Args:
+"   -line: the line to convert
+function! s:ConvertLeadingWhiteSpace(line) abort
+    let toReturn = a:line
+    while toReturn =~# '^ *\t'
+        let toReturn = substitute(toReturn, '^ *\zs\t\ze', s:TabSpace(), 'g')
+    endwhile
+
+    if !&expandtab
+        let toReturn = s:ConvertLeadingSpacesToTabs(toReturn)
+    endif
+
+    return toReturn
+endfunction
+
+
+" Function: s:CountNonESCedOccurances(str, searchstr, escChar)
+" This function counts the number of substrings contained in another string.
+" These substrings are only counted if they are not escaped with escChar
+" Args:
+"   -str: the string to look for searchstr in
+"   -searchstr: the substring to search for in str
+"   -escChar: the escape character which, when preceding an instance of
+"    searchstr, will cause it not to be counted
+function! s:CountNonESCedOccurances(str, searchstr, escChar) abort
+    "get the index of the first occurrence of searchstr
+    let indx = stridx(a:str, a:searchstr)
+
+    "if there is an instance of searchstr in str process it
+    if indx !=# -1
+        "get the remainder of str after this instance of searchstr is removed
+        let lensearchstr = strlen(a:searchstr)
+        let strLeft = strpart(a:str, indx+lensearchstr)
+
+        "if this instance of searchstr is not escaped, add one to the count
+        "and recurse. If it is escaped, just recurse
+        if !s:IsEscaped(a:str, indx, a:escChar)
+            return 1 + s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar)
+        else
+            return s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar)
+        endif
+    endif
+endfunction
+" Function: s:DoesBlockHaveDelim(delim, top, bottom)
+" Returns 1 if the given block of lines has a delimiter (a:delim) in it
+" Args:
+"   -delim: the comment delimiter to check the block for
+"   -top: the top line number of the block
+"   -bottom: the bottom line number of the block
+function! s:DoesBlockHaveDelim(delim, top, bottom) abort
+    let currentLine = a:top
+    while currentLine < a:bottom
+        let theline = getline(currentLine)
+        if s:FindDelimiterIndex(a:delim, theline) !=# -1
+            return 1
+        endif
+        let currentLine = currentLine + 1
+    endwhile
+    return 0
+endfunction
+
+" Function: s:DoesBlockHaveMultipartDelim(top, bottom)
+" Returns 1 if the given block has a >= 1 multipart delimiter in it
+" Args:
+"   -top: the top line number of the block
+"   -bottom: the bottom line number of the block
+function! s:DoesBlockHaveMultipartDelim(top, bottom) abort
+    if s:HasMultipartDelims()
+        if s:Multipart()
+            return s:DoesBlockHaveDelim(s:Left(), a:top, a:bottom) || s:DoesBlockHaveDelim(s:Right(), a:top, a:bottom)
+        else
+            return s:DoesBlockHaveDelim(s:Left({'alt': 1}), a:top, a:bottom) || s:DoesBlockHaveDelim(s:Right({'alt': 1}), a:top, a:bottom)
+        endif
+    endif
+    return 0
+endfunction
+
+
+" Function: s:Esc(str)
+" Escapes all the tricky chars in the given string
+function! s:Esc(str) abort
+    let charsToEsc = '*/\."&$+[]'
+    return escape(a:str, charsToEsc)
+endfunction
+
+" Function: s:FindDelimiterIndex(delimiter, line)
+" This function is used to get the string index of the input comment delimiter
+" on the input line. If no valid comment delimiter is found in the line then
+" -1 is returned
+" Args:
+"   -delimiter: the delimiter we are looking to find the index of
+"   -line: the line we are looking for delimiter on
+function! s:FindDelimiterIndex(delimiter, line) abort
+
+    "make sure the delimiter isn't empty otherwise we go into an infinite loop.
+    if a:delimiter ==# ''
+        return -1
+    endif
+
+
+    let l:delimiter = a:delimiter
+    let lenDel = strlen(l:delimiter)
+
+    "get the index of the first occurrence of the delimiter
+    let delIndx = stridx(a:line, l:delimiter)
+
+    "keep looping thru the line till we either find a real comment delimiter
+    "or run off the EOL
+    while delIndx !=# -1
+
+        "if we are not off the EOL get the str before the possible delimiter
+        "in question and check if it really is a delimiter. If it is, return
+        "its position
+        if delIndx !=# -1
+            if s:IsDelimValid(l:delimiter, delIndx, a:line)
+                return delIndx
+            endif
+        endif
+
+        "we have not yet found a real comment delimiter so move past the
+        "current one we are looking at
+        let restOfLine = strpart(a:line, delIndx + lenDel)
+        let distToNextDelim = stridx(restOfLine , l:delimiter)
+
+        "if distToNextDelim is -1 then there is no more potential delimiters
+        "on the line so set delIndx to -1. Otherwise, move along the line by
+        "distToNextDelim
+        if distToNextDelim ==# -1
+            let delIndx = -1
+        else
+            let delIndx = delIndx + lenDel + distToNextDelim
+        endif
+    endwhile
+
+    "there is no comment delimiter on this line
+    return -1
+endfunction
+
+" Function: s:FindBoundingLinesOfSexyCom(lineNum)
+" This function takes in a line number and tests whether this line number is
+" the top/bottom/middle line of a sexy comment. If it is then the top/bottom
+" lines of the sexy comment are returned
+" Args:
+"   -lineNum: the line number that is to be tested whether it is the
+"    top/bottom/middle line of a sexy com
+" Returns:
+"   A string that has the top/bottom lines of the sexy comment encoded in it.
+"   The format is 'topline,bottomline'. If a:lineNum turns out not to be the
+"   top/bottom/middle of a sexy comment then -1 is returned
+function! s:FindBoundingLinesOfSexyCom(lineNum) abort
+
+    "find which delimiters to look for as the start/end delimiters of the comment
+    let left = ''
+    let right = ''
+    if s:Multipart()
+        let left = s:Left({'esc': 1})
+        let right = s:Right({'esc': 1})
+    elseif s:AltMultipart()
+        let left = s:Left({'alt': 1, 'esc': 1})
+        let right = s:Right({'alt': 1, 'esc': 1})
+    else
+        return []
+    endif
+
+    let sexyComMarker = s:GetSexyComMarker(0, 1)
+
+    "initialise the top/bottom line numbers of the sexy comment to -1
+    let top = -1
+    let bottom = -1
+
+    let currentLine = a:lineNum
+    while top ==# -1 || bottom ==# -1
+        let theLine = getline(currentLine)
+
+        "check if the current line is the top of the sexy comment
+        if currentLine <= a:lineNum && theLine =~# '^\s*' . left && theLine !~# '.*' . right && currentLine < s:NumLinesInBuf()
+            let top = currentLine
+            let currentLine = a:lineNum
+
+        "check if the current line is the bottom of the sexy comment
+        elseif theLine =~# '^\s*' . right && theLine !~# '.*' . left && currentLine > 1
+            let bottom = currentLine
+
+        "the right delimiter is on the same line as the last sexyComMarker
+        elseif theLine =~# '^\s*' . sexyComMarker . '.*' . right
+            let bottom = currentLine
+
+        "we have not found the top or bottom line so we assume currentLine is an
+        "intermediate line and look to prove otherwise
+        else
+
+            "if the line doesn't start with a sexyComMarker then it is not a sexy
+            "comment
+            if theLine !~# '^\s*' . sexyComMarker
+                return []
+            endif
+
+        endif
+
+        "if top is -1 then we haven't found the top yet so keep looking up
+        if top ==# -1
+            let currentLine = currentLine - 1
+        "if we have found the top line then go down looking for the bottom
+        else
+            let currentLine = currentLine + 1
+        endif
+
+    endwhile
+
+    return [top, bottom]
+endfunction
+
+
+" Function: s:GetSexyComMarker()
+" Returns the sexy comment marker for the current filetype.
+"
+" C style sexy comments are assumed if possible. If not then the sexy comment
+" marker is the last char of the delimiter pair that has both left and right
+" delimiters and has the longest left delimiter
+"
+" Args:
+"   -space: specifies whether the marker is to have a space string after it
+"    (the space string will only be added if NERDSpaceDelims is set)
+"   -esc: specifies whether the tricky chars in the marker are to be ESCed
+function! s:GetSexyComMarker(space, esc) abort
+    let sexyComMarker = b:NERDSexyComMarker
+
+    "if there is no hardcoded marker then we find one
+    if sexyComMarker ==# ''
+
+        "if the filetype has c style comments then use standard c sexy
+        "comments
+        if s:HasCStyleComments()
+            let sexyComMarker = '*'
+        else
+            "find a comment marker by getting the longest available left delimiter
+            "(that has a corresponding right delimiter) and taking the last char
+            let lenLeft = strlen(s:Left())
+            let lenLeftAlt = strlen(s:Left({'alt': 1}))
+            let left = ''
+            let right = ''
+            if s:Multipart() && lenLeft >= lenLeftAlt
+                let left = s:Left()
+            elseif s:AltMultipart()
+                let left = s:Left({'alt': 1})
+            else
+                return -1
+            endif
+
+            "get the last char of left
+            let sexyComMarker = strpart(left, strlen(left)-1)
+        endif
+    endif
+
+    if a:space && g:NERDSpaceDelims
+        let sexyComMarker = sexyComMarker . s:spaceStr
+    endif
+
+    if a:esc
+        let sexyComMarker = s:Esc(sexyComMarker)
+    endif
+
+    return sexyComMarker
+endfunction
+
+" Function: s:SexyNested()
+" Returns 1 if the sexy delimeters allow nesting
+" TODO this is ugly copy&paste from the GetSexyComLeft/Right functions,
+" these could all be cleaned up
+function! s:SexyNested() abort
+    let lenLeft = strlen(s:Left())
+    let lenLeftAlt = strlen(s:Left({'alt': 1}))
+
+    "assume c style sexy comments if possible
+    if s:HasCStyleComments()
+        return (s:Left() ==# '/*' && s:Nested()) || (s:Left({'alt': 1}) ==# '/*' && s:AltNested())
+    else
+        "grab the longest left delim that has a right
+        if s:Multipart() && lenLeft >= lenLeftAlt
+            return s:Nested()
+        elseif s:AltMultipart()
+            return s:AltNested()
+        else
+            return 0
+        endif
+    endif
+endfunction
+
+" Function: s:GetSexyComLeft(space, esc)
+" Returns the left delimiter for sexy comments for this filetype or -1 if
+" there is none. C style sexy comments are used if possible
+" Args:
+"   -space: specifies if the delimiter has a space string on the end
+"   (the space string will only be added if NERDSpaceDelims is set)
+"   -esc: specifies whether the tricky chars in the string are ESCed
+function! s:GetSexyComLeft(space, esc) abort
+    let lenLeft = strlen(s:Left())
+    let lenLeftAlt = strlen(s:Left({'alt': 1}))
+    let left = ''
+
+    "assume c style sexy comments if possible
+    if s:HasCStyleComments()
+        let left = '/*'
+    else
+        "grab the longest left delimiter that has a right
+        if s:Multipart() && lenLeft >= lenLeftAlt
+            let left = s:Left()
+        elseif s:AltMultipart()
+            let left = s:Left({'alt': 1})
+        else
+            return -1
+        endif
+    endif
+
+    if a:space && g:NERDSpaceDelims
+        let left = left . s:spaceStr
+    endif
+
+    if a:esc
+        let left = s:Esc(left)
+    endif
+
+    return left
+endfunction
+
+" Function: s:GetSexyComRight(space, esc)
+" Returns the right delimiter for sexy comments for this filetype or -1 if
+" there is none. C style sexy comments are used if possible.
+" Args:
+"   -space: specifies if the delimiter has a space string on the start
+"   (the space string will only be added if NERDSpaceDelims
+"   is specified for the current filetype)
+"   -esc: specifies whether the tricky chars in the string are ESCed
+function! s:GetSexyComRight(space, esc) abort
+    let lenLeft = strlen(s:Left())
+    let lenLeftAlt = strlen(s:Left({'alt': 1}))
+    let right = ''
+
+    "assume c style sexy comments if possible
+    if s:HasCStyleComments()
+        let right = '*/'
+    else
+        "grab the right delimiter that pairs with the longest left delimiter
+        if s:Multipart() && lenLeft >= lenLeftAlt
+            let right = s:Right()
+        elseif s:AltMultipart()
+            let right = s:Right({'alt': 1})
+        else
+            return -1
+        endif
+    endif
+
+    if a:space && g:NERDSpaceDelims
+        let right = s:spaceStr . right
+    endif
+
+    if a:esc
+        let right = s:Esc(right)
+    endif
+
+    return right
+endfunction
+
+" Function: s:HasMultipartDelims()
+" Returns 1 if the current filetype has at least one set of multipart delimiters
+function! s:HasMultipartDelims() abort
+    return s:Multipart() || s:AltMultipart()
+endfunction
+
+" Function: s:HasLeadingTabs(...)
+" Returns 1 if any of the given strings have leading tabs
+function! s:HasLeadingTabs(...) abort
+    for s in a:000
+        if s =~# '^\t.*'
+            return 1
+        end
+    endfor
+    return 0
+endfunction
+" Function: s:HasCStyleComments()
+" Returns 1 if the current filetype has c style comment delimiters
+function! s:HasCStyleComments() abort
+    return (s:Left() ==# '/*' && s:Right() ==# '*/') || (s:Left({'alt': 1}) ==# '/*' && s:Right({'alt': 1}) ==# '*/')
+endfunction
+
+" Function: s:IsCommentedNormOrSexy(lineNum)
+"This function is used to determine whether the given line is commented with
+"either set of delimiters or if it is part of a sexy comment
+"
+" Args:
+"   -lineNum: the line number of the line to check
+function! s:IsCommentedNormOrSexy(lineNum) abort
+    let theLine = getline(a:lineNum)
+
+    "if the line is commented normally return 1
+    if s:IsCommented(s:Left(), s:Right(), theLine) || s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), theLine)
+        return 1
+    endif
+
+    "if the line is part of a sexy comment return 1
+    if s:IsInSexyComment(a:lineNum)
+        return 1
+    endif
+    return 0
+endfunction
+
+" Function: s:IsCommented(left, right, line)
+"This function is used to determine whether the given line is commented with
+"the given delimiters
+"
+" Args:
+"   -line: the line that to check if commented
+"   -left/right: the left and right delimiters to check for
+function! s:IsCommented(left, right, line) abort
+    "if the line isn't commented return true
+    if s:FindDelimiterIndex(a:left, a:line) !=# -1 && (s:LastIndexOfDelim(a:right, a:line) !=# -1 || !s:Multipart())
+        return 1
+    endif
+    return 0
+endfunction
+
+" Function: s:IsCommentedFromStartOfLine(left, line)
+"This function is used to determine whether the given line is commented with
+"the given delimiters at the start of the line i.e the left delimiter is the
+"first thing on the line (apart from spaces\tabs)
+"
+" Args:
+"   -line: the line that to check if commented
+"   -left: the left delimiter to check for
+function! s:IsCommentedFromStartOfLine(left, line) abort
+    let theLine = s:ConvertLeadingTabsToSpaces(a:line)
+    let numSpaces = strlen(matchstr(theLine, '^ *'))
+    let delimIndx = s:FindDelimiterIndex(a:left, theLine)
+    return delimIndx ==# numSpaces
+endfunction
+
+" Function: s:IsCommentedOutermost(left, right, leftAlt, rightAlt, line)
+" Finds the type of the outermost delimiters on the line
+"
+" Args:
+"   -line: the line that to check if the outermost comments on it are
+"    left/right
+"   -left/right: the left and right delimiters to check for
+"   -leftAlt/rightAlt: the left and right alternative delimiters to check for
+"
+" Returns:
+"   0 if the line is not commented with either set of delimiters
+"   1 if the line is commented with the left/right delimiter set
+"   2 if the line is commented with the leftAlt/rightAlt delim set
+function! s:IsCommentedOutermost(left, right, leftAlt, rightAlt, line) abort
+    "get the first positions of the left delimiters and the last positions of the
+    "right delimiters
+    let indxLeft = s:FindDelimiterIndex(a:left, a:line)
+    let indxLeftAlt = s:FindDelimiterIndex(a:leftAlt, a:line)
+    let indxRight = s:LastIndexOfDelim(a:right, a:line)
+    let indxRightAlt = s:LastIndexOfDelim(a:rightAlt, a:line)
+
+    "check if the line has a left delimiter before a leftAlt delimiter
+    if (indxLeft <= indxLeftAlt || indxLeftAlt ==# -1) && indxLeft !=# -1
+        "check if the line has a right delimiter after any rightAlt delimiter
+        if (indxRight > indxRightAlt && indxRight > indxLeft) || !s:Multipart()
+            return 1
+        endif
+
+        "check if the line has a leftAlt delimiter before a left delimiter
+    elseif (indxLeftAlt <= indxLeft || indxLeft ==# -1) && indxLeftAlt !=# -1
+        "check if the line has a rightAlt delimiter after any right delimiter
+        if (indxRightAlt > indxRight && indxRightAlt > indxLeftAlt) || !s:AltMultipart()
+            return 2
+        endif
+    else
+        return 0
+    endif
+
+    return 0
+
+endfunction
+
+
+" Function: s:IsDelimValid(delimiter, delIndx, line)
+" This function is responsible for determining whether a given instance of a
+" comment delimiter is a real delimiter or not. For example, in java the
+" // string is a comment delimiter but in the line:
+"               System.out.println("//");
+" it does not count as a comment delimiter. This function is responsible for
+" distinguishing between such cases. It does so by applying a set of
+" heuristics that are not fool proof but should work most of the time.
+"
+" Args:
+"   -delimiter: the delimiter we are validating
+"   -delIndx: the position of delimiter in line
+"   -line: the line that delimiter occurs in
+"
+" Returns:
+" 0 if the given delimiter is not a real delimiter (as far as we can tell) ,
+" 1 otherwise
+function! s:IsDelimValid(delimiter, delIndx, line) abort
+    "get the delimiter without the escchars
+    let l:delimiter = a:delimiter
+
+    "get the strings before and after the delimiter
+    let preComStr = strpart(a:line, 0, a:delIndx)
+    let postComStr = strpart(a:line, a:delIndx+strlen(delimiter))
+
+    "to check if the delimiter is real, make sure it isn't preceded by
+    "an odd number of quotes and followed by the same (which would indicate
+    "that it is part of a string and therefore is not a comment)
+    if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, '"', '\\'))
+        return 0
+    endif
+    if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "'", '\\')) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "'", '\\'))
+        return 0
+    endif
+    if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '`', '\\')) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, '`', '\\'))
+        return 0
+    endif
+
+
+    "if the comment delimiter is escaped, assume it isn't a real delimiter
+    if s:IsEscaped(a:line, a:delIndx, "\\")
+        return 0
+    endif
+
+    "vim comments are so fucking stupid!! Why the hell do they have comment
+    "delimiters that are used elsewhere in the syntax?!?! We need to check
+    "some conditions especially for vim
+    if &filetype ==# 'vim'
+        if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\"))
+            return 0
+        endif
+
+        "if the delimiter is on the very first char of the line or is the
+        "first non-tab/space char on the line then it is a valid comment delimiter
+        if a:delIndx ==# 0 || a:line =~# "^\s\\{" . a:delIndx . "\\}\".*$"
+            return 1
+        endif
+
+        let numLeftParen =s:CountNonESCedOccurances(preComStr, '(', '\\')
+        let numRightParen =s:CountNonESCedOccurances(preComStr, ')', '\\')
+
+        "if the quote is inside brackets then assume it isn't a comment
+        if numLeftParen > numRightParen
+            return 0
+        endif
+
+        "if the line has an even num of unescaped "'s then we can assume that
+        "any given " is not a comment delimiter
+        if s:IsNumEven(s:CountNonESCedOccurances(a:line, '"', '\\'))
+            return 0
+        endif
+    endif
+
+    return 1
+
+endfunction
+
+" Function: s:IsNumEven(num)
+" A small function the returns 1 if the input number is even and 0 otherwise
+" Args:
+"   -num: the number to check
+function! s:IsNumEven(num) abort
+    return (a:num % 2) ==# 0
+endfunction
+
+" Function: s:IsEscaped(str, indx, escChar)
+" This function takes a string, an index into that string and an esc char and
+" returns 1 if the char at the index is escaped (i.e if it is preceded by an
+" odd number of esc chars)
+" Args:
+"   -str: the string to check
+"   -indx: the index into str that we want to check
+"   -escChar: the escape char the char at indx may be ESCed with
+function! s:IsEscaped(str, indx, escChar) abort
+    "initialise numEscChars to 0 and look at the char before indx
+    let numEscChars = 0
+    let curIndx = a:indx-1
+
+    "keep going back thru str until we either reach the start of the str or
+    "run out of esc chars
+    while curIndx >= 0 && strpart(a:str, curIndx, 1) ==# a:escChar
+
+        "we have found another esc char so add one to the count and move left
+        "one char
+        let numEscChars  = numEscChars + 1
+        let curIndx = curIndx - 1
+
+    endwhile
+
+    "if there is an odd num of esc chars directly before the char at indx then
+    "the char at indx is escaped
+    return !s:IsNumEven(numEscChars)
+endfunction
+
+" Function: s:IsInSexyComment(line)
+" returns 1 if the given line number is part of a sexy comment
+function! s:IsInSexyComment(line) abort
+    return !empty(s:FindBoundingLinesOfSexyCom(a:line))
+endfunction
+
+" Function: s:IsSexyComment(topline, bottomline)
+" This function takes in 2 line numbers and returns 1 if the lines between and
+" including the given line numbers are a sexy comment. It returns 0 otherwise.
+" Args:
+"   -topline: the line that the possible sexy comment starts on
+"   -bottomline: the line that the possible sexy comment stops on
+function! s:IsSexyComment(topline, bottomline) abort
+
+    "get the delimiter set that would be used for a sexy comment
+    let left = ''
+    let right = ''
+    if s:Multipart()
+        let left = s:Left()
+        let right = s:Right()
+    elseif s:AltMultipart()
+        let left = s:Left({'alt': 1})
+        let right = s:Right({'alt': 1})
+    else
+        return 0
+    endif
+
+    "swap the top and bottom line numbers around if need be
+    let topline = a:topline
+    let bottomline = a:bottomline
+    if bottomline < topline
+        let topline = bottomline
+        let bottomline = a:topline
+    endif
+
+    "if there is < 2 lines in the comment it cannot be sexy
+    if (bottomline - topline) <= 0
+        return 0
+    endif
+
+    "if the top line doesn't begin with a left delimiter then the comment isn't sexy
+    if getline(a:topline) !~# '^\s*' . left
+        return 0
+    endif
+
+    "if there is a right delimiter on the top line then this isn't a sexy comment
+    if s:LastIndexOfDelim(right, getline(a:topline)) !=# -1
+        return 0
+    endif
+
+    "if there is a left delimiter on the bottom line then this isn't a sexy comment
+    if s:FindDelimiterIndex(left, getline(a:bottomline)) !=# -1
+        return 0
+    endif
+
+    "if the bottom line doesn't begin with a right delimiter then the comment isn't
+    "sexy
+    if getline(a:bottomline) !~# '^.*' . right . '$'
+        return 0
+    endif
+
+    let sexyComMarker = s:GetSexyComMarker(0, 1)
+
+    "check each of the intermediate lines to make sure they start with a
+    "sexyComMarker
+    let currentLine = a:topline+1
+    while currentLine < a:bottomline
+        let theLine = getline(currentLine)
+
+        if theLine !~# '^\s*' . sexyComMarker
+            return 0
+        endif
+
+        "if there is a right delimiter in an intermediate line then the block isn't
+        "a sexy comment
+        if s:LastIndexOfDelim(right, theLine) !=# -1
+            return 0
+        endif
+
+        let currentLine = currentLine + 1
+    endwhile
+
+    "we have not found anything to suggest that this isn't a sexy comment so
+    return 1
+
+endfunction
+
+" Function: s:LastIndexOfDelim(delim, str)
+" This function takes a string and a delimiter and returns the last index of
+" that delimiter in string
+" Args:
+"   -delim: the delimiter to look for
+"   -str: the string to look for delimiter in
+function! s:LastIndexOfDelim(delim, str) abort
+    let delim = a:delim
+    let lenDelim = strlen(delim)
+
+    "set index to the first occurrence of delimiter. If there is no occurrence then
+    "bail
+    let indx = s:FindDelimiterIndex(delim, a:str)
+    if indx ==# -1
+        return -1
+    endif
+
+    "keep moving to the next instance of delimiter in str till there is none left
+    while 1
+
+        "search for the next delimiter after the previous one
+        let searchStr = strpart(a:str, indx+lenDelim)
+        let indx2 = s:FindDelimiterIndex(delim, searchStr)
+
+        "if we find a delimiter update indx to record the position of it, if we
+        "don't find another delimiter then indx is the last one so break out of
+        "this loop
+        if indx2 !=# -1
+            let indx = indx + indx2 + lenDelim
+        else
+            break
+        endif
+    endwhile
+
+    return indx
+
+endfunction
+
+" Function: s:Left(...)
+" returns left delimiter data
+function! s:Left(...) abort
+    let params = a:0 ? a:1 : {}
+
+    let delim = has_key(params, 'alt') ? b:NERDCommenterDelims['leftAlt'] : b:NERDCommenterDelims['left']
+
+    if delim ==# ''
+        return ''
+    endif
+
+    if has_key(params, 'space') && g:NERDSpaceDelims
+        let delim = delim . s:spaceStr
+    endif
+
+    if has_key(params, 'esc')
+        let delim = s:Esc(delim)
+    endif
+
+    return delim
+endfunction
+
+" Function: s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline)
+" This function takes in 2 line numbers and returns the index of the left most
+" char (that is not a space or a tab) on all of these lines.
+" Args:
+"   -countCommentedLines: 1 if lines that are commented are to be checked as
+"    well. 0 otherwise
+"   -countEmptyLines: 1 if empty lines are to be counted in the search
+"   -topline: the top line to be checked
+"   -bottomline: the bottom line to be checked
+function! s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) abort
+
+    " declare the left most index as an extreme value
+    let leftMostIndx = 1000
+
+    " go thru the block line by line updating leftMostIndx
+    let currentLine = a:topline
+    while currentLine <= a:bottomline
+
+        " get the next line and if it is allowed to be commented, or is not
+        " commented, check it
+        let theLine = getline(currentLine)
+        if a:countEmptyLines || theLine !~# '^\s*$'
+            if a:countCommentedLines || (!s:IsCommented(s:Left(), s:Right(), theLine) && !s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), theLine))
+                " convert spaces to tabs and get the number of leading spaces for
+                " this line and update leftMostIndx if need be
+                let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+                let leadSpaceOfLine = strlen(matchstr(theLine, '^\s*'))
+                if leadSpaceOfLine < leftMostIndx
+                    let leftMostIndx = leadSpaceOfLine
+                endif
+            endif
+        endif
+
+        " move on to the next line
+        let currentLine = currentLine + 1
+    endwhile
+
+    if leftMostIndx ==# 1000
+        return 0
+    else
+        return leftMostIndx
+    endif
+endfunction
+
+" Function: s:Multipart()
+" returns 1 if the current delimiters are multipart
+function! s:Multipart() abort
+    return s:Right() !=# ''
+endfunction
+
+" Function: s:NerdEcho(msg, typeOfMsg)
+" Args:
+"   -msg: the message to echo
+"   -typeOfMsg: 0 = warning message
+"               1 = normal message
+function! s:NerdEcho(msg, typeOfMsg) abort
+    if a:typeOfMsg ==# 0
+        echohl WarningMsg
+        echom 'NERDCommenter:' . a:msg
+        echohl None
+    elseif a:typeOfMsg ==# 1
+        echom 'NERDCommenter:' . a:msg
+    endif
+endfunction
+
+" Function: s:Nested()
+" returns 1 if the current multipart (if any) delimiters allow nesting
+function! s:Nested() abort
+    return b:NERDCommenterDelims['nested']
+endfunction
+
+" Function: s:NumberOfLeadingTabs(s)
+" returns the number of leading tabs in the given string
+function! s:NumberOfLeadingTabs(s) abort
+    return strlen(matchstr(a:s, '^\t*'))
+endfunction
+
+" Function: s:NumLinesInBuf()
+" Returns the number of lines in the current buffer
+function! s:NumLinesInBuf() abort
+    return line('$')
+endfunction
+
+" Function: s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str)
+" This function takes in a string, 2 delimiters in that string and 2 strings
+" to replace these delimiters with.
+"
+" Args:
+"   -toReplace1: the first delimiter to replace
+"   -toReplace2: the second delimiter to replace
+"   -replacor1: the string to replace toReplace1 with
+"   -replacor2: the string to replace toReplace2 with
+"   -str: the string that the delimiters to be replaced are in
+function! s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str) abort
+    let line = s:ReplaceLeftMostDelim(a:toReplace1, a:replacor1, a:str)
+    let line = s:ReplaceRightMostDelim(a:toReplace2, a:replacor2, line)
+    return line
+endfunction
+
+" Function: s:ReplaceLeftMostDelim(toReplace, replacor, str)
+" This function takes a string and a delimiter and replaces the left most
+" occurrence of this delimiter in the string with a given string
+"
+" Args:
+"   -toReplace: the delimiter in str that is to be replaced
+"   -replacor: the string to replace toReplace with
+"   -str: the string that contains toReplace
+function! s:ReplaceLeftMostDelim(toReplace, replacor, str) abort
+    let toReplace = a:toReplace
+    let replacor = a:replacor
+    "get the left most occurrence of toReplace
+    let indxToReplace = s:FindDelimiterIndex(toReplace, a:str)
+
+    "if there IS an occurrence of toReplace in str then replace it and return
+    "the resulting string
+    if indxToReplace !=# -1
+        let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace))
+        return line
+    endif
+
+    return a:str
+endfunction
+
+" Function: s:ReplaceRightMostDelim(toReplace, replacor, str)
+" This function takes a string and a delimiter and replaces the right most
+" occurrence of this delimiter in the string with a given string
+"
+" Args:
+"   -toReplace: the delimiter in str that is to be replaced
+"   -replacor: the string to replace toReplace with
+"   -str: the string that contains toReplace
+"
+function! s:ReplaceRightMostDelim(toReplace, replacor, str) abort
+    let toReplace = a:toReplace
+    let replacor = a:replacor
+    let lenToReplace = strlen(toReplace)
+
+    "get the index of the last delimiter in str
+    let indxToReplace = s:LastIndexOfDelim(toReplace, a:str)
+
+    "if there IS a delimiter in str, replace it and return the result
+    let line = a:str
+    if indxToReplace !=# -1
+        let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace))
+    endif
+    return line
+endfunction
+
+" Function: s:Right(...)
+" returns right delimiter data
+function! s:Right(...) abort
+    let params = a:0 ? a:1 : {}
+
+    let delim = has_key(params, 'alt') ? b:NERDCommenterDelims['rightAlt'] : b:NERDCommenterDelims['right']
+
+    if delim ==# ''
+        return ''
+    endif
+
+    if has_key(params, 'space') && g:NERDSpaceDelims
+        let delim = s:spaceStr . delim
+    endif
+
+    if has_key(params, 'esc')
+        let delim = s:Esc(delim)
+    endif
+
+    return delim
+endfunction
+
+" Function: s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline)
+" This function takes in 2 line numbers and returns the index of the right most
+" char on all of these lines.
+" Args:
+"   -countCommentedLines: 1 if lines that are commented are to be checked as
+"    well. 0 otherwise
+"   -countEmptyLines: 1 if empty lines are to be counted in the search
+"   -topline: the top line to be checked
+"   -bottomline: the bottom line to be checked
+function! s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) abort
+    let rightMostIndx = -1
+
+    " go thru the block line by line updating rightMostIndx
+    let currentLine = a:topline
+    while currentLine <= a:bottomline
+
+        " get the next line and see if it is commentable, otherwise it doesn't
+        " count
+        let theLine = getline(currentLine)
+        if a:countEmptyLines || theLine !~# '^\s*$'
+
+            if a:countCommentedLines || (!s:IsCommented(s:Left(), s:Right(), theLine) && !s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), theLine))
+
+                " update rightMostIndx if need be
+                let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+                let lineLen = strlen(theLine)
+                if lineLen > rightMostIndx
+                    let rightMostIndx = lineLen
+                endif
+            endif
+        endif
+
+        " move on to the next line
+        let currentLine = currentLine + 1
+    endwhile
+
+    return rightMostIndx
+endfunction
+
+" Function: s:SwapOuterMultiPartDelimsForPlaceHolders(line)
+" This function takes a line and swaps the outer most multi-part delimiters for
+" place holders
+" Args:
+"   -line: the line to swap the delimiters in
+"
+function! s:SwapOuterMultiPartDelimsForPlaceHolders(line) abort
+    " find out if the line is commented using normal delimiters and/or
+    " alternate ones
+    let isCommented = s:IsCommented(s:Left(), s:Right(), a:line)
+    let isCommentedAlt = s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), a:line)
+
+    let line2 = a:line
+
+    "if the line is commented and there is a right delimiter, replace
+    "the delimiters with place-holders
+    if isCommented && s:Multipart()
+        let line2 = s:ReplaceDelims(s:Left(), s:Right(), g:NERDLPlace, g:NERDRPlace, a:line)
+
+    "similarly if the line is commented with the alternative
+    "delimiters
+    elseif isCommentedAlt && s:AltMultipart()
+        let line2 = s:ReplaceDelims(s:Left({'alt': 1}), s:Right({'alt': 1}), g:NERDLPlace, g:NERDRPlace, a:line)
+    endif
+
+    return line2
+endfunction
+
+" Function: s:SwapOuterPlaceHoldersForMultiPartDelims(line)
+" This function takes a line and swaps the outermost place holders for
+" multi-part delimiters
+" Args:
+"   -line: the line to swap the delimiters in
+"
+function! s:SwapOuterPlaceHoldersForMultiPartDelims(line) abort
+    let left = ''
+    let right = ''
+    if s:Multipart()
+        let left = s:Left()
+        let right = s:Right()
+    elseif s:AltMultipart()
+        let left = s:Left({'alt': 1})
+        let right = s:Right({'alt': 1})
+    endif
+
+    let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, a:line)
+    return line
+endfunction
+
+"FUNCTION: s:TabSpace()
+"returns a string of spaces equal in length to &tabstop
+function! s:TabSpace() abort
+    let tabSpace = ''
+    let spacesPerTab = &tabstop
+    while spacesPerTab > 0
+        let tabSpace = tabSpace . ' '
+        let spacesPerTab = spacesPerTab - 1
+    endwhile
+    return tabSpace
+endfunction
+
+" Function: s:UnEsc(str, escChar)
+" This function removes all the escape chars from a string
+" Args:
+"   -str: the string to remove esc chars from
+"   -escChar: the escape char to be removed
+function! s:UnEsc(str, escChar) abort
+    return substitute(a:str, a:escChar, '', 'g')
+endfunction

+ 1004 - 0
vimfiles/bundle/nerdcommenter/doc/nerdcommenter.txt

@@ -0,0 +1,1004 @@
+*nerdcommenter.txt*         Plugin for commenting code
+
+
+                        NERD COMMENTER REFERENCE MANUAL~
+
+
+
+
+
+==============================================================================
+CONTENTS                                               *NERDCommenterContents*
+
+    1.Intro...................................|NERDCommenter|
+        1.1 Leader............................|NERDCommenterLeader|
+    2.Installation............................|NERDCommenterInstallation|
+    3.Functionality provided..................|NERDCommenterFunctionality|
+        3.1 Functionality Summary.............|NERDCommenterFunctionalitySummary|
+        3.2 Functionality Details.............|NERDCommenterFunctionalityDetails|
+            3.2.1 Comment map.................|NERDCommenterComment|
+            3.2.2 Nested comment map..........|NERDCommenterNested|
+            3.2.3 Toggle comment map..........|NERDCommenterToggle|
+            3.2.4 Minimal comment map.........|NERDCommenterMinimal|
+            3.2.5 Invert comment map..........|NERDCommenterInvert|
+            3.2.6 Sexy comment map............|NERDCommenterSexy|
+            3.2.7 Yank comment map............|NERDCommenterYank|
+            3.2.8 Comment to EOL map..........|NERDCommenterToEOL|
+            3.2.9 Append com to line map......|NERDCommenterAppend|
+            3.2.10 Insert comment map.........|NERDCommenterInsert|
+            3.2.11 Use alternate delims map...|NERDCommenterAltDelims|
+            3.2.12 Comment aligned maps.......|NERDCommenterAlignLeft|
+                                              |NERDCommenterAlignBoth|
+            3.2.13 Uncomment line map.........|NERDCommenterUncomment|
+        3.3 Sexy Comments.....................|NERDCommenterSexyComments|
+        3.4 The NERDComment function..........|NERDCommenterNERDComment|
+        3.5 The Hooks.........................|NERDCommenterHooks|
+    4.Options.................................|NERDCommenterOptions|
+        4.1 Options summary...................|NERDCommenterOptionsSummary|
+        4.2 Options details...................|NERDCommenterOptionsDetails|
+        4.3 Default delimiter Options.........|NERDCommenterDefaultDelims|
+    5. Customising key mappings...............|NERDCommenterMappings|
+    6. Interfaces.............................|NERDCommenterInterfaces|
+    7. Issues with the script.................|NERDCommenterIssues|
+        7.1 Delimiter detection heuristics....|NERDCommenterHeuristics|
+        7.2 Nesting issues....................|NERDCommenterNesting|
+    8.About..     ............................|NERDCommenterAbout|
+    9.Changelog...............................|NERDCommenterChangelog|
+    10.Credits................................|NERDCommenterCredits|
+    11.License................................|NERDCommenterLicense|
+
+==============================================================================
+1. Intro                                                       *NERDCommenter*
+
+The NERD commenter provides many different commenting operations and styles
+which are invoked via key mappings and a menu. These operations are available
+for most filetypes.
+
+There are also options that allow to tweak the commenting engine to your
+taste.
+
+------------------------------------------------------------------------------
+1.1 Leader key                                           *NERDCommenterLeader*
+
+Most NERD commenter commands are executed using the |<Leader>| key. In Vim
+this is a key dedicated for user-specific customizations. It effectively
+creates a namespace so that custom commands don't interfere with Vim's
+built-in shortcuts.
+
+The leader key can be mapped to whatever the user likes (see :help mapleader).
+In the definition of custom commands |<Leader>| is the placeholder for the 
+leader key. To see the current mapping for |<Leader>| type :echo mapleader.
+If it reports an undefined variable it means the leader key is set to the
+default of '\'.
+
+==============================================================================
+2. Installation                                    *NERDCommenterInstallation*
+
+The NERD Commenter requires Vim 7 or higher.
+
+Extract the plugin files in your ~/.vim (*nix) or ~/vimfiles (Windows). You
+should have 2 files: >
+    plugin/nerdcommenter.vim
+    doc/nerdcommenter.txt
+<
+Next, to finish installing the help file run: >
+    :helptags ~/.vim/doc
+<
+See |add-local-help| for more details.
+
+Make sure that you have filetype plugins enabled, as the script makes use of
+|'commentstring'| where possible (which is usually set in a filetype plugin).
+See |filetype-plugin-on| for details, but basically, stick this in your vimrc >
+    filetype plugin on
+<
+
+==============================================================================
+3. Functionality provided                         *NERDCommenterFunctionality*
+
+------------------------------------------------------------------------------
+3.1 Functionality summary                  *NERDCommenterFunctionalitySummary*
+
+The following key mappings are provided by default (there is also a menu
+with items corresponding to all the mappings below):
+
+[count]|<Leader>|cc |NERDCommenterComment|
+Comment out the current line or text selected in visual mode.
+
+
+[count]|<Leader>|cn |NERDCommenterNested|
+Same as |<Leader>|cc but forces nesting.
+
+
+[count]|<Leader>|c<space> |NERDCommenterToggle|
+Toggles the comment state of the selected line(s). If the topmost selected
+line is commented, all selected lines are uncommented and vice versa.
+
+
+[count]|<Leader>|cm |NERDCommenterMinimal|
+Comments the given lines using only one set of multipart delimiters.
+
+
+[count]|<Leader>|ci |NERDCommenterInvert|
+Toggles the comment state of the selected line(s) individually.
+
+
+[count]|<Leader>|cs |NERDCommenterSexy|
+Comments out the selected lines ``sexily''
+
+
+[count]|<Leader>|cy |NERDCommenterYank|
+Same as |<Leader>|cc except that the commented line(s) are yanked first.
+
+
+|<Leader>|c$ |NERDCommenterToEOL|
+Comments the current line from the cursor to the end of line.
+
+
+|<Leader>|cA |NERDCommenterAppend|
+Adds comment delimiters to the end of line and goes into insert mode between
+them.
+
+
+|NERDCommenterInsert|
+Adds comment delimiters at the current cursor position and inserts between.
+Disabled by default.
+
+
+|<Leader>|ca |NERDCommenterAltDelims|
+Switches to the alternative set of delimiters.
+
+
+[count]|<Leader>|cl    |NERDCommenterAlignLeft|
+[count]|<Leader>|cb    |NERDCommenterAlignBoth|
+Same as |NERDCommenterComment| except that the delimiters are aligned down the
+left side (|<Leader>|cl) or both sides (|<Leader>|cb).
+
+
+[count]|<Leader>|cu |NERDCommenterUncomment|
+Uncomments the selected line(s).
+
+
+With the optional repeat.vim plugin (vimscript #2136), the mappings can also
+be repeated via |.|
+
+------------------------------------------------------------------------------
+3.2 Functionality details                  *NERDCommenterFunctionalityDetails*
+
+------------------------------------------------------------------------------
+3.2.1 Comment map                                       *NERDCommenterComment*
+
+Default mapping: [count]|<Leader>|cc
+Mapped to: <plug>NERDCommenterComment
+Applicable modes: normal visual visual-line visual-block.
+
+
+Comments out the current line. If multiple lines are selected in visual-line
+mode, they are all commented out.  If some text is selected in visual or
+visual-block mode then the script will try to comment out the exact text that
+is selected using multi-part delimiters if they are available.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+------------------------------------------------------------------------------
+3.2.2 Nested comment map                                 *NERDCommenterNested*
+
+Default mapping: [count]|<Leader>|cn
+Mapped to: <plug>NERDCommenterNested
+Applicable modes: normal visual visual-line visual-block.
+
+Performs nested commenting.  Works the same as |<Leader>|cc except that if a line
+is already commented then it will be commented again.
+
+If |'NERDUsePlaceHolders'| is set then the previous comment delimiters will
+be replaced by place-holder delimiters if needed.  Otherwise the nested
+comment will only be added if the current commenting delimiters have no right
+delimiter (to avoid syntax errors)
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+Related options:
+|'NERDDefaultNesting'|
+
+------------------------------------------------------------------------------
+3.2.3 Toggle comment map                                 *NERDCommenterToggle*
+
+Default mapping: [count]|<Leader>|c<space>
+Mapped to: <plug>NERDCommenterToggle
+Applicable modes: normal visual-line.
+
+Toggles commenting of the lines selected. The behaviour of this mapping
+depends on whether the first line selected is commented or not.  If so, all
+selected lines are uncommented and vice versa.
+
+With this mapping, a line is only considered to be commented if it starts with
+a left delimiter.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+------------------------------------------------------------------------------
+3.2.4 Minimal comment map                               *NERDCommenterMinimal*
+
+Default mapping: [count]|<Leader>|cm
+Mapped to: <plug>NERDCommenterMinimal
+Applicable modes: normal visual-line.
+
+Comments the selected lines using one set of multipart delimiters if possible.
+
+For example: if you are programming in c and you select 5 lines and press
+|<Leader>|cm then a '/*' will be placed at the start of the top line and a '*/'
+will be placed at the end of the last line.
+
+Sets of multipart comment delimiters that are between the top and bottom
+selected lines are replaced with place holders (see |'NERDLPlace'|) if
+|'NERDUsePlaceHolders'| is set for the current filetype. If it is not, then
+the comment will be aborted if place holders are required to prevent illegal
+syntax.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+------------------------------------------------------------------------------
+3.2.5 Invert comment map                                 *NERDCommenterInvert*
+
+Default mapping: |<Leader>|ci
+Mapped to: <plug>NERDCommenterInvert
+Applicable modes: normal visual-line.
+
+Inverts the commented state of each selected line. If the selected line is
+commented then it is uncommented and vice versa. Each line is examined and
+commented/uncommented individually.
+
+With this mapping, a line is only considered to be commented if it starts with
+a left delimiter.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+------------------------------------------------------------------------------
+3.2.6 Sexy comment map                                     *NERDCommenterSexy*
+
+Default mapping: [count]|<Leader>|cs
+Mapped to: <plug>NERDCommenterSexy
+Applicable modes: normal, visual-line.
+
+Comments the selected line(s) ``sexily''. See |NERDCommenterSexyComments| for
+a description of what sexy comments are. Can only be done on filetypes for
+which there is at least one set of multipart comment delimiters specified.
+
+Sexy comments cannot be nested and lines inside a sexy comment cannot be
+commented again.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+Related options:
+|'NERDCompactSexyComs'|
+
+------------------------------------------------------------------------------
+3.2.7 Yank comment map                                     *NERDCommenterYank*
+
+Default mapping: [count]|<Leader>|cy
+Mapped to: <plug>NERDCommenterYank
+Applicable modes: normal visual visual-line visual-block.
+
+Same as |<Leader>|cc except that it yanks the line(s) that are commented first.
+
+------------------------------------------------------------------------------
+3.2.8 Comment to EOL map                                  *NERDCommenterToEOL*
+
+Default mapping: |<Leader>|c$
+Mapped to: <plug>NERDCommenterToEOL
+Applicable modes: normal.
+
+Comments the current line from the current cursor position up to the end of
+the line.
+
+------------------------------------------------------------------------------
+3.2.9 Append com to line map                             *NERDCommenterAppend*
+
+Default mapping: |<Leader>|cA
+Mapped to: <plug>NERDCommenterAppend
+Applicable modes: normal.
+
+Appends comment delimiters to the end of the current line and goes
+to insert mode between the new delimiters.
+
+------------------------------------------------------------------------------
+3.2.10 Insert comment map                                *NERDCommenterInsert*
+
+Default mapping: disabled by default.
+Map it to: <plug>NERDCommenterInsert
+Applicable modes: insert.
+
+Adds comment delimiters at the current cursor position and inserts
+between them.
+
+NOTE: prior to version 2.1.17 this was mapped to <C-c>. To restore this
+mapping add >
+    imap <C-c> <plug>NERDCommenterInsert
+<
+to your vimrc.
+
+------------------------------------------------------------------------------
+3.2.11 Use alternate delims map                       *NERDCommenterAltDelims*
+
+Default mapping: |<Leader>|ca
+Mapped to: <plug>NERDCommenterAltDelims
+Applicable modes: normal.
+
+Changes to the alternative commenting style if one is available. For example,
+if the user is editing a c++ file using // comments and they hit |<Leader>|ca
+then they will be switched over to /**/ comments.
+
+See also |NERDCommenterDefaultDelims|
+
+------------------------------------------------------------------------------
+3.2.12 Comment aligned maps                           *NERDCommenterAlignLeft*
+                                                      *NERDCommenterAlignBoth*
+
+Default mappings: [count]|<Leader>|cl   [count]|<Leader>|cb
+Mapped to: <plug>NERDCommenterAlignLeft
+           <plug>NERDCommenterAlignBoth
+Applicable modes: normal visual-line.
+
+Same as |<Leader>|cc except that the comment delimiters are aligned on the left
+side or both sides respectively. These comments are always nested if the
+line(s) are already commented.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+------------------------------------------------------------------------------
+3.2.13 Uncomment line map                             *NERDCommenterUncomment*
+
+Default mapping: [count]|<Leader>|cu
+Mapped to: <plug>NERDCommenterUncomment
+Applicable modes: normal visual visual-line visual-block.
+
+Uncomments the current line. If multiple lines are selected in
+visual mode then they are all uncommented.
+
+When uncommenting, if the line contains multiple sets of delimiters then the
+``outermost'' pair of delimiters will be removed.
+
+The script uses a set of heuristics to distinguish ``real'' delimiters from
+``fake'' ones when uncommenting. See |NERDCommenterIssues| for details.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+Related  options:
+|'NERDRemoveAltComs'|
+|'NERDRemoveExtraSpaces'|
+
+------------------------------------------------------------------------------
+3.3 Sexy Comments                                  *NERDCommenterSexyComments*
+These are comments that use one set of multipart comment delimiters as well as
+one other marker symbol. For example: >
+    /*
+     * This is a c style sexy comment
+     * So there!
+     */
+
+    /* This is a c style sexy comment
+     * So there!
+     * But this one is ``compact'' style */
+<
+Here the multipart delimiters are /* and */ and the marker is *.
+
+------------------------------------------------------------------------------
+3.4 The NERDComment function                        *NERDCommenterNERDComment*
+
+All of the NERD commenter mappings and menu items invoke a single function
+which delegates the commenting work to other functions. This function is
+public and has the prototype: >
+    function! NERDComment(mode, type)
+<
+The arguments to this function are simple:
+    - mode: a character indicating the mode in which the comment is requested:
+     'n' for Normal mode, 'x' for Visual mode
+    - type: is used to specify what type of commenting operation is to be
+      performed, and it can be one of the following: "sexy", "invert",
+      "minimal", "toggle", "alignLeft", "alignBoth", "comment", "nested",
+      "toEOL", "append", "insert", "uncomment", "yank"
+
+For example, if you typed >
+    :call NERDComment(1, 'sexy')
+<
+then the script would do a sexy comment on the last visual selection.
+
+------------------------------------------------------------------------------
+3.5 The hooks                                             *NERDCommenterHooks*
+|fu! NERDCommenter_before()|  Before NERDComment/SwitchToAlternativeDelimiters
+|fu! NERDCommenter_after()|    After NERDComment/SwitchToAlternativeDelimiters
+
+For example, in order to handle different language blocks embedded in the same
+file such as |vim-vue|, you can change the filetype, comment something and
+change the filetype back: >
+    let g:ft = ''
+    fu! NERDCommenter_before()
+        if &ft == 'vue'
+            let g:ft = 'vue'
+            let stack = synstack(line('.'), col('.'))
+            if len(stack) > 0
+                let syn = synIDattr((stack)[0], 'name')
+                if len(syn) > 0
+                    let syn = tolower(syn)
+                    exe 'setf '.syn
+                endif
+            endif
+        endif
+    endfu
+    fu! NERDCommenter_after()
+        if g:ft == 'vue'
+            setf vue
+            let g:ft = ''
+        endif
+    endfu
+<
+
+==============================================================================
+4. Options                                              *NERDCommenterOptions*
+
+------------------------------------------------------------------------------
+4.1 Options summary                              *NERDCommenterOptionsSummary*
+
+|'loaded_nerd_comments'|              Turns off the script.
+
+|'NERDAllowAnyVisualDelims'|          Allows multipart alternative delimiters
+                                      to be used when commenting in
+                                      visual/visual-block mode.
+
+|'NERDBlockComIgnoreEmpty'|           Forces right delimiters to be placed
+                                      when doing visual-block comments.
+
+|'NERDCommentEmptyLines'|             Specifies if empty lines should be
+                                      commented (useful with regions).
+
+|'NERDCommentWholeLinesInVMode'|      Changes behaviour of visual comments.
+
+|'NERDCreateDefaultMappings'|         Turn the default mappings on/off.
+
+|'NERDCustomDelimiters'|              Add or override delimiters for any
+                                      filetypes.
+                                      
+|'NERDDefaultNesting'|                Tells the script to use nested comments
+                                      by default.
+                                      
+|'NERDMenuMode'|                      Specifies how the NERD commenter menu
+                                      will appear (if at all).
+                                      
+|'NERDLPlace'|                        Specifies what to use as the left
+                                      delimiter placeholder when nesting
+                                      comments.
+                                      
+|'NERDUsePlaceHolders'|               Specifies which filetypes may use
+                                      placeholders when nesting comments.
+                                      
+|'NERDRemoveAltComs'|                 Tells the script whether to remove
+                                      alternative comment delimiters when
+                                      uncommenting.
+                                      
+|'NERDRemoveExtraSpaces'|             Tells the script to always remove the
+                                      extra spaces when uncommenting
+                                      (regardless of whether NERDSpaceDelims
+                                      is set).
+                                      
+|'NERDRPlace'|                        Specifies what to use as the right
+                                      delimiter placeholder when nesting
+                                      comments.
+                                      
+|'NERDSpaceDelims'|                   Specifies whether to add extra spaces
+                                      around delimiters when commenting, and
+                                      whether to remove them when
+                                      uncommenting.
+                                      
+|'NERDTrimTrailingWhitespace'|        Specifies if trailing whitespace
+                                      should be deleted when uncommenting.
+
+|'NERDCompactSexyComs'|               Specifies whether to use the compact
+                                      style sexy comments.
+
+|'NERDDefaultAlign'|                  Specifies the default alignment to use,
+                                      one of 'none', 'left', 'start', or
+                                      'both'.
+
+|'NERDToggleCheckAllLines'|           Enable NERDCommenterToggle to check 
+                                      all selected lines is commented or not.
+
+------------------------------------------------------------------------------
+4.3 Options details                              *NERDCommenterOptionsDetails*
+
+To enable any of the below options you should put the given line in your
+~/.vimrc
+
+                                                       *'loaded_nerd_comments'*
+If this script is driving you insane you can turn it off by setting this
+option >
+    let loaded_nerd_comments=1
+<
+------------------------------------------------------------------------------
+                                                    *'NERDAllowAnyVisualDelims'*
+Values: 0 or 1.
+Default: 1.
+
+If set to 1 then, when doing a visual or visual-block comment (but not a
+visual-line comment), the script will choose the right delimiters to use for
+the comment. This means either using the current delimiters if they are
+multipart or using the alternative delimiters if THEY are multipart.  For
+example if we are editing the following java code: >
+    float foo = 1221;
+    float bar = 324;
+    System.out.println(foo * bar);
+<
+If we are using // comments and select the "foo" and "bar" in visual-block
+mode, as shown left below (where '|'s are used to represent the visual-block
+boundary), and comment it then the script will use the alternative delimiters
+as shown on the right: >
+
+    float |foo| = 1221;                   float /*foo*/ = 1221;
+    float |bar| = 324;                    float /*bar*/ = 324;
+    System.out.println(foo * bar);        System.out.println(foo * bar);
+<
+------------------------------------------------------------------------------
+                                                     *'NERDBlockComIgnoreEmpty'*
+Values: 0 or 1.
+Default: 1.
+
+This option  affects visual-block mode commenting. If this option is turned
+on, lines that begin outside the right boundary of the selection block will be
+ignored.
+
+For example, if you are commenting this chunk of c code in visual-block mode
+(where the '|'s are used to represent the visual-block boundary) >
+    #include <sys/types.h>
+    #include <unistd.h>
+    #include <stdio.h>
+   |int| main(){
+   |   | printf("SUCK THIS\n");
+   |   | while(1){
+   |   |     fork();
+   |   | }
+   |}  |
+<
+If NERDBlockComIgnoreEmpty=0 then this code will become: >
+    #include <sys/types.h>
+    #include <unistd.h>
+    #include <stdio.h>
+    /*int*/ main(){
+    /*   */ printf("SUCK THIS\n");
+    /*   */ while(1){
+    /*   */     fork();
+    /*   */ }
+    /*}  */
+<
+Otherwise, the code block would become: >
+    #include <sys/types.h>
+    #include <unistd.h>
+    #include <stdio.h>
+    /*int*/ main(){
+    printf("SUCK THIS\n");
+    while(1){
+        fork();
+    }
+    /*}  */
+<
+------------------------------------------------------------------------------
+                                                     *'NERDCommentEmptyLines'*
+Values: 0 or 1.
+Default: 0.
+
+This option affects commenting of empty lines. If this option is turned on,
+then empty lines will be commented as well. Useful when commenting regions of
+code.
+
+------------------------------------------------------------------------------
+                                                *'NERDCommentWholeLinesInVMode'*
+Values: 0, 1 or 2.
+Default: 0.
+
+By default the script tries to comment out exactly what is selected in visual
+mode (v). For example if you select and comment the following c code (using |
+to represent the visual boundary): >
+    in|t foo = 3;
+    int bar =| 9;
+    int baz = foo + bar;
+<
+This will result in: >
+    in/*t foo = 3;*/
+    /*int bar =*/ 9;
+    int baz = foo + bar;
+<
+But some people prefer it if the whole lines are commented like: >
+    /*int foo = 3;*/
+    /*int bar = 9;*/
+    int baz = foo + bar;
+<
+If you prefer the second option then stick this line in your vimrc: >
+    let NERDCommentWholeLinesInVMode=1
+<
+
+If the filetype you are editing only has no multipart delimiters (for example
+a shell script) and you hadn't set this option then the above would become >
+    in#t foo = 3;
+    #int bar = 9;
+<
+(where # is the comment delimiter) as this is the closest the script can
+come to commenting out exactly what was selected. If you prefer for whole
+lines to be commented out when there is no multipart delimiters but the EXACT
+text that was selected to be commented out if there IS multipart delimiters
+then stick the following line in your vimrc: >
+    let NERDCommentWholeLinesInVMode=2
+<
+
+Note that this option does not affect the behaviour of commenting in
+|visual-block| mode.
+
+------------------------------------------------------------------------------
+                                                 *'NERDCreateDefaultMappings'*
+Values: 0 or 1.
+Default: 1.
+
+If set to 0, none of the default mappings will be created.
+
+See also |NERDCommenterMappings|.
+
+------------------------------------------------------------------------------
+                                                      *'NERDCustomDelimiters'*
+Values: A map (format specified below).
+Default: {}
+
+Use this option if you have new filetypes you want the script to handle, or if
+you want to override the default delimiters of a filetype.
+
+Example: >
+    let g:NERDCustomDelimiters = {
+        \ 'ruby': { 'left': '#', 'leftAlt': 'FOO', 'rightAlt': 'BAR' },
+        \ 'grondle': { 'left': '{{', 'right': '}}' }
+    \ }
+<
+
+Here we override the delimiter settings for ruby and add FOO/BAR as alternative
+delimiters. We also add {{ and }} as delimiters for a new filetype called
+'grondle'.
+
+------------------------------------------------------------------------------
+                                                           *'NERDRemoveAltComs'*
+Values: 0 or 1.
+Default: 1.
+
+When uncommenting a line (for a filetype with an alternative commenting style)
+this option tells the script whether to look for, and remove, comment
+delimiters of the alternative style.
+
+For example, if you are editing a c++ file using // style comments and you go
+|<Leader>|cu on this line: >
+    /* This is a c++ comment baby! */
+<
+It will not be uncommented if the NERDRemoveAltComs is set to 0.
+
+------------------------------------------------------------------------------
+                                                       *'NERDRemoveExtraSpaces'*
+Values: 0 or 1.
+Default: 0.
+
+By default, the NERD commenter will remove spaces around comment delimiters if
+either:
+1. |'NERDSpaceDelims'| is set to 1.
+2. NERDRemoveExtraSpaces is set to 1.
+
+This means that if we have the following lines in a c code file: >
+    /* int foo = 5; */
+    /* int bar = 10; */
+    int baz = foo + bar
+<
+If either of the above conditions hold then if these lines are uncommented
+they will become: >
+    int foo = 5;
+    int bar = 10;
+    int baz = foo + bar
+<
+Otherwise they would become: >
+     int foo = 5;
+     int bar = 10;
+    int baz = foo + bar
+<
+
+Note: When using 'start' as the default alignment, the enabling of
+NERDRemoveExtraSpaces will still result in the removal of a space after the
+delimiter.  This can be undesirable since aligning the delimiters at the very
+start of the line (index 0) will usually result in spaces between the comment
+delimiters and the text which probably shouldn't be removed.  So when using
+'start' as the default alignment, take care to also disable
+NERDRemoveExtraSpaces.
+
+------------------------------------------------------------------------------
+                                                                  *'NERDLPlace'*
+                                                                  *'NERDRPlace'*
+Values: arbitrary string.
+Default:
+    NERDLPlace: "[>"
+    NERDRPlace: "<]"
+
+These options are used to control the strings used as place-holder delimiters.
+Place holder delimiters are used when performing nested commenting when the
+filetype supports commenting styles with both left and right delimiters.
+To set these options use lines like: >
+    let NERDLPlace="FOO"
+    let NERDRPlace="BAR"
+<
+Following the above example, if we have line of c code: >
+    /* int horse */
+<
+and we comment it with |<Leader>|cn it will be changed to: >
+    /*FOO int horse BAR*/
+<
+When we uncomment this line it will go back to what it was.
+
+------------------------------------------------------------------------------
+                                                                *'NERDMenuMode'*
+Values: 0, 1, 2, 3.
+Default: 3
+
+This option can take 4 values:
+    "0": Turns the menu off.
+    "1": Turns the 'comment' menu on with no menu shortcut.
+    "2": Turns the 'comment' menu on with <alt>-c as the shortcut.
+    "3": Turns the 'Plugin -> comment' menu on with <alt>-c as the shortcut.
+
+------------------------------------------------------------------------------
+                                                         *'NERDUsePlaceHolders'*
+Values: 0 or 1.
+Default 1.
+
+This option is used to specify whether place-holder delimiters should be used
+when creating a nested comment.
+
+------------------------------------------------------------------------------
+                                                             *'NERDSpaceDelims'*
+Values: 0 or 1.
+Default 0.
+
+Some people prefer a space after the left delimiter and before the right
+delimiter like this: >
+    /* int foo=2; */
+<
+as opposed to this: >
+    /*int foo=2;*/
+<
+If you want spaces to be added then set NERDSpaceDelims to 1 in your vimrc.
+
+See also |'NERDRemoveExtraSpaces'|.
+
+------------------------------------------------------------------------------
+                                                  *'NERDTrimTrailingWhitespace'*
+Values: 0 or 1.
+Default 0.
+
+When uncommenting an empty line some whitespace may be left as a result of
+alignment padding. With this option enabled any trailing whitespace will be
+deleted when uncommenting a line.
+
+------------------------------------------------------------------------------
+                                                             *'NERDDefaultAlign'*
+Values: 'none', 'left', 'start', 'both'
+Default 'none'.
+
+Specifies the default alignment to use when inserting comments.
+
+Note: When using 'start' as the default alignment be sure to disable
+NERDRemoveExtraSpaces.  See the note at the bottom of |NERDRemoveExtraSpaces|
+for more details.
+
+------------------------------------------------------------------------------
+                                                         *'NERDCompactSexyComs'*
+Values: 0 or 1.
+Default 0.
+
+Some people may want their sexy comments to be like this: >
+    /* Hi There!
+     * This is a sexy comment
+     * in c */
+<
+As opposed to like this: >
+    /*
+     * Hi There!
+     * This is a sexy comment
+     * in c
+     */
+<
+If this option is set to 1 then the top style will be used.
+
+------------------------------------------------------------------------------
+                                                          *'NERDDefaultNesting'*
+Values: 0 or 1.
+Default 1.
+
+When this option is set to 1, comments are nested automatically. That is, if
+you hit |<Leader>|cc on a line that is already commented it will be commented
+again.
+
+------------------------------------------------------------------------------
+                                                   *'NERDToggleCheckAllLines'*
+Values: 0 or 1.
+Default 0.
+
+When this option is set to 1, NERDCommenterToggle will check all selected line, 
+if there have oneline not be commented, then comment all lines.
+
+------------------------------------------------------------------------------
+                                                *'NERDDisableTabsInBlockComm'*
+Values: 0 or 1.
+Default 0.
+
+When this option is set to 1, NERDDisableTabsInBlockComm will not add
+whitespaces align the start location of the ending comment symbol with the
+end location of the starting comment symbol. For example, in Fortran, the new
+style will be as the following: >
+    close (inpt,iostat=ierr,iomsg=error_message)
+    call io_error(pname,input_fname,2,__LINE__,__FILE__,ierr,error_message)
+<
+to >
+    !===BEGIN===!
+    ! close (inpt,iostat=ierr,iomsg=error_message)
+    ! call io_error(pname,input_fname,2,__LINE__,__FILE__,ierr,error_message)
+    !===END===!
+<
+for the block comment style if customized comment symbols are set up in vimrc
+file by the following line >
+    let g:NERDCustomDelimiters = {
+    \ 'fortran':{'left':'!','leftAlt':'!===BEGIN===!','rightAlt':'!===END===!'}
+    \ }
+<
+
+------------------------------------------------------------------------------
+3.3 Default delimiter customisation               *NERDCommenterDefaultDelims*
+
+If you want the NERD commenter to use the alternative delimiters for a
+specific filetype by default then put a line of this form into your vimrc: >
+    let g:NERDAltDelims_<filetype> = 1
+<
+Example: java uses // style comments by default, but you want it to default to
+/* */ style comments instead. You would put this line in your vimrc: >
+    let g:NERDAltDelims_java = 1
+<
+
+See |NERDCommenterAltDelims| for switching commenting styles at runtime.
+
+==============================================================================
+5. Key mapping customisation                           *NERDCommenterMappings*
+
+To change a mapping just map another key combo to the internal <plug> mapping.
+For example, to remap the |NERDCommenterComment| mapping to ",omg" you would put
+this line in your vimrc: >
+    map ,omg <plug>NERDCommenterComment
+<
+This will stop the corresponding default mappings from being created.
+
+See the help for the mapping in question to see which <plug> mapping to
+map to.
+
+See also |'NERDCreateDefaultMappings'|.
+
+==============================================================================
+6. Interfaces                                        *NERDCommenterInterfaces*
+
+NERDCommentIsLineCommented({lineNo})            *NERDCommentIsLineCommented()*
+            Check if the line is a comment
+            Note this function checks if the line is **completely** a comment
+            Args:
+              {lineNo}:     the line number of the line to check
+            Return: Number, 1 if the line is a comment, 0 else
+
+
+NERDComment({mode}, {type})                                    *NERDComment()*
+            This function is a Wrapper for the main commenting functions
+
+            Args:
+              {mode}:       character indicating the mode in which the comment
+                            is requested:
+                            'n' for Normal mode, 'x' for Visual mode
+              {type}:       the type of commenting requested. Can be 'Sexy', 
+                            'Invert', 'Minimal', 'Toggle', 'AlignLeft', 
+                            'AlignBoth', 'Comment', 'Nested', 'ToEOL', 'Append',
+                            'Insert', 'Uncomment', 'Yank'
+
+
+NERDCommentIsCharCommented({line}, {col})       *NERDCommentIsCharCommented()*
+            Check if the character at [{line}, {col}] is inside a comment
+            Note the Comment delimeter it self is considered as part of the 
+            comment
+
+            Args:
+              {line}       the line number of the character
+              {col}        the column number of the character
+            Return: Number, 1 if the character is inside a comment, 0 else
+
+
+==============================================================================
+7. Issues with the script                                *NERDCommenterIssues*
+
+
+------------------------------------------------------------------------------
+7.1 Delimiter detection heuristics                   *NERDCommenterHeuristics*
+
+Heuristics are used to distinguish the real comment delimiters
+
+Because we have comment mappings that place delimiters in the middle of lines,
+removing comment delimiters is a bit tricky. This is because if comment
+delimiters appear in a line doesn't mean they really ARE delimiters. For
+example, Java uses // comments but the line >
+    System.out.println("//");
+<
+clearly contains no real comment delimiters.
+
+To distinguish between ``real'' comment delimiters and ``fake'' ones we use a
+set of heuristics. For example, one such heuristic states that any comment
+delimiter that has an odd number of non-escaped " characters both preceding
+and following it on the line is not a comment because it is probably part of a
+string. These heuristics, while usually pretty accurate, will not work for all
+cases.
+
+------------------------------------------------------------------------------
+7.2 Nesting issues                                      *NERDCommenterNesting*
+
+If we have some line of code like this: >
+    /*int foo */ = /*5 + 9;*/
+<
+This will not be uncommented legally. The NERD commenter will remove the
+"outer most" delimiters so the line will become: >
+    int foo */ = /*5 + 9;
+<
+which almost certainly will not be what you want. Nested sets of comments will
+uncomment fine though. E.g.: >
+    /*int/* foo =*/ 5 + 9;*/
+<
+will become: >
+    int/* foo =*/ 5 + 9;
+<
+(Note that in the above examples I have deliberately not used place holders
+for simplicity)
+
+==============================================================================
+8. About                                                  *NERDCommenterAbout*
+
+This plugin was originally written in 2007 by Martin Grenfell, aka @scrooloose
+on Github: https://github.com/scrooloose
+
+Since 2016 it has been maintained primarily by Caleb Maclennan, aka @alerque
+on Github: https://github.com/alerque
+
+Lots of features and many of the supported filetypes have come from the
+community, see |NERDCommenterCredits|.
+
+Additional file type support, bug fixes, and new feature contributons are all
+welcome, please send them as Pull Requests on Github. If you can't contribute
+yourself please also feel free to open issues to report problems or request
+features: https://github.com/preservim/nerdcommenter
+
+==============================================================================
+9. Changelog                                          *NERDCommenterChangelog*
+
+See the included CHANGELOG.md file or the Github Releases page for the latest
+info on tagged releases. https://github.com/preservim/nerdcommenter/releases
+
+The `master` branch is considered stable and will have the latest filetype
+support and bugfixes.
+
+==============================================================================
+10. Credits                                              *NERDCommenterCredits*
+
+Well over 100 people have contributed towards this plugin, it's functions, and
+specific filetype support. Please check out the up do date list of all
+contributors on Github:
+
+https://github.com/preservim/nerdcommenter/graphs/contributors
+
+==============================================================================
+11. License                                             *NERDCommenterLicense*
+
+NERD Commenter is released under the Creative-Commons CCO 1.0 Universal
+license. See the included LICENE file for details.

+ 61 - 0
vimfiles/bundle/nerdcommenter/doc/tags

@@ -0,0 +1,61 @@
+'NERDAllowAnyVisualDelims'	nerdcommenter.txt	/*'NERDAllowAnyVisualDelims'*
+'NERDBlockComIgnoreEmpty'	nerdcommenter.txt	/*'NERDBlockComIgnoreEmpty'*
+'NERDCommentEmptyLines'	nerdcommenter.txt	/*'NERDCommentEmptyLines'*
+'NERDCommentWholeLinesInVMode'	nerdcommenter.txt	/*'NERDCommentWholeLinesInVMode'*
+'NERDCompactSexyComs'	nerdcommenter.txt	/*'NERDCompactSexyComs'*
+'NERDCreateDefaultMappings'	nerdcommenter.txt	/*'NERDCreateDefaultMappings'*
+'NERDCustomDelimiters'	nerdcommenter.txt	/*'NERDCustomDelimiters'*
+'NERDDefaultAlign'	nerdcommenter.txt	/*'NERDDefaultAlign'*
+'NERDDefaultNesting'	nerdcommenter.txt	/*'NERDDefaultNesting'*
+'NERDDisableTabsInBlockComm'	nerdcommenter.txt	/*'NERDDisableTabsInBlockComm'*
+'NERDLPlace'	nerdcommenter.txt	/*'NERDLPlace'*
+'NERDMenuMode'	nerdcommenter.txt	/*'NERDMenuMode'*
+'NERDRPlace'	nerdcommenter.txt	/*'NERDRPlace'*
+'NERDRemoveAltComs'	nerdcommenter.txt	/*'NERDRemoveAltComs'*
+'NERDRemoveExtraSpaces'	nerdcommenter.txt	/*'NERDRemoveExtraSpaces'*
+'NERDSpaceDelims'	nerdcommenter.txt	/*'NERDSpaceDelims'*
+'NERDToggleCheckAllLines'	nerdcommenter.txt	/*'NERDToggleCheckAllLines'*
+'NERDTrimTrailingWhitespace'	nerdcommenter.txt	/*'NERDTrimTrailingWhitespace'*
+'NERDUsePlaceHolders'	nerdcommenter.txt	/*'NERDUsePlaceHolders'*
+'loaded_nerd_comments'	nerdcommenter.txt	/*'loaded_nerd_comments'*
+NERDComment()	nerdcommenter.txt	/*NERDComment()*
+NERDCommentIsCharCommented()	nerdcommenter.txt	/*NERDCommentIsCharCommented()*
+NERDCommentIsLineCommented()	nerdcommenter.txt	/*NERDCommentIsLineCommented()*
+NERDCommenter	nerdcommenter.txt	/*NERDCommenter*
+NERDCommenterAbout	nerdcommenter.txt	/*NERDCommenterAbout*
+NERDCommenterAlignBoth	nerdcommenter.txt	/*NERDCommenterAlignBoth*
+NERDCommenterAlignLeft	nerdcommenter.txt	/*NERDCommenterAlignLeft*
+NERDCommenterAltDelims	nerdcommenter.txt	/*NERDCommenterAltDelims*
+NERDCommenterAppend	nerdcommenter.txt	/*NERDCommenterAppend*
+NERDCommenterChangelog	nerdcommenter.txt	/*NERDCommenterChangelog*
+NERDCommenterComment	nerdcommenter.txt	/*NERDCommenterComment*
+NERDCommenterContents	nerdcommenter.txt	/*NERDCommenterContents*
+NERDCommenterCredits	nerdcommenter.txt	/*NERDCommenterCredits*
+NERDCommenterDefaultDelims	nerdcommenter.txt	/*NERDCommenterDefaultDelims*
+NERDCommenterFunctionality	nerdcommenter.txt	/*NERDCommenterFunctionality*
+NERDCommenterFunctionalityDetails	nerdcommenter.txt	/*NERDCommenterFunctionalityDetails*
+NERDCommenterFunctionalitySummary	nerdcommenter.txt	/*NERDCommenterFunctionalitySummary*
+NERDCommenterHeuristics	nerdcommenter.txt	/*NERDCommenterHeuristics*
+NERDCommenterHooks	nerdcommenter.txt	/*NERDCommenterHooks*
+NERDCommenterInsert	nerdcommenter.txt	/*NERDCommenterInsert*
+NERDCommenterInstallation	nerdcommenter.txt	/*NERDCommenterInstallation*
+NERDCommenterInterfaces	nerdcommenter.txt	/*NERDCommenterInterfaces*
+NERDCommenterInvert	nerdcommenter.txt	/*NERDCommenterInvert*
+NERDCommenterIssues	nerdcommenter.txt	/*NERDCommenterIssues*
+NERDCommenterLeader	nerdcommenter.txt	/*NERDCommenterLeader*
+NERDCommenterLicense	nerdcommenter.txt	/*NERDCommenterLicense*
+NERDCommenterMappings	nerdcommenter.txt	/*NERDCommenterMappings*
+NERDCommenterMinimal	nerdcommenter.txt	/*NERDCommenterMinimal*
+NERDCommenterNERDComment	nerdcommenter.txt	/*NERDCommenterNERDComment*
+NERDCommenterNested	nerdcommenter.txt	/*NERDCommenterNested*
+NERDCommenterNesting	nerdcommenter.txt	/*NERDCommenterNesting*
+NERDCommenterOptions	nerdcommenter.txt	/*NERDCommenterOptions*
+NERDCommenterOptionsDetails	nerdcommenter.txt	/*NERDCommenterOptionsDetails*
+NERDCommenterOptionsSummary	nerdcommenter.txt	/*NERDCommenterOptionsSummary*
+NERDCommenterSexy	nerdcommenter.txt	/*NERDCommenterSexy*
+NERDCommenterSexyComments	nerdcommenter.txt	/*NERDCommenterSexyComments*
+NERDCommenterToEOL	nerdcommenter.txt	/*NERDCommenterToEOL*
+NERDCommenterToggle	nerdcommenter.txt	/*NERDCommenterToggle*
+NERDCommenterUncomment	nerdcommenter.txt	/*NERDCommenterUncomment*
+NERDCommenterYank	nerdcommenter.txt	/*NERDCommenterYank*
+nerdcommenter.txt	nerdcommenter.txt	/*nerdcommenter.txt*

+ 131 - 0
vimfiles/bundle/nerdcommenter/plugin/nerdcommenter.vim

@@ -0,0 +1,131 @@
+if exists('loaded_nerd_comments')
+    finish
+endif
+if v:version < 700
+    echoerr "NERDCommenter: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!"
+    finish
+endif
+let loaded_nerd_comments = 1
+
+" Function: s:InitVariable() function
+" This function is used to initialise a given variable to a given value. The
+" variable is only initialised if it does not exist prior
+"
+" Args:
+"   -var: the name of the var to be initialised
+"   -value: the value to initialise var to
+"
+" Returns:
+"   0
+function s:InitVariable(var, value)
+    if !exists(a:var)
+        execute 'let ' . a:var . ' = ' . string(a:value)
+    endif
+endfunction
+
+" Section: variable initialization
+call s:InitVariable('g:NERDAllowAnyVisualDelims', 1)
+call s:InitVariable('g:NERDBlockComIgnoreEmpty', 0)
+call s:InitVariable('g:NERDCommentWholeLinesInVMode', 0)
+call s:InitVariable('g:NERDCommentEmptyLines', 0)
+call s:InitVariable('g:NERDCompactSexyComs', 0)
+call s:InitVariable('g:NERDCreateDefaultMappings', 1)
+call s:InitVariable('g:NERDDefaultNesting', 1)
+call s:InitVariable('g:NERDMenuMode', 3)
+call s:InitVariable('g:NERDLPlace', '[>')
+call s:InitVariable('g:NERDUsePlaceHolders', 1)
+call s:InitVariable('g:NERDRemoveAltComs', 1)
+call s:InitVariable('g:NERDRemoveExtraSpaces', 0)
+call s:InitVariable('g:NERDRPlace', '<]')
+call s:InitVariable('g:NERDSpaceDelims', 0)
+call s:InitVariable('g:NERDDefaultAlign', 'none')
+call s:InitVariable('g:NERDTrimTrailingWhitespace', 0)
+call s:InitVariable('g:NERDToggleCheckAllLines', 0)
+call s:InitVariable('g:NERDDisableTabsInBlockComm', 0)
+call s:InitVariable('g:NERDSuppressWarnings', 0)
+
+" Section: Comment mapping and menu item setup
+" ===========================================================================
+
+" Create menu items for the specified modes.  If a:combo is not empty, then
+" also define mappings and show a:combo in the menu items.
+function! s:CreateMaps(modes, target, desc, combo)
+    " Build up a map command like
+    " 'noremap <silent> <Plug>NERDCommenterComment :call nerdcommenter#Comment("n", "Comment")'
+    let plug = '<Plug>NERDCommenter' . a:target
+    let plug_start = 'noremap <silent> ' . plug . ' :call nerdcommenter#Comment("'
+    let plug_end = '", "' . a:target . '")<CR>'
+    " Build up a menu command like
+    " 'menu <silent> comment.Comment<Tab>\\cc <Plug>NERDCommenterComment'
+    let menuRoot = get(['', 'comment', '&comment', '&Plugin.&comment', '&Plugin.Nerd\ &Commenter'],
+                \ g:NERDMenuMode, '')
+    let menu_command = 'menu <silent> ' . menuRoot . '.' . escape(a:desc, ' ')
+    if strlen(a:combo)
+        let leader = exists('g:mapleader') ? g:mapleader : '\'
+        let menu_command .= '<Tab>' . escape(leader, '\') . a:combo
+    endif
+    let menu_command .= ' ' . (strlen(a:combo) ? plug : a:target)
+    " Execute the commands built above for each requested mode.
+    for mode in (a:modes ==# '') ? [''] : split(a:modes, '\zs')
+        if strlen(a:combo)
+            execute mode . plug_start . mode . plug_end
+            if g:NERDCreateDefaultMappings && !hasmapto(plug, mode)
+                execute mode . 'map <leader>' . a:combo . ' ' . plug
+            endif
+        endif
+        " Check if the user wants the menu to be displayed.
+        if g:NERDMenuMode !=# 0
+            execute mode . menu_command
+        endif
+    endfor
+endfunction
+
+call s:CreateMaps('nx', 'Comment',    'Comment', 'cc')
+call s:CreateMaps('nx', 'Toggle',     'Toggle', 'c<Space>')
+call s:CreateMaps('nx', 'Minimal',    'Minimal', 'cm')
+call s:CreateMaps('nx', 'Nested',     'Nested', 'cn')
+call s:CreateMaps('n',  'ToEOL',      'To EOL', 'c$')
+call s:CreateMaps('nx', 'Invert',     'Invert', 'ci')
+call s:CreateMaps('nx', 'Sexy',       'Sexy', 'cs')
+call s:CreateMaps('nx', 'Yank',       'Yank then comment', 'cy')
+call s:CreateMaps('n',  'Append',     'Append', 'cA')
+call s:CreateMaps('',   ':',          '-Sep-', '')
+call s:CreateMaps('nx', 'AlignLeft',  'Left aligned', 'cl')
+call s:CreateMaps('nx', 'AlignBoth',  'Left and right aligned', 'cb')
+call s:CreateMaps('',   ':',          '-Sep2-', '')
+call s:CreateMaps('nx', 'Uncomment',  'Uncomment', 'cu')
+call s:CreateMaps('n',  'AltDelims',  'Switch Delimiters', 'ca')
+call s:CreateMaps('i',  'Insert',     'Insert Comment Here', '')
+call s:CreateMaps('',   ':',          '-Sep3-', '')
+call s:CreateMaps('',   ':help NERDCommenterContents<CR>', 'Help', '')
+
+" Shim functions so old code gets passed through to the autoload functions
+function! NERDComment(mode, type) range
+    if !g:NERDSuppressWarnings
+        echom 'Function NERDComment() has been deprecated, please use nerdcommenter#Comment() instead'
+    endif
+	if a:firstline != a:lastline
+		echoerr "Sorry! We can't pass a range through this deprecation shim, please update your code."
+		return v:false
+	endif
+    return nerdcommenter#Comment(a:mode, a:type)
+endfunction
+
+function! NERDCommentIsLineCommented(lineNo)
+    if !g:NERDSuppressWarnings
+        echom 'Function NERDCommentIsLineCommented() has been deprecated, please use nerdcommenter#IsLineCommented() instead'
+    endif
+    return nerdcommenter#IsLineCommented(a:lineNo)
+endfunction
+
+function! NERDCommentIsCharCommented(line, col)
+    if !g:NERDSuppressWarnings
+        echom 'Function NERDCommentIsCharCommented() has been deprecated, please use nerdcommenter#IsCharCommented() instead'
+    endif
+    return nerdcommenter#IsCharCommented(a:line, a:col)
+endfunction
+
+inoremap <silent> <Plug>NERDCommenterInsert <C-\><C-O>:call nerdcommenter#Comment('i', "Insert")<CR>
+
+" switch to/from alternative delimiters (does not use wrapper function)
+nnoremap <Plug>NERDCommenterAltDelims :call nerdcommenter#SwitchToAlternativeDelimiters(1)<CR>

+ 249 - 0
vimfiles/bundle/nerdtree/autoload/nerdtree.vim

@@ -0,0 +1,249 @@
+if exists('g:loaded_nerdtree_autoload')
+    finish
+endif
+let g:loaded_nerdtree_autoload = 1
+
+let s:rootNERDTreePath = resolve(expand('<sfile>:p:h:h'))
+
+"FUNCTION: nerdtree#version(...) {{{1
+"  If any value is given as an argument, the entire line of text from the
+"  change log is shown for the current version; otherwise, only the version
+"  number is shown.
+function! nerdtree#version(...) abort
+    let l:text = 'Unknown'
+    try
+        let l:changelog = readfile(join([s:rootNERDTreePath, 'CHANGELOG.md'], nerdtree#slash()))
+        let l:line = 0
+        while l:line <= len(l:changelog)
+            if l:changelog[l:line] =~# '\d\+\.\d\+'
+                let l:text = substitute(l:changelog[l:line], '.*\(\d\+.\d\+\).*', '\1', '')
+                let l:text .= substitute(l:changelog[l:line+1], '^.\{-}\(\.\d\+\).\{-}:\(.*\)', a:0>0 ? '\1:\2' : '\1', '')
+                break
+            endif
+            let l:line += 1
+        endwhile
+    catch
+    endtry
+    return l:text
+endfunction
+
+" SECTION: General Functions {{{1
+"============================================================
+
+" FUNCTION: nerdtree#closeTreeOnOpen() {{{2
+function! nerdtree#closeTreeOnOpen() abort
+    return g:NERDTreeQuitOnOpen == 1 || g:NERDTreeQuitOnOpen == 3
+endfunction
+
+" FUNCTION: nerdtree#closeBookmarksOnOpen() {{{2
+function! nerdtree#closeBookmarksOnOpen() abort
+    return g:NERDTreeQuitOnOpen == 2 || g:NERDTreeQuitOnOpen == 3
+endfunction
+
+" FUNCTION: nerdtree#slash() {{{2
+" Return the path separator used by the underlying file system.  Special
+" consideration is taken for the use of the 'shellslash' option on Windows
+" systems.
+function! nerdtree#slash() abort
+    if nerdtree#runningWindows()
+        if exists('+shellslash') && &shellslash
+            return '/'
+        endif
+
+        return '\'
+    endif
+
+    return '/'
+endfunction
+
+"FUNCTION: nerdtree#checkForBrowse(dir) {{{2
+"inits a window tree in the current buffer if appropriate
+function! nerdtree#checkForBrowse(dir) abort
+    if !isdirectory(a:dir)
+        return
+    endif
+
+    if s:reuseWin(a:dir)
+        return
+    endif
+
+    call g:NERDTreeCreator.CreateWindowTree(a:dir)
+endfunction
+
+"FUNCTION: s:reuseWin(dir) {{{2
+"finds a NERDTree buffer with root of dir, and opens it.
+function! s:reuseWin(dir) abort
+    let path = g:NERDTreePath.New(fnamemodify(a:dir, ':p'))
+
+    for i in range(1, bufnr('$'))
+        unlet! nt
+        let nt = getbufvar(i, 'NERDTree')
+        if empty(nt)
+            continue
+        endif
+
+        if nt.isWinTree() && nt.root.path.equals(path)
+            call nt.setPreviousBuf(bufnr('#'))
+            exec 'buffer ' . i
+            return 1
+        endif
+    endfor
+
+    return 0
+endfunction
+
+" FUNCTION: nerdtree#completeBookmarks(A,L,P) {{{2
+" completion function for the bookmark commands
+function! nerdtree#completeBookmarks(A,L,P) abort
+    return filter(g:NERDTreeBookmark.BookmarkNames(), 'v:val =~# "^' . a:A . '"')
+endfunction
+
+"FUNCTION: nerdtree#compareNodes(n1, n2) {{{2
+function! nerdtree#compareNodes(n1, n2) abort
+    return nerdtree#compareNodePaths(a:n1.path, a:n2.path)
+endfunction
+
+"FUNCTION: nerdtree#compareNodePaths(p1, p2) {{{2
+function! nerdtree#compareNodePaths(p1, p2) abort
+    let sortKey1 = a:p1.getSortKey()
+    let sortKey2 = a:p2.getSortKey()
+    let i = 0
+    while i < min([len(sortKey1), len(sortKey2)])
+        " Compare chunks upto common length.
+        " If chunks have different type, the one which has
+        " integer type is the lesser.
+        if type(sortKey1[i]) == type(sortKey2[i])
+            if sortKey1[i] <# sortKey2[i]
+                return - 1
+            elseif sortKey1[i] ># sortKey2[i]
+                return 1
+            endif
+        elseif type(sortKey1[i]) == type(0)
+            return -1
+        elseif type(sortKey2[i]) == type(0)
+            return 1
+        endif
+        let i += 1
+    endwhile
+
+    " Keys are identical upto common length.
+    " The key which has smaller chunks is the lesser one.
+    if len(sortKey1) < len(sortKey2)
+        return -1
+    elseif len(sortKey1) > len(sortKey2)
+        return 1
+    else
+        return 0
+    endif
+endfunction
+
+" FUNCTION: nerdtree#deprecated(func, [msg]) {{{2
+" Issue a deprecation warning for a:func. If a second arg is given, use this
+" as the deprecation message
+function! nerdtree#deprecated(func, ...) abort
+    let msg = a:0 ? a:func . ' ' . a:1 : a:func . ' is deprecated'
+
+    if !exists('s:deprecationWarnings')
+        let s:deprecationWarnings = {}
+    endif
+    if !has_key(s:deprecationWarnings, a:func)
+        let s:deprecationWarnings[a:func] = 1
+        echomsg msg
+    endif
+endfunction
+
+" FUNCTION: nerdtree#exec(cmd, ignoreAll) {{{2
+" Same as :exec cmd but, if ignoreAll is TRUE, set eventignore=all for the duration
+function! nerdtree#exec(cmd, ignoreAll) abort
+    let old_ei = &eventignore
+    if a:ignoreAll
+        set eventignore=all
+    endif
+    try
+        exec a:cmd
+    finally
+        let &eventignore = old_ei
+    endtry
+endfunction
+
+" FUNCTION: nerdtree#has_opt(options, name) {{{2
+function! nerdtree#has_opt(options, name) abort
+    return has_key(a:options, a:name) && a:options[a:name] ==# 1
+endfunction
+
+" FUNCTION: nerdtree#loadClassFiles() {{{2
+function! nerdtree#loadClassFiles() abort
+    runtime lib/nerdtree/path.vim
+    runtime lib/nerdtree/menu_controller.vim
+    runtime lib/nerdtree/menu_item.vim
+    runtime lib/nerdtree/key_map.vim
+    runtime lib/nerdtree/bookmark.vim
+    runtime lib/nerdtree/tree_file_node.vim
+    runtime lib/nerdtree/tree_dir_node.vim
+    runtime lib/nerdtree/opener.vim
+    runtime lib/nerdtree/creator.vim
+    runtime lib/nerdtree/flag_set.vim
+    runtime lib/nerdtree/nerdtree.vim
+    runtime lib/nerdtree/ui.vim
+    runtime lib/nerdtree/event.vim
+    runtime lib/nerdtree/notifier.vim
+endfunction
+
+" FUNCTION: nerdtree#postSourceActions() {{{2
+function! nerdtree#postSourceActions() abort
+    call g:NERDTreeBookmark.CacheBookmarks(1)
+    call nerdtree#ui_glue#createDefaultBindings()
+
+    "load all nerdtree plugins
+    runtime! nerdtree_plugin/**/*.vim
+endfunction
+
+"FUNCTION: nerdtree#runningWindows(dir) {{{2
+function! nerdtree#runningWindows() abort
+    return has('win16') || has('win32') || has('win64')
+endfunction
+
+"FUNCTION: nerdtree#runningCygwin(dir) {{{2
+function! nerdtree#runningCygwin() abort
+    return has('win32unix')
+endfunction
+
+" SECTION: View Functions {{{1
+"============================================================
+
+"FUNCTION: nerdtree#echo  {{{2
+"A wrapper for :echo. Appends 'NERDTree:' on the front of all messages
+"
+"Args:
+"msg: the message to echo
+function! nerdtree#echo(msg) abort
+    redraw
+    echomsg empty(a:msg) ? '' : ('NERDTree: ' . a:msg)
+endfunction
+
+"FUNCTION: nerdtree#echoError {{{2
+"Wrapper for nerdtree#echo, sets the message type to errormsg for this message
+"Args:
+"msg: the message to echo
+function! nerdtree#echoError(msg) abort
+    echohl errormsg
+    call nerdtree#echo(a:msg)
+    echohl normal
+endfunction
+
+"FUNCTION: nerdtree#echoWarning {{{2
+"Wrapper for nerdtree#echo, sets the message type to warningmsg for this message
+"Args:
+"msg: the message to echo
+function! nerdtree#echoWarning(msg) abort
+    echohl warningmsg
+    call nerdtree#echo(a:msg)
+    echohl normal
+endfunction
+
+"FUNCTION: nerdtree#renderView {{{2
+function! nerdtree#renderView() abort
+    call b:NERDTree.render()
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:

+ 732 - 0
vimfiles/bundle/nerdtree/autoload/nerdtree/ui_glue.vim

@@ -0,0 +1,732 @@
+if exists('g:loaded_nerdtree_ui_glue_autoload')
+    finish
+endif
+let g:loaded_nerdtree_ui_glue_autoload = 1
+
+" FUNCTION: nerdtree#ui_glue#createDefaultBindings() {{{1
+function! nerdtree#ui_glue#createDefaultBindings() abort
+    let s = '<SNR>' . s:SID() . '_'
+
+    call NERDTreeAddKeyMap({ 'key': '<MiddleMouse>', 'scope': 'all', 'callback': s . 'handleMiddleMouse' })
+    call NERDTreeAddKeyMap({ 'key': '<LeftRelease>', 'scope': 'all', 'callback': s.'handleLeftClick' })
+    call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': 'DirNode', 'callback': s.'activateDirNode' })
+    call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': 'FileNode', 'callback': s.'activateFileNode' })
+    call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': 'Bookmark', 'callback': s.'activateBookmark' })
+    call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': 'all', 'callback': s.'activateAll' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'FileNode', 'callback': s.'customOpenFile'})
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'DirNode', 'callback': s.'customOpenDir'})
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'Bookmark', 'callback': s.'customOpenBookmark'})
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'all', 'callback': s.'activateAll' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': 'DirNode', 'callback': s.'activateDirNode' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': 'FileNode', 'callback': s.'activateFileNode' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': 'Bookmark', 'callback': s.'activateBookmark' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': 'Bookmark', 'callback': s.'previewBookmark' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': 'all', 'callback': s.'activateAll' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': 'FileNode', 'callback': s.'openHSplit' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': 'Bookmark', 'callback': s.'openHSplitBookmark' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': 'FileNode', 'callback': s.'openVSplit' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': 'Bookmark', 'callback': s.'openVSplitBookmark' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': 'FileNode', 'callback': s.'previewNodeCurrent' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': 'FileNode', 'callback': s.'previewNodeHSplit' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': 'Bookmark', 'callback': s.'previewNodeHSplitBookmark' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': 'FileNode', 'callback': s.'previewNodeVSplit' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': 'Bookmark', 'callback': s.'previewNodeVSplitBookmark' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenRecursively, 'scope': 'DirNode', 'callback': s.'openNodeRecursively' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdir, 'scope': 'all', 'callback': s . 'upDirCurrentRootClosed' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdirKeepOpen, 'scope': 'all', 'callback': s . 'upDirCurrentRootOpen' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChangeRoot, 'scope': 'Node', 'callback': s . 'chRoot' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChdir, 'scope': 'Node', 'callback': s.'chCwd' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapQuit, 'scope': 'all', 'callback': s.'closeTreeWindow' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCWD, 'scope': 'all', 'callback': 'nerdtree#ui_glue#chRootCwd' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefreshRoot, 'scope': 'all', 'callback': s.'refreshRoot' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefresh, 'scope': 'Node', 'callback': s.'refreshCurrent' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapHelp, 'scope': 'all', 'callback': s.'displayHelp' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleZoom, 'scope': 'all', 'callback': s.'toggleZoom' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleHidden, 'scope': 'all', 'callback': s.'toggleShowHidden' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFilters, 'scope': 'all', 'callback': s.'toggleIgnoreFilter' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFiles, 'scope': 'all', 'callback': s.'toggleShowFiles' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleBookmarks, 'scope': 'all', 'callback': s.'toggleShowBookmarks' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseDir, 'scope': 'Node', 'callback': s.'closeCurrentDir' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseChildren, 'scope': 'DirNode', 'callback': s.'closeChildren' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapMenu, 'scope': 'Node', 'callback': s.'showMenu' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpParent, 'scope': 'Node', 'callback': s.'jumpToParent' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpFirstChild, 'scope': 'Node', 'callback': s.'jumpToFirstChild' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpLastChild, 'scope': 'Node', 'callback': s.'jumpToLastChild' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpRoot, 'scope': 'all', 'callback': s.'jumpToRoot' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpNextSibling, 'scope': 'Node', 'callback': s.'jumpToNextSibling' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpPrevSibling, 'scope': 'Node', 'callback': s.'jumpToPrevSibling' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': 'Node', 'callback': s . 'openInNewTab' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': 'Node', 'callback': s . 'openInNewTabSilent' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': 'Bookmark', 'callback': s . 'openInNewTab' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': 'Bookmark', 'callback': s . 'openInNewTabSilent' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenExpl, 'scope': 'DirNode', 'callback': s.'openExplorer' })
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenExpl, 'scope': 'FileNode', 'callback': s.'openExplorer' })
+
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapDeleteBookmark, 'scope': 'Bookmark', 'callback': s.'deleteBookmark' })
+endfunction
+
+
+"SECTION: Interface bindings {{{1
+"============================================================
+
+"FUNCTION: s:customOpenFile() {{{1
+" Open file node with the 'custom' key, initially <CR>.
+function! s:customOpenFile(node) abort
+    call a:node.activate(s:initCustomOpenArgs().file)
+endfunction
+
+"FUNCTION: s:customOpenDir() {{{1
+" Open directory node with the 'custom' key, initially <CR>.
+function! s:customOpenDir(node) abort
+    call s:activateDirNode(a:node, s:initCustomOpenArgs().dir)
+endfunction
+
+"FUNCTION: s:customOpenBookmark() {{{1
+" Open bookmark node with the 'custom' key, initially <CR>.
+function! s:customOpenBookmark(node) abort
+    if a:node.path.isDirectory
+        call a:node.activate(b:NERDTree, s:initCustomOpenArgs().dir)
+    else
+        call a:node.activate(b:NERDTree, s:initCustomOpenArgs().file)
+    endif
+endfunction
+
+"FUNCTION: s:initCustomOpenArgs() {{{1
+function! s:initCustomOpenArgs() abort
+    let l:defaultOpenArgs = {'file': {'reuse': 'all', 'where': 'p', 'keepopen':!nerdtree#closeTreeOnOpen()}, 'dir': {}}
+    try
+        let g:NERDTreeCustomOpenArgs = get(g:, 'NERDTreeCustomOpenArgs', {})
+        call  extend(g:NERDTreeCustomOpenArgs, l:defaultOpenArgs, 'keep')
+    catch /^Vim(\a\+):E712:/
+        call nerdtree#echoWarning('g:NERDTreeCustomOpenArgs is not set properly. Using default value.')
+        let g:NERDTreeCustomOpenArgs = l:defaultOpenArgs
+    finally
+        return g:NERDTreeCustomOpenArgs
+    endtry
+endfunction
+
+"FUNCTION: s:activateAll() {{{1
+"handle the user activating the updir line
+function! s:activateAll() abort
+    if getline('.') ==# g:NERDTreeUI.UpDirLine()
+        return nerdtree#ui_glue#upDir(0)
+    endif
+endfunction
+
+" FUNCTION: s:activateDirNode(directoryNode, options) {{{1
+" Open a directory with optional options
+function! s:activateDirNode(directoryNode, ...) abort
+
+    if a:directoryNode.isRoot() && a:directoryNode.isOpen
+        call nerdtree#echo('cannot close tree root')
+        return
+    endif
+
+    call a:directoryNode.activate((a:0 > 0) ? a:1 : {})
+endfunction
+
+"FUNCTION: s:activateFileNode() {{{1
+"handle the user activating a tree node
+function! s:activateFileNode(node) abort
+    call a:node.activate({'reuse': 'all', 'where': 'p', 'keepopen': !nerdtree#closeTreeOnOpen()})
+endfunction
+
+"FUNCTION: s:activateBookmark(bookmark) {{{1
+"handle the user activating a bookmark
+function! s:activateBookmark(bm) abort
+    call a:bm.activate(b:NERDTree, !a:bm.path.isDirectory ? {'where': 'p', 'keepopen': !nerdtree#closeTreeOnOpen()} : {})
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#bookmarkNode(name) {{{1
+" Associate the current node with the given name
+function! nerdtree#ui_glue#bookmarkNode(...) abort
+    let currentNode = g:NERDTreeFileNode.GetSelected()
+    if currentNode !=# {}
+        let name = a:1
+        if empty(name)
+            let name = currentNode.path.getLastPathComponent(0)
+        endif
+        try
+            call currentNode.bookmark(name)
+            call b:NERDTree.render()
+        catch /^NERDTree.IllegalBookmarkNameError/
+            call nerdtree#echo('bookmark names must not contain spaces')
+        endtry
+    else
+        call nerdtree#echo('select a node first')
+    endif
+endfunction
+
+" FUNCTION: s:chCwd(node) {{{1
+function! s:chCwd(node) abort
+    try
+        call a:node.path.changeToDir()
+    catch /^NERDTree.PathChangeError/
+        call nerdtree#echoWarning('could not change cwd')
+    endtry
+endfunction
+
+" FUNCTION: s:chRoot(node) {{{1
+" changes the current root to the selected one
+function! s:chRoot(node) abort
+    call b:NERDTree.changeRoot(a:node)
+endfunction
+
+" FUNCTION: s:nerdtree#ui_glue#chRootCwd() {{{1
+" Change the NERDTree root to match the current working directory.
+function! nerdtree#ui_glue#chRootCwd() abort
+    NERDTreeCWD
+endfunction
+
+" FUNCTION: nnerdtree#ui_glue#clearBookmarks(bookmarks) {{{1
+function! nerdtree#ui_glue#clearBookmarks(bookmarks) abort
+    if a:bookmarks ==# ''
+        let currentNode = g:NERDTreeFileNode.GetSelected()
+        if currentNode !=# {}
+            call currentNode.clearBookmarks()
+        endif
+    else
+        for name in split(a:bookmarks, ' ')
+            let bookmark = g:NERDTreeBookmark.BookmarkFor(name)
+            call bookmark.delete()
+        endfor
+    endif
+    call b:NERDTree.root.refresh()
+    call b:NERDTree.render()
+endfunction
+
+" FUNCTION: s:closeChildren(node) {{{1
+" closes all childnodes of the current node
+function! s:closeChildren(node) abort
+    call a:node.closeChildren()
+    call b:NERDTree.render()
+    call a:node.putCursorHere(0, 0)
+endfunction
+
+" FUNCTION: s:closeCurrentDir(node) {{{1
+" Close the parent directory of the current node.
+function! s:closeCurrentDir(node) abort
+
+    if a:node.isRoot()
+        call nerdtree#echo('cannot close parent of tree root')
+        return
+    endif
+
+    let l:parent = a:node.parent
+
+    while l:parent.isCascadable()
+        let l:parent = l:parent.parent
+    endwhile
+
+    if l:parent.isRoot()
+        call nerdtree#echo('cannot close tree root')
+        return
+    endif
+
+    call l:parent.close()
+    call b:NERDTree.render()
+    call l:parent.putCursorHere(0, 0)
+endfunction
+
+" FUNCTION: s:closeTreeWindow() {{{1
+" close the tree window
+function! s:closeTreeWindow() abort
+    if b:NERDTree.isWinTree() && b:NERDTree.previousBuf() !=# -1
+        exec 'buffer ' . b:NERDTree.previousBuf()
+    else
+        if winnr('$') > 1
+            call g:NERDTree.Close()
+        else
+            call nerdtree#echo('Cannot close last window')
+        endif
+    endif
+endfunction
+
+" FUNCTION: s:deleteBookmark(bookmark) {{{1
+" Prompt the user to confirm the deletion of the selected bookmark.
+function! s:deleteBookmark(bookmark) abort
+    let l:message = 'Delete the bookmark "' . a:bookmark.name
+                \ . '" from the bookmark list?'
+
+    let l:choices = "&Yes\n&No"
+
+    echo | redraw
+    let l:selection = confirm(l:message, l:choices, 1, 'Warning')
+
+    if l:selection !=# 1
+        call nerdtree#echo('bookmark not deleted')
+        return
+    endif
+
+    try
+        call a:bookmark.delete()
+        silent call b:NERDTree.root.refresh()
+        call b:NERDTree.render()
+        echo | redraw
+    catch /^NERDTree/
+        call nerdtree#echoWarning('could not remove bookmark')
+    endtry
+endfunction
+
+" FUNCTION: s:displayHelp() {{{1
+" toggles the help display
+function! s:displayHelp() abort
+    call b:NERDTree.ui.toggleHelp()
+    call b:NERDTree.render()
+    call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:findAndRevealPath(pathStr) {{{1
+function! s:findAndRevealPath(pathStr) abort
+    let l:pathStr = !empty(a:pathStr) ? a:pathStr : expand('%:p')
+    let l:revealOpts = {}
+
+    if empty(l:pathStr)
+        call nerdtree#echoWarning('no file for the current buffer')
+        return
+    endif
+
+    if !filereadable(l:pathStr)
+        let l:pathStr = fnamemodify(l:pathStr, ':h')
+        let l:revealOpts['open'] = 1
+    endif
+
+    try
+        let l:pathStr = g:NERDTreePath.Resolve(l:pathStr)
+        let l:pathObj = g:NERDTreePath.New(l:pathStr)
+    catch /^NERDTree.InvalidArgumentsError/
+        call nerdtree#echoWarning('invalid path')
+        return
+    endtry
+
+    if !g:NERDTree.ExistsForTab()
+        try
+            let l:cwd = g:NERDTreePath.New(getcwd())
+        catch /^NERDTree.InvalidArgumentsError/
+            call nerdtree#echo('current directory does not exist.')
+            let l:cwd = l:pathObj.getParent()
+        endtry
+
+        if l:pathObj.isUnder(l:cwd)
+            call g:NERDTreeCreator.CreateTabTree(l:cwd.str())
+        else
+            call g:NERDTreeCreator.CreateTabTree(l:pathObj.getParent().str())
+        endif
+    else
+        NERDTreeFocus
+
+        if !l:pathObj.isUnder(b:NERDTree.root.path)
+            call s:chRoot(g:NERDTreeDirNode.New(l:pathObj.getParent(), b:NERDTree))
+        endif
+    endif
+
+    if l:pathObj.isHiddenUnder(b:NERDTree.root.path)
+        call b:NERDTree.ui.setShowHidden(1)
+    endif
+
+    let l:node = b:NERDTree.root.reveal(l:pathObj, l:revealOpts)
+    call b:NERDTree.render()
+    call l:node.putCursorHere(1, 0)
+endfunction
+
+"FUNCTION: s:handleLeftClick() {{{1
+"Checks if the click should open the current node
+function! s:handleLeftClick() abort
+    let currentNode = g:NERDTreeFileNode.GetSelected()
+    if currentNode !=# {}
+
+        "the dir arrows are multibyte chars, and vim's string functions only
+        "deal with single bytes - so split the line up with the hack below and
+        "take the line substring manually
+        let line = split(getline(line('.')), '\zs')
+        let startToCur = ''
+        for i in range(0,len(line)-1)
+            let startToCur .= line[i]
+        endfor
+
+        if currentNode.path.isDirectory
+            if startToCur =~# g:NERDTreeUI.MarkupReg() && startToCur =~# '[+~'.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \?$'
+                call currentNode.activate()
+                return
+            endif
+        endif
+
+        if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3
+            let char = strpart(startToCur, strlen(startToCur)-1, 1)
+            if char !~# g:NERDTreeUI.MarkupReg()
+                if currentNode.path.isDirectory
+                    call currentNode.activate()
+                else
+                    call currentNode.activate({'reuse': 'all', 'where': 'p', 'keepopen':!nerdtree#closeTreeOnOpen()})
+                endif
+                return
+            endif
+        endif
+    endif
+endfunction
+
+" FUNCTION: s:handleMiddleMouse() {{{1
+function! s:handleMiddleMouse() abort
+
+    " A middle mouse click does not automatically position the cursor as one
+    " would expect. Forcing the execution of a regular left mouse click here
+    " fixes this problem.
+    execute "normal! \<LeftMouse>"
+
+    let l:currentNode = g:NERDTreeFileNode.GetSelected()
+    if empty(l:currentNode)
+        call nerdtree#echoError('use the pointer to select a node')
+        return
+    endif
+
+    if l:currentNode.path.isDirectory
+        call l:currentNode.openExplorer()
+    else
+        call l:currentNode.open({'where': 'h'})
+    endif
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#invokeKeyMap(key) {{{1
+"this is needed since I cant figure out how to invoke dict functions from a
+"key map
+function! nerdtree#ui_glue#invokeKeyMap(key) abort
+    call g:NERDTreeKeyMap.Invoke(a:key)
+endfunction
+
+" FUNCTION: s:jumpToFirstChild(node) {{{1
+function! s:jumpToFirstChild(node) abort
+    call s:jumpToChild(a:node, 0)
+endfunction
+
+" FUNCTION: s:jumpToLastChild(node) {{{1
+function! s:jumpToLastChild(node) abort
+    call s:jumpToChild(a:node, 1)
+endfunction
+
+" FUNCTION: s:jumpToChild(node, last) {{{1
+" Jump to the first or last child node at the same file system level.
+"
+" Args:
+" node: the node on which the cursor currently sits
+" last: 1 (true) if jumping to last child, 0 (false) if jumping to first
+function! s:jumpToChild(node, last) abort
+    let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node
+
+    if l:node.isRoot()
+        return
+    endif
+
+    let l:parent = l:node.parent
+    let l:children = l:parent.getVisibleChildren()
+
+    let l:target = a:last ? l:children[len(l:children) - 1] : l:children[0]
+
+    call l:target.putCursorHere(1, 0)
+    call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:jumpToParent(node) {{{1
+" Move the cursor to the parent of the specified node.  For a cascade, move to
+" the parent of the cascade's first node.  At the root node, do nothing.
+function! s:jumpToParent(node) abort
+    let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node
+
+    if l:node.isRoot()
+        return
+    endif
+
+    if empty(l:node.parent)
+        call nerdtree#echo('could not jump to parent node')
+        return
+    endif
+
+    call l:node.parent.putCursorHere(1, 0)
+    call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:jumpToRoot() {{{1
+" moves the cursor to the root node
+function! s:jumpToRoot() abort
+    call b:NERDTree.root.putCursorHere(1, 0)
+    call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: s:jumpToNextSibling(node) {{{1
+function! s:jumpToNextSibling(node) abort
+    call s:jumpToSibling(a:node, 1)
+endfunction
+
+" FUNCTION: s:jumpToPrevSibling(node) {{{1
+function! s:jumpToPrevSibling(node) abort
+    call s:jumpToSibling(a:node, 0)
+endfunction
+
+" FUNCTION: s:jumpToSibling(node, forward) {{{1
+" Move the cursor to the next or previous node at the same file system level.
+"
+" Args:
+" node: the node on which the cursor currently sits
+" forward: 0 to jump to previous sibling, 1 to jump to next sibling
+function! s:jumpToSibling(node, forward) abort
+    let l:node = a:node.path.isDirectory ? a:node.getCascadeRoot() : a:node
+    let l:sibling = l:node.findSibling(a:forward)
+
+    if empty(l:sibling)
+        return
+    endif
+
+    call l:sibling.putCursorHere(1, 0)
+    call b:NERDTree.ui.centerView()
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#openBookmark(name) {{{1
+" Open the Bookmark that has the specified name. This function provides the
+" implementation for the :OpenBookmark command.
+function! nerdtree#ui_glue#openBookmark(name) abort
+    try
+        let l:bookmark = g:NERDTreeBookmark.BookmarkFor(a:name)
+    catch /^NERDTree.BookmarkNotFoundError/
+        call nerdtree#echoError('bookmark "' . a:name . '" not found')
+        return
+    endtry
+    if l:bookmark.path.isDirectory
+        call l:bookmark.open(b:NERDTree)
+        return
+    endif
+
+    call l:bookmark.open(b:NERDTree, s:initCustomOpenArgs().file)
+endfunction
+
+" FUNCTION: s:openHSplit(target) {{{1
+function! s:openHSplit(target) abort
+    call a:target.activate({'where': 'h', 'keepopen': !nerdtree#closeTreeOnOpen()})
+endfunction
+
+" FUNCTION: s:openVSplit(target) {{{1
+function! s:openVSplit(target) abort
+    call a:target.activate({'where': 'v', 'keepopen': !nerdtree#closeTreeOnOpen()})
+endfunction
+
+"FUNCTION: s:openHSplitBookmark(bookmark) {{{1
+"handle the user activating a bookmark
+function! s:openHSplitBookmark(bm) abort
+    call a:bm.activate(b:NERDTree, !a:bm.path.isDirectory ? {'where': 'h', 'keepopen': !nerdtree#closeTreeOnOpen()} : {})
+endfunction
+
+"FUNCTION: s:openVSplitBookmark(bookmark) {{{1
+"handle the user activating a bookmark
+function! s:openVSplitBookmark(bm) abort
+    call a:bm.activate(b:NERDTree, !a:bm.path.isDirectory ? {'where': 'v', 'keepopen': !nerdtree#closeTreeOnOpen()} : {})
+endfunction
+
+" FUNCTION: s:previewHSplitBookmark(bookmark) {{{1
+function! s:previewNodeHSplitBookmark(bookmark) abort
+    call a:bookmark.activate(b:NERDTree, !a:bookmark.path.isDirectory ? {'stay': 1, 'where': 'h', 'keepopen': 1} : {})
+endfunction
+
+" FUNCTION: s:previewVSplitBookmark(bookmark) {{{1
+function! s:previewNodeVSplitBookmark(bookmark) abort
+    call a:bookmark.activate(b:NERDTree, !a:bookmark.path.isDirectory ? {'stay': 1, 'where': 'v', 'keepopen': 1} : {})
+endfunction
+
+" FUNCTION: s:openExplorer(node) {{{1
+function! s:openExplorer(node) abort
+    call a:node.openExplorer()
+endfunction
+
+" FUNCTION: s:openInNewTab(target) {{{1
+function! s:openInNewTab(target) abort
+    let l:opener = g:NERDTreeOpener.New(a:target.path, {'where': 't', 'keepopen': !nerdtree#closeTreeOnOpen()})
+    call l:opener.open(a:target)
+endfunction
+
+" FUNCTION: s:openInNewTabSilent(target) {{{1
+function! s:openInNewTabSilent(target) abort
+    let l:opener = g:NERDTreeOpener.New(a:target.path, {'where': 't', 'keepopen': !nerdtree#closeTreeOnOpen(), 'stay': 1})
+    call l:opener.open(a:target)
+endfunction
+
+" FUNCTION: s:openNodeRecursively(node) {{{1
+function! s:openNodeRecursively(node) abort
+    call nerdtree#echo('Recursively opening node. Please wait...')
+    call a:node.openRecursively()
+    call b:NERDTree.render()
+    call nerdtree#echo('')
+endfunction
+
+" FUNCTION: s:previewBookmark(bookmark) {{{1
+function! s:previewBookmark(bookmark) abort
+    if a:bookmark.path.isDirectory
+        execute 'NERDTreeFind '.a:bookmark.path.str()
+    else
+        call a:bookmark.activate(b:NERDTree, {'stay': 1, 'where': 'p', 'keepopen': 1})
+    endif
+endfunction
+
+"FUNCTION: s:previewNodeCurrent(node) {{{1
+function! s:previewNodeCurrent(node) abort
+    call a:node.open({'stay': 1, 'where': 'p', 'keepopen': 1})
+endfunction
+
+"FUNCTION: s:previewNodeHSplit(node) {{{1
+function! s:previewNodeHSplit(node) abort
+    call a:node.open({'stay': 1, 'where': 'h', 'keepopen': 1})
+endfunction
+
+"FUNCTION: s:previewNodeVSplit(node) {{{1
+function! s:previewNodeVSplit(node) abort
+    call a:node.open({'stay': 1, 'where': 'v', 'keepopen': 1})
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#revealBookmark(name) {{{1
+" put the cursor on the node associate with the given name
+function! nerdtree#ui_glue#revealBookmark(name) abort
+    try
+        let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0, b:NERDTree)
+        call targetNode.putCursorHere(0, 1)
+    catch /^NERDTree.BookmarkNotFoundError/
+        call nerdtree#echo('Bookmark isn''t cached under the current root')
+    endtry
+endfunction
+
+" FUNCTION: s:refreshRoot() {{{1
+" Reloads the current root. All nodes below this will be lost and the root dir
+" will be reloaded.
+function! s:refreshRoot() abort
+    if !g:NERDTree.IsOpen()
+        return
+    endif
+    call nerdtree#echo('Refreshing the root node. This could take a while...')
+
+    let l:curWin = winnr()
+    call nerdtree#exec(g:NERDTree.GetWinNum() . 'wincmd w', 1)
+    call b:NERDTree.root.refresh()
+    call b:NERDTree.render()
+    redraw
+    call nerdtree#exec(l:curWin . 'wincmd w', 1)
+    call nerdtree#echo('')
+endfunction
+
+" FUNCTION: s:refreshCurrent(node) {{{1
+" refreshes the root for the current node
+function! s:refreshCurrent(node) abort
+    let node = a:node
+    if !node.path.isDirectory
+        let node = node.parent
+    endif
+
+    call nerdtree#echo('Refreshing node. This could take a while...')
+    call node.refresh()
+    call b:NERDTree.render()
+    call nerdtree#echo('')
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#setupCommands() {{{1
+function! nerdtree#ui_glue#setupCommands() abort
+    command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreateTabTree('<args>')
+    command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.ToggleTabTree('<args>')
+    command! -n=0 -bar NERDTreeClose :call g:NERDTree.Close()
+    command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreateTabTree('<args>')
+    command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror()
+    command! -n=? -complete=file -bar NERDTreeFind call s:findAndRevealPath('<args>')
+    command! -n=0 -bar NERDTreeRefreshRoot call s:refreshRoot()
+    command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
+    command! -n=0 -bar NERDTreeCWD call NERDTreeCWD()
+endfunction
+
+" Function: s:SID()   {{{1
+function! s:SID() abort
+    if !exists('s:sid')
+        let s:sid = matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
+    endif
+    return s:sid
+endfun
+
+" FUNCTION: s:showMenu(node) {{{1
+function! s:showMenu(node) abort
+    let mc = g:NERDTreeMenuController.New(g:NERDTreeMenuItem.AllEnabled())
+    call mc.showMenu()
+endfunction
+
+" FUNCTION: s:toggleIgnoreFilter() {{{1
+function! s:toggleIgnoreFilter() abort
+    call b:NERDTree.ui.toggleIgnoreFilter()
+endfunction
+
+" FUNCTION: s:toggleShowBookmarks() {{{1
+function! s:toggleShowBookmarks() abort
+    call b:NERDTree.ui.toggleShowBookmarks()
+endfunction
+
+" FUNCTION: s:toggleShowFiles() {{{1
+function! s:toggleShowFiles() abort
+    call b:NERDTree.ui.toggleShowFiles()
+endfunction
+
+" FUNCTION: s:toggleShowHidden() {{{1
+" toggles the display of hidden files
+function! s:toggleShowHidden() abort
+    call b:NERDTree.ui.toggleShowHidden()
+endfunction
+
+" FUNCTION: s:toggleZoom() {{{1
+function! s:toggleZoom() abort
+    call b:NERDTree.ui.toggleZoom()
+endfunction
+
+" FUNCTION: nerdtree#ui_glue#upDir(preserveState) {{{1
+" Move the NERDTree up one level.
+"
+" Args:
+" preserveState: if 1, the current root is left open when the new tree is
+" rendered; if 0, the current root node is closed
+function! nerdtree#ui_glue#upDir(preserveState) abort
+
+    try
+        call b:NERDTree.root.cacheParent()
+    catch /^NERDTree.CannotCacheParentError/
+        call nerdtree#echo('already at root directory')
+        return
+    endtry
+
+    let l:oldRoot = b:NERDTree.root
+    let l:newRoot = b:NERDTree.root.parent
+
+    call l:newRoot.open()
+    call l:newRoot.transplantChild(l:oldRoot)
+
+    if !a:preserveState
+        call l:oldRoot.close()
+    endif
+
+    call b:NERDTree.changeRoot(l:newRoot)
+    call l:oldRoot.putCursorHere(0, 0)
+endfunction
+
+" FUNCTION: s:upDirCurrentRootOpen() {{{1
+function! s:upDirCurrentRootOpen() abort
+    call nerdtree#ui_glue#upDir(1)
+endfunction
+
+" FUNCTION: s:upDirCurrentRootClosed() {{{1
+function! s:upDirCurrentRootClosed() abort
+    call nerdtree#ui_glue#upDir(0)
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:

+ 1534 - 0
vimfiles/bundle/nerdtree/doc/NERDTree.txt

@@ -0,0 +1,1534 @@
+*NERDTree.txt*   A tree explorer plugin to rule the Vim world. Bwahahaha!!
+
+                                    # #### ####                                ~
+                                  ### \/#|### |/####                           ~
+   d8   888                      ##\/#/ \||/##/_/##/_#                         ~
+  d88   888 ee   ,e e,         ###  \/###|/ \/ # ###                           ~
+ d88888 888 88b d88 88b      ##_\_#\_\## | #/###_/_####                        ~
+  888   888 888 888   ,     ## #### # \ #| /  #### ##/##                       ~
+  888   888 888  "YeeP"     __#_--###`. |{,###---###-~                         ~
+                                     \ % @%                                    ~
+  Y88b Y88 888'Y88 888 88e  888 88e   \%@%  88P'888'Y88                        ~
+   Y88b Y8 888 ,'Y 888 888D 888 888b   %o%  P'  888  'Y 888,8,  ,e e,   ,e e,  ~
+  b Y88b Y 888C8   888 88"  888 8888D  %@%      888     888 "  d88 88b d88 88b ~
+  8b Y88b  888 ",d 888 b,   888 888P   %@%      888     888    888   , 888   , ~
+  88b Y88b 888,d88 888 88b, 888 88"    %@%      888     888     "YeeP"  "YeeP" ~
+                                 , -=-%{@%-^- _                                ~
+                                   ejm `}               Reference Manual       ~
+                                        {                                      ~
+==============================================================================
+CONTENTS                                                     *NERDTree-contents*
+
+    1.Intro...................................|NERDTree|
+    2.Functionality provided..................|NERDTreeFunctionality|
+        2.1.Global commands...................|NERDTreeGlobalCommands|
+        2.2.Bookmarks.........................|NERDTreeBookmarks|
+            2.2.1.The bookmark table..........|NERDTreeBookmarkTable|
+            2.2.2.Bookmark commands...........|NERDTreeBookmarkCommands|
+            2.2.3.Invalid bookmarks...........|NERDTreeInvalidBookmarks|
+        2.3.NERDTree mappings.................|NERDTreeMappings|
+        2.4.The NERDTree menu.................|NERDTreeMenu|
+    3.Settings................................|NERDTreeSettings|
+        3.1.Settings summary..................|NERDTreeSettingsSummary|
+        3.2.Settings details..................|NERDTreeSettingsDetails|
+    4.The NERDTree API........................|NERDTreeAPI|
+        4.1.Key map API.......................|NERDTreeKeymapAPI|
+        4.2.Menu API..........................|NERDTreeMenuAPI|
+        4.3.Menu API..........................|NERDTreeAddPathFilter()|
+        4.4.Path Listener API.................|NERDTreePathListenerAPI|
+    5.About...................................|NERDTreeAbout|
+    6.License.................................|NERDTreeLicense|
+
+==============================================================================
+1. Intro                                                              *NERDTree*
+
+What is this "NERDTree"??
+
+The NERDTree allows you to explore your filesystem and to open files and
+directories. It presents the filesystem to you in the form of a tree which you
+manipulate with the keyboard and/or mouse. It also allows you to perform
+simple filesystem operations.
+
+The following features and functionality are provided by the NERDTree:
+    * Files and directories are displayed in a hierarchical tree structure
+    * Different highlighting is provided for the following types of nodes:
+        * files
+        * directories
+        * sym-links
+        * windows .lnk files
+        * read-only files
+        * executable files
+    * Many (customisable) mappings are provided to manipulate the tree:
+        * Mappings to open/close/explore directory nodes
+        * Mappings to open files in new/existing windows/tabs
+        * Mappings to change the current root of the tree
+        * Mappings to navigate around the tree
+        * ...
+    * Directories and files can be bookmarked.
+    * Most NERDTree navigation can also be done with the mouse
+    * Filtering of tree content (can be toggled at runtime)
+        * custom file filters to prevent e.g. vim backup files being displayed
+        * optional displaying of hidden files (. files)
+        * files can be "turned off" so that only directories are displayed
+    * The position and size of the NERDTree window can be customised
+    * The order in which the nodes in the tree are listed can be customised.
+    * A model of your filesystem is created/maintained as you explore it. This
+      has several advantages:
+        * All filesystem information is cached and is only re-read on demand
+        * If you revisit a part of the tree that you left earlier in your
+          session, the directory nodes will be opened/closed as you left them
+    * The script remembers the cursor position and window position in the NERD
+      tree so you can toggle it off (or just close the tree window) and then
+      reopen it (with NERDTreeToggle) the NERDTree window will appear exactly
+      as you left it
+    * You can have a separate NERDTree for each tab, share trees across tabs,
+      or a mix of both.
+    * By default the script overrides the default file browser (netrw), so if
+      you :edit a directory a (slightly modified) NERDTree will appear in the
+      current window
+    * A programmable menu system is provided (simulates right clicking on a
+      node)
+        * one default menu plugin is provided to perform basic filesystem
+          operations (create/delete/move/copy files/directories)
+    * There's an API for adding your own keymappings
+
+
+==============================================================================
+2. Functionality provided                                *NERDTreeFunctionality*
+
+------------------------------------------------------------------------------
+2.1. Global Commands                                    *NERDTreeGlobalCommands*
+
+:NERDTree [<start-directory> | <bookmark>]                           *:NERDTree*
+    Opens a fresh NERDTree. The root of the tree depends on the argument
+    given. There are 3 cases: If no argument is given, the current directory
+    will be used.  If a directory is given, that will be used. If a bookmark
+    name is given, the corresponding directory will be used.  For example: >
+        :NERDTree /home/marty/vim7/src
+        :NERDTree foo   (foo is the name of a bookmark)
+<
+:NERDTreeVCS [<start-directory> | <bookmark>]                     *:NERDTreeVCS*
+    Like |:NERDTree|, but searches up the directory tree to find the top of
+    the version control system repository, and roots the NERDTree there. It
+    works with Git, Subversion, Mercurial, Bazaar, and Darcs repositories. A
+    couple of examples: >
+        :NERDTreeVCS /home/marty/nerdtree/doc  (opens /home/marty/nerdtree)
+        :NERDTreeVCS              (opens root of repository containing CWD)
+<
+:NERDTreeFromBookmark <bookmark>                         *:NERDTreeFromBookmark*
+    Opens a fresh NERDTree with the root initialized to the directory for
+    <bookmark>.  The only reason to use this command over :NERDTree is for
+    the completion (which is for bookmarks rather than directories).
+
+:NERDTreeToggle [<start-directory> | <bookmark>]               *:NERDTreeToggle*
+    If a NERDTree already exists for this tab, it is reopened and rendered
+    again. If <start-directory> or <bookmark> is given, the root of NERDTree
+    is set to that path. If no NERDTree exists for this tab then this command
+    acts the same as the |:NERDTree| command.
+
+:NERDTreeToggleVCS [<start-directory> | <bookmark>]         *:NERDTreeToggleVCS*
+    Like |:NERDTreeToggle|, but searches up the directory tree to find the top of
+    the version control system repository, and roots the NERDTree there. It
+    works with Git, Subversion, Mercurial, Bazaar, and Darcs repositories. A
+    couple of examples: >
+        :NERDTreeToggleVCS /home/marty/nerdtree/doc  (opens /home/marty/nerdtree)
+        :NERDTreeToggleVCS              (opens root of repository containing CWD)
+
+:NERDTreeFocus                                                  *:NERDTreeFocus*
+    Opens (or reopens) the NERDTree if it is not currently visible;
+    otherwise, the cursor is moved to the already-open NERDTree.
+
+:NERDTreeMirror                                                *:NERDTreeMirror*
+    Shares an existing NERDTree, from another tab, in the current tab.
+    Changes made to one tree are reflected in both as they are actually the
+    same buffer.
+
+    If only one other NERDTree exists, that tree is automatically mirrored.
+    If more than one exists, the script will ask which tree to mirror.
+
+:NERDTreeClose                                                  *:NERDTreeClose*
+    Close the NERDTree in this tab.
+
+:NERDTreeFind [<path>]                                           *:NERDTreeFind*
+    Without the optional argument, find and reveal the file for the active
+    buffer in the NERDTree window.  With the <path> argument, find and
+    reveal the specified path.
+
+    Focus will be shifted to the NERDTree window, and the cursor will be
+    placed on the tree node for the determined path.  If a NERDTree for the
+    current tab does not exist, a new one will be initialized.
+
+:NERDTreeCWD                                                      *:NERDTreeCWD*
+    Change the NERDTree root to the current working directory.  If no
+    NERDTree exists for this tab, a new one is opened.
+
+:NERDTreeRefreshRoot                                      *:NERDTreeRefreshRoot*
+    Refreshes the NERDTree root node.
+
+------------------------------------------------------------------------------
+2.2. Bookmarks                                               *NERDTreeBookmarks*
+
+Bookmarks in the NERDTree are a way to tag files or directories of interest.
+For example, you could use bookmarks to tag all of your project directories.
+
+------------------------------------------------------------------------------
+2.2.1. The Bookmark Table                                *NERDTreeBookmarkTable*
+
+If the bookmark table is active (see |NERDTree-B| and
+|NERDTreeShowBookmarks|), it will be rendered above the tree. You can double
+click bookmarks or use the |NERDTree-o| mapping to activate them. See also,
+|NERDTree-t| and |NERDTree-T|
+
+------------------------------------------------------------------------------
+2.2.2. Bookmark commands                              *NERDTreeBookmarkCommands*
+
+Note: The following commands are only available within the NERDTree buffer.
+
+:Bookmark [<name>]
+    Bookmark the current node as <name>. If there is already a <name>
+    bookmark, it is overwritten. <name> must not contain spaces.
+    If <name> is not provided, it defaults to the file or directory name.
+    For directories, a trailing slash is present.
+
+:BookmarkToRoot <bookmark>
+    Make the directory corresponding to <bookmark> the new root. If a treenode
+    corresponding to <bookmark> is already cached somewhere in the tree then
+    the current tree will be used, otherwise a fresh tree will be opened.
+    Note that if <bookmark> points to a file then its parent will be used
+    instead.
+
+:RevealBookmark <bookmark>
+    If the node is cached under the current root then it will be revealed
+    (i.e. directory nodes above it will be opened) and the cursor will be
+    placed on it.
+
+:OpenBookmark <name>
+    The Bookmark named <name> is opened as if |NERDTree-o| was applied to
+    its entry in the Bookmark table. If the Bookmark points to a directory,
+    it is made the new root of the current NERDTree. If the Bookmark points
+    to a file, that file is opened for editing in another window.
+
+:ClearBookmarks [<bookmarks>]
+    Remove all the given bookmarks. If no bookmarks are given then remove all
+    bookmarks on the current node.
+
+:ClearAllBookmarks
+    Remove all bookmarks.
+
+:EditBookmarks
+    Opens the bookmarks file for manual editing, e.g. for removing invalid
+    bookmarks.
+
+:ReadBookmarks
+    Re-read the bookmarks in the |NERDTreeBookmarksFile|.
+
+See also |:NERDTree| and |:NERDTreeFromBookmark|.
+
+------------------------------------------------------------------------------
+2.2.3. Invalid Bookmarks                              *NERDTreeInvalidBookmarks*
+
+If invalid bookmarks are detected, the script will issue an error message and
+the invalid bookmarks will become unavailable for use.
+
+These bookmarks will still be stored in the bookmarks file (see
+|NERDTreeBookmarksFile|), down at the bottom. There will always be a blank line
+after the valid bookmarks but before the invalid ones.
+
+Each line in the bookmarks file represents one bookmark. The proper format is:
+<bookmark name><space><full path to the bookmark location>
+
+You can use the :EditBookmarks command to open the bookmarks file for editing.
+After you have corrected any invalid bookmarks, either restart vim, or run
+:ReadBookmarks from the NERDTree window.
+
+------------------------------------------------------------------------------
+2.3. NERDTree Mappings                                        *NERDTreeMappings*
+
+Default~
+Key      Description                                                  help-tag~
+
+o........Open files, directories and bookmarks......................|NERDTree-o|
+go.......Open selected file, but leave cursor in the NERDTree......|NERDTree-go|
+         Find selected bookmark directory in current NERDTree
+t........Open selected node/bookmark in a new tab...................|NERDTree-t|
+T........Same as 't' but keep the focus on the current tab..........|NERDTree-T|
+i........Open selected file in a split window.......................|NERDTree-i|
+gi.......Same as i, but leave the cursor on the NERDTree...........|NERDTree-gi|
+s........Open selected file in a new vsplit.........................|NERDTree-s|
+gs.......Same as s, but leave the cursor on the NERDTree...........|NERDTree-gs|
+<CR>.....User-definable custom open action.......................|NERDTree-<CR>|
+O........Recursively open the selected directory....................|NERDTree-O|
+x........Close the current nodes parent.............................|NERDTree-x|
+X........Recursively close all children of the current node.........|NERDTree-X|
+e........Edit the current directory.................................|NERDTree-e|
+
+double-click....same as |NERDTree-o|.
+middle-click....same as |NERDTree-i| for files, and |NERDTree-e| for directories.
+
+D........Delete the current bookmark ...............................|NERDTree-D|
+
+P........Jump to the root node......................................|NERDTree-P|
+p........Jump to current nodes parent...............................|NERDTree-p|
+K........Jump up inside directories at the current tree depth.......|NERDTree-K|
+J........Jump down inside directories at the current tree depth.....|NERDTree-J|
+<C-J>....Jump down to next sibling of the current directory.......|NERDTree-C-J|
+<C-K>....Jump up to previous sibling of the current directory.....|NERDTree-C-K|
+
+C........Change the tree root to the selected directory.............|NERDTree-C|
+u........Move the tree root up one directory........................|NERDTree-u|
+U........Same as 'u' except the old root node is left open..........|NERDTree-U|
+r........Recursively refresh the current directory..................|NERDTree-r|
+R........Recursively refresh the current root.......................|NERDTree-R|
+m........Display the NERDTree menu..................................|NERDTree-m|
+cd.......Change the CWD to the directory of the selected node......|NERDTree-cd|
+CD.......Change tree root to the CWD...............................|NERDTree-CD|
+
+I........Toggle whether hidden files displayed......................|NERDTree-I|
+f........Toggle whether the file filters are used...................|NERDTree-f|
+F........Toggle whether files are displayed.........................|NERDTree-F|
+B........Toggle whether the bookmark table is displayed.............|NERDTree-B|
+
+q........Close the NERDTree window..................................|NERDTree-q|
+A........Zoom (maximize/minimize) the NERDTree window...............|NERDTree-A|
+?........Toggle the display of the quick help.......................|NERDTree-?|
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-o*
+Default key: o
+Map setting: NERDTreeMapActivateNode
+Applies to: files and directories.
+
+If a file node is selected, it is opened in the previous window.
+
+If a directory is selected it is opened or closed depending on its current
+state.
+
+If a bookmark that links to a directory is selected then that directory
+becomes the new root.
+
+If a bookmark that links to a file is selected then that file is opened in the
+previous window.
+
+------------------------------------------------------------------------------
+                                                                   *NERDTree-go*
+Default key: go
+Map setting: NERDTreeMapPreview
+Applies to: files.
+
+If a file node or a bookmark that links to a file is selected, it is opened in
+the previous window, but the cursor does not move.
+
+If a bookmark that links to a directory is selected then that directory
+becomes the new root.
+
+The default key combo for this mapping is "g" + NERDTreeMapActivateNode (see
+|NERDTree-o|).
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-t*
+Default key: t
+Map setting: *NERDTreeMapOpenInTab*
+Applies to: files and directories.
+
+Opens the selected file in a new tab. If a directory is selected, a fresh
+NERDTree for that directory is opened in a new tab.
+
+If a bookmark which points to a directory is selected, open a NERDTree for
+that directory in a new tab. If the bookmark points to a file, open that file
+in a new tab.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-T*
+Default key: T
+Map setting: *NERDTreeMapOpenInTabSilent*
+Applies to: files and directories.
+
+The same as |NERDTree-t| except that the focus is kept in the current tab.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-i*
+Default key: i
+Map setting: *NERDTreeMapOpenSplit*
+Applies to: files, and bookmarks pointing to files.
+
+Opens the selected file in a new split window and puts the cursor in the new
+window.
+
+------------------------------------------------------------------------------
+                                                                   *NERDTree-gi*
+Default key: gi
+Map setting: *NERDTreeMapPreviewSplit*
+Applies to: files, and bookmarks pointing to files.
+
+The same as |NERDTree-i| except that the cursor is not moved.
+
+The default key combo for this mapping is "g" + NERDTreeMapOpenSplit (see
+|NERDTree-i|).
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-s*
+Default key: s
+Map setting: *NERDTreeMapOpenVSplit*
+Applies to: files, and bookmarks pointing to files.
+
+Opens the selected file in a new vertically split window and puts the cursor
+in the new window.
+
+------------------------------------------------------------------------------
+                                                                   *NERDTree-gs*
+Default key: gs
+Map setting: *NERDTreeMapPreviewVSplit*
+Applies to: files, and bookmarks pointing to files.
+
+The same as |NERDTree-s| except that the cursor is not moved.
+
+The default key combo for this mapping is "g" + NERDTreeMapOpenVSplit (see
+|NERDTree-s|).
+
+------------------------------------------------------------------------------
+                                                                 *NERDTree-<CR>*
+Default key: <CR>
+Map setting: *NERDTreeMapCustomOpen*
+Applies to: files, directories, and bookmarks
+
+Performs a customized open action on the selected node. This allows the user
+to define an action that behaves differently from any of the standard
+keys. See |NERDTreeCustomOpenArgs| for more details.
+------------------------------------------------------------------------------
+                                                                    *NERDTree-O*
+Default key: O
+Map setting: *NERDTreeMapOpenRecursively*
+Applies to: directories.
+
+Recursively opens the selected directory.
+
+All files and directories are cached, but if a directory would not be
+displayed due to file filters (see |NERDTreeIgnore| |NERDTree-f|) or the
+hidden file filter (see |NERDTreeShowHidden|) then its contents are not
+cached. This is handy, especially if you have .svn directories.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-x*
+Default key: x
+Map setting: *NERDTreeMapCloseDir*
+Applies to: files and directories.
+
+Closes the parent of the selected node.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-X*
+Default key: X
+Map setting: *NERDTreeMapCloseChildren*
+Applies to: directories.
+
+Recursively closes all children of the selected directory.
+
+Tip: To quickly "reset" the tree, use |NERDTree-P| with this mapping.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-e*
+Default key: e
+Map setting: *NERDTreeMapOpenExpl*
+Applies to: files and directories.
+
+|:edit|s the selected directory, or the selected file's directory. This could
+result in a NERDTree or a netrw being opened, depending on
+|NERDTreeHijackNetrw|.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-D*
+Default key: D
+Map setting: *NERDTreeMapDeleteBookmark*
+Applies to: lines in the bookmarks table
+
+Deletes the currently selected bookmark.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-P*
+Default key: P
+Map setting: *NERDTreeMapJumpRoot*
+Applies to: no restrictions.
+
+Jump to the tree root.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-p*
+Default key: p
+Map setting: *NERDTreeMapJumpParent*
+Applies to: files and directories.
+
+Jump to the parent node of the selected node.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-K*
+Default key: K
+Map setting: *NERDTreeMapJumpFirstChild*
+Applies to: files and directories.
+
+Jump to the first child of the current nodes parent.
+
+If the cursor is already on the first node then do the following:
+    * loop back thru the siblings of the current nodes parent until we find an
+      open directory with children
+    * go to the first child of that node
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-J*
+Default key: J
+Map setting: *NERDTreeMapJumpLastChild*
+Applies to: files and directories.
+
+Jump to the last child of the current nodes parent.
+
+If the cursor is already on the last node then do the following:
+    * loop forward thru the siblings of the current nodes parent until we find
+      an open directory with children
+    * go to the last child of that node
+
+------------------------------------------------------------------------------
+                                                                  *NERDTree-C-J*
+Default key: <C-J>
+Map setting: *NERDTreeMapJumpNextSibling*
+Applies to: files and directories.
+
+Jump to the next sibling of the selected node.
+
+------------------------------------------------------------------------------
+                                                                  *NERDTree-C-K*
+Default key: <C-K>
+Map setting: *NERDTreeMapJumpPrevSibling*
+Applies to: files and directories.
+
+Jump to the previous sibling of the selected node.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-C*
+Default key: C
+Map setting: *NERDTreeMapChangeRoot*
+Applies to: files and directories.
+
+Make the selected directory node the new tree root. If a file is selected, its
+parent is used.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-u*
+Default key: u
+Map setting: *NERDTreeMapUpdir*
+Applies to: no restrictions.
+
+Move the tree root up a directory (like doing a "cd ..").
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-U*
+Default key: U
+Map setting: *NERDTreeMapUpdirKeepOpen*
+Applies to: no restrictions.
+
+Like |NERDTree-u| except that the old tree root is kept open.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-r*
+Default key: r
+Map setting: *NERDTreeMapRefresh*
+Applies to: files and directories.
+
+If a directory is selected, recursively refresh that directory, i.e. scan the
+filesystem for changes and represent them in the tree.
+
+If a file node is selected then the above is done on it's parent.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-R*
+Default key: R
+Map setting: *NERDTreeMapRefreshRoot*
+Applies to: no restrictions.
+
+Recursively refresh the tree root.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-m*
+Default key: m
+Map setting: *NERDTreeMapMenu*
+Applies to: files and directories.
+
+Display the NERDTree menu. See |NERDTreeMenu| for details.
+
+------------------------------------------------------------------------------
+                                                                   *NERDTree-cd*
+Default key: cd
+Map setting: *NERDTreeMapChdir*
+Applies to: files and directories.
+
+Change Vim's current working directory to that of the selected node.
+
+------------------------------------------------------------------------------
+                                                                   *NERDTree-CD*
+Default key: CD
+Map setting: *NERDTreeMapCWD*
+Applies to: no restrictions.
+
+Change the NERDTree root to Vim's current working directory.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-I*
+Default key: I
+Map setting: *NERDTreeMapToggleHidden*
+Applies to: no restrictions.
+
+Toggles whether hidden files (i.e. "dot files") are displayed.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-f*
+Default key: f
+Map setting: *NERDTreeMapToggleFilters*
+Applies to: no restrictions.
+
+Toggles whether file filters are used. See |NERDTreeIgnore| for details.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-F*
+Default key: F
+Map setting: *NERDTreeMapToggleFiles*
+Applies to: no restrictions.
+
+Toggles whether file nodes are displayed.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-B*
+Default key: B
+Map setting: *NERDTreeMapToggleBookmarks*
+Applies to: no restrictions.
+
+Toggles whether the bookmarks table is displayed.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-q*
+Default key: q
+Map setting: *NERDTreeMapQuit*
+Applies to: no restrictions.
+
+Closes the NERDTree window.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-A*
+Default key: A
+Map setting: *NERDTreeMapToggleZoom*
+Applies to: no restrictions.
+
+Maximize (zoom) and minimize the NERDTree window.
+
+------------------------------------------------------------------------------
+                                                                    *NERDTree-?*
+Default key: ?
+Map setting: *NERDTreeMapHelp*
+Applies to: no restrictions.
+
+Toggles whether the quickhelp is displayed.
+
+------------------------------------------------------------------------------
+ 2.3. The NERDTree menu                                           *NERDTreeMenu*
+
+The NERDTree has a menu that can be programmed via the an API (see
+|NERDTreeMenuAPI|). The idea is to simulate the "right click" menus that most
+file explorers have.
+
+The script comes with two default menu plugins: exec_menuitem.vim and
+fs_menu.vim. fs_menu.vim adds some basic filesystem operations to the menu for
+creating/deleting/moving/copying files and directories. exec_menuitem.vim
+provides a menu item to execute executable files.
+
+Related tags: |NERDTree-m| |NERDTreeApi|
+
+------------------------------------------------------------------------------
+                                                                *NERDTreeMenu-j*
+Default key: j
+Map option: *NERDTreeMenuDown*
+Applies to: The NERDTree menu.
+
+Moves the cursor down.
+
+------------------------------------------------------------------------------
+                                                                *NERDTreeMenu-k*
+Default key: k
+Map option: *NERDTreeMenuUp*
+Applies to: The NERDTree menu.
+
+Moves the cursor up.
+
+==============================================================================
+3. Customisation                                              *NERDTreeSettings*
+
+
+------------------------------------------------------------------------------
+3.1. Customisation summary                             *NERDTreeSettingsSummary*
+
+The plugin provides the following settings that can customise the behaviour
+the NERDTree. These settings should be set in your vimrc, using `:let`.
+
+|loaded_nerd_tree|            Turns off the script.
+
+|NERDTreeAutoCenter|          Controls whether the NERDTree window centers
+                            when the cursor moves within a specified
+                            distance to the top/bottom of the window.
+
+|NERDTreeAutoCenterThreshold| Controls the sensitivity of autocentering.
+
+|NERDTreeCaseSensitiveSort|   Tells the NERDTree whether to be case
+                            sensitive or not when sorting nodes.
+
+|NERDTreeNaturalSort|         Tells the NERDTree whether to use natural sort
+                            order or not when sorting nodes.
+
+|NERDTreeSortHiddenFirst|     Tells the NERDTree whether to take the dot at
+                            the beginning of the hidden file names into
+                            account when sorting nodes.
+
+|NERDTreeChDirMode|           Tells the NERDTree if/when it should change
+                            vim's current working directory.
+
+|NERDTreeHighlightCursorline| Tell the NERDTree whether to highlight the
+                            current cursor line.
+
+|NERDTreeHijackNetrw|         Tell the NERDTree whether to replace the netrw
+                            autocommands for exploring local directories.
+
+|NERDTreeIgnore|              Tells the NERDTree which files to ignore.
+
+|NERDTreeRespectWildIgnore|   Tells the NERDTree to respect `'wildignore'`.
+
+|NERDTreeBookmarksFile|       Where the bookmarks are stored.
+
+|NERDTreeBookmarksSort|       Control how the Bookmark table is sorted.
+
+|NERDTreeMarkBookmarks|       Render bookmarked nodes with markers.
+
+|NERDTreeMouseMode|           Manage the interpretation of mouse clicks.
+
+|NERDTreeQuitOnOpen|          Closes the tree window or bookmark table after
+                            opening a file.
+
+|NERDTreeShowBookmarks|       Tells the NERDTree whether to display the
+                            bookmarks table on startup.
+
+|NERDTreeShowFiles|           Tells the NERDTree whether to display files in
+                            the tree on startup.
+
+|NERDTreeShowHidden|          Tells the NERDTree whether to display hidden
+                            files on startup.
+
+|NERDTreeShowLineNumbers|     Tells the NERDTree whether to display line
+                            numbers in the tree window.
+
+|NERDTreeSortOrder|           Tell the NERDTree how to sort the nodes in the
+                            tree.
+
+|NERDTreeStatusline|          Set a statusline for NERDTree windows.
+
+|NERDTreeWinPos|              Tells the script where to put the NERDTree
+                            window.
+
+|NERDTreeWinSize|             Sets the window size when the NERDTree is
+                            opened.
+
+|NERDTreeWinSizeMax|          Sets the maximum window size when the NERDTree
+                            is zoomed.
+
+|NERDTreeMinimalUI|           Disables display of the 'Bookmarks' label and
+                            'Press ? for help' text.
+
+|NERDTreeMinimalMenu|         Use a compact menu that fits on a single line
+                            for adding, copying, deleting, etc
+
+|NERDTreeCascadeSingleChildDir|
+                            Collapses on the same line directories that have
+                            only one child directory.
+
+|NERDTreeCascadeOpenSingleChildDir|
+                            Cascade open while selected directory has only
+                            one child that also is a directory.
+
+|NERDTreeAutoDeleteBuffer|    Tells the NERDTree to automatically remove a
+                            buffer when a file is being deleted or renamed
+                            via a context menu command.
+
+|NERDTreeCreatePrefix|        Specify a prefix to be used when creating the
+                            NERDTree window.
+
+|NERDTreeRemoveFileCmd|       Specify a custom shell command to be used when
+                            deleting files. Note that it should include one
+                            space character at the end of the command and it
+                            applies only to files.
+
+|NERDTreeRemoveDirCmd|        Specify a custom shell command to be used when
+                            deleting directories. Note that it should
+                            include one space character at the end of the
+                            command and it applies only to directories.
+
+|NERDTreeDirArrowCollapsible| These characters indicate when a directory is
+|NERDTreeDirArrowExpandable|  either collapsible or expandable.
+
+|NERDTreeNodeDelimiter|       A single character that is used to separate the
+                            file or directory name from the rest of the
+                            characters on the line of text.
+
+|NERDTreeCustomOpenArgs|      A dictionary with values that control how a node
+                            is opened with the |NERDTree-<CR>| key.
+
+------------------------------------------------------------------------------
+3.2. Customisation details                             *NERDTreeSettingsDetails*
+
+To enable any of the below settings you should put an appropriate >
+    let <setting>=<value>
+<line in your ~/.vimrc.
+
+                                                              *loaded_nerd_tree*
+If this plugin is making you feel homicidal, it may be a good idea to turn it
+off with this line in your vimrc: >
+    let loaded_nerd_tree=1
+<
+------------------------------------------------------------------------------
+                                                            *NERDTreeAutoCenter*
+Values: 0 or 1.
+Default: 1
+
+If set to 1, the NERDTree window will center around the cursor if it moves to
+within |NERDTreeAutoCenterThreshold| lines of the top/bottom of the window.
+
+This is ONLY done in response to tree navigation mappings,
+i.e. |NERDTree-J| |NERDTree-K| |NERDTree-C-J| |NERDTree-C-K| |NERDTree-p|
+|NERDTree-P|
+
+The centering is done with a |zz| operation.
+
+------------------------------------------------------------------------------
+                                                   *NERDTreeAutoCenterThreshold*
+Values: Any natural number.
+Default: 3
+
+This setting controls the "sensitivity" of the NERDTree auto centering. See
+|NERDTreeAutoCenter| for details.
+
+------------------------------------------------------------------------------
+                                                     *NERDTreeCaseSensitiveSort*
+Values: 0 or 1.
+Default: 0.
+
+By default the NERDTree does not sort nodes case sensitively, i.e. nodes
+could appear like this: >
+    bar.c
+    Baz.c
+    blarg.c
+    boner.c
+    Foo.c
+<
+But, if you set this setting to 1 then the case of the nodes will be taken
+into account. The above nodes would then be sorted like this: >
+    Baz.c
+    Foo.c
+    bar.c
+    blarg.c
+    boner.c
+<
+------------------------------------------------------------------------------
+                                                           *NERDTreeNaturalSort*
+Values: 0 or 1.
+Default: 0.
+
+By default the NERDTree does not sort nodes in natural sort order, i.e. nodes
+could appear like this: >
+    z1.txt
+    z10.txt
+    z100.txt
+    z11.txt
+    z110.txt
+    z2.txt
+    z20.txt
+    z3.txt
+<
+But if you set this setting to 1 then the natural sort order will be used. The
+above nodes would then be sorted like this: >
+    z1.txt
+    z2.txt
+    z3.txt
+    z10.txt
+    z11.txt
+    z20.txt
+    z100.txt
+    z110.txt
+<
+------------------------------------------------------------------------------
+                                                                *NERDTreeUseTCD*
+Values: 0 or 1.
+Default: 0.
+
+By default, NERDTree will use the `:cd` command to change the current working
+directory. If this setting is turned on, and the `:tcd` command is available, it
+will be used instead.
+
+------------------------------------------------------------------------------
+                                                             *NERDTreeChDirMode*
+Values: 0, 1, 2, or 3.
+Default: 0.
+
+Use this setting to tell the script when (if at all) to change the current
+working directory (CWD) for vim.
+
+If it is set to 0 then the CWD is never changed by the NERDTree.
+
+If set to 1 then the CWD is changed when the NERDTree is first loaded to the
+directory it is initialized in. For example, if you start the NERDTree with >
+    :NERDTree /home/marty/foobar
+<
+then the CWD will be changed to /home/marty/foobar and will not be changed
+again unless you init another NERDTree with a similar command.
+
+If the setting is set to 2 then it behaves the same as if set to 1 except that
+the CWD is changed whenever the tree root is changed. For example, if the CWD
+is /home/marty/foobar and you make the node for /home/marty/foobar/baz the new
+root then the CWD will become /home/marty/foobar/baz.
+
+If the set to 3, then it behaves the same as if set to 2, and the CWD is
+changed whenever changing tabs to whatever the tree root is on that tab.
+
+------------------------------------------------------------------------------
+                                                   *NERDTreeHighlightCursorline*
+Values: 0 or 1.
+Default: 1.
+
+If set to 1, the current cursor line in the NERDTree buffer will be
+highlighted. This is done using the `'cursorline'` Vim option.
+
+------------------------------------------------------------------------------
+                                                           *NERDTreeHijackNetrw*
+Values: 0 or 1.
+Default: 1.
+
+If set to 1, doing a >
+    :edit <some directory>
+<
+will open up a window level NERDTree instead of a netrw in the target window.
+
+Window level trees behaves slightly different from a regular trees in the
+following respects:
+    1. 'o' will open the selected file in the same window as the tree,
+       replacing it.
+    2. you can have one tree per window - instead of per tab.
+
+------------------------------------------------------------------------------
+                                                                *NERDTreeIgnore*
+Values: a list of regular expressions.
+Default: ['\~$'].
+
+This setting is used to specify which files the NERDTree should ignore.  It
+must be a list of regular expressions. When the NERDTree is rendered, any
+files/directories that match any of the regex's in NERDTreeIgnore won't be
+displayed.
+
+For example if you put the following line in your vimrc: >
+    let NERDTreeIgnore=['\.vim$', '\~$']
+<
+then all files ending in .vim or ~ will be ignored.
+
+There are 3 magic flags that can be appended to the end of each regular
+expression to specify that the regex should match only filenames, only lowest
+level directories, or a full path. These flags are "[[dir]]", "[[file]]", and
+"[[path]]". Example: >
+    let NERDTreeIgnore=['\.d$[[dir]]', '\.o$[[file]]', 'tmp/cache$[[path]]']
+<
+This will cause all directories ending in ".d" to be ignored, all files ending
+in ".o" to be ignored, and the "cache" subdirectory of any "tmp" directory to
+be ignored. All other "cache" directories will be displayed.
+
+When using the "[[path]]" tag on Windows, make sure you use escaped
+backslashes for the separators in the regex, eg. 'Temp\\cache$[[path]]'
+
+Note: to tell the NERDTree not to ignore any files you must use the following
+line: >
+    let NERDTreeIgnore=[]
+<
+The file filters can be turned on and off dynamically with the |NERDTree-f|
+mapping.
+
+------------------------------------------------------------------------------
+                                                     *NERDTreeRespectWildIgnore*
+Values: 0 or 1.
+Default: 0.
+
+If set to 1, the `'wildignore'` setting is respected.
+
+------------------------------------------------------------------------------
+                                                         *NERDTreeBookmarksFile*
+Values: a path
+Default: $HOME/.NERDTreeBookmarks
+
+This is where bookmarks are saved. See |NERDTreeBookmarkCommands|.
+
+------------------------------------------------------------------------------
+                                                         *NERDTreeBookmarksSort*
+Values: 0, 1, or 2
+Default: 1
+
+This setting controls the method by which the list of user bookmarks is
+sorted. When sorted, bookmarks will render in alphabetical order by name.
+
+If set to 0, the bookmarks list is not sorted.
+If set to 1, the bookmarks list is sorted in a case-insensitive manner.
+If set to 2, the bookmarks list is sorted in a case-sensitive manner.
+
+------------------------------------------------------------------------------
+                                                         *NERDTreeMarkBookmarks*
+Values: 0 or 1
+Default: 1
+
+If set to 1, Bookmarks will be specially marked whenever the NERDTree is
+rendered. Users of the |NERDTreeMinimalUI| setting may prefer to disable
+this setting for even less visual clutter.
+
+------------------------------------------------------------------------------
+                                                             *NERDTreeMouseMode*
+Values: 1, 2 or 3.
+Default: 1.
+
+If set to 1 then a double click on a node is required to open it.
+If set to 2 then a single click will open directory nodes, while a double
+click will still be required for file nodes.
+If set to 3 then a single click will open any node.
+
+Note: a double click anywhere on a line that a tree node is on will
+activate it, but all single-click activations must be done on name of the node
+itself. For example, if you have the following node: >
+    | | |-application.rb
+<
+then (to single click activate it) you must click somewhere in
+'application.rb'.
+
+------------------------------------------------------------------------------
+                                                            *NERDTreeQuitOnOpen*
+Values: 0,1,2 or 3.
+Default: 0
+
+This setting governs whether the NERDTree window or the bookmarks table closes
+after opening a file with the |NERDTree-o|, |NERDTree-i|, |NERDTree-t| and
+|NERDTree-T| mappings.
+
+ Value  | NERDTree Window Behavior
+ -------+-------------------------------------------------------
+ 0      | No change
+ 1      | Closes after opening a file
+ 2      | Closes the bookmark table after opening a bookmark
+ 3(1+2) | Same as both 1 and 2
+
+------------------------------------------------------------------------------
+                                                         *NERDTreeShowBookmarks*
+Values: 0 or 1.
+Default: 0.
+
+If this setting is set to 1 then the bookmarks table will be displayed.
+
+This setting can be toggled dynamically, per tree, with the |NERDTree-B|
+mapping.
+
+------------------------------------------------------------------------------
+                                                             *NERDTreeShowFiles*
+Values: 0 or 1.
+Default: 1.
+
+If this setting is set to 1 then files are displayed in the NERDTree. If it
+is set to 0 then only directories are displayed.
+
+This setting can be toggled dynamically, per tree, with the |NERDTree-F|
+mapping and is useful for drastically shrinking the tree when you are
+navigating to a different part of the tree.
+
+------------------------------------------------------------------------------
+                                                            *NERDTreeShowHidden*
+Values: 0 or 1.
+Default: 0.
+
+This setting tells vim whether to display hidden files by default. This
+setting can be dynamically toggled, per tree, with the |NERDTree-I| mapping.
+Use one of the follow lines for this setting: >
+    let NERDTreeShowHidden=0
+    let NERDTreeShowHidden=1
+<
+------------------------------------------------------------------------------
+                                                       *NERDTreeShowLineNumbers*
+Values: 0 or 1.
+Default: 0.
+
+This setting tells vim whether to display line numbers for the NERDTree
+window.  Use one of the follow lines for this setting: >
+    let NERDTreeShowLineNumbers=0
+    let NERDTreeShowLineNumbers=1
+<
+------------------------------------------------------------------------------
+                                                             *NERDTreeSortOrder*
+Values: a list of regular expressions.
+Default: ['\/$', '*', '\.swp$',  '\.bak$', '\~$']
+
+This setting is a list of regular expressions which are used to group or sort
+the nodes under their parent.
+
+For example, if the setting is: >
+    ['\.vim$', '\.c$', '\.h$', '*', 'foobar']
+<
+then all .vim files will be grouped at the top, followed by all .c files then
+all .h files. All files containing the string 'foobar' will be placed at the
+end.  The star is a special flag: it tells the script that every node that
+doesn't match any of the other regexps should be placed here.
+
+If no star is present in NERDTreeSortOrder, then one is automatically
+appended to the end of the list.
+
+The regex '\/$' should be used to match directory nodes.
+
+Files can also be sorted by 1) the modification timestamp, 2) the size, or 3)
+the extension. Directories are always sorted by name. To accomplish this, the
+following special flags are used:
+  [[timestamp]]   [[-timestamp]]   [[size]]   [[-size]]   [[extension]]
+The hyphen specifies a descending sort; extensions are sorted in ascending
+order only. If placed at the beginning of the list, files are sorted according
+to these flags first, and then grouped by the remaining items in the list. If
+the flags are in any other position of the list, this special sorting is done
+secondarily. See examples 4, 5, and 6 below.
+
+After this sorting is done, the files in each group are sorted alphabetically.
+
+Examples: >
+    (1) ['*', '\/$']
+    (2) []
+    (3) ['\/$', '\.rb$', '\.php$', '*', '\.swp$',  '\.bak$', '\~$']
+    (4) ['[[-size]]']
+    (5) ['\/$', '*', '[[timestamp]]']
+    (6) ['foo','\/$','[[extension]]']
+<
+1. Directories will appear last, everything else will appear above.
+2. Everything will simply appear in alphabetical order.
+3. Directories will appear first, then ruby and php. Swap files, bak files
+   and vim backup files will appear last with everything else preceding them.
+4. Everything is sorted by size, largest to smallest, with directories
+   considered to have size 0 bytes.
+5. Directories will appear first alphabetically, followed by files, sorted by
+   timestamp, oldest first.
+6. Files and directories matching 'foo' first, followed by other directories,
+   then all other files. Each section of files is sorted by file extension.
+
+------------------------------------------------------------------------------
+                                                            *NERDTreeStatusline*
+Values: Any valid `'statusline'` setting.
+Default: %{exists('b:NERDTree')?b:NERDTree.root.path.str():''}
+
+Defines the value for the `'statusline'` setting in NERDTree windows.
+
+Note: The setting is actually applied using |:let-&|, not |:set|, so
+escaping spaces is not necessary.
+
+Setting this to -1 will deactivate it so that your global `'statusline'`
+setting is used.
+
+------------------------------------------------------------------------------
+                                                                *NERDTreeWinPos*
+Values: "left" or "right"
+Default: "left".
+
+This setting is used to determine where NERDTree window is placed on the
+screen.
+
+This setting makes it possible to use two different explorer plugins
+simultaneously. For example, you could have the taglist plugin on the left of
+the window and the NERDTree on the right.
+
+------------------------------------------------------------------------------
+                                                               *NERDTreeWinSize*
+Values: a positive integer.
+Default: 31.
+
+This setting is used to change the size of the NERDTree when it is loaded.
+
+------------------------------------------------------------------------------
+                                                             *NERDTreeMinimalUI*
+Values: 0 or 1
+Default: 0
+
+This setting disables the 'Bookmarks' label 'Press ? for help' text. Use one
+of the following lines for this setting: >
+    let NERDTreeMinimalUI=0
+    let NERDTreeMinimalUI=1
+<
+------------------------------------------------------------------------------
+                                                           *NERDTreeMinimalMenu*
+Values: 0 or 1
+Default: 0
+
+This setting makes NERDTree use a smaller, more compact menu for adding,
+copying, deleting nodes. This menu fits on a single line so Vim doesn't need to
+scroll down to present it. This setting is recommended for users already
+familiar with the menu items. It will look similar to this:
+
+  Menu: [ (a)dd ,m,d,r,o,q,c,l] (Use j/k/enter or shortcut):
+
+An action can be selected with its shortcut key or with the NERDTreeMenuUp and
+NERDTreeMenuDown keys, then pressing enter.
+
+Use one of the following lines for this setting: >
+    let NERDTreeMinimalMenu=0
+    let NERDTreeMinimalMenu=1
+<
+------------------------------------------------------------------------------
+                                                 *NERDTreeCascadeSingleChildDir*
+Values: 0 or 1
+Default: 1.
+
+When displaying directory nodes, this setting tells NERDTree to collapse
+directories that have only one child. Use one of the following lines for this
+setting: >
+    let NERDTreeCascadeSingleChildDir=0
+    let NERDTreeCascadeSingleChildDir=1
+<
+------------------------------------------------------------------------------
+                                             *NERDTreeCascadeOpenSingleChildDir*
+Values: 0 or 1
+Default: 1.
+
+When opening directory nodes, this setting tells NERDTree to recursively open
+directories that have only one child which is also a directory. NERDTree will
+stop when it finds a directory that contains anything but another single
+directory. This setting also causes the |NERDTree-x| mapping to close
+directories in the same manner. This setting may be useful for Java projects.
+Use one of the following lines for this setting: >
+    let NERDTreeCascadeOpenSingleChildDir=0
+    let NERDTreeCascadeOpenSingleChildDir=1
+<
+------------------------------------------------------------------------------
+                                                      *NERDTreeAutoDeleteBuffer*
+Values: 0 or 1
+Default: 0.
+
+When using a context menu to delete or rename a file you may also want to
+delete the buffer which is no more valid. If the setting is not set you will
+see a confirmation if you really want to delete an old buffer. If you always
+press 'y' then it's worth it to set this setting to 1. Use one of the
+following lines for this setting: >
+    let NERDTreeAutoDeleteBuffer=0
+    let NERDTreeAutoDeleteBuffer=1
+<
+------------------------------------------------------------------------------
+                                                          *NERDTreeCreatePrefix*
+Values: Any valid command prefix.
+Default: "silent".
+
+Internally, NERDTree uses the |:edit| command to create a buffer in which to
+display its tree view. You can augment this behavior by specifying a prefix
+string such as "keepalt" or similar. For example, to have NERDTree create its
+tree window using `silent keepalt keepjumps edit`: >
+    let NERDTreeCreatePrefix='silent keepalt keepjumps'
+<
+------------------------------------------------------------------------------
+                        *NERDTreeDirArrowCollapsible* *NERDTreeDirArrowExpandable*
+Values: Any single character.
+Defaults:   Windows: ~ and +    Others: ▾ and ▸
+
+These characters indicate whether a directory is collapsible or expandable.
+Example: >
+    let NERDTreeDirArrowExpandable=">"
+    let NERDTreeDirArrowCollapsible="v"
+<
+They can be set to "\u00a0" to replace the arrows with a non-breaking space.
+If you do this you may need to change the node delimiter. See
+|NERDTreeNodeDelimiter|. You cannot use the same character for both the arrows
+and the delimiter.
+
+Alternatively, they can be set to '' (an empty string). This removes the
+arrows and the single space that follows them, shifting the entire tree two
+character positions to the left.
+
+------------------------------------------------------------------------------
+                                                         *NERDTreeNodeDelimiter*
+Values: Any single character.
+Default: varies (see below)
+
+This character is used to separate the file or directory name from the rest of
+the characters in the line of text. It allows filenames to contain special
+characters that are otherwise used in the NERDTree, such as square brackets,
+braces, trailing asterisk, and leading space. For more details, see the
+responsible pull request: https://github.com/preservim/nerdtree/pull/868.
+
+The default value of this variable depends on the features compiled into your
+vim and the values of |NERDTreeDirArrowCollapsible| and
+|NERDTreeDirArrowExpandable|.
+  * If your vim is compiled with the +conceal feature, it is the "\x07"
+    (BEL) character, and it is hidden by setting 'conceallevel' to 2. If you
+    use autocommands, make sure none of them change that setting in the
+    NERD_Tree_* buffers.
+  * If your vim does NOT have the +conceal feature and you're using "\u00a0"
+    (non-breaking space) to hide the directory arrows, "\u00b7" (middle dot)
+    is used as the default delimiter.
+  * If neither condition above applies, NERDTree uses "\u00a0" (non-breaking
+    space) as the default delimiter.
+
+In the 2nd and 3rd cases, NERDTree will use the Ignore highlight group to
+"hide" the delimiter. It should appear as an empty space.
+
+Other plugins can interfere with these defaults, so if you need to change the
+delimiter, be sure to choose a character that won't appear in your filenames
+or any of the flags set by your installed NERDTree plugins. The suggestions
+below are but a few of the many possibilities. Remember to use double quotes
+when specifying by hex or Unicode. >
+    let NERDTreeNodeDelimiter="\x07"     "bell
+    let NERDTreeNodeDelimiter="\u00b7"   "middle dot
+    let NERDTreeNodeDelimiter="\u00a0"   "non-breaking space
+    let NERDTreeNodeDelimiter="😀"       "smiley face
+<
+------------------------------------------------------------------------------
+                                                        *NERDTreeCustomOpenArgs*
+Values: A nested dictionary, as described below
+Default: {'file': {'reuse': 'all', 'where': 'p'}, 'dir': {}}
+
+This dictionary contains two keys, 'file' and 'dir', whose values each are
+another dictionary. The inner dictionary is a set of parameters used by
+|NERDTree-<CR>| to open a file or directory. Setting these parameters allows you
+to customize the way the node is opened. The default value matches what
+|NERDTree-o| does. To change that behavior, use these keys and
+values in the inner dictionaries:
+
+'where':    specifies whether the node should be opened in a new split ("h" or
+            "v"), in a new tab ("t") or, in the last window ("p").
+'reuse':    if file is already shown in a window, jump there; takes values
+            "all", "currenttab", or empty
+'keepopen': boolean (0 or 1); if true, the tree window will not be closed
+'stay':     boolean (0 or 1); if true, remain in tree window after opening
+
+For example:
+To open files and directories (creating a new NERDTree) in a new tab, >
+    {'file':{'where': 't'}, 'dir':{'where':'t'}}
+<
+To open a file always in the current tab, and expand directories in place, >
+    {'file': {'reuse':'currenttab', 'where':'p', 'keepopen':1, 'stay':1}}
+<
+==============================================================================
+4. The NERDTree API                                                *NERDTreeAPI*
+
+The NERDTree script allows you to add custom key mappings and menu items via
+a set of API calls. Any scripts that use this API should be placed in
+~/.vim/nerdtree_plugin/ (*nix) or ~/vimfiles/nerdtree_plugin (windows).
+
+The script exposes some prototype objects that can be used to manipulate the
+tree and/or get information from it: >
+    g:NERDTreePath
+    g:NERDTreeDirNode
+    g:NERDTreeFileNode
+    g:NERDTreeBookmark
+<
+See the code/comments in NERD_tree.vim to find how to use these objects. The
+following code conventions are used:
+    * class members start with a capital letter
+    * instance members start with a lower case letter
+    * private members start with an underscore
+
+See this blog post for more details:
+ http://got-ravings.blogspot.com/2008/09/vim-pr0n-prototype-based-objects.html
+
+A number of API functions take a callback argument to call. The callback can
+be either a string with the name of a function to call, or a |Funcref| object
+which will be called directly.
+
+------------------------------------------------------------------------------
+4.1. Key map API                                             *NERDTreeKeymapAPI*
+
+NERDTreeAddKeyMap({options})                               *NERDTreeAddKeyMap()*
+    Adds a new keymapping for all NERDTree buffers.
+    {options} must be a dictionary, and must contain the following keys:
+    "key" - the trigger key for the new mapping
+    "callback" - the function the new mapping will be bound to
+    "quickhelpText" - the text that will appear in the quickhelp (see
+    |NERDTree-?|)
+    "override" - if 1 then this new mapping will override whatever previous
+    mapping was defined for the key/scope combo. Useful for overriding the
+    default mappings.
+
+    Additionally, a "scope" argument may be supplied. This constrains the
+    mapping so that it is only activated if the cursor is on a certain object.
+    That object is then passed into the handling method. Possible values are:
+
+      "FileNode" .... a file node
+      "DirNode" ..... a directory node
+      "Node" ........ a file node OR a directory node
+      "Bookmark" .... a bookmark
+      "all" ......... global scope; handler receives no arguments (default)
+
+    Example: >
+        call NERDTreeAddKeyMap({
+               \ 'key': 'foo',
+               \ 'callback': 'NERDTreeEchoPathHandler',
+               \ 'quickhelpText': 'echo full path of current node',
+               \ 'scope': 'DirNode' })
+
+        function! NERDTreeEchoPathHandler(dirnode)
+            echo a:dirnode.path.str()
+        endfunction
+<
+    This code should sit in a file like ~/.vim/nerdtree_plugin/mymapping.vim.
+    It adds a (redundant) mapping on 'foo' which changes vim's CWD to that of
+    the current directory node. Note this mapping will only fire when the
+    cursor is on a directory node.
+
+------------------------------------------------------------------------------
+4.2. Menu API                                                  *NERDTreeMenuAPI*
+
+NERDTreeAddSubmenu({options})                             *NERDTreeAddSubmenu()*
+    Creates and returns a new submenu.
+
+    {options} must be a dictionary and must contain the following keys:
+    "text" - the text of the submenu that the user will see
+    "shortcut" - a shortcut key for the submenu (need not be unique)
+
+    The following keys are optional:
+    "isActiveCallback" - a function that will be called to determine whether
+    this submenu item will be displayed or not. The callback function must
+    return 0 or 1.
+    "parent" - the parent submenu of the new submenu (returned from a previous
+    invocation of NERDTreeAddSubmenu()). If this key is left out then the new
+    submenu will sit under the top level menu.
+
+    See below for an example.
+
+NERDTreeAddMenuItem({options})                           *NERDTreeAddMenuItem()*
+    Adds a new menu item to the NERDTree menu (see |NERDTreeMenu|).
+
+    {options} must be a dictionary and must contain the
+    following keys:
+    "text" - the text of the menu item which the user will see
+    "shortcut" - a shortcut key for the menu item (need not be unique)
+    "callback" - the function that will be called when the user activates the
+    menu item.
+
+    The following keys are optional:
+    "isActiveCallback" - a function that will be called to determine whether
+    this menu item will be displayed or not. The callback function must return
+    0 or 1.
+    "parent" - if the menu item belongs under a submenu then this key must be
+    specified. This value for this key will be the object that
+    was returned when the submenu was created with |NERDTreeAddSubmenu()|.
+
+    See below for an example.
+
+NERDTreeAddMenuSeparator([{options}])               *NERDTreeAddMenuSeparator()*
+    Adds a menu separator (a row of dashes).
+
+    {options} is an optional dictionary that may contain the following keys:
+    "isActiveCallback" - see description in |NERDTreeAddMenuItem()|.
+
+Below is an example of the menu API in action. >
+    call NERDTreeAddMenuSeparator()
+
+    call NERDTreeAddMenuItem({
+                \ 'text': 'a (t)op level menu item',
+                \ 'shortcut': 't',
+                \ 'callback': 'SomeFunction' })
+
+    let submenu = NERDTreeAddSubmenu({
+                \ 'text': 'a (s)ub menu',
+                \ 'shortcut': 's' })
+
+    call NERDTreeAddMenuItem({
+                \ 'text': '(n)ested item 1',
+                \ 'shortcut': 'n',
+                \ 'callback': 'SomeFunction',
+                \ 'parent': submenu })
+
+    call NERDTreeAddMenuItem({
+                \ 'text': '(n)ested item 2',
+                \ 'shortcut': 'n',
+                \ 'callback': 'SomeFunction',
+                \ 'parent': submenu })
+<
+This will create the following menu: >
+  --------------------
+  a (t)op level menu item
+  a (s)ub menu
+<
+Where selecting "a (s)ub menu" will lead to a second menu: >
+  (n)ested item 1
+  (n)ested item 2
+<
+When any of the 3 concrete menu items are selected the function "SomeFunction"
+will be called.
+
+------------------------------------------------------------------------------
+4.3 NERDTreeAddPathFilter(callback)                    *NERDTreeAddPathFilter()*
+
+Path filters are essentially a more powerful version of  |NERDTreeIgnore|.
+If the simple regex matching in |NERDTreeIgnore| is not enough then use
+|NERDTreeAddPathFilter()| to add a callback function that paths will be
+checked against when the decision to ignore them is made. Example >
+
+    call NERDTreeAddPathFilter('MyFilter')
+
+    function! MyFilter(params)
+        "params is a dict containing keys: 'nerdtree' and 'path' which are
+        "g:NERDTree and g:NERDTreePath objects
+
+        "return 1 to ignore params['path'] or 0 otherwise
+    endfunction
+<
+------------------------------------------------------------------------------
+4.4 Path Listener API                                  *NERDTreePathListenerAPI*
+
+Use this API if you want to run a callback for events on Path objects. E.G >
+
+    call g:NERDTreePathNotifier.AddListener("init", "MyListener")
+
+    "....
+
+    function! MyListener(event)
+        "This function will be called whenever a Path object is created.
+
+        "a:event is an object that contains a bunch of relevant info -
+        "including the affected path. See lib/nerdtree/event.vim for details.
+    endfunction
+<
+Current events supported:
+  init ~
+  refresh ~
+  refreshFlags ~
+
+------------------------------------------------------------------------------
+NERDTreeRender()                                              *NERDTreeRender()*
+    Re-renders the NERDTree buffer. Useful if you change the state of the
+    tree and you want to it to be reflected in the UI.
+
+==============================================================================
+5. About                                                         *NERDTreeAbout*
+
+The author of the NERDTree is a terrible terrible monster called Martyzilla
+who gobbles up small children with milk and sugar for breakfast.
+
+He can be reached at martin.grenfell at gmail dot com. He would love to hear
+from you, so feel free to send him suggestions and/or comments about this
+plugin.  Don't be shy --- the worst he can do is slaughter you and stuff you
+in the fridge for later ;)
+
+Martyzilla recruited two other unwitting accomplices to become his minions in
+his quest to conquer the Vim plugin world. While he may still love to receive
+your emails, the best way to send suggestions, bug reports, and questions is
+to submit an issue at http://github.com/preservim/nerdtree/issues.
+
+The latest stable and development versions are on Github.
+    Stable: http://github.com/preservim/nerdtree (master branch)
+    Development: http://github.com/preservim/nerdtree/branches
+
+Title Credit:
+  * http://ascii.co.uk/art/tree
+
+  * Patrick Gillespie's Text ASCII Art Generator
+    http://patorjk.com/software/taag
+    http://patorjk.com/software/taag/#p=display&f=Rozzo&t=the%20NERD%20Tree
+
+==============================================================================
+6. License                                                     *NERDTreeLicense*
+
+The NERDTree is released under the wtfpl.
+See http://sam.zoy.org/wtfpl/COPYING.
+
+------------------------------------------------------------------------------
+ vim:tw=78:ts=8:ft=help:noet:nospell

+ 143 - 0
vimfiles/bundle/nerdtree/doc/tags

@@ -0,0 +1,143 @@
+:NERDTree	NERDTree.txt	/*:NERDTree*
+:NERDTreeCWD	NERDTree.txt	/*:NERDTreeCWD*
+:NERDTreeClose	NERDTree.txt	/*:NERDTreeClose*
+:NERDTreeFind	NERDTree.txt	/*:NERDTreeFind*
+:NERDTreeFocus	NERDTree.txt	/*:NERDTreeFocus*
+:NERDTreeFromBookmark	NERDTree.txt	/*:NERDTreeFromBookmark*
+:NERDTreeMirror	NERDTree.txt	/*:NERDTreeMirror*
+:NERDTreeRefreshRoot	NERDTree.txt	/*:NERDTreeRefreshRoot*
+:NERDTreeToggle	NERDTree.txt	/*:NERDTreeToggle*
+:NERDTreeToggleVCS	NERDTree.txt	/*:NERDTreeToggleVCS*
+:NERDTreeVCS	NERDTree.txt	/*:NERDTreeVCS*
+NERDTree	NERDTree.txt	/*NERDTree*
+NERDTree-<CR>	NERDTree.txt	/*NERDTree-<CR>*
+NERDTree-?	NERDTree.txt	/*NERDTree-?*
+NERDTree-A	NERDTree.txt	/*NERDTree-A*
+NERDTree-B	NERDTree.txt	/*NERDTree-B*
+NERDTree-C	NERDTree.txt	/*NERDTree-C*
+NERDTree-C-J	NERDTree.txt	/*NERDTree-C-J*
+NERDTree-C-K	NERDTree.txt	/*NERDTree-C-K*
+NERDTree-CD	NERDTree.txt	/*NERDTree-CD*
+NERDTree-D	NERDTree.txt	/*NERDTree-D*
+NERDTree-F	NERDTree.txt	/*NERDTree-F*
+NERDTree-I	NERDTree.txt	/*NERDTree-I*
+NERDTree-J	NERDTree.txt	/*NERDTree-J*
+NERDTree-K	NERDTree.txt	/*NERDTree-K*
+NERDTree-O	NERDTree.txt	/*NERDTree-O*
+NERDTree-P	NERDTree.txt	/*NERDTree-P*
+NERDTree-R	NERDTree.txt	/*NERDTree-R*
+NERDTree-T	NERDTree.txt	/*NERDTree-T*
+NERDTree-U	NERDTree.txt	/*NERDTree-U*
+NERDTree-X	NERDTree.txt	/*NERDTree-X*
+NERDTree-cd	NERDTree.txt	/*NERDTree-cd*
+NERDTree-contents	NERDTree.txt	/*NERDTree-contents*
+NERDTree-e	NERDTree.txt	/*NERDTree-e*
+NERDTree-f	NERDTree.txt	/*NERDTree-f*
+NERDTree-gi	NERDTree.txt	/*NERDTree-gi*
+NERDTree-go	NERDTree.txt	/*NERDTree-go*
+NERDTree-gs	NERDTree.txt	/*NERDTree-gs*
+NERDTree-i	NERDTree.txt	/*NERDTree-i*
+NERDTree-m	NERDTree.txt	/*NERDTree-m*
+NERDTree-o	NERDTree.txt	/*NERDTree-o*
+NERDTree-p	NERDTree.txt	/*NERDTree-p*
+NERDTree-q	NERDTree.txt	/*NERDTree-q*
+NERDTree-r	NERDTree.txt	/*NERDTree-r*
+NERDTree-s	NERDTree.txt	/*NERDTree-s*
+NERDTree-t	NERDTree.txt	/*NERDTree-t*
+NERDTree-u	NERDTree.txt	/*NERDTree-u*
+NERDTree-x	NERDTree.txt	/*NERDTree-x*
+NERDTree.txt	NERDTree.txt	/*NERDTree.txt*
+NERDTreeAPI	NERDTree.txt	/*NERDTreeAPI*
+NERDTreeAbout	NERDTree.txt	/*NERDTreeAbout*
+NERDTreeAddKeyMap()	NERDTree.txt	/*NERDTreeAddKeyMap()*
+NERDTreeAddMenuItem()	NERDTree.txt	/*NERDTreeAddMenuItem()*
+NERDTreeAddMenuSeparator()	NERDTree.txt	/*NERDTreeAddMenuSeparator()*
+NERDTreeAddPathFilter()	NERDTree.txt	/*NERDTreeAddPathFilter()*
+NERDTreeAddSubmenu()	NERDTree.txt	/*NERDTreeAddSubmenu()*
+NERDTreeAutoCenter	NERDTree.txt	/*NERDTreeAutoCenter*
+NERDTreeAutoCenterThreshold	NERDTree.txt	/*NERDTreeAutoCenterThreshold*
+NERDTreeAutoDeleteBuffer	NERDTree.txt	/*NERDTreeAutoDeleteBuffer*
+NERDTreeBookmarkCommands	NERDTree.txt	/*NERDTreeBookmarkCommands*
+NERDTreeBookmarkTable	NERDTree.txt	/*NERDTreeBookmarkTable*
+NERDTreeBookmarks	NERDTree.txt	/*NERDTreeBookmarks*
+NERDTreeBookmarksFile	NERDTree.txt	/*NERDTreeBookmarksFile*
+NERDTreeBookmarksSort	NERDTree.txt	/*NERDTreeBookmarksSort*
+NERDTreeCascadeOpenSingleChildDir	NERDTree.txt	/*NERDTreeCascadeOpenSingleChildDir*
+NERDTreeCascadeSingleChildDir	NERDTree.txt	/*NERDTreeCascadeSingleChildDir*
+NERDTreeCaseSensitiveSort	NERDTree.txt	/*NERDTreeCaseSensitiveSort*
+NERDTreeChDirMode	NERDTree.txt	/*NERDTreeChDirMode*
+NERDTreeCreatePrefix	NERDTree.txt	/*NERDTreeCreatePrefix*
+NERDTreeCustomOpenArgs	NERDTree.txt	/*NERDTreeCustomOpenArgs*
+NERDTreeDirArrowCollapsible	NERDTree.txt	/*NERDTreeDirArrowCollapsible*
+NERDTreeDirArrowExpandable	NERDTree.txt	/*NERDTreeDirArrowExpandable*
+NERDTreeFunctionality	NERDTree.txt	/*NERDTreeFunctionality*
+NERDTreeGlobalCommands	NERDTree.txt	/*NERDTreeGlobalCommands*
+NERDTreeHighlightCursorline	NERDTree.txt	/*NERDTreeHighlightCursorline*
+NERDTreeHijackNetrw	NERDTree.txt	/*NERDTreeHijackNetrw*
+NERDTreeIgnore	NERDTree.txt	/*NERDTreeIgnore*
+NERDTreeInvalidBookmarks	NERDTree.txt	/*NERDTreeInvalidBookmarks*
+NERDTreeKeymapAPI	NERDTree.txt	/*NERDTreeKeymapAPI*
+NERDTreeLicense	NERDTree.txt	/*NERDTreeLicense*
+NERDTreeMapCWD	NERDTree.txt	/*NERDTreeMapCWD*
+NERDTreeMapChangeRoot	NERDTree.txt	/*NERDTreeMapChangeRoot*
+NERDTreeMapChdir	NERDTree.txt	/*NERDTreeMapChdir*
+NERDTreeMapCloseChildren	NERDTree.txt	/*NERDTreeMapCloseChildren*
+NERDTreeMapCloseDir	NERDTree.txt	/*NERDTreeMapCloseDir*
+NERDTreeMapCustomOpen	NERDTree.txt	/*NERDTreeMapCustomOpen*
+NERDTreeMapDeleteBookmark	NERDTree.txt	/*NERDTreeMapDeleteBookmark*
+NERDTreeMapHelp	NERDTree.txt	/*NERDTreeMapHelp*
+NERDTreeMapJumpFirstChild	NERDTree.txt	/*NERDTreeMapJumpFirstChild*
+NERDTreeMapJumpLastChild	NERDTree.txt	/*NERDTreeMapJumpLastChild*
+NERDTreeMapJumpNextSibling	NERDTree.txt	/*NERDTreeMapJumpNextSibling*
+NERDTreeMapJumpParent	NERDTree.txt	/*NERDTreeMapJumpParent*
+NERDTreeMapJumpPrevSibling	NERDTree.txt	/*NERDTreeMapJumpPrevSibling*
+NERDTreeMapJumpRoot	NERDTree.txt	/*NERDTreeMapJumpRoot*
+NERDTreeMapMenu	NERDTree.txt	/*NERDTreeMapMenu*
+NERDTreeMapOpenExpl	NERDTree.txt	/*NERDTreeMapOpenExpl*
+NERDTreeMapOpenInTab	NERDTree.txt	/*NERDTreeMapOpenInTab*
+NERDTreeMapOpenInTabSilent	NERDTree.txt	/*NERDTreeMapOpenInTabSilent*
+NERDTreeMapOpenRecursively	NERDTree.txt	/*NERDTreeMapOpenRecursively*
+NERDTreeMapOpenSplit	NERDTree.txt	/*NERDTreeMapOpenSplit*
+NERDTreeMapOpenVSplit	NERDTree.txt	/*NERDTreeMapOpenVSplit*
+NERDTreeMapPreviewSplit	NERDTree.txt	/*NERDTreeMapPreviewSplit*
+NERDTreeMapPreviewVSplit	NERDTree.txt	/*NERDTreeMapPreviewVSplit*
+NERDTreeMapQuit	NERDTree.txt	/*NERDTreeMapQuit*
+NERDTreeMapRefresh	NERDTree.txt	/*NERDTreeMapRefresh*
+NERDTreeMapRefreshRoot	NERDTree.txt	/*NERDTreeMapRefreshRoot*
+NERDTreeMapToggleBookmarks	NERDTree.txt	/*NERDTreeMapToggleBookmarks*
+NERDTreeMapToggleFiles	NERDTree.txt	/*NERDTreeMapToggleFiles*
+NERDTreeMapToggleFilters	NERDTree.txt	/*NERDTreeMapToggleFilters*
+NERDTreeMapToggleHidden	NERDTree.txt	/*NERDTreeMapToggleHidden*
+NERDTreeMapToggleZoom	NERDTree.txt	/*NERDTreeMapToggleZoom*
+NERDTreeMapUpdir	NERDTree.txt	/*NERDTreeMapUpdir*
+NERDTreeMapUpdirKeepOpen	NERDTree.txt	/*NERDTreeMapUpdirKeepOpen*
+NERDTreeMappings	NERDTree.txt	/*NERDTreeMappings*
+NERDTreeMarkBookmarks	NERDTree.txt	/*NERDTreeMarkBookmarks*
+NERDTreeMenu	NERDTree.txt	/*NERDTreeMenu*
+NERDTreeMenu-j	NERDTree.txt	/*NERDTreeMenu-j*
+NERDTreeMenu-k	NERDTree.txt	/*NERDTreeMenu-k*
+NERDTreeMenuAPI	NERDTree.txt	/*NERDTreeMenuAPI*
+NERDTreeMenuDown	NERDTree.txt	/*NERDTreeMenuDown*
+NERDTreeMenuUp	NERDTree.txt	/*NERDTreeMenuUp*
+NERDTreeMinimalMenu	NERDTree.txt	/*NERDTreeMinimalMenu*
+NERDTreeMinimalUI	NERDTree.txt	/*NERDTreeMinimalUI*
+NERDTreeMouseMode	NERDTree.txt	/*NERDTreeMouseMode*
+NERDTreeNaturalSort	NERDTree.txt	/*NERDTreeNaturalSort*
+NERDTreeNodeDelimiter	NERDTree.txt	/*NERDTreeNodeDelimiter*
+NERDTreePathListenerAPI	NERDTree.txt	/*NERDTreePathListenerAPI*
+NERDTreeQuitOnOpen	NERDTree.txt	/*NERDTreeQuitOnOpen*
+NERDTreeRender()	NERDTree.txt	/*NERDTreeRender()*
+NERDTreeRespectWildIgnore	NERDTree.txt	/*NERDTreeRespectWildIgnore*
+NERDTreeSettings	NERDTree.txt	/*NERDTreeSettings*
+NERDTreeSettingsDetails	NERDTree.txt	/*NERDTreeSettingsDetails*
+NERDTreeSettingsSummary	NERDTree.txt	/*NERDTreeSettingsSummary*
+NERDTreeShowBookmarks	NERDTree.txt	/*NERDTreeShowBookmarks*
+NERDTreeShowFiles	NERDTree.txt	/*NERDTreeShowFiles*
+NERDTreeShowHidden	NERDTree.txt	/*NERDTreeShowHidden*
+NERDTreeShowLineNumbers	NERDTree.txt	/*NERDTreeShowLineNumbers*
+NERDTreeSortOrder	NERDTree.txt	/*NERDTreeSortOrder*
+NERDTreeStatusline	NERDTree.txt	/*NERDTreeStatusline*
+NERDTreeUseTCD	NERDTree.txt	/*NERDTreeUseTCD*
+NERDTreeWinPos	NERDTree.txt	/*NERDTreeWinPos*
+NERDTreeWinSize	NERDTree.txt	/*NERDTreeWinSize*
+loaded_nerd_tree	NERDTree.txt	/*loaded_nerd_tree*

+ 365 - 0
vimfiles/bundle/nerdtree/lib/nerdtree/bookmark.vim

@@ -0,0 +1,365 @@
+" ============================================================================
+" CLASS: Bookmark
+"
+" The Bookmark class serves two purposes:
+"   (1) It is the top-level prototype for new, concrete Bookmark objects.
+"   (2) It provides an interface for client code to query and manipulate the
+"       global list of Bookmark objects within the current Vim session.
+" ============================================================================
+
+
+let s:Bookmark = {}
+let g:NERDTreeBookmark = s:Bookmark
+
+" FUNCTION: Bookmark.activate(nerdtree) {{{1
+function! s:Bookmark.activate(nerdtree, ...)
+    call self.open(a:nerdtree, a:0 ? a:1 : {})
+endfunction
+
+" FUNCTION: Bookmark.AddBookmark(name, path) {{{1
+" Class method to add a new bookmark to the list, if a previous bookmark exists
+" with the same name, just update the path for that bookmark
+function! s:Bookmark.AddBookmark(name, path)
+    for i in s:Bookmark.Bookmarks()
+        if i.name ==# a:name
+            let i.path = a:path
+            return
+        endif
+    endfor
+    call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path))
+endfunction
+
+" FUNCTION: Bookmark.Bookmarks() {{{1
+" Class method to get all bookmarks. Lazily initializes the bookmarks global
+" variable
+function! s:Bookmark.Bookmarks()
+    if !exists('g:NERDTreeBookmarks')
+        let g:NERDTreeBookmarks = []
+    endif
+    return g:NERDTreeBookmarks
+endfunction
+
+" FUNCTION: Bookmark.BookmarkExistsFor(name) {{{1
+" class method that returns 1 if a bookmark with the given name is found, 0
+" otherwise
+function! s:Bookmark.BookmarkExistsFor(name)
+    try
+        call s:Bookmark.BookmarkFor(a:name)
+        return 1
+    catch /^NERDTree.BookmarkNotFoundError/
+        return 0
+    endtry
+endfunction
+
+" FUNCTION: Bookmark.BookmarkFor(name) {{{1
+" Class method that returns the Bookmark object having the specified name.
+" Throws NERDTree.BookmarkNotFoundError if no Bookmark is found.
+function! s:Bookmark.BookmarkFor(name)
+    let l:result = {}
+    for l:bookmark in s:Bookmark.Bookmarks()
+        if l:bookmark.name ==# a:name
+            let l:result = l:bookmark
+            break
+        endif
+    endfor
+    if empty(l:result)
+        throw 'NERDTree.BookmarkNotFoundError: "' . a:name  . '" not found'
+    endif
+    return l:result
+endfunction
+
+" FUNCTION: Bookmark.BookmarkNames() {{{1
+" Class method to return an array of all bookmark names
+function! s:Bookmark.BookmarkNames()
+    let names = []
+    for i in s:Bookmark.Bookmarks()
+        call add(names, i.name)
+    endfor
+    return names
+endfunction
+
+" FUNCTION: Bookmark.CacheBookmarks(silent) {{{1
+" Class method to read all bookmarks from the bookmarks file initialize
+" bookmark objects for each one.
+"
+" Args:
+" silent - dont echo an error msg if invalid bookmarks are found
+function! s:Bookmark.CacheBookmarks(silent)
+    if filereadable(g:NERDTreeBookmarksFile)
+        let g:NERDTreeBookmarks = []
+        let g:NERDTreeInvalidBookmarks = []
+        let bookmarkStrings = readfile(g:NERDTreeBookmarksFile)
+        let invalidBookmarksFound = 0
+        for i in bookmarkStrings
+
+            "ignore blank lines
+            if i !=# ''
+
+                let name = substitute(i, '^\(.\{-}\) .*$', '\1', '')
+                let path = substitute(i, '^.\{-} \(.*\)$', '\1', '')
+                let path = fnamemodify(path, ':p')
+
+                try
+                    let bookmark = s:Bookmark.New(name, g:NERDTreePath.New(path))
+                    call add(g:NERDTreeBookmarks, bookmark)
+                catch /^NERDTree.InvalidArgumentsError/
+                    call add(g:NERDTreeInvalidBookmarks, i)
+                    let invalidBookmarksFound += 1
+                endtry
+            endif
+        endfor
+        if invalidBookmarksFound
+            call s:Bookmark.Write()
+            if !a:silent
+                call nerdtree#echo(invalidBookmarksFound . ' invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.')
+            endif
+        endif
+    endif
+endfunction
+
+" FUNCTION: Bookmark.CompareBookmarksByName(firstBookmark, secondBookmark) {{{1
+" Class method that indicates the relative position of two bookmarks when
+" placed in alphabetical order by name. Case-sensitivity is determined by an
+" option. Supports the s:Bookmark.SortBookmarksList() method.
+function! s:Bookmark.CompareBookmarksByName(firstBookmark, secondBookmark)
+    let l:result = 0
+    if g:NERDTreeBookmarksSort ==# 1
+        if a:firstBookmark.name <? a:secondBookmark.name
+            let l:result = -1
+        elseif a:firstBookmark.name >? a:secondBookmark.name
+            let l:result = 1
+        endif
+    elseif g:NERDTreeBookmarksSort ==# 2
+        if a:firstBookmark.name <# a:secondBookmark.name
+            let l:result = -1
+        elseif a:firstBookmark.name ># a:secondBookmark.name
+            let l:result = 1
+        endif
+    endif
+    return l:result
+endfunction
+
+" FUNCTION: Bookmark.ClearAll() {{{1
+" Class method to delete all bookmarks.
+function! s:Bookmark.ClearAll()
+    for i in s:Bookmark.Bookmarks()
+        call i.delete()
+    endfor
+    call s:Bookmark.Write()
+endfunction
+
+" FUNCTION: Bookmark.delete() {{{1
+" Delete this bookmark. If the node for this bookmark is under the current
+" root, then recache bookmarks for its Path object
+function! s:Bookmark.delete()
+    call remove(s:Bookmark.Bookmarks(), index(s:Bookmark.Bookmarks(), self))
+    call s:Bookmark.Write()
+endfunction
+
+" FUNCTION: s:Edit() {{{1
+" opens the NERDTreeBookmarks file for manual editing
+function! s:Bookmark.Edit()
+    call nerdtree#exec('wincmd w', 1)
+    call nerdtree#exec('edit '.g:NERDTreeBookmarksFile, 1)
+endfunction
+
+" FUNCTION: Bookmark.getNode(nerdtree, searchFromAbsoluteRoot) {{{1
+" Returns the tree node object associated with this Bookmark.
+" Throws NERDTree.BookmarkedNodeNotFoundError if the node is not found.
+"
+" Args:
+" searchFromAbsoluteRoot: boolean flag, search from the highest cached node
+"   if true and from the current tree root if false
+function! s:Bookmark.getNode(nerdtree, searchFromAbsoluteRoot)
+    if a:searchFromAbsoluteRoot
+        let l:searchRoot = a:nerdtree.root.AbsoluteTreeRoot()
+    else
+        let l:searchRoot = a:nerdtree.root
+    endif
+    let l:targetNode = l:searchRoot.findNode(self.path)
+    if empty(l:targetNode)
+        throw 'NERDTree.BookmarkedNodeNotFoundError: node for bookmark "' . self.name . '" not found'
+    endif
+    return l:targetNode
+endfunction
+
+" FUNCTION: Bookmark.GetNodeForName(name, searchFromAbsoluteRoot, nerdtree) {{{1
+" Class method that returns the tree node object for the Bookmark with the
+" given name. Throws NERDTree.BookmarkNotFoundError if a Bookmark with the
+" name does not exist. Throws NERDTree.BookmarkedNodeNotFoundError if a
+" tree node for the named Bookmark could not be found.
+function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot, nerdtree)
+    let l:bookmark = s:Bookmark.BookmarkFor(a:name)
+    return l:bookmark.getNode(a:nerdtree, a:searchFromAbsoluteRoot)
+endfunction
+
+" FUNCTION: Bookmark.GetSelected() {{{1
+" returns the Bookmark the cursor is over, or {}
+function! s:Bookmark.GetSelected()
+    let line = getline('.')
+    let name = substitute(line, '^>\(.\{-}\) .\+$', '\1', '')
+    if name !=# line
+        try
+            return s:Bookmark.BookmarkFor(name)
+        catch /^NERDTree.BookmarkNotFoundError/
+            return {}
+        endtry
+    endif
+    return {}
+endfunction
+
+" FUNCTION: Bookmark.InvalidBookmarks() {{{1
+" Class method to get all invalid bookmark strings read from the bookmarks
+" file
+function! s:Bookmark.InvalidBookmarks()
+    if !exists('g:NERDTreeInvalidBookmarks')
+        let g:NERDTreeInvalidBookmarks = []
+    endif
+    return g:NERDTreeInvalidBookmarks
+endfunction
+
+" FUNCTION: Bookmark.mustExist() {{{1
+function! s:Bookmark.mustExist()
+    if !self.path.exists()
+        call s:Bookmark.CacheBookmarks(1)
+        throw 'NERDTree.BookmarkPointsToInvalidLocationError: the bookmark "'.
+            \ self.name .'" points to a non existing location: "'. self.path.str()
+    endif
+endfunction
+
+" FUNCTION: Bookmark.New(name, path) {{{1
+" Create a new bookmark object with the given name and path object
+function! s:Bookmark.New(name, path)
+    if a:name =~# ' '
+        throw 'NERDTree.IllegalBookmarkNameError: illegal name:' . a:name
+    endif
+
+    let newBookmark = copy(self)
+    let newBookmark.name = a:name
+    let newBookmark.path = a:path
+    return newBookmark
+endfunction
+
+" FUNCTION: Bookmark.open(nerdtree, [options]) {{{1
+"Args:
+"
+"nerdtree: the tree to load open the bookmark in
+"
+"A dictionary containing the following keys (all optional):
+"  'where': Specifies whether the node should be opened in new split/tab or in
+"           the previous window. Can be either 'v' (vertical split), 'h'
+"           (horizontal split), 't' (new tab) or 'p' (previous window).
+"  'reuse': if a window is displaying the file then jump the cursor there
+"  'keepopen': dont close the tree window
+"  'stay': open the file, but keep the cursor in the tree win
+"
+function! s:Bookmark.open(nerdtree, ...)
+    let opts = a:0 ? a:1 : {}
+
+    if nerdtree#closeBookmarksOnOpen()
+        call a:nerdtree.ui.toggleShowBookmarks()
+    endif
+
+    if self.path.isDirectory && !has_key(opts, 'where')
+        call self.toRoot(a:nerdtree)
+    else
+        let opener = g:NERDTreeOpener.New(self.path, opts)
+        call opener.open(self)
+    endif
+endfunction
+
+" FUNCTION: Bookmark.openInNewTab(options) {{{1
+" Create a new bookmark object with the given name and path object
+function! s:Bookmark.openInNewTab(options)
+    call nerdtree#deprecated('Bookmark.openInNewTab', 'is deprecated, use open() instead')
+    call self.open(a:options)
+endfunction
+
+" FUNCTION: Bookmark.setPath(path) {{{1
+" makes this bookmark point to the given path
+function! s:Bookmark.setPath(path)
+    let self.path = a:path
+endfunction
+
+" FUNCTION: Bookmark.SortBookmarksList() {{{1
+" Class method that sorts the global list of bookmarks alphabetically by name.
+" Note that case-sensitivity is determined by a user option.
+function! s:Bookmark.SortBookmarksList()
+    call sort(s:Bookmark.Bookmarks(), s:Bookmark.CompareBookmarksByName, s:Bookmark)
+endfunction
+
+" FUNCTION: Bookmark.str() {{{1
+" Get the string that should be rendered in the view for this bookmark
+function! s:Bookmark.str()
+    let pathStrMaxLen = winwidth(g:NERDTree.GetWinNum()) - 4 - strdisplaywidth(self.name)
+    if &number
+        let pathStrMaxLen = pathStrMaxLen - &numberwidth
+    endif
+
+    let pathStr = self.path.str({'format': 'UI'})
+    if strdisplaywidth(pathStr) > pathStrMaxLen
+        while strdisplaywidth(pathStr) > pathStrMaxLen && strchars(pathStr) > 0
+            let pathStr = substitute(pathStr, '^.', '', '')
+        endwhile
+        let pathStr = '<' . pathStr
+    endif
+    return '>' . self.name . ' ' . pathStr
+endfunction
+
+" FUNCTION: Bookmark.toRoot(nerdtree) {{{1
+" Set the root of the given NERDTree to the node for this Bookmark. If a node
+" for this Bookmark does not exist, a new one is initialized.
+function! s:Bookmark.toRoot(nerdtree)
+    if self.validate()
+        try
+            let l:targetNode = self.getNode(a:nerdtree, 1)
+            call l:targetNode.closeChildren()
+        catch /^NERDTree.BookmarkedNodeNotFoundError/
+            let l:targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path, a:nerdtree)
+        endtry
+        call a:nerdtree.changeRoot(l:targetNode)
+    endif
+endfunction
+
+" FUNCTION: Bookmark.ToRoot(name, nerdtree) {{{1
+" Class method that makes the Bookmark with the given name the root of
+" specified NERDTree.
+function! s:Bookmark.ToRoot(name, nerdtree)
+    let l:bookmark = s:Bookmark.BookmarkFor(a:name)
+    call l:bookmark.toRoot(a:nerdtree)
+endfunction
+
+" FUNCTION: Bookmark.validate() {{{1
+function! s:Bookmark.validate()
+    if self.path.exists()
+        return 1
+    else
+        call s:Bookmark.CacheBookmarks(1)
+        call nerdtree#echo(self.name . 'now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.')
+        return 0
+    endif
+endfunction
+
+" FUNCTION: Bookmark.Write() {{{1
+" Class method to write all bookmarks to the bookmarks file
+function! s:Bookmark.Write()
+    let bookmarkStrings = []
+    for i in s:Bookmark.Bookmarks()
+        call add(bookmarkStrings, i.name . ' ' . fnamemodify(i.path.str(), ':~'))
+    endfor
+
+    "add a blank line before the invalid ones
+    call add(bookmarkStrings, '')
+
+    for j in s:Bookmark.InvalidBookmarks()
+        call add(bookmarkStrings, j)
+    endfor
+
+    try
+        call writefile(bookmarkStrings, g:NERDTreeBookmarksFile)
+    catch
+        call nerdtree#echoError('Failed to write bookmarks file. Make sure g:NERDTreeBookmarksFile points to a valid location.')
+    endtry
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:

+ 402 - 0
vimfiles/bundle/nerdtree/lib/nerdtree/creator.vim

@@ -0,0 +1,402 @@
+" ============================================================================
+" CLASS: Creator
+"
+" This class is responsible for creating NERDTree instances.  The new NERDTree
+" may be a tab tree, a window tree, or a mirrored tree.  In the process of
+" creating a NERDTree, it sets up all of the window and buffer options and key
+" mappings etc.
+" ============================================================================
+
+
+let s:Creator = {}
+let g:NERDTreeCreator = s:Creator
+
+" FUNCTION: s:Creator._bindMappings() {{{1
+function! s:Creator._bindMappings()
+    call g:NERDTreeKeyMap.BindAll()
+
+    command! -buffer -nargs=? Bookmark :call nerdtree#ui_glue#bookmarkNode('<args>')
+    command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#ui_glue#revealBookmark('<args>')
+    command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark call nerdtree#ui_glue#openBookmark('<args>')
+    command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#ui_glue#clearBookmarks('<args>')
+    command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('<args>', b:NERDTree)
+    command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() <bar> call b:NERDTree.render()
+    command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <bar> call b:NERDTree.render()
+    command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write()
+    command! -buffer -nargs=0 EditBookmarks call g:NERDTreeBookmark.Edit()
+endfunction
+
+" FUNCTION: s:Creator._broadcastInitEvent() {{{1
+function! s:Creator._broadcastInitEvent()
+    if exists('#User#NERDTreeInit')
+        doautocmd User NERDTreeInit
+    endif
+endfunction
+
+" FUNCTION: s:Creator.BufNamePrefix() {{{1
+function! s:Creator.BufNamePrefix()
+    return 'NERD_tree_'
+endfunction
+
+" FUNCTION: s:Creator.CreateTabTree(a:name) {{{1
+function! s:Creator.CreateTabTree(name)
+    let creator = s:Creator.New()
+    call creator.createTabTree(a:name)
+endfunction
+
+" FUNCTION: s:Creator.createTabTree(a:name) {{{1
+" name: the name of a bookmark or a directory
+function! s:Creator.createTabTree(name)
+    let l:path = self._pathForString(a:name)
+
+    " Abort if an exception was thrown (i.e., if the bookmark or directory
+    " does not exist).
+    if empty(l:path)
+        return
+    endif
+
+    " Obey the user's preferences for changing the working directory.
+    if g:NERDTreeChDirMode != 0
+        call l:path.changeToDir()
+    endif
+
+    if g:NERDTree.ExistsForTab()
+        call g:NERDTree.Close()
+        call self._removeTreeBufForTab()
+    endif
+
+    call self._createTreeWin()
+    call self._createNERDTree(l:path, 'tab')
+    call b:NERDTree.render()
+    call b:NERDTree.root.putCursorHere(0, 0)
+
+    call self._broadcastInitEvent()
+endfunction
+
+" FUNCTION: s:Creator.CreateWindowTree(dir) {{{1
+function! s:Creator.CreateWindowTree(dir)
+    let creator = s:Creator.New()
+    call creator.createWindowTree(a:dir)
+endfunction
+
+" FUNCTION: s:Creator.createWindowTree(dir) {{{1
+function! s:Creator.createWindowTree(dir)
+    try
+        let path = g:NERDTreePath.New(a:dir)
+    catch /^NERDTree.InvalidArgumentsError/
+        call nerdtree#echo('Invalid directory name:' . a:dir)
+        return
+    endtry
+
+    "we want the directory buffer to disappear when we do the :edit below
+    setlocal bufhidden=wipe
+
+    let previousBuf = expand('#')
+
+    "we need a unique name for each window tree buffer to ensure they are
+    "all independent
+    exec g:NERDTreeCreatePrefix . ' edit ' . self._nextBufferName()
+
+    call self._createNERDTree(path, 'window')
+    let b:NERDTree._previousBuf = bufnr(previousBuf)
+    call self._setCommonBufOptions()
+
+    call b:NERDTree.render()
+
+    call self._broadcastInitEvent()
+endfunction
+
+" FUNCTION: s:Creator._createNERDTree(path) {{{1
+function! s:Creator._createNERDTree(path, type)
+    let b:NERDTree = g:NERDTree.New(a:path, a:type)
+
+    " TODO: This assignment is kept for compatibility reasons.  Many other
+    " plugins use b:NERDTreeRoot instead of b:NERDTree.root.  Remove this
+    " assignment in the future.
+    let b:NERDTreeRoot = b:NERDTree.root
+
+    call b:NERDTree.root.open()
+endfunction
+
+" FUNCTION: s:Creator.CreateMirror() {{{1
+function! s:Creator.CreateMirror()
+    let creator = s:Creator.New()
+    call creator.createMirror()
+endfunction
+
+" FUNCTION: s:Creator.createMirror() {{{1
+function! s:Creator.createMirror()
+    "get the names off all the nerd tree buffers
+    let treeBufNames = []
+    for i in range(1, tabpagenr('$'))
+        let nextName = self._tabpagevar(i, 'NERDTreeBufName')
+        if nextName != -1 && (!exists('t:NERDTreeBufName') || nextName != t:NERDTreeBufName)
+            call add(treeBufNames, nextName)
+        endif
+    endfor
+    let treeBufNames = self._uniq(treeBufNames)
+
+    "map the option names (that the user will be prompted with) to the nerd
+    "tree buffer names
+    let options = {}
+    let i = 0
+    while i < len(treeBufNames)
+        let bufName = treeBufNames[i]
+        let treeRoot = getbufvar(bufName, 'NERDTree').root
+        let options[i+1 . '. ' . treeRoot.path.str() . '  (buf name: ' . bufName . ')'] = bufName
+        let i = i + 1
+    endwhile
+
+    "work out which tree to mirror, if there is more than 1 then ask the user
+    let bufferName = ''
+    if len(keys(options)) > 1
+        let choices = ['Choose a tree to mirror']
+        let choices = extend(choices, sort(keys(options)))
+        let choice = inputlist(choices)
+        if choice < 1 || choice > len(options) || choice ==# ''
+            return
+        endif
+
+        let bufferName = options[sort(keys(options))[choice-1]]
+    elseif len(keys(options)) ==# 1
+        let bufferName = values(options)[0]
+    else
+        call nerdtree#echo('No trees to mirror')
+        return
+    endif
+
+    if g:NERDTree.ExistsForTab() && g:NERDTree.IsOpen()
+        call g:NERDTree.Close()
+    endif
+
+    let t:NERDTreeBufName = bufferName
+    call self._createTreeWin()
+    exec 'buffer ' .  bufferName
+    call b:NERDTree.ui.restoreScreenState()
+    if !&hidden
+        call b:NERDTree.render()
+    endif
+endfunction
+
+" FUNCTION: s:Creator._createTreeWin() {{{1
+" Initialize the NERDTree window.  Open the window, size it properly, set all
+" local options, etc.
+function! s:Creator._createTreeWin()
+    let l:splitLocation = g:NERDTreeWinPos ==# 'left' ? 'topleft ' : 'botright '
+    let l:splitSize = g:NERDTreeWinSize
+
+    if !g:NERDTree.ExistsForTab()
+        let t:NERDTreeBufName = self._nextBufferName()
+        silent! execute l:splitLocation . 'vertical ' . l:splitSize . ' new'
+        silent! execute 'edit ' . t:NERDTreeBufName
+        silent! execute 'vertical resize '. l:splitSize
+    else
+        silent! execute l:splitLocation . 'vertical ' . l:splitSize . ' split'
+        silent! execute 'buffer ' . t:NERDTreeBufName
+    endif
+
+    setlocal winfixwidth
+
+    call self._setCommonBufOptions()
+
+    if has('patch-7.4.1925')
+        clearjumps
+    endif
+
+endfunction
+
+" FUNCTION: s:Creator._isBufHidden(nr) {{{1
+function! s:Creator._isBufHidden(nr)
+    redir => bufs
+    silent ls!
+    redir END
+
+    return bufs =~ a:nr . '..h'
+endfunction
+
+" FUNCTION: s:Creator.New() {{{1
+function! s:Creator.New()
+    let newCreator = copy(self)
+    return newCreator
+endfunction
+
+" FUNCTION: s:Creator._nextBufferName() {{{1
+" returns the buffer name for the next nerd tree
+function! s:Creator._nextBufferName()
+    let name = s:Creator.BufNamePrefix() . self._nextBufferNumber()
+    return name
+endfunction
+
+" FUNCTION: s:Creator._nextBufferNumber() {{{1
+" the number to add to the nerd tree buffer name to make the buf name unique
+function! s:Creator._nextBufferNumber()
+    if !exists('s:Creator._NextBufNum')
+        let s:Creator._NextBufNum = 1
+    else
+        let s:Creator._NextBufNum += 1
+    endif
+
+    return s:Creator._NextBufNum
+endfunction
+
+" FUNCTION: s:Creator._pathForString(str) {{{1
+" find a bookmark or adirectory for the given string
+function! s:Creator._pathForString(str)
+    let path = {}
+    if g:NERDTreeBookmark.BookmarkExistsFor(a:str)
+        let path = g:NERDTreeBookmark.BookmarkFor(a:str).path
+    else
+        let dir = a:str ==# '' ? getcwd() : a:str
+
+        "hack to get an absolute path if a relative path is given
+        if dir =~# '^\.'
+            let dir = getcwd() . nerdtree#slash() . dir
+        endif
+
+        "hack to prevent removing slash if dir is the root of the file system.
+        if dir !=# '/'
+            let dir = g:NERDTreePath.Resolve(dir)
+        endif
+
+        try
+            let path = g:NERDTreePath.New(dir)
+        catch /^NERDTree.InvalidArgumentsError/
+            call nerdtree#echo('No bookmark or directory found for: ' . a:str)
+            return {}
+        endtry
+    endif
+    if !path.isDirectory
+        let path = path.getParent()
+    endif
+
+    return path
+endfunction
+
+" Function: s:Creator._removeTreeBufForTab()   {{{1
+function! s:Creator._removeTreeBufForTab()
+    let buf = bufnr(t:NERDTreeBufName)
+
+    "if &hidden is not set then it will already be gone
+    if buf != -1
+
+        "nerdtree buf may be mirrored/displayed elsewhere
+        if self._isBufHidden(buf)
+            exec 'bwipeout ' . buf
+        endif
+
+    endif
+
+    unlet t:NERDTreeBufName
+endfunction
+
+" FUNCTION: s:Creator._setCommonBufOptions() {{{1
+function! s:Creator._setCommonBufOptions()
+
+    " Options for a non-file/control buffer.
+    setlocal bufhidden=hide
+    setlocal buftype=nofile
+    setlocal noswapfile
+
+    " Options for controlling buffer/window appearance.
+    setlocal foldcolumn=0
+    setlocal foldmethod=manual
+    setlocal nobuflisted
+    setlocal nofoldenable
+    setlocal nolist
+    setlocal nospell
+    setlocal nowrap
+
+    if g:NERDTreeShowLineNumbers
+        setlocal number
+    else
+        setlocal nonumber
+        if v:version >= 703
+            setlocal norelativenumber
+        endif
+    endif
+
+    iabc <buffer>
+
+    if g:NERDTreeHighlightCursorline
+        setlocal cursorline
+    endif
+
+    call self._setupStatusline()
+    call self._bindMappings()
+
+    setlocal filetype=nerdtree
+endfunction
+
+" FUNCTION: s:Creator._setupStatusline() {{{1
+function! s:Creator._setupStatusline()
+    if g:NERDTreeStatusline != -1
+        let &l:statusline = g:NERDTreeStatusline
+    endif
+endfunction
+
+" FUNCTION: s:Creator._tabpagevar(tabnr, var) {{{1
+function! s:Creator._tabpagevar(tabnr, var)
+    let currentTab = tabpagenr()
+    let old_ei = &eventignore
+    set eventignore=all
+
+    try
+        exec 'tabnext ' . a:tabnr
+        let v = -1
+        if exists('t:' . a:var)
+            exec 'let v = t:' . a:var
+        endif
+        exec 'tabnext ' . currentTab
+
+    finally
+        let &eventignore = old_ei
+    endtry
+
+    return v
+endfunction
+
+" FUNCTION: s:Creator.ToggleTabTree(dir) {{{1
+function! s:Creator.ToggleTabTree(dir)
+    let creator = s:Creator.New()
+    call creator.toggleTabTree(a:dir)
+endfunction
+
+" FUNCTION: s:Creator.toggleTabTree(dir) {{{1
+" Toggles the NERD tree. I.e if the NERD tree is open, it is closed. If it is
+" closed, it is restored or initialized. If dir is not empty, it will be set
+" as the new root.
+"
+" Args:
+" dir: the full path for the root node (is used if the NERD tree is being
+" initialized, or to change the root to a new dir.)
+function! s:Creator.toggleTabTree(dir)
+    if g:NERDTree.ExistsForTab()
+        if !g:NERDTree.IsOpen()
+            call self._createTreeWin()
+            if !empty(a:dir) && a:dir !=# b:NERDTree.root.path.str()
+                call self.createTabTree(a:dir)
+            elseif !&hidden
+                call b:NERDTree.render()
+            endif
+            call b:NERDTree.ui.restoreScreenState()
+        else
+            call g:NERDTree.Close()
+        endif
+    else
+        call self.createTabTree(a:dir)
+    endif
+endfunction
+
+" Function: s:Creator._uniq(list)   {{{1
+" returns a:list without duplicates
+function! s:Creator._uniq(list)
+  let uniqlist = []
+  for elem in a:list
+    if index(uniqlist, elem) ==# -1
+      let uniqlist += [elem]
+    endif
+  endfor
+  return uniqlist
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:

+ 13 - 0
vimfiles/bundle/nerdtree/lib/nerdtree/event.vim

@@ -0,0 +1,13 @@
+"CLASS: Event
+"============================================================
+let s:Event = {}
+let g:NERDTreeEvent = s:Event
+
+function! s:Event.New(nerdtree, subject, action, params) abort
+    let newObj = copy(self)
+    let newObj.nerdtree = a:nerdtree
+    let newObj.subject = a:subject
+    let newObj.action = a:action
+    let newObj.params = a:params
+    return newObj
+endfunction

+ 58 - 0
vimfiles/bundle/nerdtree/lib/nerdtree/flag_set.vim

@@ -0,0 +1,58 @@
+"CLASS: FlagSet
+"============================================================
+let s:FlagSet = {}
+let g:NERDTreeFlagSet = s:FlagSet
+
+"FUNCTION: FlagSet.addFlag(scope, flag) {{{1
+function! s:FlagSet.addFlag(scope, flag)
+    let flags = self._flagsForScope(a:scope)
+    if index(flags, a:flag) == -1
+        call add(flags, a:flag)
+    end
+endfunction
+
+"FUNCTION: FlagSet.clearFlags(scope) {{{1
+function! s:FlagSet.clearFlags(scope)
+    let self._flags[a:scope] = []
+endfunction
+
+"FUNCTION: FlagSet._flagsForScope(scope) {{{1
+function! s:FlagSet._flagsForScope(scope)
+    if !has_key(self._flags, a:scope)
+        let self._flags[a:scope] = []
+    endif
+    return self._flags[a:scope]
+endfunction
+
+"FUNCTION: FlagSet.New() {{{1
+function! s:FlagSet.New()
+    let newObj = copy(self)
+    let newObj._flags = {}
+    return newObj
+endfunction
+
+"FUNCTION: FlagSet.removeFlag(scope, flag) {{{1
+function! s:FlagSet.removeFlag(scope, flag)
+    let flags = self._flagsForScope(a:scope)
+
+    let i = index(flags, a:flag)
+    if i >= 0
+        call remove(flags, i)
+    endif
+endfunction
+
+"FUNCTION: FlagSet.renderToString() {{{1
+function! s:FlagSet.renderToString()
+    let flagstring = ''
+    for i in values(self._flags)
+        let flagstring .= join(i)
+    endfor
+
+    if len(flagstring) == 0
+        return ''
+    endif
+
+    return '[' . flagstring . ']'
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:

+ 164 - 0
vimfiles/bundle/nerdtree/lib/nerdtree/key_map.vim

@@ -0,0 +1,164 @@
+"CLASS: KeyMap
+"============================================================
+let s:KeyMap = {}
+let g:NERDTreeKeyMap = s:KeyMap
+let s:keyMaps = {}
+
+"FUNCTION: KeyMap.All() {{{1
+function! s:KeyMap.All()
+    let sortedKeyMaps = values(s:keyMaps)
+    call sort(sortedKeyMaps, s:KeyMap.Compare, s:KeyMap)
+
+    return sortedKeyMaps
+endfunction
+
+"FUNCTION: KeyMap.Compare(keyMap1, keyMap2) {{{1
+function! s:KeyMap.Compare(keyMap1, keyMap2)
+
+    if a:keyMap1.key >? a:keyMap2.key
+        return 1
+    endif
+
+    if a:keyMap1.key <? a:keyMap2.key
+        return -1
+    endif
+
+    return 0
+endfunction
+
+"FUNCTION: KeyMap.FindFor(key, scope) {{{1
+function! s:KeyMap.FindFor(key, scope)
+    return get(s:keyMaps, a:key . a:scope, {})
+endfunction
+
+"FUNCTION: KeyMap.BindAll() {{{1
+function! s:KeyMap.BindAll()
+    for i in values(s:keyMaps)
+        call i.bind()
+    endfor
+endfunction
+
+"FUNCTION: KeyMap.bind() {{{1
+function! s:KeyMap.bind()
+    " If the key sequence we're trying to map contains any '<>' notation, we
+    " must replace each of the '<' characters with '<lt>' to ensure the string
+    " is not translated into its corresponding keycode during the later part
+    " of the map command below
+    " :he <>
+    let specialNotationRegex = '\m<\([[:alnum:]_-]\+>\)'
+    if self.key =~# specialNotationRegex
+        let keymapInvokeString = substitute(self.key, specialNotationRegex, '<lt>\1', 'g')
+    else
+        let keymapInvokeString = self.key
+    endif
+    let keymapInvokeString = escape(keymapInvokeString, '\"')
+
+    let premap = self.key ==# '<LeftRelease>' ? ' <LeftRelease>' : ' '
+
+    exec 'nnoremap <buffer> <silent> '. self.key . premap . ':call nerdtree#ui_glue#invokeKeyMap("'. keymapInvokeString .'")<cr>'
+endfunction
+
+"FUNCTION: KeyMap.Remove(key, scope) {{{1
+function! s:KeyMap.Remove(key, scope)
+    return remove(s:keyMaps, a:key . a:scope)
+endfunction
+
+"FUNCTION: KeyMap.invoke() {{{1
+"Call the KeyMaps callback function
+function! s:KeyMap.invoke(...)
+    let l:Callback = type(self.callback) ==# type(function('tr')) ? self.callback : function(self.callback)
+    if a:0
+        call l:Callback(a:1)
+    else
+        call l:Callback()
+    endif
+endfunction
+
+"FUNCTION: KeyMap.Invoke() {{{1
+"Find a keymapping for a:key and the current scope invoke it.
+"
+"Scope is determined as follows:
+"   * if the cursor is on a dir node then DirNode
+"   * if the cursor is on a file node then FileNode
+"   * if the cursor is on a bookmark then Bookmark
+"
+"If a keymap has the scope of 'all' then it will be called if no other keymap
+"is found for a:key and the scope.
+function! s:KeyMap.Invoke(key)
+
+    "required because clicking the command window below another window still
+    "invokes the <LeftRelease> mapping - but changes the window cursor
+    "is in first
+    "
+    "TODO: remove this check when the vim bug is fixed
+    if !g:NERDTree.ExistsForBuf()
+        return {}
+    endif
+
+    let node = g:NERDTreeFileNode.GetSelected()
+    if !empty(node)
+
+        "try file node
+        if !node.path.isDirectory
+            let km = s:KeyMap.FindFor(a:key, 'FileNode')
+            if !empty(km)
+                return km.invoke(node)
+            endif
+        endif
+
+        "try dir node
+        if node.path.isDirectory
+            let km = s:KeyMap.FindFor(a:key, 'DirNode')
+            if !empty(km)
+                return km.invoke(node)
+            endif
+        endif
+
+        "try generic node
+        let km = s:KeyMap.FindFor(a:key, 'Node')
+        if !empty(km)
+            return km.invoke(node)
+        endif
+
+    endif
+
+    "try bookmark
+    let bm = g:NERDTreeBookmark.GetSelected()
+    if !empty(bm)
+        let km = s:KeyMap.FindFor(a:key, 'Bookmark')
+        if !empty(km)
+            return km.invoke(bm)
+        endif
+    endif
+
+    "try all
+    let km = s:KeyMap.FindFor(a:key, 'all')
+    if !empty(km)
+        return km.invoke()
+    endif
+endfunction
+
+"FUNCTION: KeyMap.Create(options) {{{1
+function! s:KeyMap.Create(options)
+    let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options))
+
+    "dont override other mappings unless the 'override' option is given
+    if get(opts, 'override', 0) ==# 0 && !empty(s:KeyMap.FindFor(opts['key'], opts['scope']))
+        return
+    end
+
+    let newKeyMap = copy(self)
+    let newKeyMap.key = opts['key']
+    let newKeyMap.quickhelpText = opts['quickhelpText']
+    let newKeyMap.callback = opts['callback']
+    let newKeyMap.scope = opts['scope']
+
+    call s:KeyMap.Add(newKeyMap)
+endfunction
+
+"FUNCTION: KeyMap.Add(keymap) {{{1
+function! s:KeyMap.Add(keymap)
+    let s:keyMaps[a:keymap.key . a:keymap.scope] = a:keymap
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:

+ 211 - 0
vimfiles/bundle/nerdtree/lib/nerdtree/menu_controller.vim

@@ -0,0 +1,211 @@
+"CLASS: MenuController
+"============================================================
+let s:MenuController = {}
+let g:NERDTreeMenuController = s:MenuController
+
+"FUNCTION: MenuController.New(menuItems) {{{1
+"create a new menu controller that operates on the given menu items
+function! s:MenuController.New(menuItems)
+    let newMenuController =  copy(self)
+    if a:menuItems[0].isSeparator()
+        let newMenuController.menuItems = a:menuItems[1:-1]
+    else
+        let newMenuController.menuItems = a:menuItems
+    endif
+    return newMenuController
+endfunction
+
+" FUNCTION: s:MenuController.isMinimal() {{{1
+function! s:MenuController.isMinimal()
+    return g:NERDTreeMinimalMenu
+endfunction
+
+" FUNCTION: MenuController.showMenu() {{{1
+" Enter the main loop of the NERDTree menu, prompting the user to select
+" a menu item.
+function! s:MenuController.showMenu()
+    call self._saveOptions()
+
+    try
+        let self.selection = 0
+        let l:done = 0
+
+        while !l:done
+            if has('nvim')
+                mode
+            else
+                redraw!
+            endif
+            call self._echoPrompt()
+
+            let l:key = nr2char(getchar())
+            let l:done = self._handleKeypress(l:key)
+        endwhile
+    finally
+        call self._restoreOptions()
+
+        " Redraw when Ctrl-C or Esc is received.
+        if !l:done || self.selection ==# -1
+            redraw!
+        endif
+    endtry
+
+    if self.selection !=# -1
+        let l:m = self._current()
+        call l:m.execute()
+    endif
+endfunction
+
+"FUNCTION: MenuController._echoPrompt() {{{1
+function! s:MenuController._echoPrompt()
+    let navHelp = 'Use ' . g:NERDTreeMenuDown . '/' . g:NERDTreeMenuUp . '/enter'
+
+    if self.isMinimal()
+        let selection = self.menuItems[self.selection].text
+        let keyword = matchstr(selection, '[^ ]*([^ ]*')
+
+        let shortcuts = map(copy(self.menuItems), "v:val['shortcut']")
+        let shortcuts[self.selection] = ' ' . keyword . ' '
+
+        echo 'Menu: [' . join(shortcuts, ',') . '] (' . navHelp . ' or shortcut): '
+    else
+        echo 'NERDTree Menu. ' . navHelp . ', or the shortcuts indicated'
+        echo '========================================================='
+
+        for i in range(0, len(self.menuItems)-1)
+            if self.selection ==# i
+                echo '> ' . self.menuItems[i].text
+            else
+                echo '  ' . self.menuItems[i].text
+            endif
+        endfor
+    endif
+endfunction
+
+"FUNCTION: MenuController._current(key) {{{1
+"get the MenuItem that is currently selected
+function! s:MenuController._current()
+    return self.menuItems[self.selection]
+endfunction
+
+"FUNCTION: MenuController._handleKeypress(key) {{{1
+"change the selection (if appropriate) and return 1 if the user has made
+"their choice, 0 otherwise
+function! s:MenuController._handleKeypress(key)
+    if a:key ==# g:NERDTreeMenuDown
+        call self._cursorDown()
+    elseif a:key ==# g:NERDTreeMenuUp
+        call self._cursorUp()
+    elseif a:key ==# nr2char(27) "escape
+        let self.selection = -1
+        return 1
+    elseif a:key ==# "\r" || a:key ==# "\n" "enter and ctrl-j
+        return 1
+    else
+        let index = self._nextIndexFor(a:key)
+        if index !=# -1
+            let self.selection = index
+            if len(self._allIndexesFor(a:key)) ==# 1
+                return 1
+            endif
+        endif
+    endif
+
+    return 0
+endfunction
+
+"FUNCTION: MenuController._allIndexesFor(shortcut) {{{1
+"get indexes to all menu items with the given shortcut
+function! s:MenuController._allIndexesFor(shortcut)
+    let toReturn = []
+
+    for i in range(0, len(self.menuItems)-1)
+        if self.menuItems[i].shortcut ==# a:shortcut
+            call add(toReturn, i)
+        endif
+    endfor
+
+    return toReturn
+endfunction
+
+"FUNCTION: MenuController._nextIndexFor(shortcut) {{{1
+"get the index to the next menu item with the given shortcut, starts from the
+"current cursor location and wraps around to the top again if need be
+function! s:MenuController._nextIndexFor(shortcut)
+    for i in range(self.selection+1, len(self.menuItems)-1)
+        if self.menuItems[i].shortcut ==# a:shortcut
+            return i
+        endif
+    endfor
+
+    for i in range(0, self.selection)
+        if self.menuItems[i].shortcut ==# a:shortcut
+            return i
+        endif
+    endfor
+
+    return -1
+endfunction
+
+"FUNCTION: MenuController._setCmdheight() {{{1
+"sets &cmdheight to whatever is needed to display the menu
+function! s:MenuController._setCmdheight()
+    if self.isMinimal()
+        let &cmdheight = 1
+    else
+        let &cmdheight = len(self.menuItems) + 3
+    endif
+endfunction
+
+"FUNCTION: MenuController._saveOptions() {{{1
+"set any vim options that are required to make the menu work (saving their old
+"values)
+function! s:MenuController._saveOptions()
+    let self._oldLazyredraw = &lazyredraw
+    let self._oldCmdheight = &cmdheight
+    set nolazyredraw
+    call self._setCmdheight()
+endfunction
+
+"FUNCTION: MenuController._restoreOptions() {{{1
+"restore the options we saved in _saveOptions()
+function! s:MenuController._restoreOptions()
+    let &cmdheight = self._oldCmdheight
+    let &lazyredraw = self._oldLazyredraw
+endfunction
+
+"FUNCTION: MenuController._cursorDown() {{{1
+"move the cursor to the next menu item, skipping separators
+function! s:MenuController._cursorDown()
+    let done = 0
+    while !done
+        if self.selection < len(self.menuItems)-1
+            let self.selection += 1
+        else
+            let self.selection = 0
+        endif
+
+        if !self._current().isSeparator()
+            let done = 1
+        endif
+    endwhile
+endfunction
+
+"FUNCTION: MenuController._cursorUp() {{{1
+"move the cursor to the previous menu item, skipping separators
+function! s:MenuController._cursorUp()
+    let done = 0
+    while !done
+        if self.selection > 0
+            let self.selection -= 1
+        else
+            let self.selection = len(self.menuItems)-1
+        endif
+
+        if !self._current().isSeparator()
+            let done = 1
+        endif
+    endwhile
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:

+ 118 - 0
vimfiles/bundle/nerdtree/lib/nerdtree/menu_item.vim

@@ -0,0 +1,118 @@
+"CLASS: MenuItem
+"============================================================
+let s:MenuItem = {}
+let g:NERDTreeMenuItem = s:MenuItem
+
+"FUNCTION: MenuItem.All() {{{1
+"get all top level menu items
+function! s:MenuItem.All()
+    if !exists('s:menuItems')
+        let s:menuItems = []
+    endif
+    return s:menuItems
+endfunction
+
+"FUNCTION: MenuItem.AllEnabled() {{{1
+"get all top level menu items that are currently enabled
+function! s:MenuItem.AllEnabled()
+    let toReturn = []
+    for i in s:MenuItem.All()
+        if i.enabled()
+            call add(toReturn, i)
+        endif
+    endfor
+    return toReturn
+endfunction
+
+"FUNCTION: MenuItem.Create(options) {{{1
+"make a new menu item and add it to the global list
+function! s:MenuItem.Create(options)
+    let newMenuItem = copy(self)
+
+    let newMenuItem.text = a:options['text']
+    let newMenuItem.shortcut = a:options['shortcut']
+    let newMenuItem.children = []
+
+    let newMenuItem.isActiveCallback = -1
+    if has_key(a:options, 'isActiveCallback')
+        let newMenuItem.isActiveCallback = a:options['isActiveCallback']
+    endif
+
+    let newMenuItem.callback = -1
+    if has_key(a:options, 'callback')
+        let newMenuItem.callback = a:options['callback']
+    endif
+
+    if has_key(a:options, 'parent')
+        call add(a:options['parent'].children, newMenuItem)
+    else
+        call add(s:MenuItem.All(), newMenuItem)
+    endif
+
+    return newMenuItem
+endfunction
+
+"FUNCTION: MenuItem.CreateSeparator(options) {{{1
+"make a new separator menu item and add it to the global list
+function! s:MenuItem.CreateSeparator(options)
+    let standard_options = { 'text': '--------------------',
+                \ 'shortcut': -1,
+                \ 'callback': -1 }
+    let options = extend(a:options, standard_options, 'force')
+
+    return s:MenuItem.Create(options)
+endfunction
+
+"FUNCTION: MenuItem.CreateSubmenu(options) {{{1
+"make a new submenu and add it to global list
+function! s:MenuItem.CreateSubmenu(options)
+    let standard_options = { 'callback': -1 }
+    let options = extend(a:options, standard_options, 'force')
+
+    return s:MenuItem.Create(options)
+endfunction
+
+"FUNCTION: MenuItem.enabled() {{{1
+"return 1 if this menu item should be displayed
+"
+"delegates off to the isActiveCallback, and defaults to 1 if no callback was
+"specified
+function! s:MenuItem.enabled()
+    if self.isActiveCallback != -1
+        return type(self.isActiveCallback) == type(function('tr')) ? self.isActiveCallback() : {self.isActiveCallback}()
+    endif
+    return 1
+endfunction
+
+"FUNCTION: MenuItem.execute() {{{1
+"perform the action behind this menu item, if this menuitem has children then
+"display a new menu for them, otherwise deletegate off to the menuitem's
+"callback
+function! s:MenuItem.execute()
+    if len(self.children)
+        let mc = g:NERDTreeMenuController.New(self.children)
+        call mc.showMenu()
+    else
+        if self.callback != -1
+            if type(self.callback) == type(function('tr'))
+                call self.callback()
+            else
+                call {self.callback}()
+            endif
+        endif
+    endif
+endfunction
+
+"FUNCTION: MenuItem.isSeparator() {{{1
+"return 1 if this menuitem is a separator
+function! s:MenuItem.isSeparator()
+    return self.callback == -1 && self.children == []
+endfunction
+
+"FUNCTION: MenuItem.isSubmenu() {{{1
+"return 1 if this menuitem is a submenu
+function! s:MenuItem.isSubmenu()
+    return self.callback == -1 && !empty(self.children)
+endfunction
+
+" vim: set sw=4 sts=4 et fdm=marker:

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff