diff --git a/config/.Xresources b/config/.Xresources index 0d573b9..d6a1aab 100644 --- a/config/.Xresources +++ b/config/.Xresources @@ -12,8 +12,8 @@ *.color9: #e91e63 ! green -*.color2: #237885 -*.color10: #00ffaf +*.color2: #00ffaf +*.color10: #237885 ! yellow *.color3: #ffbb24 diff --git a/config/.local/share/ranger/bookmarks b/config/.local/share/ranger/bookmarks index 2cea84e..4fb7048 100644 --- a/config/.local/share/ranger/bookmarks +++ b/config/.local/share/ranger/bookmarks @@ -5,7 +5,7 @@ m:/run/media/tuan a:/home/tuan/Documents/Arbeit l:/home/tuan/Local c:/home/tuan/Documents/CTF/picoCTF -':/home/tuan/.dotfiles/config +':/home/tuan t:/home/tuan/Templates w:/home/tuan/workspace_l/Projects k:/home/tuan/Documents/Fachschaft/Berufungskomission diff --git a/vim/.vim/autoload/plug.vim b/vim/.vim/autoload/plug.vim new file mode 100644 index 0000000..02fac8d --- /dev/null +++ b/vim/.vim/autoload/plug.vim @@ -0,0 +1,2541 @@ +" vim-plug: Vim plugin manager +" ============================ +" +" Download plug.vim and put it in ~/.vim/autoload +" +" curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ +" https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim +" +" Edit your .vimrc +" +" call plug#begin('~/.vim/plugged') +" +" " Make sure you use single quotes +" +" " Shorthand notation; fetches https://github.com/junegunn/vim-easy-align +" Plug 'junegunn/vim-easy-align' +" +" " Any valid git URL is allowed +" Plug 'https://github.com/junegunn/vim-github-dashboard.git' +" +" " Multiple Plug commands can be written in a single line using | separators +" Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets' +" +" " On-demand loading +" Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } +" Plug 'tpope/vim-fireplace', { 'for': 'clojure' } +" +" " Using a non-master branch +" Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' } +" +" " Using a tagged release; wildcard allowed (requires git 1.9.2 or above) +" Plug 'fatih/vim-go', { 'tag': '*' } +" +" " Plugin options +" Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' } +" +" " Plugin outside ~/.vim/plugged with post-update hook +" Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } +" +" " Unmanaged plugin (manually installed and updated) +" Plug '~/my-prototype-plugin' +" +" " Initialize plugin system +" call plug#end() +" +" Then reload .vimrc and :PlugInstall to install plugins. +" +" Plug options: +" +"| Option | Description | +"| ----------------------- | ------------------------------------------------ | +"| `branch`/`tag`/`commit` | Branch/tag/commit of the repository to use | +"| `rtp` | Subdirectory that contains Vim plugin | +"| `dir` | Custom directory for the plugin | +"| `as` | Use different name for the plugin | +"| `do` | Post-update hook (string or funcref) | +"| `on` | On-demand loading: Commands or ``-mappings | +"| `for` | On-demand loading: File types | +"| `frozen` | Do not update unless explicitly specified | +" +" More information: https://github.com/junegunn/vim-plug +" +" +" Copyright (c) 2017 Junegunn Choi +" +" MIT License +" +" Permission is hereby granted, free of charge, to any person obtaining +" a copy of this software and associated documentation files (the +" "Software"), to deal in the Software without restriction, including +" without limitation the rights to use, copy, modify, merge, publish, +" distribute, sublicense, and/or sell copies of the Software, and to +" permit persons to whom the Software is furnished to do so, subject to +" the following conditions: +" +" The above copyright notice and this permission notice shall be +" included in all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +if exists('g:loaded_plug') + finish +endif +let g:loaded_plug = 1 + +let s:cpo_save = &cpo +set cpo&vim + +let s:plug_src = 'https://github.com/junegunn/vim-plug.git' +let s:plug_tab = get(s:, 'plug_tab', -1) +let s:plug_buf = get(s:, 'plug_buf', -1) +let s:mac_gui = has('gui_macvim') && has('gui_running') +let s:is_win = has('win32') +let s:nvim = has('nvim-0.2') || (has('nvim') && exists('*jobwait') && !s:is_win) +let s:vim8 = has('patch-8.0.0039') && exists('*job_start') +let s:me = resolve(expand(':p')) +let s:base_spec = { 'branch': 'master', 'frozen': 0 } +let s:TYPE = { +\ 'string': type(''), +\ 'list': type([]), +\ 'dict': type({}), +\ 'funcref': type(function('call')) +\ } +let s:loaded = get(s:, 'loaded', {}) +let s:triggers = get(s:, 'triggers', {}) + +function! plug#begin(...) + if a:0 > 0 + let s:plug_home_org = a:1 + let home = s:path(fnamemodify(expand(a:1), ':p')) + elseif exists('g:plug_home') + let home = s:path(g:plug_home) + elseif !empty(&rtp) + let home = s:path(split(&rtp, ',')[0]) . '/plugged' + else + return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.') + endif + if fnamemodify(home, ':t') ==# 'plugin' && fnamemodify(home, ':h') ==# s:first_rtp + return s:err('Invalid plug home. '.home.' is a standard Vim runtime path and is not allowed.') + endif + + let g:plug_home = home + let g:plugs = {} + let g:plugs_order = [] + let s:triggers = {} + + call s:define_commands() + return 1 +endfunction + +function! s:define_commands() + command! -nargs=+ -bar Plug call plug#() + if !executable('git') + return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.') + endif + command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install(0, []) + command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update(0, []) + command! -nargs=0 -bar -bang PlugClean call s:clean(0) + command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:esc(s:me) | endif + command! -nargs=0 -bar PlugStatus call s:status() + command! -nargs=0 -bar PlugDiff call s:diff() + command! -nargs=? -bar -bang -complete=file PlugSnapshot call s:snapshot(0, ) +endfunction + +function! s:to_a(v) + return type(a:v) == s:TYPE.list ? a:v : [a:v] +endfunction + +function! s:to_s(v) + return type(a:v) == s:TYPE.string ? a:v : join(a:v, "\n") . "\n" +endfunction + +function! s:glob(from, pattern) + return s:lines(globpath(a:from, a:pattern)) +endfunction + +function! s:source(from, ...) + let found = 0 + for pattern in a:000 + for vim in s:glob(a:from, pattern) + execute 'source' s:esc(vim) + let found = 1 + endfor + endfor + return found +endfunction + +function! s:assoc(dict, key, val) + let a:dict[a:key] = add(get(a:dict, a:key, []), a:val) +endfunction + +function! s:ask(message, ...) + call inputsave() + echohl WarningMsg + let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) ')) + echohl None + call inputrestore() + echo "\r" + return (a:0 && answer =~? '^a') ? 2 : (answer =~? '^y') ? 1 : 0 +endfunction + +function! s:ask_no_interrupt(...) + try + return call('s:ask', a:000) + catch + return 0 + endtry +endfunction + +function! s:lazy(plug, opt) + return has_key(a:plug, a:opt) && + \ (empty(s:to_a(a:plug[a:opt])) || + \ !isdirectory(a:plug.dir) || + \ len(s:glob(s:rtp(a:plug), 'plugin')) || + \ len(s:glob(s:rtp(a:plug), 'after/plugin'))) +endfunction + +function! plug#end() + if !exists('g:plugs') + return s:err('Call plug#begin() first') + endif + + if exists('#PlugLOD') + augroup PlugLOD + autocmd! + augroup END + augroup! PlugLOD + endif + let lod = { 'ft': {}, 'map': {}, 'cmd': {} } + + if exists('g:did_load_filetypes') + filetype off + endif + for name in g:plugs_order + if !has_key(g:plugs, name) + continue + endif + let plug = g:plugs[name] + if get(s:loaded, name, 0) || !s:lazy(plug, 'on') && !s:lazy(plug, 'for') + let s:loaded[name] = 1 + continue + endif + + if has_key(plug, 'on') + let s:triggers[name] = { 'map': [], 'cmd': [] } + for cmd in s:to_a(plug.on) + if cmd =~? '^.\+' + if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i')) + call s:assoc(lod.map, cmd, name) + endif + call add(s:triggers[name].map, cmd) + elseif cmd =~# '^[A-Z]' + let cmd = substitute(cmd, '!*$', '', '') + if exists(':'.cmd) != 2 + call s:assoc(lod.cmd, cmd, name) + endif + call add(s:triggers[name].cmd, cmd) + else + call s:err('Invalid `on` option: '.cmd. + \ '. Should start with an uppercase letter or ``.') + endif + endfor + endif + + if has_key(plug, 'for') + let types = s:to_a(plug.for) + if !empty(types) + augroup filetypedetect + call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') + augroup END + endif + for type in types + call s:assoc(lod.ft, type, name) + endfor + endif + endfor + + for [cmd, names] in items(lod.cmd) + execute printf( + \ 'command! -nargs=* -range -bang -complete=file %s call s:lod_cmd(%s, "", , , , %s)', + \ cmd, string(cmd), string(names)) + endfor + + for [map, names] in items(lod.map) + for [mode, map_prefix, key_prefix] in + \ [['i', '', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']] + execute printf( + \ '%snoremap %s %s:call lod_map(%s, %s, %s, "%s")', + \ mode, map, map_prefix, string(map), string(names), mode != 'i', key_prefix) + endfor + endfor + + for [ft, names] in items(lod.ft) + augroup PlugLOD + execute printf('autocmd FileType %s call lod_ft(%s, %s)', + \ ft, string(ft), string(names)) + augroup END + endfor + + call s:reorg_rtp() + filetype plugin indent on + if has('vim_starting') + if has('syntax') && !exists('g:syntax_on') + syntax enable + end + else + call s:reload_plugins() + endif +endfunction + +function! s:loaded_names() + return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)') +endfunction + +function! s:load_plugin(spec) + call s:source(s:rtp(a:spec), 'plugin/**/*.vim', 'after/plugin/**/*.vim') +endfunction + +function! s:reload_plugins() + for name in s:loaded_names() + call s:load_plugin(g:plugs[name]) + endfor +endfunction + +function! s:trim(str) + return substitute(a:str, '[\/]\+$', '', '') +endfunction + +function! s:version_requirement(val, min) + for idx in range(0, len(a:min) - 1) + let v = get(a:val, idx, 0) + if v < a:min[idx] | return 0 + elseif v > a:min[idx] | return 1 + endif + endfor + return 1 +endfunction + +function! s:git_version_requirement(...) + if !exists('s:git_version') + let s:git_version = map(split(split(s:system('git --version'))[2], '\.'), 'str2nr(v:val)') + endif + return s:version_requirement(s:git_version, a:000) +endfunction + +function! s:progress_opt(base) + return a:base && !s:is_win && + \ s:git_version_requirement(1, 7, 1) ? '--progress' : '' +endfunction + +function! s:rtp(spec) + return s:path(a:spec.dir . get(a:spec, 'rtp', '')) +endfunction + +if s:is_win + function! s:path(path) + return s:trim(substitute(a:path, '/', '\', 'g')) + endfunction + + function! s:dirpath(path) + return s:path(a:path) . '\' + endfunction + + function! s:is_local_plug(repo) + return a:repo =~? '^[a-z]:\|^[%~]' + endfunction + + " Copied from fzf + function! s:wrap_cmds(cmds) + let use_chcp = executable('sed') + return map([ + \ '@echo off', + \ 'setlocal enabledelayedexpansion'] + \ + (use_chcp ? [ + \ 'for /f "usebackq" %%a in (`chcp ^| sed "s/[^0-9]//gp"`) do set origchcp=%%a', + \ 'chcp 65001 > nul'] : []) + \ + (type(a:cmds) == type([]) ? a:cmds : [a:cmds]) + \ + (use_chcp ? ['chcp !origchcp! > nul'] : []) + \ + ['endlocal'], + \ 'v:val."\r"') + endfunction + + function! s:batchfile(cmd) + let batchfile = tempname().'.bat' + call writefile(s:wrap_cmds(a:cmd), batchfile) + let cmd = plug#shellescape(batchfile, {'shell': &shell, 'script': 1}) + if &shell =~# 'powershell\.exe$' + let cmd = '& ' . cmd + endif + return [batchfile, cmd] + endfunction +else + function! s:path(path) + return s:trim(a:path) + endfunction + + function! s:dirpath(path) + return substitute(a:path, '[/\\]*$', '/', '') + endfunction + + function! s:is_local_plug(repo) + return a:repo[0] =~ '[/$~]' + endfunction +endif + +function! s:err(msg) + echohl ErrorMsg + echom '[vim-plug] '.a:msg + echohl None +endfunction + +function! s:warn(cmd, msg) + echohl WarningMsg + execute a:cmd 'a:msg' + echohl None +endfunction + +function! s:esc(path) + return escape(a:path, ' ') +endfunction + +function! s:escrtp(path) + return escape(a:path, ' ,') +endfunction + +function! s:remove_rtp() + for name in s:loaded_names() + let rtp = s:rtp(g:plugs[name]) + execute 'set rtp-='.s:escrtp(rtp) + let after = globpath(rtp, 'after') + if isdirectory(after) + execute 'set rtp-='.s:escrtp(after) + endif + endfor +endfunction + +function! s:reorg_rtp() + if !empty(s:first_rtp) + execute 'set rtp-='.s:first_rtp + execute 'set rtp-='.s:last_rtp + endif + + " &rtp is modified from outside + if exists('s:prtp') && s:prtp !=# &rtp + call s:remove_rtp() + unlet! s:middle + endif + + let s:middle = get(s:, 'middle', &rtp) + let rtps = map(s:loaded_names(), 's:rtp(g:plugs[v:val])') + let afters = filter(map(copy(rtps), 'globpath(v:val, "after")'), '!empty(v:val)') + let rtp = join(map(rtps, 'escape(v:val, ",")'), ',') + \ . ','.s:middle.',' + \ . join(map(afters, 'escape(v:val, ",")'), ',') + let &rtp = substitute(substitute(rtp, ',,*', ',', 'g'), '^,\|,$', '', 'g') + let s:prtp = &rtp + + if !empty(s:first_rtp) + execute 'set rtp^='.s:first_rtp + execute 'set rtp+='.s:last_rtp + endif +endfunction + +function! s:doautocmd(...) + if exists('#'.join(a:000, '#')) + execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '' : '') join(a:000) + endif +endfunction + +function! s:dobufread(names) + for name in a:names + let path = s:rtp(g:plugs[name]) + for dir in ['ftdetect', 'ftplugin', 'after/ftdetect', 'after/ftplugin'] + if len(finddir(dir, path)) + if exists('#BufRead') + doautocmd BufRead + endif + return + endif + endfor + endfor +endfunction + +function! plug#load(...) + if a:0 == 0 + return s:err('Argument missing: plugin name(s) required') + endif + if !exists('g:plugs') + return s:err('plug#begin was not called') + endif + let names = a:0 == 1 && type(a:1) == s:TYPE.list ? a:1 : a:000 + let unknowns = filter(copy(names), '!has_key(g:plugs, v:val)') + if !empty(unknowns) + let s = len(unknowns) > 1 ? 's' : '' + return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', '))) + end + let unloaded = filter(copy(names), '!get(s:loaded, v:val, 0)') + if !empty(unloaded) + for name in unloaded + call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + endfor + call s:dobufread(unloaded) + return 1 + end + return 0 +endfunction + +function! s:remove_triggers(name) + if !has_key(s:triggers, a:name) + return + endif + for cmd in s:triggers[a:name].cmd + execute 'silent! delc' cmd + endfor + for map in s:triggers[a:name].map + execute 'silent! unmap' map + execute 'silent! iunmap' map + endfor + call remove(s:triggers, a:name) +endfunction + +function! s:lod(names, types, ...) + for name in a:names + call s:remove_triggers(name) + let s:loaded[name] = 1 + endfor + call s:reorg_rtp() + + for name in a:names + let rtp = s:rtp(g:plugs[name]) + for dir in a:types + call s:source(rtp, dir.'/**/*.vim') + endfor + if a:0 + if !s:source(rtp, a:1) && !empty(s:glob(rtp, a:2)) + execute 'runtime' a:1 + endif + call s:source(rtp, a:2) + endif + call s:doautocmd('User', name) + endfor +endfunction + +function! s:lod_ft(pat, names) + let syn = 'syntax/'.a:pat.'.vim' + call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn) + execute 'autocmd! PlugLOD FileType' a:pat + call s:doautocmd('filetypeplugin', 'FileType') + call s:doautocmd('filetypeindent', 'FileType') +endfunction + +function! s:lod_cmd(cmd, bang, l1, l2, args, names) + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + call s:dobufread(a:names) + execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args) +endfunction + +function! s:lod_map(map, names, with_prefix, prefix) + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + call s:dobufread(a:names) + let extra = '' + while 1 + let c = getchar(0) + if c == 0 + break + endif + let extra .= nr2char(c) + endwhile + + if a:with_prefix + let prefix = v:count ? v:count : '' + let prefix .= '"'.v:register.a:prefix + if mode(1) == 'no' + if v:operator == 'c' + let prefix = "\" . prefix + endif + let prefix .= v:operator + endif + call feedkeys(prefix, 'n') + endif + call feedkeys(substitute(a:map, '^', "\", '') . extra) +endfunction + +function! plug#(repo, ...) + if a:0 > 1 + return s:err('Invalid number of arguments (1..2)') + endif + + try + let repo = s:trim(a:repo) + let opts = a:0 == 1 ? s:parse_options(a:1) : s:base_spec + let name = get(opts, 'as', fnamemodify(repo, ':t:s?\.git$??')) + let spec = extend(s:infer_properties(name, repo), opts) + if !has_key(g:plugs, name) + call add(g:plugs_order, name) + endif + let g:plugs[name] = spec + let s:loaded[name] = get(s:loaded, name, 0) + catch + return s:err(v:exception) + endtry +endfunction + +function! s:parse_options(arg) + let opts = copy(s:base_spec) + let type = type(a:arg) + if type == s:TYPE.string + let opts.tag = a:arg + elseif type == s:TYPE.dict + call extend(opts, a:arg) + if has_key(opts, 'dir') + let opts.dir = s:dirpath(expand(opts.dir)) + endif + else + throw 'Invalid argument type (expected: string or dictionary)' + endif + return opts +endfunction + +function! s:infer_properties(name, repo) + let repo = a:repo + if s:is_local_plug(repo) + return { 'dir': s:dirpath(expand(repo)) } + else + if repo =~ ':' + let uri = repo + else + if repo !~ '/' + throw printf('Invalid argument: %s (implicit `vim-scripts'' expansion is deprecated)', repo) + endif + let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git') + let uri = printf(fmt, repo) + endif + return { 'dir': s:dirpath(g:plug_home.'/'.a:name), 'uri': uri } + endif +endfunction + +function! s:install(force, names) + call s:update_impl(0, a:force, a:names) +endfunction + +function! s:update(force, names) + call s:update_impl(1, a:force, a:names) +endfunction + +function! plug#helptags() + if !exists('g:plugs') + return s:err('plug#begin was not called') + endif + for spec in values(g:plugs) + let docd = join([s:rtp(spec), 'doc'], '/') + if isdirectory(docd) + silent! execute 'helptags' s:esc(docd) + endif + endfor + return 1 +endfunction + +function! s:syntax() + syntax clear + syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber + syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX + syn match plugNumber /[0-9]\+[0-9.]*/ contained + syn match plugBracket /[[\]]/ contained + syn match plugX /x/ contained + syn match plugDash /^-/ + syn match plugPlus /^+/ + syn match plugStar /^*/ + syn match plugMessage /\(^- \)\@<=.*/ + syn match plugName /\(^- \)\@<=[^ ]*:/ + syn match plugSha /\%(: \)\@<=[0-9a-f]\{4,}$/ + syn match plugTag /(tag: [^)]\+)/ + syn match plugInstall /\(^+ \)\@<=[^:]*/ + syn match plugUpdate /\(^* \)\@<=[^:]*/ + syn match plugCommit /^ \X*[0-9a-f]\{7,9} .*/ contains=plugRelDate,plugEdge,plugTag + syn match plugEdge /^ \X\+$/ + syn match plugEdge /^ \X*/ contained nextgroup=plugSha + syn match plugSha /[0-9a-f]\{7,9}/ contained + syn match plugRelDate /([^)]*)$/ contained + syn match plugNotLoaded /(not loaded)$/ + syn match plugError /^x.*/ + syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/ + syn match plugH2 /^.*:\n-\+$/ + syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean + hi def link plug1 Title + hi def link plug2 Repeat + hi def link plugH2 Type + hi def link plugX Exception + hi def link plugBracket Structure + hi def link plugNumber Number + + hi def link plugDash Special + hi def link plugPlus Constant + hi def link plugStar Boolean + + hi def link plugMessage Function + hi def link plugName Label + hi def link plugInstall Function + hi def link plugUpdate Type + + hi def link plugError Error + hi def link plugDeleted Ignore + hi def link plugRelDate Comment + hi def link plugEdge PreProc + hi def link plugSha Identifier + hi def link plugTag Constant + + hi def link plugNotLoaded Comment +endfunction + +function! s:lpad(str, len) + return a:str . repeat(' ', a:len - len(a:str)) +endfunction + +function! s:lines(msg) + return split(a:msg, "[\r\n]") +endfunction + +function! s:lastline(msg) + return get(s:lines(a:msg), -1, '') +endfunction + +function! s:new_window() + execute get(g:, 'plug_window', 'vertical topleft new') +endfunction + +function! s:plug_window_exists() + let buflist = tabpagebuflist(s:plug_tab) + return !empty(buflist) && index(buflist, s:plug_buf) >= 0 +endfunction + +function! s:switch_in() + if !s:plug_window_exists() + return 0 + endif + + if winbufnr(0) != s:plug_buf + let s:pos = [tabpagenr(), winnr(), winsaveview()] + execute 'normal!' s:plug_tab.'gt' + let winnr = bufwinnr(s:plug_buf) + execute winnr.'wincmd w' + call add(s:pos, winsaveview()) + else + let s:pos = [winsaveview()] + endif + + setlocal modifiable + return 1 +endfunction + +function! s:switch_out(...) + call winrestview(s:pos[-1]) + setlocal nomodifiable + if a:0 > 0 + execute a:1 + endif + + if len(s:pos) > 1 + execute 'normal!' s:pos[0].'gt' + execute s:pos[1] 'wincmd w' + call winrestview(s:pos[2]) + endif +endfunction + +function! s:finish_bindings() + nnoremap R :call retry() + nnoremap D :PlugDiff + nnoremap S :PlugStatus + nnoremap U :call status_update() + xnoremap U :call status_update() + nnoremap ]] :silent! call section('') + nnoremap [[ :silent! call section('b') +endfunction + +function! s:prepare(...) + if empty(getcwd()) + throw 'Invalid current working directory. Cannot proceed.' + endif + + for evar in ['$GIT_DIR', '$GIT_WORK_TREE'] + if exists(evar) + throw evar.' detected. Cannot proceed.' + endif + endfor + + call s:job_abort() + if s:switch_in() + if b:plug_preview == 1 + pc + endif + enew + else + call s:new_window() + endif + + nnoremap q :if b:plug_preview==1pcendifbd + if a:0 == 0 + call s:finish_bindings() + endif + let b:plug_preview = -1 + let s:plug_tab = tabpagenr() + let s:plug_buf = winbufnr(0) + call s:assign_name() + + for k in ['', 'L', 'o', 'X', 'd', 'dd'] + execute 'silent! unmap ' k + endfor + setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline modifiable nospell + if exists('+colorcolumn') + setlocal colorcolumn= + endif + setf vim-plug + if exists('g:syntax_on') + call s:syntax() + endif +endfunction + +function! s:assign_name() + " Assign buffer name + let prefix = '[Plugins]' + let name = prefix + let idx = 2 + while bufexists(name) + let name = printf('%s (%s)', prefix, idx) + let idx = idx + 1 + endwhile + silent! execute 'f' fnameescape(name) +endfunction + +function! s:chsh(swap) + let prev = [&shell, &shellcmdflag, &shellredir] + if !s:is_win && a:swap + set shell=sh shellredir=>%s\ 2>&1 + endif + return prev +endfunction + +function! s:bang(cmd, ...) + let batchfile = '' + try + let [sh, shellcmdflag, shrd] = s:chsh(a:0) + " FIXME: Escaping is incomplete. We could use shellescape with eval, + " but it won't work on Windows. + let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd + if s:is_win + let [batchfile, cmd] = s:batchfile(cmd) + endif + let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%') + execute "normal! :execute g:_plug_bang\\" + finally + unlet g:_plug_bang + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win && filereadable(batchfile) + call delete(batchfile) + endif + endtry + return v:shell_error ? 'Exit status: ' . v:shell_error : '' +endfunction + +function! s:regress_bar() + let bar = substitute(getline(2)[1:-2], '.*\zs=', 'x', '') + call s:progress_bar(2, bar, len(bar)) +endfunction + +function! s:is_updated(dir) + return !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"', a:dir)) +endfunction + +function! s:do(pull, force, todo) + for [name, spec] in items(a:todo) + if !isdirectory(spec.dir) + continue + endif + let installed = has_key(s:update.new, name) + let updated = installed ? 0 : + \ (a:pull && index(s:update.errors, name) < 0 && s:is_updated(spec.dir)) + if a:force || installed || updated + execute 'cd' s:esc(spec.dir) + call append(3, '- Post-update hook for '. name .' ... ') + let error = '' + let type = type(spec.do) + if type == s:TYPE.string + if spec.do[0] == ':' + if !get(s:loaded, name, 0) + let s:loaded[name] = 1 + call s:reorg_rtp() + endif + call s:load_plugin(spec) + try + execute spec.do[1:] + catch + let error = v:exception + endtry + if !s:plug_window_exists() + cd - + throw 'Warning: vim-plug was terminated by the post-update hook of '.name + endif + else + let error = s:bang(spec.do) + endif + elseif type == s:TYPE.funcref + try + let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') + call spec.do({ 'name': name, 'status': status, 'force': a:force }) + catch + let error = v:exception + endtry + else + let error = 'Invalid hook type' + endif + call s:switch_in() + call setline(4, empty(error) ? (getline(4) . 'OK') + \ : ('x' . getline(4)[1:] . error)) + if !empty(error) + call add(s:update.errors, name) + call s:regress_bar() + endif + cd - + endif + endfor +endfunction + +function! s:hash_match(a, b) + return stridx(a:a, a:b) == 0 || stridx(a:b, a:a) == 0 +endfunction + +function! s:checkout(spec) + let sha = a:spec.commit + let output = s:system('git rev-parse HEAD', a:spec.dir) + if !v:shell_error && !s:hash_match(sha, s:lines(output)[0]) + let output = s:system( + \ 'git fetch --depth 999999 && git checkout '.s:esc(sha).' --', a:spec.dir) + endif + return output +endfunction + +function! s:finish(pull) + let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen')) + if new_frozen + let s = new_frozen > 1 ? 's' : '' + call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s)) + endif + call append(3, '- Finishing ... ') | 4 + redraw + call plug#helptags() + call plug#end() + call setline(4, getline(4) . 'Done!') + redraw + let msgs = [] + if !empty(s:update.errors) + call add(msgs, "Press 'R' to retry.") + endif + if a:pull && len(s:update.new) < len(filter(getline(5, '$'), + \ "v:val =~ '^- ' && v:val !~# 'Already up.to.date'")) + call add(msgs, "Press 'D' to see the updated changes.") + endif + echo join(msgs, ' ') + call s:finish_bindings() +endfunction + +function! s:retry() + if empty(s:update.errors) + return + endif + echo + call s:update_impl(s:update.pull, s:update.force, + \ extend(copy(s:update.errors), [s:update.threads])) +endfunction + +function! s:is_managed(name) + return has_key(g:plugs[a:name], 'uri') +endfunction + +function! s:names(...) + return sort(filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)')) +endfunction + +function! s:check_ruby() + silent! ruby require 'thread'; VIM::command("let g:plug_ruby = '#{RUBY_VERSION}'") + if !exists('g:plug_ruby') + redraw! + return s:warn('echom', 'Warning: Ruby interface is broken') + endif + let ruby_version = split(g:plug_ruby, '\.') + unlet g:plug_ruby + return s:version_requirement(ruby_version, [1, 8, 7]) +endfunction + +function! s:update_impl(pull, force, args) abort + let sync = index(a:args, '--sync') >= 0 || has('vim_starting') + let args = filter(copy(a:args), 'v:val != "--sync"') + let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ? + \ remove(args, -1) : get(g:, 'plug_threads', 16) + + let managed = filter(copy(g:plugs), 's:is_managed(v:key)') + let todo = empty(args) ? filter(managed, '!v:val.frozen || !isdirectory(v:val.dir)') : + \ filter(managed, 'index(args, v:key) >= 0') + + if empty(todo) + return s:warn('echo', 'No plugin to '. (a:pull ? 'update' : 'install')) + endif + + if !s:is_win && s:git_version_requirement(2, 3) + let s:git_terminal_prompt = exists('$GIT_TERMINAL_PROMPT') ? $GIT_TERMINAL_PROMPT : '' + let $GIT_TERMINAL_PROMPT = 0 + for plug in values(todo) + let plug.uri = substitute(plug.uri, + \ '^https://git::@github\.com', 'https://github.com', '') + endfor + endif + + if !isdirectory(g:plug_home) + try + call mkdir(g:plug_home, 'p') + catch + return s:err(printf('Invalid plug directory: %s. '. + \ 'Try to call plug#begin with a valid directory', g:plug_home)) + endtry + endif + + if has('nvim') && !exists('*jobwait') && threads > 1 + call s:warn('echom', '[vim-plug] Update Neovim for parallel installer') + endif + + let use_job = s:nvim || s:vim8 + let python = (has('python') || has('python3')) && !use_job + let ruby = has('ruby') && !use_job && (v:version >= 703 || v:version == 702 && has('patch374')) && !(s:is_win && has('gui_running')) && threads > 1 && s:check_ruby() + + let s:update = { + \ 'start': reltime(), + \ 'all': todo, + \ 'todo': copy(todo), + \ 'errors': [], + \ 'pull': a:pull, + \ 'force': a:force, + \ 'new': {}, + \ 'threads': (python || ruby || use_job) ? min([len(todo), threads]) : 1, + \ 'bar': '', + \ 'fin': 0 + \ } + + call s:prepare(1) + call append(0, ['', '']) + normal! 2G + silent! redraw + + let s:clone_opt = get(g:, 'plug_shallow', 1) ? + \ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : '' + + if has('win32unix') || has('wsl') + let s:clone_opt .= ' -c core.eol=lf -c core.autocrlf=input' + endif + + let s:submodule_opt = s:git_version_requirement(2, 8) ? ' --jobs='.threads : '' + + " Python version requirement (>= 2.7) + if python && !has('python3') && !ruby && !use_job && s:update.threads > 1 + redir => pyv + silent python import platform; print platform.python_version() + redir END + let python = s:version_requirement( + \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 6]) + endif + + if (python || ruby) && s:update.threads > 1 + try + let imd = &imd + if s:mac_gui + set noimd + endif + if ruby + call s:update_ruby() + else + call s:update_python() + endif + catch + let lines = getline(4, '$') + let printed = {} + silent! 4,$d _ + for line in lines + let name = s:extract_name(line, '.', '') + if empty(name) || !has_key(printed, name) + call append('$', line) + if !empty(name) + let printed[name] = 1 + if line[0] == 'x' && index(s:update.errors, name) < 0 + call add(s:update.errors, name) + end + endif + endif + endfor + finally + let &imd = imd + call s:update_finish() + endtry + else + call s:update_vim() + while use_job && sync + sleep 100m + if s:update.fin + break + endif + endwhile + endif +endfunction + +function! s:log4(name, msg) + call setline(4, printf('- %s (%s)', a:msg, a:name)) + redraw +endfunction + +function! s:update_finish() + if exists('s:git_terminal_prompt') + let $GIT_TERMINAL_PROMPT = s:git_terminal_prompt + endif + if s:switch_in() + call append(3, '- Updating ...') | 4 + for [name, spec] in items(filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && (s:update.force || s:update.pull || has_key(s:update.new, v:key))')) + let [pos, _] = s:logpos(name) + if !pos + continue + endif + if has_key(spec, 'commit') + call s:log4(name, 'Checking out '.spec.commit) + let out = s:checkout(spec) + elseif has_key(spec, 'tag') + let tag = spec.tag + if tag =~ '\*' + let tags = s:lines(s:system('git tag --list '.plug#shellescape(tag).' --sort -version:refname 2>&1', spec.dir)) + if !v:shell_error && !empty(tags) + let tag = tags[0] + call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag)) + call append(3, '') + endif + endif + call s:log4(name, 'Checking out '.tag) + let out = s:system('git checkout -q '.s:esc(tag).' -- 2>&1', spec.dir) + else + let branch = s:esc(get(spec, 'branch', 'master')) + call s:log4(name, 'Merging origin/'.branch) + let out = s:system('git checkout -q '.branch.' -- 2>&1' + \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only origin/'.branch.' 2>&1')), spec.dir) + endif + if !v:shell_error && filereadable(spec.dir.'/.gitmodules') && + \ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir)) + call s:log4(name, 'Updating submodules. This may take a while.') + let out .= s:bang('git submodule update --init --recursive'.s:submodule_opt.' 2>&1', spec.dir) + endif + let msg = s:format_message(v:shell_error ? 'x': '-', name, out) + if v:shell_error + call add(s:update.errors, name) + call s:regress_bar() + silent execute pos 'd _' + call append(4, msg) | 4 + elseif !empty(out) + call setline(pos, msg[0]) + endif + redraw + endfor + silent 4 d _ + try + call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")')) + catch + call s:warn('echom', v:exception) + call s:warn('echo', '') + return + endtry + call s:finish(s:update.pull) + call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.') + call s:switch_out('normal! gg') + endif +endfunction + +function! s:job_abort() + if (!s:nvim && !s:vim8) || !exists('s:jobs') + return + endif + + for [name, j] in items(s:jobs) + if s:nvim + silent! call jobstop(j.jobid) + elseif s:vim8 + silent! call job_stop(j.jobid) + endif + if j.new + call s:system('rm -rf ' . plug#shellescape(g:plugs[name].dir)) + endif + endfor + let s:jobs = {} +endfunction + +function! s:last_non_empty_line(lines) + let len = len(a:lines) + for idx in range(len) + let line = a:lines[len-idx-1] + if !empty(line) + return line + endif + endfor + return '' +endfunction + +function! s:job_out_cb(self, data) abort + let self = a:self + let data = remove(self.lines, -1) . a:data + let lines = map(split(data, "\n", 1), 'split(v:val, "\r", 1)[-1]') + call extend(self.lines, lines) + " To reduce the number of buffer updates + let self.tick = get(self, 'tick', -1) + 1 + if !self.running || self.tick % len(s:jobs) == 0 + let bullet = self.running ? (self.new ? '+' : '*') : (self.error ? 'x' : '-') + let result = self.error ? join(self.lines, "\n") : s:last_non_empty_line(self.lines) + call s:log(bullet, self.name, result) + endif +endfunction + +function! s:job_exit_cb(self, data) abort + let a:self.running = 0 + let a:self.error = a:data != 0 + call s:reap(a:self.name) + call s:tick() +endfunction + +function! s:job_cb(fn, job, ch, data) + if !s:plug_window_exists() " plug window closed + return s:job_abort() + endif + call call(a:fn, [a:job, a:data]) +endfunction + +function! s:nvim_cb(job_id, data, event) dict abort + return a:event == 'stdout' ? + \ s:job_cb('s:job_out_cb', self, 0, join(a:data, "\n")) : + \ s:job_cb('s:job_exit_cb', self, 0, a:data) +endfunction + +function! s:spawn(name, cmd, opts) + let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''], + \ 'new': get(a:opts, 'new', 0) } + let s:jobs[a:name] = job + let cmd = has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir, 0) : a:cmd + let argv = s:is_win ? ['cmd', '/s', '/c', '"'.cmd.'"'] : ['sh', '-c', cmd] + + if s:nvim + call extend(job, { + \ 'on_stdout': function('s:nvim_cb'), + \ 'on_exit': function('s:nvim_cb'), + \ }) + let jid = jobstart(argv, job) + if jid > 0 + let job.jobid = jid + else + let job.running = 0 + let job.error = 1 + let job.lines = [jid < 0 ? argv[0].' is not executable' : + \ 'Invalid arguments (or job table is full)'] + endif + elseif s:vim8 + let jid = job_start(s:is_win ? join(argv, ' ') : argv, { + \ 'out_cb': function('s:job_cb', ['s:job_out_cb', job]), + \ 'exit_cb': function('s:job_cb', ['s:job_exit_cb', job]), + \ 'out_mode': 'raw' + \}) + if job_status(jid) == 'run' + let job.jobid = jid + else + let job.running = 0 + let job.error = 1 + let job.lines = ['Failed to start job'] + endif + else + let job.lines = s:lines(call('s:system', [cmd])) + let job.error = v:shell_error != 0 + let job.running = 0 + endif +endfunction + +function! s:reap(name) + let job = s:jobs[a:name] + if job.error + call add(s:update.errors, a:name) + elseif get(job, 'new', 0) + let s:update.new[a:name] = 1 + endif + let s:update.bar .= job.error ? 'x' : '=' + + let bullet = job.error ? 'x' : '-' + let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines) + call s:log(bullet, a:name, empty(result) ? 'OK' : result) + call s:bar() + + call remove(s:jobs, a:name) +endfunction + +function! s:bar() + if s:switch_in() + let total = len(s:update.all) + call setline(1, (s:update.pull ? 'Updating' : 'Installing'). + \ ' plugins ('.len(s:update.bar).'/'.total.')') + call s:progress_bar(2, s:update.bar, total) + call s:switch_out() + endif +endfunction + +function! s:logpos(name) + for i in range(4, line('$')) + if getline(i) =~# '^[-+x*] '.a:name.':' + for j in range(i + 1, line('$')) + if getline(j) !~ '^ ' + return [i, j - 1] + endif + endfor + return [i, i] + endif + endfor + return [0, 0] +endfunction + +function! s:log(bullet, name, lines) + if s:switch_in() + let [b, e] = s:logpos(a:name) + if b > 0 + silent execute printf('%d,%d d _', b, e) + if b > winheight('.') + let b = 4 + endif + else + let b = 4 + endif + " FIXME For some reason, nomodifiable is set after :d in vim8 + setlocal modifiable + call append(b - 1, s:format_message(a:bullet, a:name, a:lines)) + call s:switch_out() + endif +endfunction + +function! s:update_vim() + let s:jobs = {} + + call s:bar() + call s:tick() +endfunction + +function! s:tick() + let pull = s:update.pull + let prog = s:progress_opt(s:nvim || s:vim8) +while 1 " Without TCO, Vim stack is bound to explode + if empty(s:update.todo) + if empty(s:jobs) && !s:update.fin + call s:update_finish() + let s:update.fin = 1 + endif + return + endif + + let name = keys(s:update.todo)[0] + let spec = remove(s:update.todo, name) + let new = empty(globpath(spec.dir, '.git', 1)) + + call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...') + redraw + + let has_tag = has_key(spec, 'tag') + if !new + let [error, _] = s:git_validate(spec, 0) + if empty(error) + if pull + let fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : '' + call s:spawn(name, printf('git fetch %s %s 2>&1', fetch_opt, prog), { 'dir': spec.dir }) + else + let s:jobs[name] = { 'running': 0, 'lines': ['Already installed'], 'error': 0 } + endif + else + let s:jobs[name] = { 'running': 0, 'lines': s:lines(error), 'error': 1 } + endif + else + call s:spawn(name, + \ printf('git clone %s %s %s %s 2>&1', + \ has_tag ? '' : s:clone_opt, + \ prog, + \ plug#shellescape(spec.uri, {'script': 0}), + \ plug#shellescape(s:trim(spec.dir), {'script': 0})), { 'new': 1 }) + endif + + if !s:jobs[name].running + call s:reap(name) + endif + if len(s:jobs) >= s:update.threads + break + endif +endwhile +endfunction + +function! s:update_python() +let py_exe = has('python') ? 'python' : 'python3' +execute py_exe "<< EOF" +import datetime +import functools +import os +try: + import queue +except ImportError: + import Queue as queue +import random +import re +import shutil +import signal +import subprocess +import tempfile +import threading as thr +import time +import traceback +import vim + +G_NVIM = vim.eval("has('nvim')") == '1' +G_PULL = vim.eval('s:update.pull') == '1' +G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1 +G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)')) +G_CLONE_OPT = vim.eval('s:clone_opt') +G_PROGRESS = vim.eval('s:progress_opt(1)') +G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads')) +G_STOP = thr.Event() +G_IS_WIN = vim.eval('s:is_win') == '1' + +class PlugError(Exception): + def __init__(self, msg): + self.msg = msg +class CmdTimedOut(PlugError): + pass +class CmdFailed(PlugError): + pass +class InvalidURI(PlugError): + pass +class Action(object): + INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-'] + +class Buffer(object): + def __init__(self, lock, num_plugs, is_pull): + self.bar = '' + self.event = 'Updating' if is_pull else 'Installing' + self.lock = lock + self.maxy = int(vim.eval('winheight(".")')) + self.num_plugs = num_plugs + + def __where(self, name): + """ Find first line with name in current buffer. Return line num. """ + found, lnum = False, 0 + matcher = re.compile('^[-+x*] {0}:'.format(name)) + for line in vim.current.buffer: + if matcher.search(line) is not None: + found = True + break + lnum += 1 + + if not found: + lnum = -1 + return lnum + + def header(self): + curbuf = vim.current.buffer + curbuf[0] = self.event + ' plugins ({0}/{1})'.format(len(self.bar), self.num_plugs) + + num_spaces = self.num_plugs - len(self.bar) + curbuf[1] = '[{0}{1}]'.format(self.bar, num_spaces * ' ') + + with self.lock: + vim.command('normal! 2G') + vim.command('redraw') + + def write(self, action, name, lines): + first, rest = lines[0], lines[1:] + msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)] + msg.extend([' ' + line for line in rest]) + + try: + if action == Action.ERROR: + self.bar += 'x' + vim.command("call add(s:update.errors, '{0}')".format(name)) + elif action == Action.DONE: + self.bar += '=' + + curbuf = vim.current.buffer + lnum = self.__where(name) + if lnum != -1: # Found matching line num + del curbuf[lnum] + if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]): + lnum = 3 + else: + lnum = 3 + curbuf.append(msg, lnum) + + self.header() + except vim.error: + pass + +class Command(object): + CD = 'cd /d' if G_IS_WIN else 'cd' + + def __init__(self, cmd, cmd_dir=None, timeout=60, cb=None, clean=None): + self.cmd = cmd + if cmd_dir: + self.cmd = '{0} {1} && {2}'.format(Command.CD, cmd_dir, self.cmd) + self.timeout = timeout + self.callback = cb if cb else (lambda msg: None) + self.clean = clean if clean else (lambda: None) + self.proc = None + + @property + def alive(self): + """ Returns true only if command still running. """ + return self.proc and self.proc.poll() is None + + def execute(self, ntries=3): + """ Execute the command with ntries if CmdTimedOut. + Returns the output of the command if no Exception. + """ + attempt, finished, limit = 0, False, self.timeout + + while not finished: + try: + attempt += 1 + result = self.try_command() + finished = True + return result + except CmdTimedOut: + if attempt != ntries: + self.notify_retry() + self.timeout += limit + else: + raise + + def notify_retry(self): + """ Retry required for command, notify user. """ + for count in range(3, 0, -1): + if G_STOP.is_set(): + raise KeyboardInterrupt + msg = 'Timeout. Will retry in {0} second{1} ...'.format( + count, 's' if count != 1 else '') + self.callback([msg]) + time.sleep(1) + self.callback(['Retrying ...']) + + def try_command(self): + """ Execute a cmd & poll for callback. Returns list of output. + Raises CmdFailed -> return code for Popen isn't 0 + Raises CmdTimedOut -> command exceeded timeout without new output + """ + first_line = True + + try: + tfile = tempfile.NamedTemporaryFile(mode='w+b') + preexec_fn = not G_IS_WIN and os.setsid or None + self.proc = subprocess.Popen(self.cmd, stdout=tfile, + stderr=subprocess.STDOUT, + stdin=subprocess.PIPE, shell=True, + preexec_fn=preexec_fn) + thrd = thr.Thread(target=(lambda proc: proc.wait()), args=(self.proc,)) + thrd.start() + + thread_not_started = True + while thread_not_started: + try: + thrd.join(0.1) + thread_not_started = False + except RuntimeError: + pass + + while self.alive: + if G_STOP.is_set(): + raise KeyboardInterrupt + + if first_line or random.random() < G_LOG_PROB: + first_line = False + line = '' if G_IS_WIN else nonblock_read(tfile.name) + if line: + self.callback([line]) + + time_diff = time.time() - os.path.getmtime(tfile.name) + if time_diff > self.timeout: + raise CmdTimedOut(['Timeout!']) + + thrd.join(0.5) + + tfile.seek(0) + result = [line.decode('utf-8', 'replace').rstrip() for line in tfile] + + if self.proc.returncode != 0: + raise CmdFailed([''] + result) + + return result + except: + self.terminate() + raise + + def terminate(self): + """ Terminate process and cleanup. """ + if self.alive: + if G_IS_WIN: + os.kill(self.proc.pid, signal.SIGINT) + else: + os.killpg(self.proc.pid, signal.SIGTERM) + self.clean() + +class Plugin(object): + def __init__(self, name, args, buf_q, lock): + self.name = name + self.args = args + self.buf_q = buf_q + self.lock = lock + self.tag = args.get('tag', 0) + + def manage(self): + try: + if os.path.exists(self.args['dir']): + self.update() + else: + self.install() + with self.lock: + thread_vim_command("let s:update.new['{0}'] = 1".format(self.name)) + except PlugError as exc: + self.write(Action.ERROR, self.name, exc.msg) + except KeyboardInterrupt: + G_STOP.set() + self.write(Action.ERROR, self.name, ['Interrupted!']) + except: + # Any exception except those above print stack trace + msg = 'Trace:\n{0}'.format(traceback.format_exc().rstrip()) + self.write(Action.ERROR, self.name, msg.split('\n')) + raise + + def install(self): + target = self.args['dir'] + if target[-1] == '\\': + target = target[0:-1] + + def clean(target): + def _clean(): + try: + shutil.rmtree(target) + except OSError: + pass + return _clean + + self.write(Action.INSTALL, self.name, ['Installing ...']) + callback = functools.partial(self.write, Action.INSTALL, self.name) + cmd = 'git clone {0} {1} {2} {3} 2>&1'.format( + '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'], + esc(target)) + com = Command(cmd, None, G_TIMEOUT, callback, clean(target)) + result = com.execute(G_RETRIES) + self.write(Action.DONE, self.name, result[-1:]) + + def repo_uri(self): + cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url' + command = Command(cmd, self.args['dir'], G_TIMEOUT,) + result = command.execute(G_RETRIES) + return result[-1] + + def update(self): + actual_uri = self.repo_uri() + expect_uri = self.args['uri'] + regex = re.compile(r'^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$') + ma = regex.match(actual_uri) + mb = regex.match(expect_uri) + if ma is None or mb is None or ma.groups() != mb.groups(): + msg = ['', + 'Invalid URI: {0}'.format(actual_uri), + 'Expected {0}'.format(expect_uri), + 'PlugClean required.'] + raise InvalidURI(msg) + + if G_PULL: + self.write(Action.UPDATE, self.name, ['Updating ...']) + callback = functools.partial(self.write, Action.UPDATE, self.name) + fetch_opt = '--depth 99999999' if self.tag and os.path.isfile(os.path.join(self.args['dir'], '.git/shallow')) else '' + cmd = 'git fetch {0} {1} 2>&1'.format(fetch_opt, G_PROGRESS) + com = Command(cmd, self.args['dir'], G_TIMEOUT, callback) + result = com.execute(G_RETRIES) + self.write(Action.DONE, self.name, result[-1:]) + else: + self.write(Action.DONE, self.name, ['Already installed']) + + def write(self, action, name, msg): + self.buf_q.put((action, name, msg)) + +class PlugThread(thr.Thread): + def __init__(self, tname, args): + super(PlugThread, self).__init__() + self.tname = tname + self.args = args + + def run(self): + thr.current_thread().name = self.tname + buf_q, work_q, lock = self.args + + try: + while not G_STOP.is_set(): + name, args = work_q.get_nowait() + plug = Plugin(name, args, buf_q, lock) + plug.manage() + work_q.task_done() + except queue.Empty: + pass + +class RefreshThread(thr.Thread): + def __init__(self, lock): + super(RefreshThread, self).__init__() + self.lock = lock + self.running = True + + def run(self): + while self.running: + with self.lock: + thread_vim_command('noautocmd normal! a') + time.sleep(0.33) + + def stop(self): + self.running = False + +if G_NVIM: + def thread_vim_command(cmd): + vim.session.threadsafe_call(lambda: vim.command(cmd)) +else: + def thread_vim_command(cmd): + vim.command(cmd) + +def esc(name): + return '"' + name.replace('"', '\"') + '"' + +def nonblock_read(fname): + """ Read a file with nonblock flag. Return the last line. """ + fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK) + buf = os.read(fread, 100000).decode('utf-8', 'replace') + os.close(fread) + + line = buf.rstrip('\r\n') + left = max(line.rfind('\r'), line.rfind('\n')) + if left != -1: + left += 1 + line = line[left:] + + return line + +def main(): + thr.current_thread().name = 'main' + nthreads = int(vim.eval('s:update.threads')) + plugs = vim.eval('s:update.todo') + mac_gui = vim.eval('s:mac_gui') == '1' + + lock = thr.Lock() + buf = Buffer(lock, len(plugs), G_PULL) + buf_q, work_q = queue.Queue(), queue.Queue() + for work in plugs.items(): + work_q.put(work) + + start_cnt = thr.active_count() + for num in range(nthreads): + tname = 'PlugT-{0:02}'.format(num) + thread = PlugThread(tname, (buf_q, work_q, lock)) + thread.start() + if mac_gui: + rthread = RefreshThread(lock) + rthread.start() + + while not buf_q.empty() or thr.active_count() != start_cnt: + try: + action, name, msg = buf_q.get(True, 0.25) + buf.write(action, name, ['OK'] if not msg else msg) + buf_q.task_done() + except queue.Empty: + pass + except KeyboardInterrupt: + G_STOP.set() + + if mac_gui: + rthread.stop() + rthread.join() + +main() +EOF +endfunction + +function! s:update_ruby() + ruby << EOF + module PlugStream + SEP = ["\r", "\n", nil] + def get_line + buffer = '' + loop do + char = readchar rescue return + if SEP.include? char.chr + buffer << $/ + break + else + buffer << char + end + end + buffer + end + end unless defined?(PlugStream) + + def esc arg + %["#{arg.gsub('"', '\"')}"] + end + + def killall pid + pids = [pid] + if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM + pids.each { |pid| Process.kill 'INT', pid.to_i rescue nil } + else + unless `which pgrep 2> /dev/null`.empty? + children = pids + until children.empty? + children = children.map { |pid| + `pgrep -P #{pid}`.lines.map { |l| l.chomp } + }.flatten + pids += children + end + end + pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil } + end + end + + def compare_git_uri a, b + regex = %r{^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$} + regex.match(a).to_a.drop(1) == regex.match(b).to_a.drop(1) + end + + require 'thread' + require 'fileutils' + require 'timeout' + running = true + iswin = VIM::evaluate('s:is_win').to_i == 1 + pull = VIM::evaluate('s:update.pull').to_i == 1 + base = VIM::evaluate('g:plug_home') + all = VIM::evaluate('s:update.todo') + limit = VIM::evaluate('get(g:, "plug_timeout", 60)') + tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1 + nthr = VIM::evaluate('s:update.threads').to_i + maxy = VIM::evaluate('winheight(".")').to_i + vim7 = VIM::evaluate('v:version').to_i <= 703 && RUBY_PLATFORM =~ /darwin/ + cd = iswin ? 'cd /d' : 'cd' + tot = VIM::evaluate('len(s:update.todo)') || 0 + bar = '' + skip = 'Already installed' + mtx = Mutex.new + take1 = proc { mtx.synchronize { running && all.shift } } + logh = proc { + cnt = bar.length + $curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})" + $curbuf[2] = '[' + bar.ljust(tot) + ']' + VIM::command('normal! 2G') + VIM::command('redraw') + } + where = proc { |name| (1..($curbuf.length)).find { |l| $curbuf[l] =~ /^[-+x*] #{name}:/ } } + log = proc { |name, result, type| + mtx.synchronize do + ing = ![true, false].include?(type) + bar += type ? '=' : 'x' unless ing + b = case type + when :install then '+' when :update then '*' + when true, nil then '-' else + VIM::command("call add(s:update.errors, '#{name}')") + 'x' + end + result = + if type || type.nil? + ["#{b} #{name}: #{result.lines.to_a.last || 'OK'}"] + elsif result =~ /^Interrupted|^Timeout/ + ["#{b} #{name}: #{result}"] + else + ["#{b} #{name}"] + result.lines.map { |l| " " << l } + end + if lnum = where.call(name) + $curbuf.delete lnum + lnum = 4 if ing && lnum > maxy + end + result.each_with_index do |line, offset| + $curbuf.append((lnum || 4) - 1 + offset, line.gsub(/\e\[./, '').chomp) + end + logh.call + end + } + bt = proc { |cmd, name, type, cleanup| + tried = timeout = 0 + begin + tried += 1 + timeout += limit + fd = nil + data = '' + if iswin + Timeout::timeout(timeout) do + tmp = VIM::evaluate('tempname()') + system("(#{cmd}) > #{tmp}") + data = File.read(tmp).chomp + File.unlink tmp rescue nil + end + else + fd = IO.popen(cmd).extend(PlugStream) + first_line = true + log_prob = 1.0 / nthr + while line = Timeout::timeout(timeout) { fd.get_line } + data << line + log.call name, line.chomp, type if name && (first_line || rand < log_prob) + first_line = false + end + fd.close + end + [$? == 0, data.chomp] + rescue Timeout::Error, Interrupt => e + if fd && !fd.closed? + killall fd.pid + fd.close + end + cleanup.call if cleanup + if e.is_a?(Timeout::Error) && tried < tries + 3.downto(1) do |countdown| + s = countdown > 1 ? 's' : '' + log.call name, "Timeout. Will retry in #{countdown} second#{s} ...", type + sleep 1 + end + log.call name, 'Retrying ...', type + retry + end + [false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"] + end + } + main = Thread.current + threads = [] + watcher = Thread.new { + if vim7 + while VIM::evaluate('getchar(1)') + sleep 0.1 + end + else + require 'io/console' # >= Ruby 1.9 + nil until IO.console.getch == 3.chr + end + mtx.synchronize do + running = false + threads.each { |t| t.raise Interrupt } unless vim7 + end + threads.each { |t| t.join rescue nil } + main.kill + } + refresh = Thread.new { + while true + mtx.synchronize do + break unless running + VIM::command('noautocmd normal! a') + end + sleep 0.2 + end + } if VIM::evaluate('s:mac_gui') == 1 + + clone_opt = VIM::evaluate('s:clone_opt') + progress = VIM::evaluate('s:progress_opt(1)') + nthr.times do + mtx.synchronize do + threads << Thread.new { + while pair = take1.call + name = pair.first + dir, uri, tag = pair.last.values_at *%w[dir uri tag] + exists = File.directory? dir + ok, result = + if exists + chdir = "#{cd} #{iswin ? dir : esc(dir)}" + ret, data = bt.call "#{chdir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url", nil, nil, nil + current_uri = data.lines.to_a.last + if !ret + if data =~ /^Interrupted|^Timeout/ + [false, data] + else + [false, [data.chomp, "PlugClean required."].join($/)] + end + elsif !compare_git_uri(current_uri, uri) + [false, ["Invalid URI: #{current_uri}", + "Expected: #{uri}", + "PlugClean required."].join($/)] + else + if pull + log.call name, 'Updating ...', :update + fetch_opt = (tag && File.exist?(File.join(dir, '.git/shallow'))) ? '--depth 99999999' : '' + bt.call "#{chdir} && git fetch #{fetch_opt} #{progress} 2>&1", name, :update, nil + else + [true, skip] + end + end + else + d = esc dir.sub(%r{[\\/]+$}, '') + log.call name, 'Installing ...', :install + bt.call "git clone #{clone_opt unless tag} #{progress} #{uri} #{d} 2>&1", name, :install, proc { + FileUtils.rm_rf dir + } + end + mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok + log.call name, result, ok + end + } if running + end + end + threads.each { |t| t.join rescue nil } + logh.call + refresh.kill if refresh + watcher.kill +EOF +endfunction + +function! s:shellesc_cmd(arg, script) + let escaped = substitute('"'.a:arg.'"', '[&|<>()@^!"]', '^&', 'g') + return substitute(escaped, '%', (a:script ? '%' : '^') . '&', 'g') +endfunction + +function! s:shellesc_ps1(arg) + return "'".substitute(escape(a:arg, '\"'), "'", "''", 'g')."'" +endfunction + +function! plug#shellescape(arg, ...) + let opts = a:0 > 0 && type(a:1) == s:TYPE.dict ? a:1 : {} + let shell = get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh') + let script = get(opts, 'script', 1) + if shell =~# 'cmd\.exe$' + return s:shellesc_cmd(a:arg, script) + elseif shell =~# 'powershell\.exe$' || shell =~# 'pwsh$' + return s:shellesc_ps1(a:arg) + endif + return shellescape(a:arg) +endfunction + +function! s:glob_dir(path) + return map(filter(s:glob(a:path, '**'), 'isdirectory(v:val)'), 's:dirpath(v:val)') +endfunction + +function! s:progress_bar(line, bar, total) + call setline(a:line, '[' . s:lpad(a:bar, a:total) . ']') +endfunction + +function! s:compare_git_uri(a, b) + " See `git help clone' + " https:// [user@] github.com[:port] / junegunn/vim-plug [.git] + " [git@] github.com[:port] : junegunn/vim-plug [.git] + " file:// / junegunn/vim-plug [/] + " / junegunn/vim-plug [/] + let pat = '^\%(\w\+://\)\='.'\%([^@/]*@\)\='.'\([^:/]*\%(:[0-9]*\)\=\)'.'[:/]'.'\(.\{-}\)'.'\%(\.git\)\=/\?$' + let ma = matchlist(a:a, pat) + let mb = matchlist(a:b, pat) + return ma[1:2] ==# mb[1:2] +endfunction + +function! s:format_message(bullet, name, message) + if a:bullet != 'x' + return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))] + else + let lines = map(s:lines(a:message), '" ".v:val') + return extend([printf('x %s:', a:name)], lines) + endif +endfunction + +function! s:with_cd(cmd, dir, ...) + let script = a:0 > 0 ? a:1 : 1 + return printf('cd%s %s && %s', s:is_win ? ' /d' : '', plug#shellescape(a:dir, {'script': script}), a:cmd) +endfunction + +function! s:system(cmd, ...) + let batchfile = '' + try + let [sh, shellcmdflag, shrd] = s:chsh(1) + let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd + if s:is_win + let [batchfile, cmd] = s:batchfile(cmd) + endif + return system(cmd) + finally + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win && filereadable(batchfile) + call delete(batchfile) + endif + endtry +endfunction + +function! s:system_chomp(...) + let ret = call('s:system', a:000) + return v:shell_error ? '' : substitute(ret, '\n$', '', '') +endfunction + +function! s:git_validate(spec, check_branch) + let err = '' + if isdirectory(a:spec.dir) + let result = s:lines(s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url', a:spec.dir)) + let remote = result[-1] + if v:shell_error + let err = join([remote, 'PlugClean required.'], "\n") + elseif !s:compare_git_uri(remote, a:spec.uri) + let err = join(['Invalid URI: '.remote, + \ 'Expected: '.a:spec.uri, + \ 'PlugClean required.'], "\n") + elseif a:check_branch && has_key(a:spec, 'commit') + let result = s:lines(s:system('git rev-parse HEAD 2>&1', a:spec.dir)) + let sha = result[-1] + if v:shell_error + let err = join(add(result, 'PlugClean required.'), "\n") + elseif !s:hash_match(sha, a:spec.commit) + let err = join([printf('Invalid HEAD (expected: %s, actual: %s)', + \ a:spec.commit[:6], sha[:6]), + \ 'PlugUpdate required.'], "\n") + endif + elseif a:check_branch + let branch = result[0] + " Check tag + if has_key(a:spec, 'tag') + let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir) + if a:spec.tag !=# tag && a:spec.tag !~ '\*' + let err = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.', + \ (empty(tag) ? 'N/A' : tag), a:spec.tag) + endif + " Check branch + elseif a:spec.branch !=# branch + let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', + \ branch, a:spec.branch) + endif + if empty(err) + let [ahead, behind] = split(s:lastline(s:system(printf( + \ 'git rev-list --count --left-right HEAD...origin/%s', + \ a:spec.branch), a:spec.dir)), '\t') + if !v:shell_error && ahead + if behind + " Only mention PlugClean if diverged, otherwise it's likely to be + " pushable (and probably not that messed up). + let err = printf( + \ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n" + \ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', a:spec.branch, ahead, behind) + else + let err = printf("Ahead of origin/%s by %d commit(s).\n" + \ .'Cannot update until local changes are pushed.', + \ a:spec.branch, ahead) + endif + endif + endif + endif + else + let err = 'Not found' + endif + return [err, err =~# 'PlugClean'] +endfunction + +function! s:rm_rf(dir) + if isdirectory(a:dir) + call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . plug#shellescape(a:dir)) + endif +endfunction + +function! s:clean(force) + call s:prepare() + call append(0, 'Searching for invalid plugins in '.g:plug_home) + call append(1, '') + + " List of valid directories + let dirs = [] + let errs = {} + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + if !s:is_managed(name) + call add(dirs, spec.dir) + else + let [err, clean] = s:git_validate(spec, 1) + if clean + let errs[spec.dir] = s:lines(err)[0] + else + call add(dirs, spec.dir) + endif + endif + let cnt += 1 + call s:progress_bar(2, repeat('=', cnt), total) + normal! 2G + redraw + endfor + + let allowed = {} + for dir in dirs + let allowed[s:dirpath(fnamemodify(dir, ':h:h'))] = 1 + let allowed[dir] = 1 + for child in s:glob_dir(dir) + let allowed[child] = 1 + endfor + endfor + + let todo = [] + let found = sort(s:glob_dir(g:plug_home)) + while !empty(found) + let f = remove(found, 0) + if !has_key(allowed, f) && isdirectory(f) + call add(todo, f) + call append(line('$'), '- ' . f) + if has_key(errs, f) + call append(line('$'), ' ' . errs[f]) + endif + let found = filter(found, 'stridx(v:val, f) != 0') + end + endwhile + + 4 + redraw + if empty(todo) + call append(line('$'), 'Already clean.') + else + let s:clean_count = 0 + call append(3, ['Directories to delete:', '']) + redraw! + if a:force || s:ask_no_interrupt('Delete all directories?') + call s:delete([6, line('$')], 1) + else + call setline(4, 'Cancelled.') + nnoremap d :set opfunc=delete_opg@ + nmap dd d_ + xnoremap d :call delete_op(visualmode(), 1) + echo 'Delete the lines (d{motion}) to delete the corresponding directories' + endif + endif + 4 + setlocal nomodifiable +endfunction + +function! s:delete_op(type, ...) + call s:delete(a:0 ? [line("'<"), line("'>")] : [line("'["), line("']")], 0) +endfunction + +function! s:delete(range, force) + let [l1, l2] = a:range + let force = a:force + while l1 <= l2 + let line = getline(l1) + if line =~ '^- ' && isdirectory(line[2:]) + execute l1 + redraw! + let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1) + let force = force || answer > 1 + if answer + call s:rm_rf(line[2:]) + setlocal modifiable + call setline(l1, '~'.line[1:]) + let s:clean_count += 1 + call setline(4, printf('Removed %d directories.', s:clean_count)) + setlocal nomodifiable + endif + endif + let l1 += 1 + endwhile +endfunction + +function! s:upgrade() + echo 'Downloading the latest version of vim-plug' + redraw + let tmp = tempname() + let new = tmp . '/plug.vim' + + try + let out = s:system(printf('git clone --depth 1 %s %s', plug#shellescape(s:plug_src), plug#shellescape(tmp))) + if v:shell_error + return s:err('Error upgrading vim-plug: '. out) + endif + + if readfile(s:me) ==# readfile(new) + echo 'vim-plug is already up-to-date' + return 0 + else + call rename(s:me, s:me . '.old') + call rename(new, s:me) + unlet g:loaded_plug + echo 'vim-plug has been upgraded' + return 1 + endif + finally + silent! call s:rm_rf(tmp) + endtry +endfunction + +function! s:upgrade_specs() + for spec in values(g:plugs) + let spec.frozen = get(spec, 'frozen', 0) + endfor +endfunction + +function! s:status() + call s:prepare() + call append(0, 'Checking plugins') + call append(1, '') + + let ecnt = 0 + let unloaded = 0 + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + let is_dir = isdirectory(spec.dir) + if has_key(spec, 'uri') + if is_dir + let [err, _] = s:git_validate(spec, 1) + let [valid, msg] = [empty(err), empty(err) ? 'OK' : err] + else + let [valid, msg] = [0, 'Not found. Try PlugInstall.'] + endif + else + if is_dir + let [valid, msg] = [1, 'OK'] + else + let [valid, msg] = [0, 'Not found.'] + endif + endif + let cnt += 1 + let ecnt += !valid + " `s:loaded` entry can be missing if PlugUpgraded + if is_dir && get(s:loaded, name, -1) == 0 + let unloaded = 1 + let msg .= ' (not loaded)' + endif + call s:progress_bar(2, repeat('=', cnt), total) + call append(3, s:format_message(valid ? '-' : 'x', name, msg)) + normal! 2G + redraw + endfor + call setline(1, 'Finished. '.ecnt.' error(s).') + normal! gg + setlocal nomodifiable + if unloaded + echo "Press 'L' on each line to load plugin, or 'U' to update" + nnoremap L :call status_load(line('.')) + xnoremap L :call status_load(line('.')) + end +endfunction + +function! s:extract_name(str, prefix, suffix) + return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$') +endfunction + +function! s:status_load(lnum) + let line = getline(a:lnum) + let name = s:extract_name(line, '-', '(not loaded)') + if !empty(name) + call plug#load(name) + setlocal modifiable + call setline(a:lnum, substitute(line, ' (not loaded)$', '', '')) + setlocal nomodifiable + endif +endfunction + +function! s:status_update() range + let lines = getline(a:firstline, a:lastline) + let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)') + if !empty(names) + echo + execute 'PlugUpdate' join(names) + endif +endfunction + +function! s:is_preview_window_open() + silent! wincmd P + if &previewwindow + wincmd p + return 1 + endif +endfunction + +function! s:find_name(lnum) + for lnum in reverse(range(1, a:lnum)) + let line = getline(lnum) + if empty(line) + return '' + endif + let name = s:extract_name(line, '-', '') + if !empty(name) + return name + endif + endfor + return '' +endfunction + +function! s:preview_commit() + if b:plug_preview < 0 + let b:plug_preview = !s:is_preview_window_open() + endif + + let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7,9}') + if empty(sha) + return + endif + + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir) + return + endif + + if exists('g:plug_pwindow') && !s:is_preview_window_open() + execute g:plug_pwindow + execute 'e' sha + else + execute 'pedit' sha + wincmd P + endif + setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable + let batchfile = '' + try + let [sh, shellcmdflag, shrd] = s:chsh(1) + let cmd = 'cd '.plug#shellescape(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha + if s:is_win + let [batchfile, cmd] = s:batchfile(cmd) + endif + execute 'silent %!' cmd + finally + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win && filereadable(batchfile) + call delete(batchfile) + endif + endtry + setlocal nomodifiable + nnoremap q :q + wincmd p +endfunction + +function! s:section(flags) + call search('\(^[x-] \)\@<=[^:]\+:', a:flags) +endfunction + +function! s:format_git_log(line) + let indent = ' ' + let tokens = split(a:line, nr2char(1)) + if len(tokens) != 5 + return indent.substitute(a:line, '\s*$', '', '') + endif + let [graph, sha, refs, subject, date] = tokens + let tag = matchstr(refs, 'tag: [^,)]\+') + let tag = empty(tag) ? ' ' : ' ('.tag.') ' + return printf('%s%s%s%s%s (%s)', indent, graph, sha, tag, subject, date) +endfunction + +function! s:append_ul(lnum, text) + call append(a:lnum, ['', a:text, repeat('-', len(a:text))]) +endfunction + +function! s:diff() + call s:prepare() + call append(0, ['Collecting changes ...', '']) + let cnts = [0, 0] + let bar = '' + let total = filter(copy(g:plugs), 's:is_managed(v:key) && isdirectory(v:val.dir)') + call s:progress_bar(2, bar, len(total)) + for origin in [1, 0] + let plugs = reverse(sort(items(filter(copy(total), (origin ? '' : '!').'(has_key(v:val, "commit") || has_key(v:val, "tag"))')))) + if empty(plugs) + continue + endif + call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:') + for [k, v] in plugs + let range = origin ? '..origin/'.v.branch : 'HEAD@{1}..' + let cmd = 'git log --graph --color=never '.join(map(['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range], 'plug#shellescape(v:val)')) + if has_key(v, 'rtp') + let cmd .= ' -- '.plug#shellescape(v.rtp) + endif + let diff = s:system_chomp(cmd, v.dir) + if !empty(diff) + let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : '' + call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)'))) + let cnts[origin] += 1 + endif + let bar .= '=' + call s:progress_bar(2, bar, len(total)) + normal! 2G + redraw + endfor + if !cnts[origin] + call append(5, ['', 'N/A']) + endif + endfor + call setline(1, printf('%d plugin(s) updated.', cnts[0]) + \ . (cnts[1] ? printf(' %d plugin(s) have pending updates.', cnts[1]) : '')) + + if cnts[0] || cnts[1] + nnoremap (plug-preview) :silent! call preview_commit() + if empty(maparg("\", 'n')) + nmap (plug-preview) + endif + if empty(maparg('o', 'n')) + nmap o (plug-preview) + endif + endif + if cnts[0] + nnoremap X :call revert() + echo "Press 'X' on each block to revert the update" + endif + normal! gg + setlocal nomodifiable +endfunction + +function! s:revert() + if search('^Pending updates', 'bnW') + return + endif + + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || + \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y' + return + endif + + call s:system('git reset --hard HEAD@{1} && git checkout '.s:esc(g:plugs[name].branch).' --', g:plugs[name].dir) + setlocal modifiable + normal! "_dap + setlocal nomodifiable + echo 'Reverted' +endfunction + +function! s:snapshot(force, ...) abort + call s:prepare() + setf vim + call append(0, ['" Generated by vim-plug', + \ '" '.strftime("%c"), + \ '" :source this file in vim to restore the snapshot', + \ '" or execute: vim -S snapshot.vim', + \ '', '', 'PlugUpdate!']) + 1 + let anchor = line('$') - 3 + let names = sort(keys(filter(copy(g:plugs), + \'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)'))) + for name in reverse(names) + let sha = s:system_chomp('git rev-parse --short HEAD', g:plugs[name].dir) + if !empty(sha) + call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha)) + redraw + endif + endfor + + if a:0 > 0 + let fn = expand(a:1) + if filereadable(fn) && !(a:force || s:ask(a:1.' already exists. Overwrite?')) + return + endif + call writefile(getline(1, '$'), fn) + echo 'Saved as '.a:1 + silent execute 'e' s:esc(fn) + setf vim + endif +endfunction + +function! s:split_rtp() + return split(&rtp, '\\\@\end{itemize}k inoremap ;i \item{} inoremap "" "`"'hha inoremap ;fp \begin{tabular}{ccc}\topruleJa & Nein & Enthaltung \\ \midrule & & \\\bottomrule\end{tabular}0kk -inoremap ;sec \section{}hi -inoremap ;ssec \subsection{}hi -inoremap ;sssec \subsubsection{}hi +inoremap ;sec \section{}i +inoremap ;ssec \subsection{}i +inoremap ;sssec \subsubsection{}i " Surround stuff vnoremap da\textbf{"} diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/.gitignore b/vim/.vim/pack/coc/start/coc.nvim-release/.gitignore new file mode 100644 index 0000000..a151978 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/.gitignore @@ -0,0 +1,12 @@ +lib +*.map +coverage +__pycache__ +.pyc +.log +src +publish.sh +doc/tags +doc/tags-cn +node_modules +src/__tests__/tags diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/LICENSE.md b/vim/.vim/pack/coc/start/coc.nvim-release/LICENSE.md new file mode 100644 index 0000000..bee2bf1 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/LICENSE.md @@ -0,0 +1,7 @@ +Copyright 2018-2018 by Qiming Zhao aaa + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/Readme.md b/vim/.vim/pack/coc/start/coc.nvim-release/Readme.md new file mode 100644 index 0000000..f56bfe6 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/Readme.md @@ -0,0 +1,216 @@ +

+ + Coc Logo + +

Make your Vim/Neovim as smart as VSCode.

+

+ Software License + Bountysource + Travis + Coverage + Doc + Gitter +

+

+ +--- + +Coc is an intellisense engine for Vim/Neovim. + +Gif + +_True snippet and additional text editing support_ + +Check out [Wiki](https://github.com/neoclide/coc.nvim/wiki), or [doc/coc.txt](doc/coc.txt) for the vim interface. + +## Quick Start + +Install [nodejs](https://nodejs.org/en/download/) when necessary: + +```sh +curl -sL install-node.now.sh/lts | bash +``` + +For [vim-plug](https://github.com/junegunn/vim-plug) users: + +```vim +" Use release branch (Recommend) +Plug 'neoclide/coc.nvim', {'branch': 'release'} + +" Or latest tag +Plug 'neoclide/coc.nvim', {'tag': '*', 'branch': 'release'} +" Or build from source code by use yarn: https://yarnpkg.com +Plug 'neoclide/coc.nvim', {'do': 'yarn install --frozen-lockfile'} +``` + +in your `.vimrc` or `init.vim`, then restart vim and run `:PlugInstall`. Checkout [Install coc.nvim](https://github.com/neoclide/coc.nvim/wiki/Install-coc.nvim) wiki for more info. + +**Note**: The first time building from source code may be slow. + +## Example vim configuration + +Configuration is required to make coc.nvim easier to work with, since it doesn't +change your key-mappings or vim options. This is done as much as possible to avoid conflict with your +other plugins. + +**❗️Important**: some vim plugins could change keymappings. Use a command like +`:verbose imap ` to make sure that your keymap has taken effect. + +```vim +" if hidden is not set, TextEdit might fail. +set hidden + +" Some servers have issues with backup files, see #649 +set nobackup +set nowritebackup + +" Better display for messages +set cmdheight=2 + +" You will have bad experience for diagnostic messages when it's default 4000. +set updatetime=300 + +" don't give |ins-completion-menu| messages. +set shortmess+=c + +" always show signcolumns +set signcolumn=yes + +" Use tab for trigger completion with characters ahead and navigate. +" Use command ':verbose imap ' to make sure tab is not mapped by other plugin. +inoremap + \ pumvisible() ? "\" : + \ check_back_space() ? "\" : + \ coc#refresh() +inoremap pumvisible() ? "\" : "\" + +function! s:check_back_space() abort + let col = col('.') - 1 + return !col || getline('.')[col - 1] =~# '\s' +endfunction + +" Use to trigger completion. +inoremap coc#refresh() + +" Use to confirm completion, `u` means break undo chain at current position. +" Coc only does snippet and additional edit on confirm. +inoremap pumvisible() ? "\" : "\u\" +" Or use `complete_info` if your vim support it, like: +" inoremap complete_info()["selected"] != "-1" ? "\" : "\u\" + +" Use `[g` and `]g` to navigate diagnostics +nmap [g (coc-diagnostic-prev) +nmap ]g (coc-diagnostic-next) + +" Remap keys for gotos +nmap gd (coc-definition) +nmap gy (coc-type-definition) +nmap gi (coc-implementation) +nmap gr (coc-references) + +" Use K to show documentation in preview window +nnoremap K :call show_documentation() + +function! s:show_documentation() + if (index(['vim','help'], &filetype) >= 0) + execute 'h '.expand('') + else + call CocAction('doHover') + endif +endfunction + +" Highlight symbol under cursor on CursorHold +autocmd CursorHold * silent call CocActionAsync('highlight') + +" Remap for rename current word +nmap rn (coc-rename) + +" Remap for format selected region +xmap f (coc-format-selected) +nmap f (coc-format-selected) + +augroup mygroup + autocmd! + " Setup formatexpr specified filetype(s). + autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected') + " Update signature help on jump placeholder + autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp') +augroup end + +" Remap for do codeAction of selected region, ex: `aap` for current paragraph +xmap a (coc-codeaction-selected) +nmap a (coc-codeaction-selected) + +" Remap for do codeAction of current line +nmap ac (coc-codeaction) +" Fix autofix problem of current line +nmap qf (coc-fix-current) + +" Create mappings for function text object, requires document symbols feature of languageserver. +xmap if (coc-funcobj-i) +xmap af (coc-funcobj-a) +omap if (coc-funcobj-i) +omap af (coc-funcobj-a) + +" Use for select selections ranges, needs server support, like: coc-tsserver, coc-python +nmap (coc-range-select) +xmap (coc-range-select) + +" Use `:Format` to format current buffer +command! -nargs=0 Format :call CocAction('format') + +" Use `:Fold` to fold current buffer +command! -nargs=? Fold :call CocAction('fold', ) + +" use `:OR` for organize import of current buffer +command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport') + +" Add status line support, for integration with other plugin, checkout `:h coc-status` +set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')} + +" Using CocList +" Show all diagnostics +nnoremap a :CocList diagnostics +" Manage extensions +nnoremap e :CocList extensions +" Show commands +nnoremap c :CocList commands +" Find symbol of current document +nnoremap o :CocList outline +" Search workspace symbols +nnoremap s :CocList -I symbols +" Do default action for next item. +nnoremap j :CocNext +" Do default action for previous item. +nnoremap k :CocPrev +" Resume latest coc list +nnoremap p :CocListResume +``` + +## Articles + +- [coc.nvim 插件体系介绍](https://zhuanlan.zhihu.com/p/65524706) +- [CocList 入坑指南](https://zhuanlan.zhihu.com/p/71846145) +- [Create coc.nvim extension to improve vim experience](https://medium.com/@chemzqm/create-coc-nvim-extension-to-improve-vim-experience-4461df269173) + +## Trouble shooting + +Try these steps when you have problem with coc.nvim. + +- Make sure your vim version >= 8.0 by command `:version`. +- If service failed to start, use command `:CocInfo` or `:checkhealth` on neovim. +- Checkout the log of coc.nvim by command `:CocOpenLog`. +- When you have issue with a languageserver, it's recommended to [checkout the output](https://github.com/neoclide/coc.nvim/wiki/Debug-language-server#using-output-channel) + +## Feedback + +- If you think Coc is useful, consider giving it a star. +- If you have a question, [ask on gitter](https://gitter.im/neoclide/coc.nvim) +- 中文用户请到 [中文 gitter](https://gitter.im/neoclide/coc-cn) 讨论 +- If something is not working, [create an issue](https://github.com/neoclide/coc.nvim/issues/new). + + + +## License + +MIT diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc.vim b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc.vim new file mode 100644 index 0000000..a14e015 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc.vim @@ -0,0 +1,196 @@ +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_cygqwin_path_prefixes = get(g:, 'coc_cygqwin_path_prefixes', {}) +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 = {} + +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#refresh() abort + return "\=coc#start()\" +endfunction + +function! coc#on_enter() + if !coc#rpc#ready() + return '' + endif + if s:is_vim + call coc#rpc#notify('CocAutocmd', ['Enter', bufnr('%')]) + else + call coc#rpc#request('CocAutocmd', ['Enter', bufnr('%')]) + endif + return '' +endfunction + +function! coc#_insert_key(method, key, ...) abort + if get(a:, 1, 1) + call coc#_cancel() + endif + return "\=coc#rpc#".a:method."('doKeymap', ['".a:key."'])\" +endfunction + +function! coc#_complete() abort + let items = get(g:coc#_context, 'candidates', []) + let preselect = get(g:coc#_context, 'preselect', -1) + call complete( + \ g:coc#_context.start + 1, + \ items) + if s:select_api && len(items) && preselect != -1 + call nvim_select_popupmenu_item(preselect, v:false, v:false, {}) + endif + return '' +endfunction + +function! coc#_do_complete(start, items, preselect) + let g:coc#_context = { + \ 'start': a:start, + \ 'candidates': a:items, + \ 'preselect': a:preselect + \} + if mode() =~# 'i' && &paste != 1 + call feedkeys("\CocRefresh", 'i') + endif +endfunction + +function! coc#_select_confirm() + if !exists('##TextChangedP') + return "\" + endif + let hasSelected = coc#rpc#request('hasSelected', []) + if hasSelected | return "\" | endif + return "\\" +endfunction + +function! coc#_selected() + if !pumvisible() | return 0 | endif + return coc#rpc#request('hasSelected', []) +endfunction + +function! coc#_hide() abort + if !pumvisible() | return | endif + call feedkeys("\", 'in') +endfunction + +function! coc#_cancel() + call coc#util#close_popup() + " hack for close pum + if pumvisible() && &paste != 1 + let g:coc#_context = {'start': 0, 'preselect': -1,'candidates': []} + call feedkeys("\CocRefresh", 'i') + endif +endfunction + +function! coc#_select() abort + if !pumvisible() | return | endif + call feedkeys("\", 'in') +endfunction + +function! coc#start(...) + let opt = coc#util#get_complete_option() + call CocActionAsync('startCompletion', extend(opt, get(a:, 1, {}))) + return '' +endfunction + +" used for statusline +function! coc#status() + let info = get(b:, 'coc_diagnostic_info', {}) + let msgs = [] + if get(info, 'error', 0) + call add(msgs, s:error_sign . info['error']) + endif + if get(info, 'warning', 0) + call add(msgs, s:warning_sign . info['warning']) + endif + return s:trim(join(msgs, ' ') . ' ' . get(g:, 'coc_status', '')) +endfunction + +function! s:trim(str) + if exists('*trim') + return trim(a:str) + endif + return substitute(a:str, '\s\+$', '', '') +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#_map() + if !s:select_api | return | endif + for i in range(1, 9) + exe 'inoremap '.i.' call nvim_select_popupmenu_item('.(i - 1).', v:true, v:true, {})' + endfor +endfunction + +function! coc#_unmap() + if !s:select_api | return | endif + for i in range(1, 9) + exe 'silent! iunmap '.i + endfor +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 diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/api.vim b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/api.vim new file mode 100644 index 0000000..07b6eb8 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/api.vim @@ -0,0 +1,591 @@ +" ============================================================================ +" Description: Client api used by vim8 +" Author: Qiming Zhao +" Licence: MIT licence +" Last Modified: June 28, 2019 +" ============================================================================ +if has('nvim') | finish | endif +let s:funcs = {} +let s:prop_id = 1000 +let s:namespace_id = 1 +let s:namespace_cache = {} + +" helper {{ +function! s:buf_line_count(bufnr) abort + if bufnr('%') == a:bufnr + return line('$') + endif + if exists('*getbufline') + let lines = getbufline(a:bufnr, 1, '$') + return len(lines) + endif + let curr = bufnr('%') + execute 'buffer '.a:bufnr + let n = line('$') + execute '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:funcs.call_atomic(calls) + let res = [] + for [key, arglist] in a:calls + let name = key[5:] + try + call add(res, call(s:funcs[name], arglist)) + catch /.*/ + return [res, v:exception] + 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 + 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({'buflisted': 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 split(&runtimepath, ',') +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 +endfunction + +function! s:funcs.err_write(str) + echoerr a:str +endfunction + +function! s:funcs.err_writeln(str) + echoerr a:str +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 type(val) == type(v:true) + if val == v:true + let val = 1 + else + let val = 0 + endif + 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('textprop') + return + endif + let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr + let key = 'Coc'.a:hlGroup + if empty(prop_type_get(key)) + call prop_type_add(key, {'highlight': a:hlGroup, 'combine': 1}) + endif + let total = strlen(getbufline(bufnr, a:line + 1)[0]) + let end = a:colEnd + if end == -1 + let end = total + else + let end = min([end, total]) + endif + if end <= a:colStart + return + endif + let id = 0 + if a:srcId != -1 + let cached = getbufvar(bufnr, 'prop_namespace_'.a:srcId, []) + let id = s:prop_id + let s:prop_id = id + 1 + call add(cached, id) + call setbufvar(bufnr, 'prop_namespace_'.a:srcId, cached) + endif + try + call prop_add(a:line + 1, a:colStart + 1, {'length': end - a:colStart, 'bufnr': bufnr, 'type': key, 'id': id}) + catch /^Vim\%((\a\+)\)\=:E967/ + " ignore 967 + endtry +endfunction + +function! s:funcs.buf_clear_namespace(bufnr, srcId, startLine, endLine) abort + if !has('textprop') + return + endif + if a:srcId == -1 + if a:endLine == -1 + call prop_clear(a:startLine + 1, {'bufnr': a:bufnr}) + else + call prop_clear(a:startLine + 1, a:endLine + 1, {'bufnr': a:bufnr}) + endif + else + let cached = getbufvar(a:bufnr, 'prop_namespace_'.a:srcId, []) + if empty(cached) + return + endif + call setbufvar(a:bufnr, 'prop_namespace_'.a:srcId, []) + for id in cached + if a:endLine == -1 + if a:startLine == 0 && a:endLine == -1 + call prop_remove({'id':id, 'bufnr': a:bufnr}) + elseif a:endLine != -1 + call prop_remove({'id':id, 'bufnr': a:bufnr}, a:startLine, a:endLine) + else + let len = s:buf_line_count(a:bufnr) + call prop_remove({'id':id, 'bufnr': a:bufnr}, a:startLine, len) + endif + else + endif + 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 replacement = get(a:, 1, []) + let lineCount = s:buf_line_count(a:bufnr) + let startLnum = a:start >= 0 ? a:start + 1 : lineCount + a:start + 1 + 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 a:bufnr != curr && !exists('*setbufline') + let changeBuffer = 1 + exe 'buffer '.a:bufnr + endif + if a:bufnr == curr || changeBuffer + " replace + 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 = @" + silent execute start . ','.(start + delCount - 1).'d' + let @" = saved_reg + endif + endif + if changeBuffer + exe 'buffer '.curr + endif + elseif exists('*setbufline') + " replace + if delCount == len(replacement) + " 8.0.1039 + call setbufline(a:bufnr, startLnum, replacement) + else + if len(replacement) + " 8.10037 + call appendbufline(a:bufnr, startLnum - 1, replacement) + endif + if delCount + let start = startLnum + len(replacement) + "8.1.0039 + call deletebufline(a:bufnr, start, start + delCount - 1) + 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) + call setbufvar(a:bufnr, a:name, v:null) +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 + +function! s:funcs.win_get_cursor(win_id) abort + let winid = win_getid() + call win_gotoid(a:win_id) + let pos = [line('.'), col('.')-1] + call win_gotoid(winid) + return pos +endfunction + +function! s:funcs.win_get_var(win_id, name) abort + return gettabwinvar(0, a:win_id, a:name) +endfunction + +function! s:funcs.win_set_width(win_id, width) abort + let winid = win_getid() + call win_gotoid(a:win_id) + execute 'vertical resize '.a:width + call win_gotoid(winid) +endfunction + +function! s:funcs.win_get_option(win_id, name) abort + return gettabwinvar(0, a:win_id, '&'.a:name) +endfunction + +function! s:funcs.win_set_height(win_id, height) abort + let winnr = win_id2win(a:win_id) + if winnr != 0 + let curr = winnr() + if winnr == curr + execute 'resize '.a:height + else + execute winnr.'wincmd w' + execute 'resize '.a:height + wincmd p + endif + endif +endfunction + +function! s:funcs.win_set_option(win_id, name, value) abort + let val = a:value + if type(val) == type(v:true) + if val == v:true + let val = 1 + else + let val = 0 + endif + endif + call setwinvar(a:win_id, '&'.a:name, val) +endfunction + +function! s:funcs.win_set_var(win_id, name, value) abort + call setwinvar(a:win_id, a:name, a:value) +endfunction + +function! s:funcs.win_del_var(win_id, name) abort + call settabwinvar(0, a:win_id, a:name, v:null) +endfunction + +function! s:funcs.win_is_valid(win_id) abort + let info = getwininfo(a:win_id) + return !empty(info) +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 winnr = win_id2win(a:win_id) + if winnr != 0 + let [line, col] = a:pos + let curr = winnr() + if winnr == curr + call cursor(line, col + 1) + else + execute winnr.'wincmd w' + call cursor(line, col + 1) + execute curr.'wincmd w' + endif + endif +endfunction + +function! s:funcs.win_close(win_id, ...) abort + let curr = win_getid(a:win_id) + call win_gotoid(a:win_id) + close! + call win_gotoid(curr) +endfunction + +function! s:funcs.win_get_tabpage(win_id) abort + let info = getwininfo(a:win_id) + if !info + throw 'Invalid window id '.a:win_id + endif + return info[0]['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! 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 + endtry + return [err, res] +endfunction + +function! coc#api#notify(method, args) abort + call call(s:funcs[a:method], a:args) +endfunction +" vim: set sw=2 ts=2 sts=2 et tw=78 foldmarker={{,}} foldmethod=marker foldlevel=0: diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/client.vim b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/client.vim new file mode 100644 index 0000000..03e0686 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/client.vim @@ -0,0 +1,267 @@ +let s:root = expand(':h:h:h') +let s:is_vim = !has('nvim') +let s:is_win = has("win32") || has("win64") +let s:clients = {} + +let s:logfile = tempname() +if s:is_vim && get(g:, 'node_client_debug', 0) + call ch_logfile(s:logfile, 'w') +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 s:is_vim + let $VIM_NODE_RPC = 1 + let $COC_NVIM = 1 + 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)}, + \} + 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 chan_id = jobstart(self.command, { + \ 'rpc': 1, + \ 'on_stderr': {channel, msgs -> s:on_stderr(self.name, msgs)}, + \ 'on_exit': {channel, code -> s:on_exit(self.name, code)}, + \}) + 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 + let data = filter(copy(a:msgs), '!empty(v:val)') + if empty(data) | return | endif + let client = a:name ==# 'coc' ? '' : ' client '.a:name + let data[0] = '[coc.nvim]'.client.' error: ' . data[0] + call coc#util#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! s: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 = s:get_channel(self) + if empty(channel) | return '' | endif + try + if s:is_vim + let res = ch_evalexpr(channel, [a:method, a:args], {'timeout': 30000}) + if type(res) == 1 && res ==# '' + throw 'timeout after 30s' + endif + let [l:errmsg, res] = res + if !empty(l:errmsg) + throw l:errmsg + else + return res + endif + endif + return call('rpcrequest', [channel, a:method] + a:args) + 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 = s: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 = s: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() + execute 'vs '.s:logfile +endfunction diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/list.vim b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/list.vim new file mode 100644 index 0000000..1673aed --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/list.vim @@ -0,0 +1,257 @@ +let s:activated = 0 +let s:is_vim = !has('nvim') +let s:saved_ve = &t_ve +let s:saved_cursor = &guicursor +let s:gui = has('gui_running') || has('nvim') + +function! coc#list#get_chars() + return { + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '' : "\", + \ '' : "\", + \ '' : "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '<2-LeftMouse>': "\<2-LeftMouse>", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \ '': "\", + \} +endfunction + +function! coc#list#getc() abort + let c = getchar() + return type(c) == type(0) ? nr2char(c) : c +endfunction + +function! coc#list#getchar() abort + let input = coc#list#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 full_keymap = maparg(input, "l") + 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#list#getc() + if c ==# "\" || c ==# "\" + "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#list#prompt_start() abort + call timer_start(100, {-> coc#list#start_prompt()}) +endfunction + +function! coc#list#start_prompt() + if s:activated | return | endif + if s:gui && !empty(s:saved_cursor) + set guicursor+=a:ver1-Cursor-blinkoff999 + elseif s:is_vim + set t_ve= + endif + let s:activated = 1 + try + while s:activated + let ch = coc#list#getchar() + if ch ==# "\u26d4" + break + endif + if ch ==# "\" || ch ==# "\" || ch ==# "\" + continue + else + call coc#rpc#notify('InputChar', [ch, getcharmod()]) + endif + endwhile + catch /^Vim:Interrupt$/ + let s:activated = 0 + call coc#rpc#notify('InputChar', ["\"]) + return + endtry + let s:activated = 0 +endfunction + +function! coc#list#setlines(lines, append) + let total = line('$') + if a:append + silent call append(line('$'), a:lines) + else + silent call append(0, a:lines) + let n = len(a:lines) + 1 + let saved_reg = @" + silent execute n.',$d' + let @" = saved_reg + endif +endfunction + +function! coc#list#options(...) + let list = ['--top', '--tab', '--normal', '--no-sort', '--input', '--strict', + \ '--regex', '--interactive', '--number-select', '--auto-preview'] + 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#stop_prompt(...) + if get(a:, 1, 0) == 0 + if s:gui + let &guicursor = s:saved_cursor + elseif s:is_vim + let &t_ve = s:saved_ve + endif + endif + if s:activated + let s:activated = 0 + call feedkeys("\u26d4", 'int') + endif +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) + nohlsearch + 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 number + else + setl nonumber + setl foldcolumn=2 + endif + return [bufnr('%'), win_getid()] +endfunction + +function! coc#list#setup(source) + let b:list_status = {} + let statusParts = [ + \ '%#CocListMode#-- %{get(b:list_status, "mode")} --%*', + \ '%{get(g:, "coc_list_loading_status", "")}', + \ '%{get(b:list_status, "args", "")}', + \ '(%L/%{get(b:list_status, "total", "")})', + \ '%=', + \ '%#CocListPath# %{get(b:list_status, "cwd", "")} %l/%L%*' + \ ] + call setwinvar(winnr(), '&statusline', join(statusParts, ' ')) + setl buftype=nofile nobuflisted nofen nowrap + setl norelativenumber bufhidden=wipe cursorline winfixheight + setl tabstop=1 nolist nocursorcolumn + setl signcolumn=auto + 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^.*$/' + nnoremap c +endfunction + +function! coc#list#has_preview() + for i in range(1, winnr('$')) + let preview = getwinvar(i, '&previewwindow') + if preview + return 1 + endif + endfor + return 0 +endfunction + +function! coc#list#restore(winid, height) + let res = win_gotoid(a:winid) + if res == 0 | return | endif + if winnr('$') == 1 + return + endif + execute 'resize '.a:height + if s:is_vim + redraw + endif +endfunction + +function! coc#list#set_height(height) abort + if winnr('$') == 1| return | endif + execute 'resize '.a:height +endfunction diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/rpc.vim b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/rpc.vim new file mode 100644 index 0000000..d041488 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/rpc.vim @@ -0,0 +1,130 @@ +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 $NODE_ENV ==# 'test' + " server already started + let s:client = coc#client#create(s:name, []) + let s:client['running'] = 1 + let s:client['chan_id'] = get(g:, 'coc_node_channel_id', 0) + call dictwatcheradd(g:, 'coc_node_channel_id', function('s:ChannelSet')) + 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 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! s:ChannelSet(dict, key, val) + let chan_id = get(a:val, 'new', 0) + if empty(s:client) | return | endif + let s:client['running'] = 1 + let s:client['chan_id'] = chan_id + call dictwatcherdel(g:, 'coc_node_channel_id', function('s:ChannelSet')) +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 + for i in range(1, winnr('$')) + if getwinvar(i, 'float') + execute i.'wincmd c' + endif + endfor + 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, res -> coc#rpc#notify('nvim_async_response_event', [a:id, err, res])} + 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]) + endtry +endfunction diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/snippet.vim b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/snippet.vim new file mode 100644 index 0000000..acb75dc --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/snippet.vim @@ -0,0 +1,66 @@ +let s:is_vim = !has('nvim') +let s:map_next = 1 + +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 ' map + endfor + + " same behaviour of ultisnips + snoremap c + snoremap c + snoremap c + snoremap "_c +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' | startinsert | endif + call timer_start(20, { -> coc#_do_complete(a:col - 1, a:values, 0)}) + redraw +endfunction + +function! coc#snippet#enable() + let b:coc_snippet_active = 1 + call coc#snippet#_select_mappings() + let nextkey = get(g:, 'coc_snippet_next', '') + let prevkey = get(g:, 'coc_snippet_prev', '') + nnoremap :call coc#rpc#request('snippetCancel', []) + if maparg(nextkey, 'i') =~# 'expand-jump' + let s:map_next = 0 + endif + if s:map_next + execute 'inoremap '.nextkey." =coc#rpc#request('snippetNext', [])" + endif + execute 'inoremap '.prevkey." =coc#rpc#request('snippetPrev', [])" + execute 'snoremap '.prevkey." :call coc#rpc#request('snippetPrev', [])" + execute 'snoremap '.nextkey." :call coc#rpc#request('snippetNext', [])" +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', '') + let prevkey = get(g:, 'coc_snippet_prev', '') + silent! nunmap + if s:map_next + silent! execute 'iunmap '.nextkey + endif + silent! execute 'iunmap '.prevkey + silent! execute 'sunmap '.prevkey + silent! execute 'sunmap '.nextkey +endfunction diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/task.vim b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/task.vim new file mode 100644 index 0000000..2ef00a1 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/task.vim @@ -0,0 +1,109 @@ +" ============================================================================ +" Description: Manage long running tasks. +" Author: Qiming Zhao +" Licence: MIT licence +" Version: 0.1 +" Last Modified: April 08, 2019 +" ============================================================================ + +let s:is_vim = !has('nvim') +let s:running_task = {} + +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()) + " 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)}, + \} + 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, filter(msgs, 'v:val !=""'))}, + \ 'on_stdout': {channel, msgs -> s:on_stdout(a:id, filter(msgs, 'v:val !=""'))}, + \ 'on_exit': {channel, code -> s:on_exit(a:id, code)}, + \ 'detach': get(a:opts, 'detach', 0), + \} + if get(a:opts, 'pty', 0) + let options['pty'] = 1 + endif + let chan_id = jobstart(cmd, options) + 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_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 len(a:msgs) + call coc#rpc#notify('TaskStderr', [a:id, a:msgs]) + endif +endfunction + +function! s:on_stdout(id, msgs) + if len(a:msgs) + call coc#rpc#notify('TaskStdout', [a:id, a:msgs]) + 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 diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/terminal.vim b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/terminal.vim new file mode 100644 index 0000000..5713565 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/terminal.vim @@ -0,0 +1,96 @@ +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) 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 8new +setl\ buftype=nofile' + setl winfixheight + setl norelativenumber + setl nonumber + setl bufhidden=hide + if exists('#User#CocTerminalOpen') + exe 'doautocmd User CocTerminalOpen' + endif + let bufnr = bufnr('%') + + function! s:OnExit(status) closure + if a:status == 0 + execute 'silent! bd! '.bufnr + endif + endfunction + + if has('nvim') + if !empty(a:env) + for key in keys(a:env) + execute 'let $'.key." = '".a:env[key]."'" + endfor + endif + let job_id = termopen(a:cmd, { + \ 'cwd': cwd, + \ 'pty': 1, + \ 'on_exit': {job, status -> s:OnExit(status)}, + \ }) + 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': a: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]) + call add(lines, '') + endif + call chansend(chan, lines) + let winnr = bufwinnr(a:bufnr) + if winnr != -1 + exe 'noa '.winnr.'wincmd w' + exe 'noa normal! G' + exe 'noa '.wincmd p + 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 diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/util.vim b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/util.vim new file mode 100644 index 0000000..ce6a20c --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/coc/util.vim @@ -0,0 +1,971 @@ +let s:root = expand(':h:h:h') +let s:is_win = has('win32') || has('win64') +let s:is_vim = !has('nvim') + +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 + +function! coc#util#has_preview() + for i in range(1, winnr('$')) + if getwinvar(i, '&previewwindow') + return i + endif + endfor + return 0 +endfunction + +function! coc#util#has_float() + for i in range(1, winnr('$')) + if getwinvar(i, 'float') + return 1 + endif + endfor + return 0 +endfunction + +function! coc#util#get_float() + for i in range(1, winnr('$')) + if getwinvar(i, 'float') + return win_getid(i) + endif + endfor + return 0 +endfunction + +function! coc#util#float_hide() + for i in range(1, winnr('$')) + if getwinvar(i, 'float') + let winid = win_getid(i) + call coc#util#close_win(winid) + endif + endfor +endfunction + +function! coc#util#float_jump() + for i in range(1, winnr('$')) + if getwinvar(i, 'float') + exe i.'wincmd w' + return + endif + endfor +endfunction + +function! coc#util#float_scrollable() + let winnr = winnr() + for i in range(1, winnr('$')) + if getwinvar(i, 'float') + let wid = win_getid(i) + let h = nvim_win_get_height(wid) + let buf = nvim_win_get_buf(wid) + let lineCount = nvim_buf_line_count(buf) + return lineCount > h + endif + endfor + return 0 +endfunction + +function! coc#util#float_scroll(forward) + let key = a:forward ? "\" : "\" + let winnr = winnr() + for i in range(1, winnr('$')) + if getwinvar(i, 'float') + return i."\w".key."\p" + endif + endfor + return "" +endfunction + +" get cursor position +function! coc#util#cursor() + let pos = getcurpos() + let content = pos[2] == 1 ? '' : getline('.')[0: pos[2] - 2] + return [pos[1] - 1, strchars(content)] +endfunction + +function! coc#util#close_win(id) + if !has('nvim') && exists('*popup_close') + call popup_close(a:id) + return + endif + if exists('*nvim_win_close') + if nvim_win_is_valid(a:id) + call nvim_win_close(a:id, 1) + endif + else + let winnr = win_id2win(a:id) + if winnr > 0 + execute winnr.'close!' + endif + endif +endfunction + +function! coc#util#close(id) abort + if exists('*nvim_win_close') + if nvim_win_is_valid(a:id) + call nvim_win_close(a:id, 1) + endif + else + let winnr = win_id2win(a:id) + if winnr > 0 + execute winnr.'close!' + endif + endif +endfunction + +function! coc#util#win_position() + let nr = winnr() + let [row, col] = win_screenpos(nr) + return [row + winline() - 2, col + wincol() - 2] +endfunction + +function! coc#util#close_popup() + if s:is_vim + if exists('*popup_close') + call popup_close(get(g:, 'coc_popup_id', 0)) + endif + else + for winnr in range(1, winnr('$')) + if getwinvar(winnr, 'popup', 0) + exe winnr.'close!' + endif + endfor + endif +endfunction + +function! coc#util#version() + let c = execute('silent version') + return matchstr(c, 'NVIM v\zs[^\n-]*') +endfunction + +function! coc#util#valid_state() + if s:is_vim && mode() !=# 'n' + return 0 + endif + if get(g: , 'EasyMotion_loaded', 0) + return EasyMotion#is_active() != 1 + endif + return 1 +endfunction + +function! coc#util#open_file(cmd, file) + let file = fnameescape(a:file) + execute a:cmd .' '.file +endfunction + +function! coc#util#platform() + if s:is_win + return 'windows' + endif + if has('mac') || has('macvim') + return 'mac' + endif + return 'linux' +endfunction + +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#job_command() + let node = get(g:, 'coc_node_path', 'node') + if !executable(node) + echohl Error | echom '[coc.nvim] '.node.' is not executable, checkout https://nodejs.org/en/download/' | echohl None + return + endif + let bundle = s:root.'/build/index.js' + if filereadable(bundle) && !get(g:, 'coc_force_debug', 0) + return [node] + get(g:, 'coc_node_args', ['--no-warnings']) + [s:root.'/build/index.js'] + endif + let file = s:root.'/lib/attach.js' + if !filereadable(file) + if !filereadable(bundle) + echohl Error | echom '[coc.nvim] javascript file not found, please compile the code or use release branch.' | echohl None + else + echohl Error | echom '[coc.nvim] compiled javascript file not found, remove let g:coc_force_debug = 1 in your vimrc.' | echohl None + endif + return + endif + return [node] + get(g:, 'coc_node_args', ['--no-warnings']) + [s:root.'/bin/server.js'] +endfunction + +function! coc#util#echo_hover(msg) + echohl MoreMsg + echo a:msg + echohl None + let g:coc_last_hover_message = a:msg +endfunction + +function! coc#util#execute(cmd) + silent exe a:cmd + if &filetype ==# '' + filetype detect + endif + if s:is_vim + redraw! + endif +endfunction + +function! coc#util#jump(cmd, filepath, ...) abort + let path = a:filepath + if (has('win32unix')) + let path = substitute(a:filepath, '\v\\', '/', 'g') + endif + let file = fnamemodify(path, ":~:.") + if a:cmd =~# '^tab' + exe a:cmd.' '.fnameescape(file) + if !empty(get(a:, 1, [])) + call cursor(a:1[0], a:1[1]) + endif + else + if !empty(get(a:, 1, [])) + exe a:cmd.' +call\ cursor('.a:1[0].','.a:1[1].')'.' '.fnameescape(file) + else + exe a:cmd.' '.fnameescape(file) + endif + endif + if &l:filetype ==# '' + filetype detect + endif + if s:is_vim + redraw + endif +endfunction + +function! coc#util#jumpTo(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) + if s:is_vim + redraw + endif +endfunction + +function! coc#util#echo_messages(hl, msgs) + if empty(a:msgs) | return | endif + if a:hl !~# 'Error' && (mode() !~# '\v^(i|n)$') + return + endif + execute 'echohl '.a:hl + let msgs = filter(copy(a:msgs), '!empty(v:val)') + for msg in msgs + echom msg + endfor + echohl None +endfunction + +function! coc#util#echo_lines(lines) + echo join(a:lines, "\n") +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#is_preview(bufnr) + let wnr = bufwinnr(a:bufnr) + if wnr == -1 | return 0 | endif + return getwinvar(wnr, '&previewwindow') +endfunction + +function! coc#util#get_bufoptions(bufnr) abort + if !bufloaded(a:bufnr) | return v:null | endif + let bufname = bufname(a:bufnr) + return { + \ 'bufname': bufname, + \ 'eol': getbufvar(a:bufnr, '&eol'), + \ 'variables': s:variables(a:bufnr), + \ 'fullpath': empty(bufname) ? '' : fnamemodify(bufname, ':p'), + \ 'buftype': getbufvar(a:bufnr, '&buftype'), + \ 'filetype': getbufvar(a:bufnr, '&filetype'), + \ 'iskeyword': getbufvar(a:bufnr, '&iskeyword'), + \ 'changedtick': getbufvar(a:bufnr, 'changedtick'), + \} +endfunction + +function! s:variables(bufnr) abort + let info = getbufinfo({'bufnr':a:bufnr, 'variables': 1}) + let variables = copy(info[0]['variables']) + for key in keys(variables) + if key !~# '\v^coc' + unlet variables[key] + endif + endfor + return variables +endfunction + +function! coc#util#root_patterns() + return coc#rpc#request('rootPatterns', [bufnr('%')]) +endfunction + +function! coc#util#on_error(msg) abort + echohl Error | echom '[coc.nvim] '.a:msg | echohl None +endfunction + +function! coc#util#preview_info(info, ...) abort + let filetype = get(a:, 1, 'markdown') + pclose + keepalt new +setlocal\ previewwindow|setlocal\ buftype=nofile|setlocal\ noswapfile|setlocal\ wrap [Document] + setl bufhidden=wipe + setl nobuflisted + setl nospell + exe 'setl filetype='.filetype + setl conceallevel=2 + setl nofoldenable + let lines = a:info + call append(0, lines) + exe "normal! z" . len(lines) . "\" + exe "normal! gg" + wincmd p +endfunction + +function! coc#util#get_config_home() + if !empty(get(g:, 'coc_config_home', '')) + return 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_input() + let pos = getcurpos() + let line = getline('.') + let l:start = pos[2] - 1 + while l:start > 0 && line[l:start - 1] =~# '\k' + let l:start -= 1 + endwhile + return pos[2] == 1 ? '' : line[l:start : pos[2] - 2] +endfunction + +function! coc#util#move_cursor(delta) + let pos = getcurpos() + call cursor(pos[1], pos[2] + a:delta) +endfunction + +function! coc#util#get_complete_option() + let disabled = get(b:, 'coc_suggest_disable', 0) + if disabled | return | endif + let blacklist = get(b:, 'coc_suggest_blacklist', []) + let pos = getcurpos() + let l:start = pos[2] - 1 + let line = getline(pos[1]) + for char in reverse(split(line[0: l:start - 1], '\zs')) + if l:start > 0 && char =~# '\k' + let l:start = l:start - strlen(char) + else + break + endif + endfor + let input = pos[2] == 1 ? '' : line[l:start : pos[2] - 2] + if !empty(blacklist) && index(blacklist, input) >= 0 + return + endif + let synname = synIDattr(synID(pos[1], l:start, 1),"name") + if !synname + let synname = '' + endif + return { + \ 'word': matchstr(line[l:start : ], '^\k\+'), + \ 'input': input, + \ 'line': line, + \ 'filetype': &filetype, + \ 'filepath': expand('%:p'), + \ 'bufnr': bufnr('%'), + \ 'linenr': pos[1], + \ 'colnr' : pos[2], + \ 'col': l:start, + \ 'synname': synname, + \ 'blacklist': blacklist, + \} +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#add_matchids(ids) + let w:coc_matchids = get(w:, 'coc_matchids', []) + a:ids +endfunction + +function! coc#util#prompt_confirm(title) + if exists('*confirm') && !s:is_vim + let choice = confirm(a:title, "&Yes\n&No") + return 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 + end + return 1 + endif +endfunction + +function! coc#util#get_syntax_name(lnum, col) + return synIDattr(synIDtrans(synID(a:lnum,a:col,1)),"name") +endfunction + +function! coc#util#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#util#unplace_signs(bufnr, sign_ids) + if !bufloaded(a:bufnr) | return | endif + for id in a:sign_ids + execute 'silent! sign unplace '.id.' buffer='.a:bufnr + endfor +endfunction + +function! coc#util#setline(lnum, line) + keepjumps call setline(a:lnum, a:line) +endfunction + +" cmd, cwd +function! coc#util#open_terminal(opts) abort + if s:is_vim && !exists('*term_start') + echohl WarningMsg | echon "Your vim doesn't have termnial 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 + 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#util#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#util#open_terminal(opts) +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 + +function! coc#util#vim_info() + return { + \ 'mode': mode(), + \ 'floating': has('nvim') && exists('*nvim_open_win') ? v:true : v:false, + \ 'extensionRoot': coc#util#extension_root(), + \ 'watchExtensions': get(g:, 'coc_watch_extensions', []), + \ 'globalExtensions': get(g:, 'coc_global_extensions', []), + \ 'config': get(g:, 'coc_user_config', {}), + \ 'pid': coc#util#getpid(), + \ 'columns': &columns, + \ 'lines': &lines, + \ 'cmdheight': &cmdheight, + \ 'filetypeMap': get(g:, 'coc_filetype_map', {}), + \ 'version': coc#util#version(), + \ 'completeOpt': &completeopt, + \ 'pumevent': exists('##MenuPopupChanged') || exists('##CompleteChanged'), + \ 'isVim': has('nvim') ? v:false : v:true, + \ 'isCygwin': has('win32unix') ? v:true : v:false, + \ 'isMacvim': has('gui_macvim') ? v:true : v:false, + \ 'colorscheme': get(g:, 'colors_name', ''), + \ 'workspaceFolders': get(g:, 'WorkspaceFolders', v:null), + \ 'background': &background, + \ 'runtimepath': &runtimepath, + \ 'locationlist': get(g:,'coc_enable_locationlist', 1), + \ 'progpath': v:progpath, + \ 'textprop': has('textprop') && has('patch-8.1.1522') && !has('nvim') ? v:true : v:false, + \} +endfunction + +function! coc#util#highlight_options() + return { + \ 'colorscheme': get(g:, 'colors_name', ''), + \ 'background': &background, + \ 'runtimepath': &runtimepath, + \} +endfunction + +" used by vim +function! coc#util#get_content(bufnr) + if !bufexists(a:bufnr) | return '' | endif + return { + \ 'content': join(getbufline(a:bufnr, 1, '$'), "\n"), + \ 'changedtick': getbufvar(a:bufnr, 'changedtick') + \ } +endfunction + +" used for TextChangedI with InsertCharPre +function! coc#util#get_changeinfo() + return { + \ 'lnum': line('.'), + \ 'line': getline('.'), + \ 'changedtick': b:changedtick, + \} +endfunction + +" show diff of current buffer +function! coc#util#diff_content(lines) abort + let tmpfile = tempname() + setl foldenable + call writefile(a:lines, tmpfile) + let ft = &filetype + diffthis + execute 'vs '.tmpfile + execute 'setf ' . ft + diffthis + setl foldenable +endfunction + +function! coc#util#clear_signs() + let buflist = filter(range(1, bufnr('$')), 'buflisted(v:val)') + for b in buflist + let signIds = [] + let lines = split(execute('sign place buffer='.b), "\n") + for line in lines + let ms = matchlist(line, 'id=\(\d\+\)\s\+name=Coc') + if len(ms) > 0 + call add(signIds, ms[1]) + endif + endfor + call coc#util#unplace_signs(b, signIds) + endfor +endfunction + +function! coc#util#clearmatches(ids, ...) + let winid = get(a:, 1, 0) + if winid != 0 && win_getid() != winid + return + endif + for id in a:ids + try + call matchdelete(id) + catch /.*/ + " matches have been cleared in other ways, + endtry + endfor + let exists = get(w:, 'coc_matchids', []) + if !empty(exists) + call filter(w:coc_matchids, 'index(a:ids, v:val) == -1') + endif +endfunction + +function! coc#util#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#util#install(...) abort + let opts = get(a:, 1, {}) + if !isdirectory(s:root.'/src') + echohl WarningMsg | echon '[coc.nvim] coc#util#install not needed for release branch.' | echohl None + return + endif + let cmd = (s:is_win ? 'install.cmd' : './install.sh') . ' nightly' + let cwd = getcwd() + exe 'lcd '.s:root + exe '!'.cmd + exe 'lcd '.cwd + call coc#rpc#restart() +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#extension_root() abort + if !empty($COC_TEST) + return s:root.'/src/__tests__/extensions' + endif + let dir = get(g:, 'coc_extension_root', '') + if empty(dir) + if s:is_win + let dir = $HOME.'/AppData/Local/coc/extensions' + else + let dir = $HOME.'/.config/coc/extensions' + endif + endif + return dir +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', []) + 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 User '.a:name + endif +endfunction + +function! coc#util#rebuild() + let dir = coc#util#extension_root() + if !isdirectory(dir) | return | endif + call coc#util#open_terminal({ + \ 'cwd': dir, + \ 'cmd': 'npm rebuild', + \ 'keepfocus': 1, + \}) +endfunction + +" content of first echo line +function! coc#util#echo_line() + let str = '' + let line = &lines - (&cmdheight - 1) + for i in range(1, &columns - 1) + let nr = screenchar(line, i) + let str = str . nr2char(nr) + endfor + return str +endfunction + +" [r, g, b] ['255', '255', '255'] +" return ['65535', '65535', '65535'] or return v:false to cancel +function! coc#util#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 s: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(s: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 + +function! coc#util#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#util#pclose() + for i in range(1, winnr('$')) + if getwinvar(i, '&previewwindow') + pclose + redraw + endif + endfor +endfunction + +function! coc#util#init_virtual_hl() + let names = ['Error', 'Warning', 'Info', 'Hint'] + for name in names + if !hlexists('Coc'.name.'VirtualText') + exe 'hi default link Coc'.name.'VirtualText Coc'.name.'Sign' + endif + endfor +endfunction + +function! coc#util#set_buf_var(bufnr, name, val) abort + if !bufloaded(a:bufnr) | return | endif + call setbufvar(a:bufnr, a:name, a:val) +endfunction + +function! coc#util#change_lines(bufnr, list) abort + if !bufloaded(a:bufnr) | return | endif + let bufnr = bufnr('%') + let changeBuffer = bufnr != a:bufnr + if changeBuffer + exe 'buffer '.a:bufnr + endif + for [lnum, line] in a:list + call setline(lnum + 1, line) + endfor + if changeBuffer + exe 'buffer '.bufnr + endif + if s:is_vim + redraw + endif +endfunction + +function! coc#util#unmap(bufnr, keys) abort + if bufnr('%') == a:bufnr + for key in a:keys + exe 'silent! nunmap '.key + endfor + endif +endfunction + +function! coc#util#open_files(files) + let bufnrs = [] + " added on latest vim8 + if exists('*bufadd') && exists('*bufload') + for file in a:files + let bufnr = bufadd(file) + call bufload(file) + call add(bufnrs, bufnr(file)) + endfor + else + noa keepalt 1new +setl\ bufhidden=wipe + for file in a:files + execute 'noa edit +setl\ bufhidden=hide '.fnameescape(file) + if &filetype ==# '' + filetype detect + endif + call add(bufnrs, bufnr('%')) + endfor + noa close + endif + return bufnrs +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 diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/autoload/health/coc.vim b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/health/coc.vim new file mode 100644 index 0000000..10f1a62 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/autoload/health/coc.vim @@ -0,0 +1,87 @@ +let s:root = expand(':h:h:h') + +function! s:checkEnvironment() abort + let valid = 1 + if !has('nvim-0.3.0') + let valid = 0 + call health#report_error('Neovim version not satisfied, 0.3.0 and above required') + endif + let node = get(g:, 'coc_node_path', 'node') + 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 !=# "" + echohl Error | echom output | echohl None + return + endif + let ms = matchlist(output, 'v\(\d\+\).\(\d\+\).\(\d\+\)') + if empty(ms) || str2nr(ms[1]) < 8 || (str2nr(ms[1]) == 8 && str2nr(ms[2]) < 10) + let valid = 0 + call health#report_error('Node.js version '.output.' < 8.10.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"') + endtry + endif + return valid +endfunction + +function! s:checkCommand() + let file = s:root.'/build/index.js' + if filereadable(file) && !get(g:, 'coc_force_debug', 0) + call health#report_ok('Javascript bundle found') + return + endif + let file = s:root.'/lib/attach.js' + if !filereadable(file) + call health#report_error('Javascript entry not found, run ":call coc#util#install()" to fix it.') + else + call health#report_ok('Build javascript found') + 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:checkInitailize() 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:checkInitailize() + call s:checkAutocmd() +endfunction diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/bin/server.js b/vim/.vim/pack/coc/start/coc.nvim-release/bin/server.js new file mode 100755 index 0000000..1d1859f --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/bin/server.js @@ -0,0 +1,28 @@ +const semver = require('semver') +const version = process.version.replace('v', '') +if (!semver.gte(version, '8.10.0')) { + console.error('node version ' + version + ' < 8.10.0, please upgrade nodejs, or use `let g:coc_node_path = "/path/to/node"` in your vimrc') + process.exit() +} +Object.defineProperty(console, 'log', { + value: () => { } +}) +const attach = require('../lib/attach').default +const logger = require('../lib/util/logger')('server') + +attach({ reader: process.stdin, writer: process.stdout }) + +process.on('uncaughtException', function (err) { + let msg = 'Uncaught exception: ' + err.stack + console.error(msg) + logger.error('uncaughtException', err.stack) +}) + +process.on('unhandledRejection', function (reason, p) { + if (reason instanceof Error) { + console.error('UnhandledRejection: ' + reason.message + '\n' + reason.stack) + } else { + console.error('UnhandledRejection: ' + reason) + } + logger.error('unhandledRejection ', p, reason) +}) diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/bin/terminateProcess.sh b/vim/.vim/pack/coc/start/coc.nvim-release/bin/terminateProcess.sh new file mode 100755 index 0000000..513068d --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/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 + diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/build/index.js b/vim/.vim/pack/coc/start/coc.nvim-release/build/index.js new file mode 100644 index 0000000..1e0e2d0 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/build/index.js @@ -0,0 +1,67150 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +const semver = __webpack_require__(1) +const version = process.version.replace('v', '') +if (!semver.gte(version, '8.10.0')) { + console.error('node version ' + version + ' < 8.10.0, please upgrade nodejs, or use `let g:coc_node_path = "/path/to/node"` in your vimrc') + process.exit() +} +Object.defineProperty(console, 'log', { + value: () => { } +}) +const attach = __webpack_require__(2).default +const logger = __webpack_require__(186)('server') + +attach({ reader: process.stdin, writer: process.stdout }) + +process.on('uncaughtException', function (err) { + let msg = 'Uncaught exception: ' + err.stack + console.error(msg) + logger.error('uncaughtException', err.stack) +}) + +process.on('unhandledRejection', function (reason, p) { + if (reason instanceof Error) { + console.error('UnhandledRejection: ' + reason.message + '\n' + reason.stack) + } else { + console.error('UnhandledRejection: ' + reason) + } + logger.error('unhandledRejection ', p, reason) +}) + + +/***/ }), +/* 1 */ +/***/ (function(module, exports) { + +exports = module.exports = SemVer + +var debug +/* istanbul ignore next */ +if (typeof process === 'object' && + process.env && + process.env.NODE_DEBUG && + /\bsemver\b/i.test(process.env.NODE_DEBUG)) { + debug = function () { + var args = Array.prototype.slice.call(arguments, 0) + args.unshift('SEMVER') + console.log.apply(console, args) + } +} else { + debug = function () {} +} + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +exports.SEMVER_SPEC_VERSION = '2.0.0' + +var MAX_LENGTH = 256 +var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || + /* istanbul ignore next */ 9007199254740991 + +// Max safe segment length for coercion. +var MAX_SAFE_COMPONENT_LENGTH = 16 + +// The actual regexps go on exports.re +var re = exports.re = [] +var src = exports.src = [] +var t = exports.tokens = {} +var R = 0 + +function tok (n) { + t[n] = R++ +} + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +tok('NUMERICIDENTIFIER') +src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*' +tok('NUMERICIDENTIFIERLOOSE') +src[t.NUMERICIDENTIFIERLOOSE] = '[0-9]+' + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +tok('NONNUMERICIDENTIFIER') +src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*' + +// ## Main Version +// Three dot-separated numeric identifiers. + +tok('MAINVERSION') +src[t.MAINVERSION] = '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + + '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + + '(' + src[t.NUMERICIDENTIFIER] + ')' + +tok('MAINVERSIONLOOSE') +src[t.MAINVERSIONLOOSE] = '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')' + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. + +tok('PRERELEASEIDENTIFIER') +src[t.PRERELEASEIDENTIFIER] = '(?:' + src[t.NUMERICIDENTIFIER] + + '|' + src[t.NONNUMERICIDENTIFIER] + ')' + +tok('PRERELEASEIDENTIFIERLOOSE') +src[t.PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[t.NUMERICIDENTIFIERLOOSE] + + '|' + src[t.NONNUMERICIDENTIFIER] + ')' + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +tok('PRERELEASE') +src[t.PRERELEASE] = '(?:-(' + src[t.PRERELEASEIDENTIFIER] + + '(?:\\.' + src[t.PRERELEASEIDENTIFIER] + ')*))' + +tok('PRERELEASELOOSE') +src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] + + '(?:\\.' + src[t.PRERELEASEIDENTIFIERLOOSE] + ')*))' + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +tok('BUILDIDENTIFIER') +src[t.BUILDIDENTIFIER] = '[0-9A-Za-z-]+' + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +tok('BUILD') +src[t.BUILD] = '(?:\\+(' + src[t.BUILDIDENTIFIER] + + '(?:\\.' + src[t.BUILDIDENTIFIER] + ')*))' + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +tok('FULL') +tok('FULLPLAIN') +src[t.FULLPLAIN] = 'v?' + src[t.MAINVERSION] + + src[t.PRERELEASE] + '?' + + src[t.BUILD] + '?' + +src[t.FULL] = '^' + src[t.FULLPLAIN] + '$' + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +tok('LOOSEPLAIN') +src[t.LOOSEPLAIN] = '[v=\\s]*' + src[t.MAINVERSIONLOOSE] + + src[t.PRERELEASELOOSE] + '?' + + src[t.BUILD] + '?' + +tok('LOOSE') +src[t.LOOSE] = '^' + src[t.LOOSEPLAIN] + '$' + +tok('GTLT') +src[t.GTLT] = '((?:<|>)?=?)' + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +tok('XRANGEIDENTIFIERLOOSE') +src[t.XRANGEIDENTIFIERLOOSE] = src[t.NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' +tok('XRANGEIDENTIFIER') +src[t.XRANGEIDENTIFIER] = src[t.NUMERICIDENTIFIER] + '|x|X|\\*' + +tok('XRANGEPLAIN') +src[t.XRANGEPLAIN] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + + '(?:' + src[t.PRERELEASE] + ')?' + + src[t.BUILD] + '?' + + ')?)?' + +tok('XRANGEPLAINLOOSE') +src[t.XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + + '(?:' + src[t.PRERELEASELOOSE] + ')?' + + src[t.BUILD] + '?' + + ')?)?' + +tok('XRANGE') +src[t.XRANGE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAIN] + '$' +tok('XRANGELOOSE') +src[t.XRANGELOOSE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAINLOOSE] + '$' + +// Coercion. +// Extract anything that could conceivably be a part of a valid semver +tok('COERCE') +src[t.COERCE] = '(^|[^\\d])' + + '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:$|[^\\d])' +tok('COERCERTL') +re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g') + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +tok('LONETILDE') +src[t.LONETILDE] = '(?:~>?)' + +tok('TILDETRIM') +src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+' +re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g') +var tildeTrimReplace = '$1~' + +tok('TILDE') +src[t.TILDE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAIN] + '$' +tok('TILDELOOSE') +src[t.TILDELOOSE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAINLOOSE] + '$' + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +tok('LONECARET') +src[t.LONECARET] = '(?:\\^)' + +tok('CARETTRIM') +src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+' +re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g') +var caretTrimReplace = '$1^' + +tok('CARET') +src[t.CARET] = '^' + src[t.LONECARET] + src[t.XRANGEPLAIN] + '$' +tok('CARETLOOSE') +src[t.CARETLOOSE] = '^' + src[t.LONECARET] + src[t.XRANGEPLAINLOOSE] + '$' + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +tok('COMPARATORLOOSE') +src[t.COMPARATORLOOSE] = '^' + src[t.GTLT] + '\\s*(' + src[t.LOOSEPLAIN] + ')$|^$' +tok('COMPARATOR') +src[t.COMPARATOR] = '^' + src[t.GTLT] + '\\s*(' + src[t.FULLPLAIN] + ')$|^$' + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +tok('COMPARATORTRIM') +src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] + + '\\s*(' + src[t.LOOSEPLAIN] + '|' + src[t.XRANGEPLAIN] + ')' + +// this one has to use the /g flag +re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g') +var comparatorTrimReplace = '$1$2$3' + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +tok('HYPHENRANGE') +src[t.HYPHENRANGE] = '^\\s*(' + src[t.XRANGEPLAIN] + ')' + + '\\s+-\\s+' + + '(' + src[t.XRANGEPLAIN] + ')' + + '\\s*$' + +tok('HYPHENRANGELOOSE') +src[t.HYPHENRANGELOOSE] = '^\\s*(' + src[t.XRANGEPLAINLOOSE] + ')' + + '\\s+-\\s+' + + '(' + src[t.XRANGEPLAINLOOSE] + ')' + + '\\s*$' + +// Star ranges basically just allow anything at all. +tok('STAR') +src[t.STAR] = '(<|>)?=?\\s*\\*' + +// Compile to actual regexp objects. +// All are flag-free, unless they were created above with a flag. +for (var i = 0; i < R; i++) { + debug(i, src[i]) + if (!re[i]) { + re[i] = new RegExp(src[i]) + } +} + +exports.parse = parse +function parse (version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (version instanceof SemVer) { + return version + } + + if (typeof version !== 'string') { + return null + } + + if (version.length > MAX_LENGTH) { + return null + } + + var r = options.loose ? re[t.LOOSE] : re[t.FULL] + if (!r.test(version)) { + return null + } + + try { + return new SemVer(version, options) + } catch (er) { + return null + } +} + +exports.valid = valid +function valid (version, options) { + var v = parse(version, options) + return v ? v.version : null +} + +exports.clean = clean +function clean (version, options) { + var s = parse(version.trim().replace(/^[=v]+/, ''), options) + return s ? s.version : null +} + +exports.SemVer = SemVer + +function SemVer (version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + if (version instanceof SemVer) { + if (version.loose === options.loose) { + return version + } else { + version = version.version + } + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version) + } + + if (version.length > MAX_LENGTH) { + throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') + } + + if (!(this instanceof SemVer)) { + return new SemVer(version, options) + } + + debug('SemVer', version, options) + this.options = options + this.loose = !!options.loose + + var m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]) + + if (!m) { + throw new TypeError('Invalid Version: ' + version) + } + + this.raw = version + + // these are actually numbers + this.major = +m[1] + this.minor = +m[2] + this.patch = +m[3] + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) { + throw new TypeError('Invalid major version') + } + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { + throw new TypeError('Invalid minor version') + } + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { + throw new TypeError('Invalid patch version') + } + + // numberify any prerelease numeric ids + if (!m[4]) { + this.prerelease = [] + } else { + this.prerelease = m[4].split('.').map(function (id) { + if (/^[0-9]+$/.test(id)) { + var num = +id + if (num >= 0 && num < MAX_SAFE_INTEGER) { + return num + } + } + return id + }) + } + + this.build = m[5] ? m[5].split('.') : [] + this.format() +} + +SemVer.prototype.format = function () { + this.version = this.major + '.' + this.minor + '.' + this.patch + if (this.prerelease.length) { + this.version += '-' + this.prerelease.join('.') + } + return this.version +} + +SemVer.prototype.toString = function () { + return this.version +} + +SemVer.prototype.compare = function (other) { + debug('SemVer.compare', this.version, this.options, other) + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + return this.compareMain(other) || this.comparePre(other) +} + +SemVer.prototype.compareMain = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + return compareIdentifiers(this.major, other.major) || + compareIdentifiers(this.minor, other.minor) || + compareIdentifiers(this.patch, other.patch) +} + +SemVer.prototype.comparePre = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) { + return -1 + } else if (!this.prerelease.length && other.prerelease.length) { + return 1 + } else if (!this.prerelease.length && !other.prerelease.length) { + return 0 + } + + var i = 0 + do { + var a = this.prerelease[i] + var b = other.prerelease[i] + debug('prerelease compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) +} + +SemVer.prototype.compareBuild = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + var i = 0 + do { + var a = this.build[i] + var b = other.build[i] + debug('prerelease compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) +} + +// preminor will bump the version up to the next minor release, and immediately +// down to pre-release. premajor and prepatch work the same way. +SemVer.prototype.inc = function (release, identifier) { + switch (release) { + case 'premajor': + this.prerelease.length = 0 + this.patch = 0 + this.minor = 0 + this.major++ + this.inc('pre', identifier) + break + case 'preminor': + this.prerelease.length = 0 + this.patch = 0 + this.minor++ + this.inc('pre', identifier) + break + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0 + this.inc('patch', identifier) + this.inc('pre', identifier) + break + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) { + this.inc('patch', identifier) + } + this.inc('pre', identifier) + break + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if (this.minor !== 0 || + this.patch !== 0 || + this.prerelease.length === 0) { + this.major++ + } + this.minor = 0 + this.patch = 0 + this.prerelease = [] + break + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) { + this.minor++ + } + this.patch = 0 + this.prerelease = [] + break + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) { + this.patch++ + } + this.prerelease = [] + break + // This probably shouldn't be used publicly. + // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. + case 'pre': + if (this.prerelease.length === 0) { + this.prerelease = [0] + } else { + var i = this.prerelease.length + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++ + i = -2 + } + } + if (i === -1) { + // didn't increment anything + this.prerelease.push(0) + } + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + if (this.prerelease[0] === identifier) { + if (isNaN(this.prerelease[1])) { + this.prerelease = [identifier, 0] + } + } else { + this.prerelease = [identifier, 0] + } + } + break + + default: + throw new Error('invalid increment argument: ' + release) + } + this.format() + this.raw = this.version + return this +} + +exports.inc = inc +function inc (version, release, loose, identifier) { + if (typeof (loose) === 'string') { + identifier = loose + loose = undefined + } + + try { + return new SemVer(version, loose).inc(release, identifier).version + } catch (er) { + return null + } +} + +exports.diff = diff +function diff (version1, version2) { + if (eq(version1, version2)) { + return null + } else { + var v1 = parse(version1) + var v2 = parse(version2) + var prefix = '' + if (v1.prerelease.length || v2.prerelease.length) { + prefix = 'pre' + var defaultResult = 'prerelease' + } + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return prefix + key + } + } + } + return defaultResult // may be undefined + } +} + +exports.compareIdentifiers = compareIdentifiers + +var numeric = /^[0-9]+$/ +function compareIdentifiers (a, b) { + var anum = numeric.test(a) + var bnum = numeric.test(b) + + if (anum && bnum) { + a = +a + b = +b + } + + return a === b ? 0 + : (anum && !bnum) ? -1 + : (bnum && !anum) ? 1 + : a < b ? -1 + : 1 +} + +exports.rcompareIdentifiers = rcompareIdentifiers +function rcompareIdentifiers (a, b) { + return compareIdentifiers(b, a) +} + +exports.major = major +function major (a, loose) { + return new SemVer(a, loose).major +} + +exports.minor = minor +function minor (a, loose) { + return new SemVer(a, loose).minor +} + +exports.patch = patch +function patch (a, loose) { + return new SemVer(a, loose).patch +} + +exports.compare = compare +function compare (a, b, loose) { + return new SemVer(a, loose).compare(new SemVer(b, loose)) +} + +exports.compareLoose = compareLoose +function compareLoose (a, b) { + return compare(a, b, true) +} + +exports.compareBuild = compareBuild +function compareBuild (a, b, loose) { + var versionA = new SemVer(a, loose) + var versionB = new SemVer(b, loose) + return versionA.compare(versionB) || versionA.compareBuild(versionB) +} + +exports.rcompare = rcompare +function rcompare (a, b, loose) { + return compare(b, a, loose) +} + +exports.sort = sort +function sort (list, loose) { + return list.sort(function (a, b) { + return exports.compareBuild(a, b, loose) + }) +} + +exports.rsort = rsort +function rsort (list, loose) { + return list.sort(function (a, b) { + return exports.compareBuild(b, a, loose) + }) +} + +exports.gt = gt +function gt (a, b, loose) { + return compare(a, b, loose) > 0 +} + +exports.lt = lt +function lt (a, b, loose) { + return compare(a, b, loose) < 0 +} + +exports.eq = eq +function eq (a, b, loose) { + return compare(a, b, loose) === 0 +} + +exports.neq = neq +function neq (a, b, loose) { + return compare(a, b, loose) !== 0 +} + +exports.gte = gte +function gte (a, b, loose) { + return compare(a, b, loose) >= 0 +} + +exports.lte = lte +function lte (a, b, loose) { + return compare(a, b, loose) <= 0 +} + +exports.cmp = cmp +function cmp (a, op, b, loose) { + switch (op) { + case '===': + if (typeof a === 'object') + a = a.version + if (typeof b === 'object') + b = b.version + return a === b + + case '!==': + if (typeof a === 'object') + a = a.version + if (typeof b === 'object') + b = b.version + return a !== b + + case '': + case '=': + case '==': + return eq(a, b, loose) + + case '!=': + return neq(a, b, loose) + + case '>': + return gt(a, b, loose) + + case '>=': + return gte(a, b, loose) + + case '<': + return lt(a, b, loose) + + case '<=': + return lte(a, b, loose) + + default: + throw new TypeError('Invalid operator: ' + op) + } +} + +exports.Comparator = Comparator +function Comparator (comp, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (comp instanceof Comparator) { + if (comp.loose === !!options.loose) { + return comp + } else { + comp = comp.value + } + } + + if (!(this instanceof Comparator)) { + return new Comparator(comp, options) + } + + debug('comparator', comp, options) + this.options = options + this.loose = !!options.loose + this.parse(comp) + + if (this.semver === ANY) { + this.value = '' + } else { + this.value = this.operator + this.semver.version + } + + debug('comp', this) +} + +var ANY = {} +Comparator.prototype.parse = function (comp) { + var r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] + var m = comp.match(r) + + if (!m) { + throw new TypeError('Invalid comparator: ' + comp) + } + + this.operator = m[1] !== undefined ? m[1] : '' + if (this.operator === '=') { + this.operator = '' + } + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) { + this.semver = ANY + } else { + this.semver = new SemVer(m[2], this.options.loose) + } +} + +Comparator.prototype.toString = function () { + return this.value +} + +Comparator.prototype.test = function (version) { + debug('Comparator.test', version, this.options.loose) + + if (this.semver === ANY || version === ANY) { + return true + } + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } + } + + return cmp(version, this.operator, this.semver, this.options) +} + +Comparator.prototype.intersects = function (comp, options) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required') + } + + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + var rangeTmp + + if (this.operator === '') { + if (this.value === '') { + return true + } + rangeTmp = new Range(comp.value, options) + return satisfies(this.value, rangeTmp, options) + } else if (comp.operator === '') { + if (comp.value === '') { + return true + } + rangeTmp = new Range(this.value, options) + return satisfies(comp.semver, rangeTmp, options) + } + + var sameDirectionIncreasing = + (this.operator === '>=' || this.operator === '>') && + (comp.operator === '>=' || comp.operator === '>') + var sameDirectionDecreasing = + (this.operator === '<=' || this.operator === '<') && + (comp.operator === '<=' || comp.operator === '<') + var sameSemVer = this.semver.version === comp.semver.version + var differentDirectionsInclusive = + (this.operator === '>=' || this.operator === '<=') && + (comp.operator === '>=' || comp.operator === '<=') + var oppositeDirectionsLessThan = + cmp(this.semver, '<', comp.semver, options) && + ((this.operator === '>=' || this.operator === '>') && + (comp.operator === '<=' || comp.operator === '<')) + var oppositeDirectionsGreaterThan = + cmp(this.semver, '>', comp.semver, options) && + ((this.operator === '<=' || this.operator === '<') && + (comp.operator === '>=' || comp.operator === '>')) + + return sameDirectionIncreasing || sameDirectionDecreasing || + (sameSemVer && differentDirectionsInclusive) || + oppositeDirectionsLessThan || oppositeDirectionsGreaterThan +} + +exports.Range = Range +function Range (range, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (range instanceof Range) { + if (range.loose === !!options.loose && + range.includePrerelease === !!options.includePrerelease) { + return range + } else { + return new Range(range.raw, options) + } + } + + if (range instanceof Comparator) { + return new Range(range.value, options) + } + + if (!(this instanceof Range)) { + return new Range(range, options) + } + + this.options = options + this.loose = !!options.loose + this.includePrerelease = !!options.includePrerelease + + // First, split based on boolean or || + this.raw = range + this.set = range.split(/\s*\|\|\s*/).map(function (range) { + return this.parseRange(range.trim()) + }, this).filter(function (c) { + // throw out any that are not relevant for whatever reason + return c.length + }) + + if (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + range) + } + + this.format() +} + +Range.prototype.format = function () { + this.range = this.set.map(function (comps) { + return comps.join(' ').trim() + }).join('||').trim() + return this.range +} + +Range.prototype.toString = function () { + return this.range +} + +Range.prototype.parseRange = function (range) { + var loose = this.options.loose + range = range.trim() + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + var hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] + range = range.replace(hr, hyphenReplace) + debug('hyphen replace', range) + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) + debug('comparator trim', range, re[t.COMPARATORTRIM]) + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[t.TILDETRIM], tildeTrimReplace) + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[t.CARETTRIM], caretTrimReplace) + + // normalize spaces + range = range.split(/\s+/).join(' ') + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + var compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] + var set = range.split(' ').map(function (comp) { + return parseComparator(comp, this.options) + }, this).join(' ').split(/\s+/) + if (this.options.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function (comp) { + return !!comp.match(compRe) + }) + } + set = set.map(function (comp) { + return new Comparator(comp, this.options) + }, this) + + return set +} + +Range.prototype.intersects = function (range, options) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required') + } + + return this.set.some(function (thisComparators) { + return ( + isSatisfiable(thisComparators, options) && + range.set.some(function (rangeComparators) { + return ( + isSatisfiable(rangeComparators, options) && + thisComparators.every(function (thisComparator) { + return rangeComparators.every(function (rangeComparator) { + return thisComparator.intersects(rangeComparator, options) + }) + }) + ) + }) + ) + }) +} + +// take a set of comparators and determine whether there +// exists a version which can satisfy it +function isSatisfiable (comparators, options) { + var result = true + var remainingComparators = comparators.slice() + var testComparator = remainingComparators.pop() + + while (result && remainingComparators.length) { + result = remainingComparators.every(function (otherComparator) { + return testComparator.intersects(otherComparator, options) + }) + + testComparator = remainingComparators.pop() + } + + return result +} + +// Mostly just for testing and legacy API reasons +exports.toComparators = toComparators +function toComparators (range, options) { + return new Range(range, options).set.map(function (comp) { + return comp.map(function (c) { + return c.value + }).join(' ').trim().split(' ') + }) +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +function parseComparator (comp, options) { + debug('comp', comp, options) + comp = replaceCarets(comp, options) + debug('caret', comp) + comp = replaceTildes(comp, options) + debug('tildes', comp) + comp = replaceXRanges(comp, options) + debug('xrange', comp) + comp = replaceStars(comp, options) + debug('stars', comp) + return comp +} + +function isX (id) { + return !id || id.toLowerCase() === 'x' || id === '*' +} + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 +function replaceTildes (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceTilde(comp, options) + }).join(' ') +} + +function replaceTilde (comp, options) { + var r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] + return comp.replace(r, function (_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + // ~1.2 == >=1.2.0 <1.3.0 + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else if (pr) { + debug('replaceTilde pr', pr) + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } else { + // ~1.2.3 == >=1.2.3 <1.3.0 + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + + debug('tilde return', ret) + return ret + }) +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceCaret(comp, options) + }).join(' ') +} + +function replaceCaret (comp, options) { + debug('caret', comp, options) + var r = options.loose ? re[t.CARETLOOSE] : re[t.CARET] + return comp.replace(r, function (_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + if (M === '0') { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else { + ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' + } + } else if (pr) { + debug('replaceCaret pr', pr) + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + (+M + 1) + '.0.0' + } + } else { + debug('no pr') + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0' + } + } + + debug('caret return', ret) + return ret + }) +} + +function replaceXRanges (comp, options) { + debug('replaceXRanges', comp, options) + return comp.split(/\s+/).map(function (comp) { + return replaceXRange(comp, options) + }).join(' ') +} + +function replaceXRange (comp, options) { + comp = comp.trim() + var r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE] + return comp.replace(r, function (ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr) + var xM = isX(M) + var xm = xM || isX(m) + var xp = xm || isX(p) + var anyX = xp + + if (gtlt === '=' && anyX) { + gtlt = '' + } + + // if we're including prereleases in the match, then we need + // to fix this to -0, the lowest possible prerelease value + pr = options.includePrerelease ? '-0' : '' + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0-0' + } else { + // nothing is forbidden + ret = '*' + } + } else if (gtlt && anyX) { + // we know patch is an x, because we have any x at all. + // replace X with 0 + if (xm) { + m = 0 + } + p = 0 + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>=' + if (xm) { + M = +M + 1 + m = 0 + p = 0 + } else { + m = +m + 1 + p = 0 + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<' + if (xm) { + M = +M + 1 + } else { + m = +m + 1 + } + } + + ret = gtlt + M + '.' + m + '.' + p + pr + } else if (xm) { + ret = '>=' + M + '.0.0' + pr + ' <' + (+M + 1) + '.0.0' + pr + } else if (xp) { + ret = '>=' + M + '.' + m + '.0' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + pr + } + + debug('xRange return', ret) + + return ret + }) +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +function replaceStars (comp, options) { + debug('replaceStars', comp, options) + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(re[t.STAR], '') +} + +// This function is passed to string.replace(re[t.HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0 +function hyphenReplace ($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + if (isX(fM)) { + from = '' + } else if (isX(fm)) { + from = '>=' + fM + '.0.0' + } else if (isX(fp)) { + from = '>=' + fM + '.' + fm + '.0' + } else { + from = '>=' + from + } + + if (isX(tM)) { + to = '' + } else if (isX(tm)) { + to = '<' + (+tM + 1) + '.0.0' + } else if (isX(tp)) { + to = '<' + tM + '.' + (+tm + 1) + '.0' + } else if (tpr) { + to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr + } else { + to = '<=' + to + } + + return (from + ' ' + to).trim() +} + +// if ANY of the sets match ALL of its comparators, then pass +Range.prototype.test = function (version) { + if (!version) { + return false + } + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } + } + + for (var i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version, this.options)) { + return true + } + } + return false +} + +function testSet (set, version, options) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) { + return false + } + } + + if (version.prerelease.length && !options.includePrerelease) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (i = 0; i < set.length; i++) { + debug(set[i].semver) + if (set[i].semver === ANY) { + continue + } + + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) { + return true + } + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false + } + + return true +} + +exports.satisfies = satisfies +function satisfies (version, range, options) { + try { + range = new Range(range, options) + } catch (er) { + return false + } + return range.test(version) +} + +exports.maxSatisfying = maxSatisfying +function maxSatisfying (versions, range, options) { + var max = null + var maxSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!max || maxSV.compare(v) === -1) { + // compare(max, v, true) + max = v + maxSV = new SemVer(max, options) + } + } + }) + return max +} + +exports.minSatisfying = minSatisfying +function minSatisfying (versions, range, options) { + var min = null + var minSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!min || minSV.compare(v) === 1) { + // compare(min, v, true) + min = v + minSV = new SemVer(min, options) + } + } + }) + return min +} + +exports.minVersion = minVersion +function minVersion (range, loose) { + range = new Range(range, loose) + + var minver = new SemVer('0.0.0') + if (range.test(minver)) { + return minver + } + + minver = new SemVer('0.0.0-0') + if (range.test(minver)) { + return minver + } + + minver = null + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] + + comparators.forEach(function (comparator) { + // Clone to avoid manipulating the comparator's semver object. + var compver = new SemVer(comparator.semver.version) + switch (comparator.operator) { + case '>': + if (compver.prerelease.length === 0) { + compver.patch++ + } else { + compver.prerelease.push(0) + } + compver.raw = compver.format() + /* fallthrough */ + case '': + case '>=': + if (!minver || gt(minver, compver)) { + minver = compver + } + break + case '<': + case '<=': + /* Ignore maximum versions */ + break + /* istanbul ignore next */ + default: + throw new Error('Unexpected operation: ' + comparator.operator) + } + }) + } + + if (minver && range.test(minver)) { + return minver + } + + return null +} + +exports.validRange = validRange +function validRange (range, options) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, options).range || '*' + } catch (er) { + return null + } +} + +// Determine if version is less than all the versions possible in the range +exports.ltr = ltr +function ltr (version, range, options) { + return outside(version, range, '<', options) +} + +// Determine if version is greater than all the versions possible in the range. +exports.gtr = gtr +function gtr (version, range, options) { + return outside(version, range, '>', options) +} + +exports.outside = outside +function outside (version, range, hilo, options) { + version = new SemVer(version, options) + range = new Range(range, options) + + var gtfn, ltefn, ltfn, comp, ecomp + switch (hilo) { + case '>': + gtfn = gt + ltefn = lte + ltfn = lt + comp = '>' + ecomp = '>=' + break + case '<': + gtfn = lt + ltefn = gte + ltfn = gt + comp = '<' + ecomp = '<=' + break + default: + throw new TypeError('Must provide a hilo val of "<" or ">"') + } + + // If it satisifes the range it is not outside + if (satisfies(version, range, options)) { + return false + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] + + var high = null + var low = null + + comparators.forEach(function (comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator + low = low || comparator + if (gtfn(comparator.semver, high.semver, options)) { + high = comparator + } else if (ltfn(comparator.semver, low.semver, options)) { + low = comparator + } + }) + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false + } + } + return true +} + +exports.prerelease = prerelease +function prerelease (version, options) { + var parsed = parse(version, options) + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null +} + +exports.intersects = intersects +function intersects (r1, r2, options) { + r1 = new Range(r1, options) + r2 = new Range(r2, options) + return r1.intersects(r2) +} + +exports.coerce = coerce +function coerce (version, options) { + if (version instanceof SemVer) { + return version + } + + if (typeof version === 'number') { + version = String(version) + } + + if (typeof version !== 'string') { + return null + } + + options = options || {} + + var match = null + if (!options.rtl) { + match = version.match(re[t.COERCE]) + } else { + // Find the right-most coercible string that does not share + // a terminus with a more left-ward coercible string. + // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' + // + // Walk through the string checking with a /g regexp + // Manually set the index so as to pick up overlapping matches. + // Stop when we get a match that ends at the string end, since no + // coercible string can be more right-ward without the same terminus. + var next + while ((next = re[t.COERCERTL].exec(version)) && + (!match || match.index + match[0].length !== version.length) + ) { + if (!match || + next.index + next[0].length !== match.index + match[0].length) { + match = next + } + re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length + } + // leave it in a clean state + re[t.COERCERTL].lastIndex = -1 + } + + if (match === null) { + return null + } + + return parse(match[2] + + '.' + (match[3] || '0') + + '.' + (match[4] || '0'), options) +} + + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const neovim_1 = __webpack_require__(4); +const log4js_1 = tslib_1.__importDefault(__webpack_require__(64)); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const plugin_1 = tslib_1.__importDefault(__webpack_require__(231)); +const semver_1 = tslib_1.__importDefault(__webpack_require__(1)); +__webpack_require__(309); +const vscode_uri_1 = __webpack_require__(180); +const logger = __webpack_require__(186)('attach'); +const isTest = "none" == 'test'; +exports.default = (opts, requestApi = true) => { + const nvim = neovim_1.attach(opts, log4js_1.default.getLogger('node-client'), requestApi); + // Overwriding the URI.file function in case of cygwin. + nvim.eval('has("win32unix")?get(g:,"coc_cygqwin_path_prefixes", v:null):v:null').then(prefixes => { + if (!prefixes) + return; + const old_uri = vscode_uri_1.URI.file; + vscode_uri_1.URI.file = (path) => { + path = path.replace(/\\/g, '/'); + Object.keys(prefixes).forEach(k => path = path.replace(new RegExp('^' + k, 'gi'), prefixes[k])); + return old_uri(path); + }; + }).logError(); + const plugin = new plugin_1.default(nvim); + let clientReady = false; + let initialized = false; + nvim.on('notification', async (method, args) => { + switch (method) { + case 'VimEnter': { + if (!initialized && clientReady) { + initialized = true; + await plugin.init(); + } + break; + } + case 'TaskExit': + case 'TaskStderr': + case 'TaskStdout': + case 'GlobalChange': + case 'InputChar': + case 'OptionSet': + await events_1.default.fire(method, args); + break; + case 'CocAutocmd': + await events_1.default.fire(args[0], args.slice(1)); + break; + default: + const m = method[0].toLowerCase() + method.slice(1); + if (typeof plugin[m] == 'function') { + try { + await Promise.resolve(plugin[m].apply(plugin, args)); + } + catch (e) { + // tslint:disable-next-line:no-console + console.error(`error on notification '${method}': ${e}`); + } + } + } + }); + nvim.on('request', async (method, args, resp) => { + try { + if (method == 'CocAutocmd') { + await events_1.default.fire(args[0], args.slice(1)); + resp.send(); + return; + } + let m = method[0].toLowerCase() + method.slice(1); + if (typeof plugin[m] !== 'function') { + return resp.send(`Method ${m} not found`, true); + } + let res = await Promise.resolve(plugin[m].apply(plugin, args)); + resp.send(res); + } + catch (e) { + logger.error(`Error on "${method}": ` + e.stack); + resp.send(e.message, true); + } + }); + nvim.channelId.then(async (channelId) => { + clientReady = true; + if (isTest) + nvim.command(`let g:coc_node_channel_id = ${channelId}`, true); + let json = __webpack_require__(410); + let { major, minor, patch } = semver_1.default.parse(json.version); + nvim.setClientInfo('coc', { major, minor, patch }, 'remote', {}, {}); + let entered = await nvim.getVvar('vim_did_enter'); + if (entered && !initialized) { + initialized = true; + await plugin.init(); + } + }).catch(e => { + console.error(`Channel create error: ${e.message}`); // tslint:disable-line + }); + return plugin; +}; +//# sourceMappingURL=attach.js.map + +/***/ }), +/* 3 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__extends", function() { return __extends; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__assign", function() { return __assign; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__rest", function() { return __rest; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__decorate", function() { return __decorate; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__param", function() { return __param; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__metadata", function() { return __metadata; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__awaiter", function() { return __awaiter; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__generator", function() { return __generator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__exportStar", function() { return __exportStar; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__values", function() { return __values; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__read", function() { return __read; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__spread", function() { return __spread; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__spreadArrays", function() { return __spreadArrays; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__await", function() { return __await; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncGenerator", function() { return __asyncGenerator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncDelegator", function() { return __asyncDelegator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncValues", function() { return __asyncValues; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__makeTemplateObject", function() { return __makeTemplateObject; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importStar", function() { return __importStar; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importDefault", function() { return __importDefault; }); +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ +/* global Reflect, Promise */ + +var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); +}; + +function __extends(d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} + +var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + } + return __assign.apply(this, arguments); +} + +function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +} + +function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} + +function __param(paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +} + +function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); +} + +function __awaiter(thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +} + +function __exportStar(m, exports) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} + +function __values(o) { + var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; + if (m) return m.call(o); + return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; +} + +function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +} + +function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; +} + +function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +}; + +function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); +} + +function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; + function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } +} + +function __asyncDelegator(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } +} + +function __asyncValues(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +} + +function __makeTemplateObject(cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; +}; + +function __importStar(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result.default = mod; + return result; +} + +function __importDefault(mod) { + return (mod && mod.__esModule) ? mod : { default: mod }; +} + + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var attach_1 = __webpack_require__(5); +exports.attach = attach_1.attach; +var index_1 = __webpack_require__(63); +exports.Neovim = index_1.Neovim; +exports.NeovimClient = index_1.NeovimClient; +exports.Buffer = index_1.Buffer; +exports.Tabpage = index_1.Tabpage; +exports.Window = index_1.Window; + + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const net_1 = __webpack_require__(6); +const client_1 = __webpack_require__(7); +function attach({ reader: _reader, writer: _writer, proc, socket, }, _logger = null, requestApi = true) { + let writer; + let reader; + let neovim; + if (socket) { + const client = net_1.createConnection(socket); + writer = client; + reader = client; + client.once('close', () => { + neovim.detach(); + }); + } + else if (_reader && _writer) { + writer = _writer; + reader = _reader; + } + else if (proc) { + writer = proc.stdin; + reader = proc.stdout; + proc.once('disconnect', () => { + neovim.detach(); + }); + } + writer.on('error', err => { + if (err.code == 'EPIPE') { + neovim.detach(); + } + }); + if (writer && reader) { + neovim = new client_1.NeovimClient(); + neovim.attach({ + writer, + reader, + }, requestApi); + return neovim; + } + throw new Error('Invalid arguments, could not attach'); +} +exports.attach = attach; + + +/***/ }), +/* 6 */ +/***/ (function(module, exports) { + +module.exports = require("net"); + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Handles attaching transport + */ +const nvim_1 = __webpack_require__(8); +const vim_1 = __webpack_require__(58); +const Neovim_1 = __webpack_require__(62); +const Buffer_1 = __webpack_require__(47); +const Window_1 = __webpack_require__(50); +const Tabpage_1 = __webpack_require__(52); +const logger_1 = __webpack_require__(54); +exports.DETACH_BUFFER = Symbol('detachBuffer'); +exports.ATTACH_BUFFER = Symbol('attachBuffer'); +const logger = logger_1.createLogger('client'); +const isVim = process.env.VIM_NODE_RPC == '1'; +class AsyncResponse { + constructor(requestId, cb) { + this.requestId = requestId; + this.cb = cb; + this.finished = false; + } + finish(err, res) { + if (this.finished) + return; + this.finished = true; + if (err) { + this.cb(new Error(err)); + return; + } + this.cb(null, res); + } +} +exports.AsyncResponse = AsyncResponse; +class NeovimClient extends Neovim_1.Neovim { + constructor() { + // Neovim has no `data` or `metadata` + super({}); + this.requestId = 1; + this.responses = new Map(); + this.attachedBuffers = new Map(); + this.pauseLevel = 0; + Object.defineProperty(this, 'client', { + value: this + }); + let transport = isVim ? new vim_1.VimTransport() : new nvim_1.NvimTransport(); + this.setTransport(transport); + this.transportAttached = false; + this.handleRequest = this.handleRequest.bind(this); + this.handleNotification = this.handleNotification.bind(this); + } + createBuffer(id) { + return new Buffer_1.Buffer({ + transport: this.transport, + data: id, + client: this + }); + } + createWindow(id) { + return new Window_1.Window({ + transport: this.transport, + data: id, + client: this + }); + } + createTabpage(id) { + return new Tabpage_1.Tabpage({ + transport: this.transport, + data: id, + client: this + }); + } + /** Attaches msgpack to read/write streams * */ + attach({ reader, writer, }, requestApi = true) { + this.transport.attach(writer, reader, this); + this.transportAttached = true; + this.setupTransport(requestApi); + } + /* called when attach process disconnected*/ + detach() { + this.transport.detach(); + this.transportAttached = false; + } + get isApiReady() { + return this.transportAttached && typeof this._channelId !== 'undefined'; + } + get channelId() { + return this._isReady.then(() => { + return this._channelId; + }); + } + isAttached(bufnr) { + return this.attachedBuffers.has(bufnr); + } + handleRequest(method, args, resp) { + this.emit('request', method, args, resp); + } + sendAsyncRequest(method, args) { + let id = this.requestId; + this.requestId = id + 1; + this.notify('nvim_call_function', ['coc#rpc#async_request', [id, method, args || []]]); + return new Promise((resolve, reject) => { + let response = new AsyncResponse(id, (err, res) => { + if (err) + return reject(err); + resolve(res); + }); + this.responses.set(id, response); + }); + } + emitNotification(method, args) { + if (method.endsWith('_event')) { + if (method.startsWith('nvim_buf_')) { + const shortName = method.replace(/nvim_buf_(.*)_event/, '$1'); + const buffer = args[0]; + const { id } = buffer; + if (!this.isAttached(id)) { + // this is a problem + return; + } + const bufferMap = this.attachedBuffers.get(id); + const cbs = bufferMap.get(shortName) || []; + cbs.forEach(cb => cb(...args)); + // Handle `nvim_buf_detach_event` + // clean `attachedBuffers` since it will no longer be attached + if (shortName === 'detach') { + this.attachedBuffers.delete(id); + } + return; + } + // async_request_event from vim + if (method.startsWith('nvim_async_request')) { + const [id, method, arr] = args; + this.handleRequest(method, arr, { + send: (resp, isError) => { + this.notify('nvim_call_function', ['coc#rpc#async_response', [id, resp, isError]]); + } + }); + } + // nvim_async_response_event + if (method.startsWith('nvim_async_response')) { + const [id, err, res] = args; + const response = this.responses.get(id); + if (!response) { + // tslint:disable-next-line: no-console + console.error(`Response not found for request ${id}`); + return; + } + this.responses.delete(id); + response.finish(err, res); + return; + } + // tslint:disable-next-line: no-console + // console.error(`Unhandled event: ${method}`) + } + else { + this.emit('notification', method, args); + } + } + handleNotification(method, args) { + this.emitNotification(method, args); + } + // Listen and setup handlers for transport + setupTransport(requestApi = true) { + if (!this.transportAttached) { + throw new Error('Not attached to input/output'); + } + this.transport.on('request', this.handleRequest); + this.transport.on('notification', this.handleNotification); + this.transport.on('detach', () => { + this.emit('disconnect'); + this.transport.removeAllListeners('request'); + this.transport.removeAllListeners('notification'); + this.transport.removeAllListeners('detach'); + }); + if (requestApi) { + this._isReady = this.generateApi(); + } + else { + this._channelId = 0; + this._isReady = Promise.resolve(true); + } + } + requestApi() { + return new Promise((resolve, reject) => { + this.transport.request('nvim_get_api_info', [], (err, res) => { + if (err) { + reject(new Error(Array.isArray(err) ? err[1] : err.message || err.toString())); + } + else { + resolve(res); + } + }); + }); + } + generateApi() { + return __awaiter(this, void 0, void 0, function* () { + let results; + try { + results = yield this.requestApi(); + } + catch (err) { + // tslint:disable-next-line: no-console + console.error('Could not get vim api results'); + logger.error(err); + } + if (results) { + try { + const [channelId, metadata] = results; + this.functions = metadata.functions.map(f => f.name); + this._channelId = channelId; + return true; + } + catch (err) { + logger.error(err.stack); + return null; + } + } + return null; + }); + } + [exports.ATTACH_BUFFER](buffer) { + this.attachedBuffers.set(buffer.id, new Map()); + } + [exports.DETACH_BUFFER](buffer) { + this.attachedBuffers.delete(buffer.id); + } + attachBufferEvent(buffer, eventName, cb) { + if (!this.isAttached(buffer.id)) + return; + const bufferMap = this.attachedBuffers.get(buffer.id); + if (!bufferMap.get(eventName)) { + bufferMap.set(eventName, []); + } + const cbs = bufferMap.get(eventName); + if (cbs.indexOf(cb) !== -1) + return; + cbs.push(cb); + bufferMap.set(eventName, cbs); + this.attachedBuffers.set(buffer.id, bufferMap); + return; + } + /** + * Returns `true` if buffer should be detached + */ + detachBufferEvent(buffer, eventName, cb) { + const bufferMap = this.attachedBuffers.get(buffer.id); + if (!bufferMap) + return; + const handlers = (bufferMap.get(eventName) || []).filter(handler => handler !== cb); + // Remove eventName listener from bufferMap if no more handlers + if (!handlers.length) { + bufferMap.delete(eventName); + } + else { + bufferMap.set(eventName, handlers); + } + } + pauseNotification() { + this.pauseLevel = this.pauseLevel + 1; + this.transport.pauseNotification(); + if (this.pauseTimer) + clearTimeout(this.pauseTimer); + this.pauseTimer = setTimeout(() => { + this.pauseLevel = 0; + // tslint:disable-next-line: no-floating-promises + this.transport.resumeNotification(); + }, 50); + } + resumeNotification(cancel, notify) { + if (this.pauseLevel == 0) + return Promise.resolve(); + this.pauseLevel = this.pauseLevel - 1; + if (cancel) + return Promise.resolve(); + if (this.pauseLevel == 0) { + if (this.pauseTimer) + clearTimeout(this.pauseTimer); + if (!notify) + return this.transport.resumeNotification(); + this.transport.resumeNotification(true); + } + return Promise.resolve(); + } + hasFunction(name) { + if (!this.functions) + return true; + return this.functions.indexOf(name) !== -1; + } +} +exports.NeovimClient = NeovimClient; + + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const msgpack = __importStar(__webpack_require__(9)); +const buffered_1 = __importDefault(__webpack_require__(45)); +const types_1 = __webpack_require__(46); +const base_1 = __importDefault(__webpack_require__(53)); +class NvimTransport extends base_1.default { + constructor() { + super(); + this.pending = new Map(); + this.nextRequestId = 1; + this.attached = false; + const codec = this.setupCodec(); + this.encodeStream = msgpack.createEncodeStream({ codec }); + this.decodeStream = msgpack.createDecodeStream({ codec }); + this.decodeStream.on('data', (msg) => { + this.parseMessage(msg); + }); + this.decodeStream.on('end', () => { + this.detach(); + this.emit('detach'); + }); + } + parseMessage(msg) { + const msgType = msg[0]; + this.debugMessage(msg); + if (msgType === 0) { + // request + // - msg[1]: id + // - msg[2]: method name + // - msg[3]: arguments + this.emit('request', msg[2].toString(), msg[3], this.createResponse(msg[1])); + } + else if (msgType === 1) { + // response to a previous request: + // - msg[1]: the id + // - msg[2]: error(if any) + // - msg[3]: result(if not errored) + const id = msg[1]; + const handler = this.pending.get(id); + if (handler) { + this.pending.delete(id); + let err = msg[2]; + if (err && err.length != 2) { + err = [0, err instanceof Error ? err.message : err]; + } + handler(err, msg[3]); + } + } + else if (msgType === 2) { + // notification/event + // - msg[1]: event name + // - msg[2]: arguments + this.emit('notification', msg[1].toString(), msg[2]); + } + else { + // tslint:disable-next-line: no-console + console.error(`Invalid message type ${msgType}`); + } + } + setupCodec() { + const codec = msgpack.createCodec(); + types_1.Metadata.forEach(({ constructor }, id) => { + codec.addExtPacker(id, constructor, (obj) => msgpack.encode(obj.data)); + codec.addExtUnpacker(id, data => new constructor({ + transport: this, + client: this.client, + data: msgpack.decode(data), + })); + }); + this.codec = codec; + return this.codec; + } + attach(writer, reader, client) { + this.encodeStream = this.encodeStream.pipe(writer); + const buffered = new buffered_1.default(); + reader.pipe(buffered).pipe(this.decodeStream); + this.writer = writer; + this.reader = reader; + this.client = client; + this.attached = true; + } + detach() { + if (!this.attached) + return; + this.attached = false; + this.encodeStream.unpipe(this.writer); + this.reader.unpipe(this.decodeStream); + } + request(method, args, cb) { + if (!this.attached) + return cb([0, 'transport disconnected']); + this.nextRequestId = this.nextRequestId + 1; + this.debug('nvim request:', this.nextRequestId, method, args); + this.encodeStream.write(msgpack.encode([0, this.nextRequestId, method, args], { + codec: this.codec, + })); + this.pending.set(this.nextRequestId, cb); + } + notify(method, args) { + if (!this.attached) + return; + if (this._paused) { + this.paused.push([method, args]); + return; + } + this.debug('nvim notification:', method, args); + this.encodeStream.write(msgpack.encode([2, method, args], { + codec: this.codec, + })); + } + createResponse(requestId) { + let called = false; + let { encodeStream } = this; + return { + send: (resp, isError) => { + if (called || !this.attached) + return; + this.debug('response:', requestId, resp, isError == true); + called = true; + encodeStream.write(msgpack.encode([ + 1, + requestId, + isError ? resp : null, + !isError ? resp : null, + ])); + } + }; + } +} +exports.NvimTransport = NvimTransport; + + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +// msgpack.js + +exports.encode = __webpack_require__(10).encode; +exports.decode = __webpack_require__(30).decode; + +exports.Encoder = __webpack_require__(36).Encoder; +exports.Decoder = __webpack_require__(38).Decoder; + +exports.createEncodeStream = __webpack_require__(39).createEncodeStream; +exports.createDecodeStream = __webpack_require__(42).createDecodeStream; + +exports.createCodec = __webpack_require__(43).createCodec; +exports.codec = __webpack_require__(44).codec; + + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +// encode.js + +exports.encode = encode; + +var EncodeBuffer = __webpack_require__(11).EncodeBuffer; + +function encode(input, options) { + var encoder = new EncodeBuffer(options); + encoder.write(input); + return encoder.read(); +} + + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +// encode-buffer.js + +exports.EncodeBuffer = EncodeBuffer; + +var preset = __webpack_require__(12).preset; + +var FlexEncoder = __webpack_require__(29).FlexEncoder; + +FlexEncoder.mixin(EncodeBuffer.prototype); + +function EncodeBuffer(options) { + if (!(this instanceof EncodeBuffer)) return new EncodeBuffer(options); + + if (options) { + this.options = options; + if (options.codec) { + var codec = this.codec = options.codec; + if (codec.bufferish) this.bufferish = codec.bufferish; + } + } +} + +EncodeBuffer.prototype.codec = preset; + +EncodeBuffer.prototype.write = function(input) { + this.codec.encode(this, input); +}; + + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + +// write-core.js + +var ExtBuffer = __webpack_require__(13).ExtBuffer; +var ExtPacker = __webpack_require__(22); +var WriteType = __webpack_require__(23); +var CodecBase = __webpack_require__(28); + +CodecBase.install({ + addExtPacker: addExtPacker, + getExtPacker: getExtPacker, + init: init +}); + +exports.preset = init.call(CodecBase.preset); + +function getEncoder(options) { + var writeType = WriteType.getWriteType(options); + return encode; + + function encode(encoder, value) { + var func = writeType[typeof value]; + if (!func) throw new Error("Unsupported type \"" + (typeof value) + "\": " + value); + func(encoder, value); + } +} + +function init() { + var options = this.options; + this.encode = getEncoder(options); + + if (options && options.preset) { + ExtPacker.setExtPackers(this); + } + + return this; +} + +function addExtPacker(etype, Class, packer) { + packer = CodecBase.filter(packer); + var name = Class.name; + if (name && name !== "Object") { + var packers = this.extPackers || (this.extPackers = {}); + packers[name] = extPacker; + } else { + // fallback for IE + var list = this.extEncoderList || (this.extEncoderList = []); + list.unshift([Class, extPacker]); + } + + function extPacker(value) { + if (packer) value = packer(value); + return new ExtBuffer(value, etype); + } +} + +function getExtPacker(value) { + var packers = this.extPackers || (this.extPackers = {}); + var c = value.constructor; + var e = c && c.name && packers[c.name]; + if (e) return e; + + // fallback for IE + var list = this.extEncoderList || (this.extEncoderList = []); + var len = list.length; + for (var i = 0; i < len; i++) { + var pair = list[i]; + if (c === pair[0]) return pair[1]; + } +} + + +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + +// ext-buffer.js + +exports.ExtBuffer = ExtBuffer; + +var Bufferish = __webpack_require__(14); + +function ExtBuffer(buffer, type) { + if (!(this instanceof ExtBuffer)) return new ExtBuffer(buffer, type); + this.buffer = Bufferish.from(buffer); + this.type = type; +} + + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + +// bufferish.js + +var Buffer = exports.global = __webpack_require__(15); +var hasBuffer = exports.hasBuffer = Buffer && !!Buffer.isBuffer; +var hasArrayBuffer = exports.hasArrayBuffer = ("undefined" !== typeof ArrayBuffer); + +var isArray = exports.isArray = __webpack_require__(16); +exports.isArrayBuffer = hasArrayBuffer ? isArrayBuffer : _false; +var isBuffer = exports.isBuffer = hasBuffer ? Buffer.isBuffer : _false; +var isView = exports.isView = hasArrayBuffer ? (ArrayBuffer.isView || _is("ArrayBuffer", "buffer")) : _false; + +exports.alloc = alloc; +exports.concat = concat; +exports.from = from; + +var BufferArray = exports.Array = __webpack_require__(17); +var BufferBuffer = exports.Buffer = __webpack_require__(18); +var BufferUint8Array = exports.Uint8Array = __webpack_require__(19); +var BufferProto = exports.prototype = __webpack_require__(20); + +/** + * @param value {Array|ArrayBuffer|Buffer|String} + * @returns {Buffer|Uint8Array|Array} + */ + +function from(value) { + if (typeof value === "string") { + return fromString.call(this, value); + } else { + return auto(this).from(value); + } +} + +/** + * @param size {Number} + * @returns {Buffer|Uint8Array|Array} + */ + +function alloc(size) { + return auto(this).alloc(size); +} + +/** + * @param list {Array} array of (Buffer|Uint8Array|Array)s + * @param [length] + * @returns {Buffer|Uint8Array|Array} + */ + +function concat(list, length) { + if (!length) { + length = 0; + Array.prototype.forEach.call(list, dryrun); + } + var ref = (this !== exports) && this || list[0]; + var result = alloc.call(ref, length); + var offset = 0; + Array.prototype.forEach.call(list, append); + return result; + + function dryrun(buffer) { + length += buffer.length; + } + + function append(buffer) { + offset += BufferProto.copy.call(buffer, result, offset); + } +} + +var _isArrayBuffer = _is("ArrayBuffer"); + +function isArrayBuffer(value) { + return (value instanceof ArrayBuffer) || _isArrayBuffer(value); +} + +/** + * @private + */ + +function fromString(value) { + var expected = value.length * 3; + var that = alloc.call(this, expected); + var actual = BufferProto.write.call(that, value); + if (expected !== actual) { + that = BufferProto.slice.call(that, 0, actual); + } + return that; +} + +function auto(that) { + return isBuffer(that) ? BufferBuffer + : isView(that) ? BufferUint8Array + : isArray(that) ? BufferArray + : hasBuffer ? BufferBuffer + : hasArrayBuffer ? BufferUint8Array + : BufferArray; +} + +function _false() { + return false; +} + +function _is(name, key) { + /* jshint eqnull:true */ + name = "[object " + name + "]"; + return function(value) { + return (value != null) && {}.toString.call(key ? value[key] : value) === name; + }; +} + +/***/ }), +/* 15 */ +/***/ (function(module, exports) { + +/* globals Buffer */ + +module.exports = + c(("undefined" !== typeof Buffer) && Buffer) || + c(this.Buffer) || + c(("undefined" !== typeof window) && window.Buffer) || + this.Buffer; + +function c(B) { + return B && B.isBuffer && B; +} + +/***/ }), +/* 16 */ +/***/ (function(module, exports) { + +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + +// bufferish-array.js + +var Bufferish = __webpack_require__(14); + +var exports = module.exports = alloc(0); + +exports.alloc = alloc; +exports.concat = Bufferish.concat; +exports.from = from; + +/** + * @param size {Number} + * @returns {Buffer|Uint8Array|Array} + */ + +function alloc(size) { + return new Array(size); +} + +/** + * @param value {Array|ArrayBuffer|Buffer|String} + * @returns {Array} + */ + +function from(value) { + if (!Bufferish.isBuffer(value) && Bufferish.isView(value)) { + // TypedArray to Uint8Array + value = Bufferish.Uint8Array.from(value); + } else if (Bufferish.isArrayBuffer(value)) { + // ArrayBuffer to Uint8Array + value = new Uint8Array(value); + } else if (typeof value === "string") { + // String to Array + return Bufferish.from.call(exports, value); + } else if (typeof value === "number") { + throw new TypeError('"value" argument must not be a number'); + } + + // Array-like to Array + return Array.prototype.slice.call(value); +} + + +/***/ }), +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { + +// bufferish-buffer.js + +var Bufferish = __webpack_require__(14); +var Buffer = Bufferish.global; + +var exports = module.exports = Bufferish.hasBuffer ? alloc(0) : []; + +exports.alloc = Bufferish.hasBuffer && Buffer.alloc || alloc; +exports.concat = Bufferish.concat; +exports.from = from; + +/** + * @param size {Number} + * @returns {Buffer|Uint8Array|Array} + */ + +function alloc(size) { + return new Buffer(size); +} + +/** + * @param value {Array|ArrayBuffer|Buffer|String} + * @returns {Buffer} + */ + +function from(value) { + if (!Bufferish.isBuffer(value) && Bufferish.isView(value)) { + // TypedArray to Uint8Array + value = Bufferish.Uint8Array.from(value); + } else if (Bufferish.isArrayBuffer(value)) { + // ArrayBuffer to Uint8Array + value = new Uint8Array(value); + } else if (typeof value === "string") { + // String to Buffer + return Bufferish.from.call(exports, value); + } else if (typeof value === "number") { + throw new TypeError('"value" argument must not be a number'); + } + + // Array-like to Buffer + if (Buffer.from && Buffer.from.length !== 1) { + return Buffer.from(value); // node v6+ + } else { + return new Buffer(value); // node v4 + } +} + + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + +// bufferish-uint8array.js + +var Bufferish = __webpack_require__(14); + +var exports = module.exports = Bufferish.hasArrayBuffer ? alloc(0) : []; + +exports.alloc = alloc; +exports.concat = Bufferish.concat; +exports.from = from; + +/** + * @param size {Number} + * @returns {Buffer|Uint8Array|Array} + */ + +function alloc(size) { + return new Uint8Array(size); +} + +/** + * @param value {Array|ArrayBuffer|Buffer|String} + * @returns {Uint8Array} + */ + +function from(value) { + if (Bufferish.isView(value)) { + // TypedArray to ArrayBuffer + var byteOffset = value.byteOffset; + var byteLength = value.byteLength; + value = value.buffer; + if (value.byteLength !== byteLength) { + if (value.slice) { + value = value.slice(byteOffset, byteOffset + byteLength); + } else { + // Android 4.1 does not have ArrayBuffer.prototype.slice + value = new Uint8Array(value); + if (value.byteLength !== byteLength) { + // TypedArray to ArrayBuffer to Uint8Array to Array + value = Array.prototype.slice.call(value, byteOffset, byteOffset + byteLength); + } + } + } + } else if (typeof value === "string") { + // String to Uint8Array + return Bufferish.from.call(exports, value); + } else if (typeof value === "number") { + throw new TypeError('"value" argument must not be a number'); + } + + return new Uint8Array(value); +} + + +/***/ }), +/* 20 */ +/***/ (function(module, exports, __webpack_require__) { + +// bufferish-proto.js + +/* jshint eqnull:true */ + +var BufferLite = __webpack_require__(21); + +exports.copy = copy; +exports.slice = slice; +exports.toString = toString; +exports.write = gen("write"); + +var Bufferish = __webpack_require__(14); +var Buffer = Bufferish.global; + +var isBufferShim = Bufferish.hasBuffer && ("TYPED_ARRAY_SUPPORT" in Buffer); +var brokenTypedArray = isBufferShim && !Buffer.TYPED_ARRAY_SUPPORT; + +/** + * @param target {Buffer|Uint8Array|Array} + * @param [targetStart] {Number} + * @param [start] {Number} + * @param [end] {Number} + * @returns {Buffer|Uint8Array|Array} + */ + +function copy(target, targetStart, start, end) { + var thisIsBuffer = Bufferish.isBuffer(this); + var targetIsBuffer = Bufferish.isBuffer(target); + if (thisIsBuffer && targetIsBuffer) { + // Buffer to Buffer + return this.copy(target, targetStart, start, end); + } else if (!brokenTypedArray && !thisIsBuffer && !targetIsBuffer && + Bufferish.isView(this) && Bufferish.isView(target)) { + // Uint8Array to Uint8Array (except for minor some browsers) + var buffer = (start || end != null) ? slice.call(this, start, end) : this; + target.set(buffer, targetStart); + return buffer.length; + } else { + // other cases + return BufferLite.copy.call(this, target, targetStart, start, end); + } +} + +/** + * @param [start] {Number} + * @param [end] {Number} + * @returns {Buffer|Uint8Array|Array} + */ + +function slice(start, end) { + // for Buffer, Uint8Array (except for minor some browsers) and Array + var f = this.slice || (!brokenTypedArray && this.subarray); + if (f) return f.call(this, start, end); + + // Uint8Array (for minor some browsers) + var target = Bufferish.alloc.call(this, end - start); + copy.call(this, target, 0, start, end); + return target; +} + +/** + * Buffer.prototype.toString() + * + * @param [encoding] {String} ignored + * @param [start] {Number} + * @param [end] {Number} + * @returns {String} + */ + +function toString(encoding, start, end) { + var f = (!isBufferShim && Bufferish.isBuffer(this)) ? this.toString : BufferLite.toString; + return f.apply(this, arguments); +} + +/** + * @private + */ + +function gen(method) { + return wrap; + + function wrap() { + var f = this[method] || BufferLite[method]; + return f.apply(this, arguments); + } +} + + +/***/ }), +/* 21 */ +/***/ (function(module, exports) { + +// buffer-lite.js + +var MAXBUFLEN = 8192; + +exports.copy = copy; +exports.toString = toString; +exports.write = write; + +/** + * Buffer.prototype.write() + * + * @param string {String} + * @param [offset] {Number} + * @returns {Number} + */ + +function write(string, offset) { + var buffer = this; + var index = offset || (offset |= 0); + var length = string.length; + var chr = 0; + var i = 0; + while (i < length) { + chr = string.charCodeAt(i++); + + if (chr < 128) { + buffer[index++] = chr; + } else if (chr < 0x800) { + // 2 bytes + buffer[index++] = 0xC0 | (chr >>> 6); + buffer[index++] = 0x80 | (chr & 0x3F); + } else if (chr < 0xD800 || chr > 0xDFFF) { + // 3 bytes + buffer[index++] = 0xE0 | (chr >>> 12); + buffer[index++] = 0x80 | ((chr >>> 6) & 0x3F); + buffer[index++] = 0x80 | (chr & 0x3F); + } else { + // 4 bytes - surrogate pair + chr = (((chr - 0xD800) << 10) | (string.charCodeAt(i++) - 0xDC00)) + 0x10000; + buffer[index++] = 0xF0 | (chr >>> 18); + buffer[index++] = 0x80 | ((chr >>> 12) & 0x3F); + buffer[index++] = 0x80 | ((chr >>> 6) & 0x3F); + buffer[index++] = 0x80 | (chr & 0x3F); + } + } + return index - offset; +} + +/** + * Buffer.prototype.toString() + * + * @param [encoding] {String} ignored + * @param [start] {Number} + * @param [end] {Number} + * @returns {String} + */ + +function toString(encoding, start, end) { + var buffer = this; + var index = start|0; + if (!end) end = buffer.length; + var string = ''; + var chr = 0; + + while (index < end) { + chr = buffer[index++]; + if (chr < 128) { + string += String.fromCharCode(chr); + continue; + } + + if ((chr & 0xE0) === 0xC0) { + // 2 bytes + chr = (chr & 0x1F) << 6 | + (buffer[index++] & 0x3F); + + } else if ((chr & 0xF0) === 0xE0) { + // 3 bytes + chr = (chr & 0x0F) << 12 | + (buffer[index++] & 0x3F) << 6 | + (buffer[index++] & 0x3F); + + } else if ((chr & 0xF8) === 0xF0) { + // 4 bytes + chr = (chr & 0x07) << 18 | + (buffer[index++] & 0x3F) << 12 | + (buffer[index++] & 0x3F) << 6 | + (buffer[index++] & 0x3F); + } + + if (chr >= 0x010000) { + // A surrogate pair + chr -= 0x010000; + + string += String.fromCharCode((chr >>> 10) + 0xD800, (chr & 0x3FF) + 0xDC00); + } else { + string += String.fromCharCode(chr); + } + } + + return string; +} + +/** + * Buffer.prototype.copy() + * + * @param target {Buffer} + * @param [targetStart] {Number} + * @param [start] {Number} + * @param [end] {Number} + * @returns {number} + */ + +function copy(target, targetStart, start, end) { + var i; + if (!start) start = 0; + if (!end && end !== 0) end = this.length; + if (!targetStart) targetStart = 0; + var len = end - start; + + if (target === this && start < targetStart && targetStart < end) { + // descending + for (i = len - 1; i >= 0; i--) { + target[i + targetStart] = this[i + start]; + } + } else { + // ascending + for (i = 0; i < len; i++) { + target[i + targetStart] = this[i + start]; + } + } + + return len; +} + + +/***/ }), +/* 22 */ +/***/ (function(module, exports, __webpack_require__) { + +// ext-packer.js + +exports.setExtPackers = setExtPackers; + +var Bufferish = __webpack_require__(14); +var Buffer = Bufferish.global; +var packTypedArray = Bufferish.Uint8Array.from; +var _encode; + +var ERROR_COLUMNS = {name: 1, message: 1, stack: 1, columnNumber: 1, fileName: 1, lineNumber: 1}; + +function setExtPackers(codec) { + codec.addExtPacker(0x0E, Error, [packError, encode]); + codec.addExtPacker(0x01, EvalError, [packError, encode]); + codec.addExtPacker(0x02, RangeError, [packError, encode]); + codec.addExtPacker(0x03, ReferenceError, [packError, encode]); + codec.addExtPacker(0x04, SyntaxError, [packError, encode]); + codec.addExtPacker(0x05, TypeError, [packError, encode]); + codec.addExtPacker(0x06, URIError, [packError, encode]); + + codec.addExtPacker(0x0A, RegExp, [packRegExp, encode]); + codec.addExtPacker(0x0B, Boolean, [packValueOf, encode]); + codec.addExtPacker(0x0C, String, [packValueOf, encode]); + codec.addExtPacker(0x0D, Date, [Number, encode]); + codec.addExtPacker(0x0F, Number, [packValueOf, encode]); + + if ("undefined" !== typeof Uint8Array) { + codec.addExtPacker(0x11, Int8Array, packTypedArray); + codec.addExtPacker(0x12, Uint8Array, packTypedArray); + codec.addExtPacker(0x13, Int16Array, packTypedArray); + codec.addExtPacker(0x14, Uint16Array, packTypedArray); + codec.addExtPacker(0x15, Int32Array, packTypedArray); + codec.addExtPacker(0x16, Uint32Array, packTypedArray); + codec.addExtPacker(0x17, Float32Array, packTypedArray); + + // PhantomJS/1.9.7 doesn't have Float64Array + if ("undefined" !== typeof Float64Array) { + codec.addExtPacker(0x18, Float64Array, packTypedArray); + } + + // IE10 doesn't have Uint8ClampedArray + if ("undefined" !== typeof Uint8ClampedArray) { + codec.addExtPacker(0x19, Uint8ClampedArray, packTypedArray); + } + + codec.addExtPacker(0x1A, ArrayBuffer, packTypedArray); + codec.addExtPacker(0x1D, DataView, packTypedArray); + } + + if (Bufferish.hasBuffer) { + codec.addExtPacker(0x1B, Buffer, Bufferish.from); + } +} + +function encode(input) { + if (!_encode) _encode = __webpack_require__(10).encode; // lazy load + return _encode(input); +} + +function packValueOf(value) { + return (value).valueOf(); +} + +function packRegExp(value) { + value = RegExp.prototype.toString.call(value).split("/"); + value.shift(); + var out = [value.pop()]; + out.unshift(value.join("/")); + return out; +} + +function packError(value) { + var out = {}; + for (var key in ERROR_COLUMNS) { + out[key] = value[key]; + } + return out; +} + + +/***/ }), +/* 23 */ +/***/ (function(module, exports, __webpack_require__) { + +// write-type.js + +var IS_ARRAY = __webpack_require__(16); +var Int64Buffer = __webpack_require__(24); +var Uint64BE = Int64Buffer.Uint64BE; +var Int64BE = Int64Buffer.Int64BE; + +var Bufferish = __webpack_require__(14); +var BufferProto = __webpack_require__(20); +var WriteToken = __webpack_require__(25); +var uint8 = __webpack_require__(27).uint8; +var ExtBuffer = __webpack_require__(13).ExtBuffer; + +var HAS_UINT8ARRAY = ("undefined" !== typeof Uint8Array); +var HAS_MAP = ("undefined" !== typeof Map); + +var extmap = []; +extmap[1] = 0xd4; +extmap[2] = 0xd5; +extmap[4] = 0xd6; +extmap[8] = 0xd7; +extmap[16] = 0xd8; + +exports.getWriteType = getWriteType; + +function getWriteType(options) { + var token = WriteToken.getWriteToken(options); + var useraw = options && options.useraw; + var binarraybuffer = HAS_UINT8ARRAY && options && options.binarraybuffer; + var isBuffer = binarraybuffer ? Bufferish.isArrayBuffer : Bufferish.isBuffer; + var bin = binarraybuffer ? bin_arraybuffer : bin_buffer; + var usemap = HAS_MAP && options && options.usemap; + var map = usemap ? map_to_map : obj_to_map; + + var writeType = { + "boolean": bool, + "function": nil, + "number": number, + "object": (useraw ? object_raw : object), + "string": _string(useraw ? raw_head_size : str_head_size), + "symbol": nil, + "undefined": nil + }; + + return writeType; + + // false -- 0xc2 + // true -- 0xc3 + function bool(encoder, value) { + var type = value ? 0xc3 : 0xc2; + token[type](encoder, value); + } + + function number(encoder, value) { + var ivalue = value | 0; + var type; + if (value !== ivalue) { + // float 64 -- 0xcb + type = 0xcb; + token[type](encoder, value); + return; + } else if (-0x20 <= ivalue && ivalue <= 0x7F) { + // positive fixint -- 0x00 - 0x7f + // negative fixint -- 0xe0 - 0xff + type = ivalue & 0xFF; + } else if (0 <= ivalue) { + // uint 8 -- 0xcc + // uint 16 -- 0xcd + // uint 32 -- 0xce + type = (ivalue <= 0xFF) ? 0xcc : (ivalue <= 0xFFFF) ? 0xcd : 0xce; + } else { + // int 8 -- 0xd0 + // int 16 -- 0xd1 + // int 32 -- 0xd2 + type = (-0x80 <= ivalue) ? 0xd0 : (-0x8000 <= ivalue) ? 0xd1 : 0xd2; + } + token[type](encoder, ivalue); + } + + // uint 64 -- 0xcf + function uint64(encoder, value) { + var type = 0xcf; + token[type](encoder, value.toArray()); + } + + // int 64 -- 0xd3 + function int64(encoder, value) { + var type = 0xd3; + token[type](encoder, value.toArray()); + } + + // str 8 -- 0xd9 + // str 16 -- 0xda + // str 32 -- 0xdb + // fixstr -- 0xa0 - 0xbf + function str_head_size(length) { + return (length < 32) ? 1 : (length <= 0xFF) ? 2 : (length <= 0xFFFF) ? 3 : 5; + } + + // raw 16 -- 0xda + // raw 32 -- 0xdb + // fixraw -- 0xa0 - 0xbf + function raw_head_size(length) { + return (length < 32) ? 1 : (length <= 0xFFFF) ? 3 : 5; + } + + function _string(head_size) { + return string; + + function string(encoder, value) { + // prepare buffer + var length = value.length; + var maxsize = 5 + length * 3; + encoder.offset = encoder.reserve(maxsize); + var buffer = encoder.buffer; + + // expected header size + var expected = head_size(length); + + // expected start point + var start = encoder.offset + expected; + + // write string + length = BufferProto.write.call(buffer, value, start); + + // actual header size + var actual = head_size(length); + + // move content when needed + if (expected !== actual) { + var targetStart = start + actual - expected; + var end = start + length; + BufferProto.copy.call(buffer, buffer, targetStart, start, end); + } + + // write header + var type = (actual === 1) ? (0xa0 + length) : (actual <= 3) ? (0xd7 + actual) : 0xdb; + token[type](encoder, length); + + // move cursor + encoder.offset += length; + } + } + + function object(encoder, value) { + // null + if (value === null) return nil(encoder, value); + + // Buffer + if (isBuffer(value)) return bin(encoder, value); + + // Array + if (IS_ARRAY(value)) return array(encoder, value); + + // int64-buffer objects + if (Uint64BE.isUint64BE(value)) return uint64(encoder, value); + if (Int64BE.isInt64BE(value)) return int64(encoder, value); + + // ext formats + var packer = encoder.codec.getExtPacker(value); + if (packer) value = packer(value); + if (value instanceof ExtBuffer) return ext(encoder, value); + + // plain old Objects or Map + map(encoder, value); + } + + function object_raw(encoder, value) { + // Buffer + if (isBuffer(value)) return raw(encoder, value); + + // others + object(encoder, value); + } + + // nil -- 0xc0 + function nil(encoder, value) { + var type = 0xc0; + token[type](encoder, value); + } + + // fixarray -- 0x90 - 0x9f + // array 16 -- 0xdc + // array 32 -- 0xdd + function array(encoder, value) { + var length = value.length; + var type = (length < 16) ? (0x90 + length) : (length <= 0xFFFF) ? 0xdc : 0xdd; + token[type](encoder, length); + + var encode = encoder.codec.encode; + for (var i = 0; i < length; i++) { + encode(encoder, value[i]); + } + } + + // bin 8 -- 0xc4 + // bin 16 -- 0xc5 + // bin 32 -- 0xc6 + function bin_buffer(encoder, value) { + var length = value.length; + var type = (length < 0xFF) ? 0xc4 : (length <= 0xFFFF) ? 0xc5 : 0xc6; + token[type](encoder, length); + encoder.send(value); + } + + function bin_arraybuffer(encoder, value) { + bin_buffer(encoder, new Uint8Array(value)); + } + + // fixext 1 -- 0xd4 + // fixext 2 -- 0xd5 + // fixext 4 -- 0xd6 + // fixext 8 -- 0xd7 + // fixext 16 -- 0xd8 + // ext 8 -- 0xc7 + // ext 16 -- 0xc8 + // ext 32 -- 0xc9 + function ext(encoder, value) { + var buffer = value.buffer; + var length = buffer.length; + var type = extmap[length] || ((length < 0xFF) ? 0xc7 : (length <= 0xFFFF) ? 0xc8 : 0xc9); + token[type](encoder, length); + uint8[value.type](encoder); + encoder.send(buffer); + } + + // fixmap -- 0x80 - 0x8f + // map 16 -- 0xde + // map 32 -- 0xdf + function obj_to_map(encoder, value) { + var keys = Object.keys(value); + var length = keys.length; + var type = (length < 16) ? (0x80 + length) : (length <= 0xFFFF) ? 0xde : 0xdf; + token[type](encoder, length); + + var encode = encoder.codec.encode; + keys.forEach(function(key) { + encode(encoder, key); + encode(encoder, value[key]); + }); + } + + // fixmap -- 0x80 - 0x8f + // map 16 -- 0xde + // map 32 -- 0xdf + function map_to_map(encoder, value) { + if (!(value instanceof Map)) return obj_to_map(encoder, value); + + var length = value.size; + var type = (length < 16) ? (0x80 + length) : (length <= 0xFFFF) ? 0xde : 0xdf; + token[type](encoder, length); + + var encode = encoder.codec.encode; + value.forEach(function(val, key, m) { + encode(encoder, key); + encode(encoder, val); + }); + } + + // raw 16 -- 0xda + // raw 32 -- 0xdb + // fixraw -- 0xa0 - 0xbf + function raw(encoder, value) { + var length = value.length; + var type = (length < 32) ? (0xa0 + length) : (length <= 0xFFFF) ? 0xda : 0xdb; + token[type](encoder, length); + encoder.send(value); + } +} + + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { + +// int64-buffer.js + +/*jshint -W018 */ // Confusing use of '!'. +/*jshint -W030 */ // Expected an assignment or function call and instead saw an expression. +/*jshint -W093 */ // Did you mean to return a conditional instead of an assignment? + +var Uint64BE, Int64BE, Uint64LE, Int64LE; + +!function(exports) { + // constants + + var UNDEFINED = "undefined"; + var BUFFER = (UNDEFINED !== typeof Buffer) && Buffer; + var UINT8ARRAY = (UNDEFINED !== typeof Uint8Array) && Uint8Array; + var ARRAYBUFFER = (UNDEFINED !== typeof ArrayBuffer) && ArrayBuffer; + var ZERO = [0, 0, 0, 0, 0, 0, 0, 0]; + var isArray = Array.isArray || _isArray; + var BIT32 = 4294967296; + var BIT24 = 16777216; + + // storage class + + var storage; // Array; + + // generate classes + + Uint64BE = factory("Uint64BE", true, true); + Int64BE = factory("Int64BE", true, false); + Uint64LE = factory("Uint64LE", false, true); + Int64LE = factory("Int64LE", false, false); + + // class factory + + function factory(name, bigendian, unsigned) { + var posH = bigendian ? 0 : 4; + var posL = bigendian ? 4 : 0; + var pos0 = bigendian ? 0 : 3; + var pos1 = bigendian ? 1 : 2; + var pos2 = bigendian ? 2 : 1; + var pos3 = bigendian ? 3 : 0; + var fromPositive = bigendian ? fromPositiveBE : fromPositiveLE; + var fromNegative = bigendian ? fromNegativeBE : fromNegativeLE; + var proto = Int64.prototype; + var isName = "is" + name; + var _isInt64 = "_" + isName; + + // properties + proto.buffer = void 0; + proto.offset = 0; + proto[_isInt64] = true; + + // methods + proto.toNumber = toNumber; + proto.toString = toString; + proto.toJSON = toNumber; + proto.toArray = toArray; + + // add .toBuffer() method only when Buffer available + if (BUFFER) proto.toBuffer = toBuffer; + + // add .toArrayBuffer() method only when Uint8Array available + if (UINT8ARRAY) proto.toArrayBuffer = toArrayBuffer; + + // isUint64BE, isInt64BE + Int64[isName] = isInt64; + + // CommonJS + exports[name] = Int64; + + return Int64; + + // constructor + function Int64(buffer, offset, value, raddix) { + if (!(this instanceof Int64)) return new Int64(buffer, offset, value, raddix); + return init(this, buffer, offset, value, raddix); + } + + // isUint64BE, isInt64BE + function isInt64(b) { + return !!(b && b[_isInt64]); + } + + // initializer + function init(that, buffer, offset, value, raddix) { + if (UINT8ARRAY && ARRAYBUFFER) { + if (buffer instanceof ARRAYBUFFER) buffer = new UINT8ARRAY(buffer); + if (value instanceof ARRAYBUFFER) value = new UINT8ARRAY(value); + } + + // Int64BE() style + if (!buffer && !offset && !value && !storage) { + // shortcut to initialize with zero + that.buffer = newArray(ZERO, 0); + return; + } + + // Int64BE(value, raddix) style + if (!isValidBuffer(buffer, offset)) { + var _storage = storage || Array; + raddix = offset; + value = buffer; + offset = 0; + buffer = new _storage(8); + } + + that.buffer = buffer; + that.offset = offset |= 0; + + // Int64BE(buffer, offset) style + if (UNDEFINED === typeof value) return; + + // Int64BE(buffer, offset, value, raddix) style + if ("string" === typeof value) { + fromString(buffer, offset, value, raddix || 10); + } else if (isValidBuffer(value, raddix)) { + fromArray(buffer, offset, value, raddix); + } else if ("number" === typeof raddix) { + writeInt32(buffer, offset + posH, value); // high + writeInt32(buffer, offset + posL, raddix); // low + } else if (value > 0) { + fromPositive(buffer, offset, value); // positive + } else if (value < 0) { + fromNegative(buffer, offset, value); // negative + } else { + fromArray(buffer, offset, ZERO, 0); // zero, NaN and others + } + } + + function fromString(buffer, offset, str, raddix) { + var pos = 0; + var len = str.length; + var high = 0; + var low = 0; + if (str[0] === "-") pos++; + var sign = pos; + while (pos < len) { + var chr = parseInt(str[pos++], raddix); + if (!(chr >= 0)) break; // NaN + low = low * raddix + chr; + high = high * raddix + Math.floor(low / BIT32); + low %= BIT32; + } + if (sign) { + high = ~high; + if (low) { + low = BIT32 - low; + } else { + high++; + } + } + writeInt32(buffer, offset + posH, high); + writeInt32(buffer, offset + posL, low); + } + + function toNumber() { + var buffer = this.buffer; + var offset = this.offset; + var high = readInt32(buffer, offset + posH); + var low = readInt32(buffer, offset + posL); + if (!unsigned) high |= 0; // a trick to get signed + return high ? (high * BIT32 + low) : low; + } + + function toString(radix) { + var buffer = this.buffer; + var offset = this.offset; + var high = readInt32(buffer, offset + posH); + var low = readInt32(buffer, offset + posL); + var str = ""; + var sign = !unsigned && (high & 0x80000000); + if (sign) { + high = ~high; + low = BIT32 - low; + } + radix = radix || 10; + while (1) { + var mod = (high % radix) * BIT32 + low; + high = Math.floor(high / radix); + low = Math.floor(mod / radix); + str = (mod % radix).toString(radix) + str; + if (!high && !low) break; + } + if (sign) { + str = "-" + str; + } + return str; + } + + function writeInt32(buffer, offset, value) { + buffer[offset + pos3] = value & 255; + value = value >> 8; + buffer[offset + pos2] = value & 255; + value = value >> 8; + buffer[offset + pos1] = value & 255; + value = value >> 8; + buffer[offset + pos0] = value & 255; + } + + function readInt32(buffer, offset) { + return (buffer[offset + pos0] * BIT24) + + (buffer[offset + pos1] << 16) + + (buffer[offset + pos2] << 8) + + buffer[offset + pos3]; + } + } + + function toArray(raw) { + var buffer = this.buffer; + var offset = this.offset; + storage = null; // Array + if (raw !== false && offset === 0 && buffer.length === 8 && isArray(buffer)) return buffer; + return newArray(buffer, offset); + } + + function toBuffer(raw) { + var buffer = this.buffer; + var offset = this.offset; + storage = BUFFER; + if (raw !== false && offset === 0 && buffer.length === 8 && Buffer.isBuffer(buffer)) return buffer; + var dest = new BUFFER(8); + fromArray(dest, 0, buffer, offset); + return dest; + } + + function toArrayBuffer(raw) { + var buffer = this.buffer; + var offset = this.offset; + var arrbuf = buffer.buffer; + storage = UINT8ARRAY; + if (raw !== false && offset === 0 && (arrbuf instanceof ARRAYBUFFER) && arrbuf.byteLength === 8) return arrbuf; + var dest = new UINT8ARRAY(8); + fromArray(dest, 0, buffer, offset); + return dest.buffer; + } + + function isValidBuffer(buffer, offset) { + var len = buffer && buffer.length; + offset |= 0; + return len && (offset + 8 <= len) && ("string" !== typeof buffer[offset]); + } + + function fromArray(destbuf, destoff, srcbuf, srcoff) { + destoff |= 0; + srcoff |= 0; + for (var i = 0; i < 8; i++) { + destbuf[destoff++] = srcbuf[srcoff++] & 255; + } + } + + function newArray(buffer, offset) { + return Array.prototype.slice.call(buffer, offset, offset + 8); + } + + function fromPositiveBE(buffer, offset, value) { + var pos = offset + 8; + while (pos > offset) { + buffer[--pos] = value & 255; + value /= 256; + } + } + + function fromNegativeBE(buffer, offset, value) { + var pos = offset + 8; + value++; + while (pos > offset) { + buffer[--pos] = ((-value) & 255) ^ 255; + value /= 256; + } + } + + function fromPositiveLE(buffer, offset, value) { + var end = offset + 8; + while (offset < end) { + buffer[offset++] = value & 255; + value /= 256; + } + } + + function fromNegativeLE(buffer, offset, value) { + var end = offset + 8; + value++; + while (offset < end) { + buffer[offset++] = ((-value) & 255) ^ 255; + value /= 256; + } + } + + // https://github.com/retrofox/is-array + function _isArray(val) { + return !!val && "[object Array]" == Object.prototype.toString.call(val); + } + +}( true && typeof exports.nodeName !== 'string' ? exports : (this || {})); + + +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { + +// write-token.js + +var ieee754 = __webpack_require__(26); +var Int64Buffer = __webpack_require__(24); +var Uint64BE = Int64Buffer.Uint64BE; +var Int64BE = Int64Buffer.Int64BE; + +var uint8 = __webpack_require__(27).uint8; +var Bufferish = __webpack_require__(14); +var Buffer = Bufferish.global; +var IS_BUFFER_SHIM = Bufferish.hasBuffer && ("TYPED_ARRAY_SUPPORT" in Buffer); +var NO_TYPED_ARRAY = IS_BUFFER_SHIM && !Buffer.TYPED_ARRAY_SUPPORT; +var Buffer_prototype = Bufferish.hasBuffer && Buffer.prototype || {}; + +exports.getWriteToken = getWriteToken; + +function getWriteToken(options) { + if (options && options.uint8array) { + return init_uint8array(); + } else if (NO_TYPED_ARRAY || (Bufferish.hasBuffer && options && options.safe)) { + return init_safe(); + } else { + return init_token(); + } +} + +function init_uint8array() { + var token = init_token(); + + // float 32 -- 0xca + // float 64 -- 0xcb + token[0xca] = writeN(0xca, 4, writeFloatBE); + token[0xcb] = writeN(0xcb, 8, writeDoubleBE); + + return token; +} + +// Node.js and browsers with TypedArray + +function init_token() { + // (immediate values) + // positive fixint -- 0x00 - 0x7f + // nil -- 0xc0 + // false -- 0xc2 + // true -- 0xc3 + // negative fixint -- 0xe0 - 0xff + var token = uint8.slice(); + + // bin 8 -- 0xc4 + // bin 16 -- 0xc5 + // bin 32 -- 0xc6 + token[0xc4] = write1(0xc4); + token[0xc5] = write2(0xc5); + token[0xc6] = write4(0xc6); + + // ext 8 -- 0xc7 + // ext 16 -- 0xc8 + // ext 32 -- 0xc9 + token[0xc7] = write1(0xc7); + token[0xc8] = write2(0xc8); + token[0xc9] = write4(0xc9); + + // float 32 -- 0xca + // float 64 -- 0xcb + token[0xca] = writeN(0xca, 4, (Buffer_prototype.writeFloatBE || writeFloatBE), true); + token[0xcb] = writeN(0xcb, 8, (Buffer_prototype.writeDoubleBE || writeDoubleBE), true); + + // uint 8 -- 0xcc + // uint 16 -- 0xcd + // uint 32 -- 0xce + // uint 64 -- 0xcf + token[0xcc] = write1(0xcc); + token[0xcd] = write2(0xcd); + token[0xce] = write4(0xce); + token[0xcf] = writeN(0xcf, 8, writeUInt64BE); + + // int 8 -- 0xd0 + // int 16 -- 0xd1 + // int 32 -- 0xd2 + // int 64 -- 0xd3 + token[0xd0] = write1(0xd0); + token[0xd1] = write2(0xd1); + token[0xd2] = write4(0xd2); + token[0xd3] = writeN(0xd3, 8, writeInt64BE); + + // str 8 -- 0xd9 + // str 16 -- 0xda + // str 32 -- 0xdb + token[0xd9] = write1(0xd9); + token[0xda] = write2(0xda); + token[0xdb] = write4(0xdb); + + // array 16 -- 0xdc + // array 32 -- 0xdd + token[0xdc] = write2(0xdc); + token[0xdd] = write4(0xdd); + + // map 16 -- 0xde + // map 32 -- 0xdf + token[0xde] = write2(0xde); + token[0xdf] = write4(0xdf); + + return token; +} + +// safe mode: for old browsers and who needs asserts + +function init_safe() { + // (immediate values) + // positive fixint -- 0x00 - 0x7f + // nil -- 0xc0 + // false -- 0xc2 + // true -- 0xc3 + // negative fixint -- 0xe0 - 0xff + var token = uint8.slice(); + + // bin 8 -- 0xc4 + // bin 16 -- 0xc5 + // bin 32 -- 0xc6 + token[0xc4] = writeN(0xc4, 1, Buffer.prototype.writeUInt8); + token[0xc5] = writeN(0xc5, 2, Buffer.prototype.writeUInt16BE); + token[0xc6] = writeN(0xc6, 4, Buffer.prototype.writeUInt32BE); + + // ext 8 -- 0xc7 + // ext 16 -- 0xc8 + // ext 32 -- 0xc9 + token[0xc7] = writeN(0xc7, 1, Buffer.prototype.writeUInt8); + token[0xc8] = writeN(0xc8, 2, Buffer.prototype.writeUInt16BE); + token[0xc9] = writeN(0xc9, 4, Buffer.prototype.writeUInt32BE); + + // float 32 -- 0xca + // float 64 -- 0xcb + token[0xca] = writeN(0xca, 4, Buffer.prototype.writeFloatBE); + token[0xcb] = writeN(0xcb, 8, Buffer.prototype.writeDoubleBE); + + // uint 8 -- 0xcc + // uint 16 -- 0xcd + // uint 32 -- 0xce + // uint 64 -- 0xcf + token[0xcc] = writeN(0xcc, 1, Buffer.prototype.writeUInt8); + token[0xcd] = writeN(0xcd, 2, Buffer.prototype.writeUInt16BE); + token[0xce] = writeN(0xce, 4, Buffer.prototype.writeUInt32BE); + token[0xcf] = writeN(0xcf, 8, writeUInt64BE); + + // int 8 -- 0xd0 + // int 16 -- 0xd1 + // int 32 -- 0xd2 + // int 64 -- 0xd3 + token[0xd0] = writeN(0xd0, 1, Buffer.prototype.writeInt8); + token[0xd1] = writeN(0xd1, 2, Buffer.prototype.writeInt16BE); + token[0xd2] = writeN(0xd2, 4, Buffer.prototype.writeInt32BE); + token[0xd3] = writeN(0xd3, 8, writeInt64BE); + + // str 8 -- 0xd9 + // str 16 -- 0xda + // str 32 -- 0xdb + token[0xd9] = writeN(0xd9, 1, Buffer.prototype.writeUInt8); + token[0xda] = writeN(0xda, 2, Buffer.prototype.writeUInt16BE); + token[0xdb] = writeN(0xdb, 4, Buffer.prototype.writeUInt32BE); + + // array 16 -- 0xdc + // array 32 -- 0xdd + token[0xdc] = writeN(0xdc, 2, Buffer.prototype.writeUInt16BE); + token[0xdd] = writeN(0xdd, 4, Buffer.prototype.writeUInt32BE); + + // map 16 -- 0xde + // map 32 -- 0xdf + token[0xde] = writeN(0xde, 2, Buffer.prototype.writeUInt16BE); + token[0xdf] = writeN(0xdf, 4, Buffer.prototype.writeUInt32BE); + + return token; +} + +function write1(type) { + return function(encoder, value) { + var offset = encoder.reserve(2); + var buffer = encoder.buffer; + buffer[offset++] = type; + buffer[offset] = value; + }; +} + +function write2(type) { + return function(encoder, value) { + var offset = encoder.reserve(3); + var buffer = encoder.buffer; + buffer[offset++] = type; + buffer[offset++] = value >>> 8; + buffer[offset] = value; + }; +} + +function write4(type) { + return function(encoder, value) { + var offset = encoder.reserve(5); + var buffer = encoder.buffer; + buffer[offset++] = type; + buffer[offset++] = value >>> 24; + buffer[offset++] = value >>> 16; + buffer[offset++] = value >>> 8; + buffer[offset] = value; + }; +} + +function writeN(type, len, method, noAssert) { + return function(encoder, value) { + var offset = encoder.reserve(len + 1); + encoder.buffer[offset++] = type; + method.call(encoder.buffer, value, offset, noAssert); + }; +} + +function writeUInt64BE(value, offset) { + new Uint64BE(this, offset, value); +} + +function writeInt64BE(value, offset) { + new Int64BE(this, offset, value); +} + +function writeFloatBE(value, offset) { + ieee754.write(this, value, offset, false, 23, 4); +} + +function writeDoubleBE(value, offset) { + ieee754.write(this, value, offset, false, 52, 8); +} + + +/***/ }), +/* 26 */ +/***/ (function(module, exports) { + +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = (nBytes * 8) - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = (nBytes * 8) - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + + value = Math.abs(value) + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } + + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = ((value * c) - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128 +} + + +/***/ }), +/* 27 */ +/***/ (function(module, exports) { + +// write-unit8.js + +var constant = exports.uint8 = new Array(256); + +for (var i = 0x00; i <= 0xFF; i++) { + constant[i] = write0(i); +} + +function write0(type) { + return function(encoder) { + var offset = encoder.reserve(1); + encoder.buffer[offset] = type; + }; +} + + +/***/ }), +/* 28 */ +/***/ (function(module, exports, __webpack_require__) { + +// codec-base.js + +var IS_ARRAY = __webpack_require__(16); + +exports.createCodec = createCodec; +exports.install = install; +exports.filter = filter; + +var Bufferish = __webpack_require__(14); + +function Codec(options) { + if (!(this instanceof Codec)) return new Codec(options); + this.options = options; + this.init(); +} + +Codec.prototype.init = function() { + var options = this.options; + + if (options && options.uint8array) { + this.bufferish = Bufferish.Uint8Array; + } + + return this; +}; + +function install(props) { + for (var key in props) { + Codec.prototype[key] = add(Codec.prototype[key], props[key]); + } +} + +function add(a, b) { + return (a && b) ? ab : (a || b); + + function ab() { + a.apply(this, arguments); + return b.apply(this, arguments); + } +} + +function join(filters) { + filters = filters.slice(); + + return function(value) { + return filters.reduce(iterator, value); + }; + + function iterator(value, filter) { + return filter(value); + } +} + +function filter(filter) { + return IS_ARRAY(filter) ? join(filter) : filter; +} + +// @public +// msgpack.createCodec() + +function createCodec(options) { + return new Codec(options); +} + +// default shared codec + +exports.preset = createCodec({preset: true}); + + +/***/ }), +/* 29 */ +/***/ (function(module, exports, __webpack_require__) { + +// flex-buffer.js + +exports.FlexDecoder = FlexDecoder; +exports.FlexEncoder = FlexEncoder; + +var Bufferish = __webpack_require__(14); + +var MIN_BUFFER_SIZE = 2048; +var MAX_BUFFER_SIZE = 65536; +var BUFFER_SHORTAGE = "BUFFER_SHORTAGE"; + +function FlexDecoder() { + if (!(this instanceof FlexDecoder)) return new FlexDecoder(); +} + +function FlexEncoder() { + if (!(this instanceof FlexEncoder)) return new FlexEncoder(); +} + +FlexDecoder.mixin = mixinFactory(getDecoderMethods()); +FlexDecoder.mixin(FlexDecoder.prototype); + +FlexEncoder.mixin = mixinFactory(getEncoderMethods()); +FlexEncoder.mixin(FlexEncoder.prototype); + +function getDecoderMethods() { + return { + bufferish: Bufferish, + write: write, + fetch: fetch, + flush: flush, + push: push, + pull: pull, + read: read, + reserve: reserve, + offset: 0 + }; + + function write(chunk) { + var prev = this.offset ? Bufferish.prototype.slice.call(this.buffer, this.offset) : this.buffer; + this.buffer = prev ? (chunk ? this.bufferish.concat([prev, chunk]) : prev) : chunk; + this.offset = 0; + } + + function flush() { + while (this.offset < this.buffer.length) { + var start = this.offset; + var value; + try { + value = this.fetch(); + } catch (e) { + if (e && e.message != BUFFER_SHORTAGE) throw e; + // rollback + this.offset = start; + break; + } + this.push(value); + } + } + + function reserve(length) { + var start = this.offset; + var end = start + length; + if (end > this.buffer.length) throw new Error(BUFFER_SHORTAGE); + this.offset = end; + return start; + } +} + +function getEncoderMethods() { + return { + bufferish: Bufferish, + write: write, + fetch: fetch, + flush: flush, + push: push, + pull: pull, + read: read, + reserve: reserve, + send: send, + maxBufferSize: MAX_BUFFER_SIZE, + minBufferSize: MIN_BUFFER_SIZE, + offset: 0, + start: 0 + }; + + function fetch() { + var start = this.start; + if (start < this.offset) { + var end = this.start = this.offset; + return Bufferish.prototype.slice.call(this.buffer, start, end); + } + } + + function flush() { + while (this.start < this.offset) { + var value = this.fetch(); + if (value) this.push(value); + } + } + + function pull() { + var buffers = this.buffers || (this.buffers = []); + var chunk = buffers.length > 1 ? this.bufferish.concat(buffers) : buffers[0]; + buffers.length = 0; // buffer exhausted + return chunk; + } + + function reserve(length) { + var req = length | 0; + + if (this.buffer) { + var size = this.buffer.length; + var start = this.offset | 0; + var end = start + req; + + // is it long enough? + if (end < size) { + this.offset = end; + return start; + } + + // flush current buffer + this.flush(); + + // resize it to 2x current length + length = Math.max(length, Math.min(size * 2, this.maxBufferSize)); + } + + // minimum buffer size + length = Math.max(length, this.minBufferSize); + + // allocate new buffer + this.buffer = this.bufferish.alloc(length); + this.start = 0; + this.offset = req; + return 0; + } + + function send(buffer) { + var length = buffer.length; + if (length > this.minBufferSize) { + this.flush(); + this.push(buffer); + } else { + var offset = this.reserve(length); + Bufferish.prototype.copy.call(buffer, this.buffer, offset); + } + } +} + +// common methods + +function write() { + throw new Error("method not implemented: write()"); +} + +function fetch() { + throw new Error("method not implemented: fetch()"); +} + +function read() { + var length = this.buffers && this.buffers.length; + + // fetch the first result + if (!length) return this.fetch(); + + // flush current buffer + this.flush(); + + // read from the results + return this.pull(); +} + +function push(chunk) { + var buffers = this.buffers || (this.buffers = []); + buffers.push(chunk); +} + +function pull() { + var buffers = this.buffers || (this.buffers = []); + return buffers.shift(); +} + +function mixinFactory(source) { + return mixin; + + function mixin(target) { + for (var key in source) { + target[key] = source[key]; + } + return target; + } +} + + +/***/ }), +/* 30 */ +/***/ (function(module, exports, __webpack_require__) { + +// decode.js + +exports.decode = decode; + +var DecodeBuffer = __webpack_require__(31).DecodeBuffer; + +function decode(input, options) { + var decoder = new DecodeBuffer(options); + decoder.write(input); + return decoder.read(); +} + +/***/ }), +/* 31 */ +/***/ (function(module, exports, __webpack_require__) { + +// decode-buffer.js + +exports.DecodeBuffer = DecodeBuffer; + +var preset = __webpack_require__(32).preset; + +var FlexDecoder = __webpack_require__(29).FlexDecoder; + +FlexDecoder.mixin(DecodeBuffer.prototype); + +function DecodeBuffer(options) { + if (!(this instanceof DecodeBuffer)) return new DecodeBuffer(options); + + if (options) { + this.options = options; + if (options.codec) { + var codec = this.codec = options.codec; + if (codec.bufferish) this.bufferish = codec.bufferish; + } + } +} + +DecodeBuffer.prototype.codec = preset; + +DecodeBuffer.prototype.fetch = function() { + return this.codec.decode(this); +}; + + +/***/ }), +/* 32 */ +/***/ (function(module, exports, __webpack_require__) { + +// read-core.js + +var ExtBuffer = __webpack_require__(13).ExtBuffer; +var ExtUnpacker = __webpack_require__(33); +var readUint8 = __webpack_require__(34).readUint8; +var ReadToken = __webpack_require__(35); +var CodecBase = __webpack_require__(28); + +CodecBase.install({ + addExtUnpacker: addExtUnpacker, + getExtUnpacker: getExtUnpacker, + init: init +}); + +exports.preset = init.call(CodecBase.preset); + +function getDecoder(options) { + var readToken = ReadToken.getReadToken(options); + return decode; + + function decode(decoder) { + var type = readUint8(decoder); + var func = readToken[type]; + if (!func) throw new Error("Invalid type: " + (type ? ("0x" + type.toString(16)) : type)); + return func(decoder); + } +} + +function init() { + var options = this.options; + this.decode = getDecoder(options); + + if (options && options.preset) { + ExtUnpacker.setExtUnpackers(this); + } + + return this; +} + +function addExtUnpacker(etype, unpacker) { + var unpackers = this.extUnpackers || (this.extUnpackers = []); + unpackers[etype] = CodecBase.filter(unpacker); +} + +function getExtUnpacker(type) { + var unpackers = this.extUnpackers || (this.extUnpackers = []); + return unpackers[type] || extUnpacker; + + function extUnpacker(buffer) { + return new ExtBuffer(buffer, type); + } +} + + +/***/ }), +/* 33 */ +/***/ (function(module, exports, __webpack_require__) { + +// ext-unpacker.js + +exports.setExtUnpackers = setExtUnpackers; + +var Bufferish = __webpack_require__(14); +var Buffer = Bufferish.global; +var _decode; + +var ERROR_COLUMNS = {name: 1, message: 1, stack: 1, columnNumber: 1, fileName: 1, lineNumber: 1}; + +function setExtUnpackers(codec) { + codec.addExtUnpacker(0x0E, [decode, unpackError(Error)]); + codec.addExtUnpacker(0x01, [decode, unpackError(EvalError)]); + codec.addExtUnpacker(0x02, [decode, unpackError(RangeError)]); + codec.addExtUnpacker(0x03, [decode, unpackError(ReferenceError)]); + codec.addExtUnpacker(0x04, [decode, unpackError(SyntaxError)]); + codec.addExtUnpacker(0x05, [decode, unpackError(TypeError)]); + codec.addExtUnpacker(0x06, [decode, unpackError(URIError)]); + + codec.addExtUnpacker(0x0A, [decode, unpackRegExp]); + codec.addExtUnpacker(0x0B, [decode, unpackClass(Boolean)]); + codec.addExtUnpacker(0x0C, [decode, unpackClass(String)]); + codec.addExtUnpacker(0x0D, [decode, unpackClass(Date)]); + codec.addExtUnpacker(0x0F, [decode, unpackClass(Number)]); + + if ("undefined" !== typeof Uint8Array) { + codec.addExtUnpacker(0x11, unpackClass(Int8Array)); + codec.addExtUnpacker(0x12, unpackClass(Uint8Array)); + codec.addExtUnpacker(0x13, [unpackArrayBuffer, unpackClass(Int16Array)]); + codec.addExtUnpacker(0x14, [unpackArrayBuffer, unpackClass(Uint16Array)]); + codec.addExtUnpacker(0x15, [unpackArrayBuffer, unpackClass(Int32Array)]); + codec.addExtUnpacker(0x16, [unpackArrayBuffer, unpackClass(Uint32Array)]); + codec.addExtUnpacker(0x17, [unpackArrayBuffer, unpackClass(Float32Array)]); + + // PhantomJS/1.9.7 doesn't have Float64Array + if ("undefined" !== typeof Float64Array) { + codec.addExtUnpacker(0x18, [unpackArrayBuffer, unpackClass(Float64Array)]); + } + + // IE10 doesn't have Uint8ClampedArray + if ("undefined" !== typeof Uint8ClampedArray) { + codec.addExtUnpacker(0x19, unpackClass(Uint8ClampedArray)); + } + + codec.addExtUnpacker(0x1A, unpackArrayBuffer); + codec.addExtUnpacker(0x1D, [unpackArrayBuffer, unpackClass(DataView)]); + } + + if (Bufferish.hasBuffer) { + codec.addExtUnpacker(0x1B, unpackClass(Buffer)); + } +} + +function decode(input) { + if (!_decode) _decode = __webpack_require__(30).decode; // lazy load + return _decode(input); +} + +function unpackRegExp(value) { + return RegExp.apply(null, value); +} + +function unpackError(Class) { + return function(value) { + var out = new Class(); + for (var key in ERROR_COLUMNS) { + out[key] = value[key]; + } + return out; + }; +} + +function unpackClass(Class) { + return function(value) { + return new Class(value); + }; +} + +function unpackArrayBuffer(value) { + return (new Uint8Array(value)).buffer; +} + + +/***/ }), +/* 34 */ +/***/ (function(module, exports, __webpack_require__) { + +// read-format.js + +var ieee754 = __webpack_require__(26); +var Int64Buffer = __webpack_require__(24); +var Uint64BE = Int64Buffer.Uint64BE; +var Int64BE = Int64Buffer.Int64BE; + +exports.getReadFormat = getReadFormat; +exports.readUint8 = uint8; + +var Bufferish = __webpack_require__(14); +var BufferProto = __webpack_require__(20); + +var HAS_MAP = ("undefined" !== typeof Map); +var NO_ASSERT = true; + +function getReadFormat(options) { + var binarraybuffer = Bufferish.hasArrayBuffer && options && options.binarraybuffer; + var int64 = options && options.int64; + var usemap = HAS_MAP && options && options.usemap; + + var readFormat = { + map: (usemap ? map_to_map : map_to_obj), + array: array, + str: str, + bin: (binarraybuffer ? bin_arraybuffer : bin_buffer), + ext: ext, + uint8: uint8, + uint16: uint16, + uint32: uint32, + uint64: read(8, int64 ? readUInt64BE_int64 : readUInt64BE), + int8: int8, + int16: int16, + int32: int32, + int64: read(8, int64 ? readInt64BE_int64 : readInt64BE), + float32: read(4, readFloatBE), + float64: read(8, readDoubleBE) + }; + + return readFormat; +} + +function map_to_obj(decoder, len) { + var value = {}; + var i; + var k = new Array(len); + var v = new Array(len); + + var decode = decoder.codec.decode; + for (i = 0; i < len; i++) { + k[i] = decode(decoder); + v[i] = decode(decoder); + } + for (i = 0; i < len; i++) { + value[k[i]] = v[i]; + } + return value; +} + +function map_to_map(decoder, len) { + var value = new Map(); + var i; + var k = new Array(len); + var v = new Array(len); + + var decode = decoder.codec.decode; + for (i = 0; i < len; i++) { + k[i] = decode(decoder); + v[i] = decode(decoder); + } + for (i = 0; i < len; i++) { + value.set(k[i], v[i]); + } + return value; +} + +function array(decoder, len) { + var value = new Array(len); + var decode = decoder.codec.decode; + for (var i = 0; i < len; i++) { + value[i] = decode(decoder); + } + return value; +} + +function str(decoder, len) { + var start = decoder.reserve(len); + var end = start + len; + return BufferProto.toString.call(decoder.buffer, "utf-8", start, end); +} + +function bin_buffer(decoder, len) { + var start = decoder.reserve(len); + var end = start + len; + var buf = BufferProto.slice.call(decoder.buffer, start, end); + return Bufferish.from(buf); +} + +function bin_arraybuffer(decoder, len) { + var start = decoder.reserve(len); + var end = start + len; + var buf = BufferProto.slice.call(decoder.buffer, start, end); + return Bufferish.Uint8Array.from(buf).buffer; +} + +function ext(decoder, len) { + var start = decoder.reserve(len+1); + var type = decoder.buffer[start++]; + var end = start + len; + var unpack = decoder.codec.getExtUnpacker(type); + if (!unpack) throw new Error("Invalid ext type: " + (type ? ("0x" + type.toString(16)) : type)); + var buf = BufferProto.slice.call(decoder.buffer, start, end); + return unpack(buf); +} + +function uint8(decoder) { + var start = decoder.reserve(1); + return decoder.buffer[start]; +} + +function int8(decoder) { + var start = decoder.reserve(1); + var value = decoder.buffer[start]; + return (value & 0x80) ? value - 0x100 : value; +} + +function uint16(decoder) { + var start = decoder.reserve(2); + var buffer = decoder.buffer; + return (buffer[start++] << 8) | buffer[start]; +} + +function int16(decoder) { + var start = decoder.reserve(2); + var buffer = decoder.buffer; + var value = (buffer[start++] << 8) | buffer[start]; + return (value & 0x8000) ? value - 0x10000 : value; +} + +function uint32(decoder) { + var start = decoder.reserve(4); + var buffer = decoder.buffer; + return (buffer[start++] * 16777216) + (buffer[start++] << 16) + (buffer[start++] << 8) + buffer[start]; +} + +function int32(decoder) { + var start = decoder.reserve(4); + var buffer = decoder.buffer; + return (buffer[start++] << 24) | (buffer[start++] << 16) | (buffer[start++] << 8) | buffer[start]; +} + +function read(len, method) { + return function(decoder) { + var start = decoder.reserve(len); + return method.call(decoder.buffer, start, NO_ASSERT); + }; +} + +function readUInt64BE(start) { + return new Uint64BE(this, start).toNumber(); +} + +function readInt64BE(start) { + return new Int64BE(this, start).toNumber(); +} + +function readUInt64BE_int64(start) { + return new Uint64BE(this, start); +} + +function readInt64BE_int64(start) { + return new Int64BE(this, start); +} + +function readFloatBE(start) { + return ieee754.read(this, start, false, 23, 4); +} + +function readDoubleBE(start) { + return ieee754.read(this, start, false, 52, 8); +} + +/***/ }), +/* 35 */ +/***/ (function(module, exports, __webpack_require__) { + +// read-token.js + +var ReadFormat = __webpack_require__(34); + +exports.getReadToken = getReadToken; + +function getReadToken(options) { + var format = ReadFormat.getReadFormat(options); + + if (options && options.useraw) { + return init_useraw(format); + } else { + return init_token(format); + } +} + +function init_token(format) { + var i; + var token = new Array(256); + + // positive fixint -- 0x00 - 0x7f + for (i = 0x00; i <= 0x7f; i++) { + token[i] = constant(i); + } + + // fixmap -- 0x80 - 0x8f + for (i = 0x80; i <= 0x8f; i++) { + token[i] = fix(i - 0x80, format.map); + } + + // fixarray -- 0x90 - 0x9f + for (i = 0x90; i <= 0x9f; i++) { + token[i] = fix(i - 0x90, format.array); + } + + // fixstr -- 0xa0 - 0xbf + for (i = 0xa0; i <= 0xbf; i++) { + token[i] = fix(i - 0xa0, format.str); + } + + // nil -- 0xc0 + token[0xc0] = constant(null); + + // (never used) -- 0xc1 + token[0xc1] = null; + + // false -- 0xc2 + // true -- 0xc3 + token[0xc2] = constant(false); + token[0xc3] = constant(true); + + // bin 8 -- 0xc4 + // bin 16 -- 0xc5 + // bin 32 -- 0xc6 + token[0xc4] = flex(format.uint8, format.bin); + token[0xc5] = flex(format.uint16, format.bin); + token[0xc6] = flex(format.uint32, format.bin); + + // ext 8 -- 0xc7 + // ext 16 -- 0xc8 + // ext 32 -- 0xc9 + token[0xc7] = flex(format.uint8, format.ext); + token[0xc8] = flex(format.uint16, format.ext); + token[0xc9] = flex(format.uint32, format.ext); + + // float 32 -- 0xca + // float 64 -- 0xcb + token[0xca] = format.float32; + token[0xcb] = format.float64; + + // uint 8 -- 0xcc + // uint 16 -- 0xcd + // uint 32 -- 0xce + // uint 64 -- 0xcf + token[0xcc] = format.uint8; + token[0xcd] = format.uint16; + token[0xce] = format.uint32; + token[0xcf] = format.uint64; + + // int 8 -- 0xd0 + // int 16 -- 0xd1 + // int 32 -- 0xd2 + // int 64 -- 0xd3 + token[0xd0] = format.int8; + token[0xd1] = format.int16; + token[0xd2] = format.int32; + token[0xd3] = format.int64; + + // fixext 1 -- 0xd4 + // fixext 2 -- 0xd5 + // fixext 4 -- 0xd6 + // fixext 8 -- 0xd7 + // fixext 16 -- 0xd8 + token[0xd4] = fix(1, format.ext); + token[0xd5] = fix(2, format.ext); + token[0xd6] = fix(4, format.ext); + token[0xd7] = fix(8, format.ext); + token[0xd8] = fix(16, format.ext); + + // str 8 -- 0xd9 + // str 16 -- 0xda + // str 32 -- 0xdb + token[0xd9] = flex(format.uint8, format.str); + token[0xda] = flex(format.uint16, format.str); + token[0xdb] = flex(format.uint32, format.str); + + // array 16 -- 0xdc + // array 32 -- 0xdd + token[0xdc] = flex(format.uint16, format.array); + token[0xdd] = flex(format.uint32, format.array); + + // map 16 -- 0xde + // map 32 -- 0xdf + token[0xde] = flex(format.uint16, format.map); + token[0xdf] = flex(format.uint32, format.map); + + // negative fixint -- 0xe0 - 0xff + for (i = 0xe0; i <= 0xff; i++) { + token[i] = constant(i - 0x100); + } + + return token; +} + +function init_useraw(format) { + var i; + var token = init_token(format).slice(); + + // raw 8 -- 0xd9 + // raw 16 -- 0xda + // raw 32 -- 0xdb + token[0xd9] = token[0xc4]; + token[0xda] = token[0xc5]; + token[0xdb] = token[0xc6]; + + // fixraw -- 0xa0 - 0xbf + for (i = 0xa0; i <= 0xbf; i++) { + token[i] = fix(i - 0xa0, format.bin); + } + + return token; +} + +function constant(value) { + return function() { + return value; + }; +} + +function flex(lenFunc, decodeFunc) { + return function(decoder) { + var len = lenFunc(decoder); + return decodeFunc(decoder, len); + }; +} + +function fix(len, method) { + return function(decoder) { + return method(decoder, len); + }; +} + + +/***/ }), +/* 36 */ +/***/ (function(module, exports, __webpack_require__) { + +// encoder.js + +exports.Encoder = Encoder; + +var EventLite = __webpack_require__(37); +var EncodeBuffer = __webpack_require__(11).EncodeBuffer; + +function Encoder(options) { + if (!(this instanceof Encoder)) return new Encoder(options); + EncodeBuffer.call(this, options); +} + +Encoder.prototype = new EncodeBuffer(); + +EventLite.mixin(Encoder.prototype); + +Encoder.prototype.encode = function(chunk) { + this.write(chunk); + this.emit("data", this.read()); +}; + +Encoder.prototype.end = function(chunk) { + if (arguments.length) this.encode(chunk); + this.flush(); + this.emit("end"); +}; + + +/***/ }), +/* 37 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * event-lite.js - Light-weight EventEmitter (less than 1KB when gzipped) + * + * @copyright Yusuke Kawasaki + * @license MIT + * @constructor + * @see https://github.com/kawanet/event-lite + * @see http://kawanet.github.io/event-lite/EventLite.html + * @example + * var EventLite = require("event-lite"); + * + * function MyClass() {...} // your class + * + * EventLite.mixin(MyClass.prototype); // import event methods + * + * var obj = new MyClass(); + * obj.on("foo", function() {...}); // add event listener + * obj.once("bar", function() {...}); // add one-time event listener + * obj.emit("foo"); // dispatch event + * obj.emit("bar"); // dispatch another event + * obj.off("foo"); // remove event listener + */ + +function EventLite() { + if (!(this instanceof EventLite)) return new EventLite(); +} + +(function(EventLite) { + // export the class for node.js + if (true) module.exports = EventLite; + + // property name to hold listeners + var LISTENERS = "listeners"; + + // methods to export + var methods = { + on: on, + once: once, + off: off, + emit: emit + }; + + // mixin to self + mixin(EventLite.prototype); + + // export mixin function + EventLite.mixin = mixin; + + /** + * Import on(), once(), off() and emit() methods into target object. + * + * @function EventLite.mixin + * @param target {Prototype} + */ + + function mixin(target) { + for (var key in methods) { + target[key] = methods[key]; + } + return target; + } + + /** + * Add an event listener. + * + * @function EventLite.prototype.on + * @param type {string} + * @param func {Function} + * @returns {EventLite} Self for method chaining + */ + + function on(type, func) { + getListeners(this, type).push(func); + return this; + } + + /** + * Add one-time event listener. + * + * @function EventLite.prototype.once + * @param type {string} + * @param func {Function} + * @returns {EventLite} Self for method chaining + */ + + function once(type, func) { + var that = this; + wrap.originalListener = func; + getListeners(that, type).push(wrap); + return that; + + function wrap() { + off.call(that, type, wrap); + func.apply(this, arguments); + } + } + + /** + * Remove an event listener. + * + * @function EventLite.prototype.off + * @param [type] {string} + * @param [func] {Function} + * @returns {EventLite} Self for method chaining + */ + + function off(type, func) { + var that = this; + var listners; + if (!arguments.length) { + delete that[LISTENERS]; + } else if (!func) { + listners = that[LISTENERS]; + if (listners) { + delete listners[type]; + if (!Object.keys(listners).length) return off.call(that); + } + } else { + listners = getListeners(that, type, true); + if (listners) { + listners = listners.filter(ne); + if (!listners.length) return off.call(that, type); + that[LISTENERS][type] = listners; + } + } + return that; + + function ne(test) { + return test !== func && test.originalListener !== func; + } + } + + /** + * Dispatch (trigger) an event. + * + * @function EventLite.prototype.emit + * @param type {string} + * @param [value] {*} + * @returns {boolean} True when a listener received the event + */ + + function emit(type, value) { + var that = this; + var listeners = getListeners(that, type, true); + if (!listeners) return false; + var arglen = arguments.length; + if (arglen === 1) { + listeners.forEach(zeroarg); + } else if (arglen === 2) { + listeners.forEach(onearg); + } else { + var args = Array.prototype.slice.call(arguments, 1); + listeners.forEach(moreargs); + } + return !!listeners.length; + + function zeroarg(func) { + func.call(that); + } + + function onearg(func) { + func.call(that, value); + } + + function moreargs(func) { + func.apply(that, args); + } + } + + /** + * @ignore + */ + + function getListeners(that, type, readonly) { + if (readonly && !that[LISTENERS]) return; + var listeners = that[LISTENERS] || (that[LISTENERS] = {}); + return listeners[type] || (listeners[type] = []); + } + +})(EventLite); + + +/***/ }), +/* 38 */ +/***/ (function(module, exports, __webpack_require__) { + +// decoder.js + +exports.Decoder = Decoder; + +var EventLite = __webpack_require__(37); +var DecodeBuffer = __webpack_require__(31).DecodeBuffer; + +function Decoder(options) { + if (!(this instanceof Decoder)) return new Decoder(options); + DecodeBuffer.call(this, options); +} + +Decoder.prototype = new DecodeBuffer(); + +EventLite.mixin(Decoder.prototype); + +Decoder.prototype.decode = function(chunk) { + if (arguments.length) this.write(chunk); + this.flush(); +}; + +Decoder.prototype.push = function(chunk) { + this.emit("data", chunk); +}; + +Decoder.prototype.end = function(chunk) { + this.decode(chunk); + this.emit("end"); +}; + + +/***/ }), +/* 39 */ +/***/ (function(module, exports, __webpack_require__) { + +// encode-stream.js + +exports.createEncodeStream = EncodeStream; + +var util = __webpack_require__(40); +var Transform = __webpack_require__(41).Transform; +var EncodeBuffer = __webpack_require__(11).EncodeBuffer; + +util.inherits(EncodeStream, Transform); + +var DEFAULT_OPTIONS = {objectMode: true}; + +function EncodeStream(options) { + if (!(this instanceof EncodeStream)) return new EncodeStream(options); + if (options) { + options.objectMode = true; + } else { + options = DEFAULT_OPTIONS; + } + Transform.call(this, options); + + var stream = this; + var encoder = this.encoder = new EncodeBuffer(options); + encoder.push = function(chunk) { + stream.push(chunk); + }; +} + +EncodeStream.prototype._transform = function(chunk, encoding, callback) { + this.encoder.write(chunk); + if (callback) callback(); +}; + +EncodeStream.prototype._flush = function(callback) { + this.encoder.flush(); + if (callback) callback(); +}; + + +/***/ }), +/* 40 */ +/***/ (function(module, exports) { + +module.exports = require("util"); + +/***/ }), +/* 41 */ +/***/ (function(module, exports) { + +module.exports = require("stream"); + +/***/ }), +/* 42 */ +/***/ (function(module, exports, __webpack_require__) { + +// decode-stream.js + +exports.createDecodeStream = DecodeStream; + +var util = __webpack_require__(40); +var Transform = __webpack_require__(41).Transform; +var DecodeBuffer = __webpack_require__(31).DecodeBuffer; + +util.inherits(DecodeStream, Transform); + +var DEFAULT_OPTIONS = {objectMode: true}; + +function DecodeStream(options) { + if (!(this instanceof DecodeStream)) return new DecodeStream(options); + if (options) { + options.objectMode = true; + } else { + options = DEFAULT_OPTIONS; + } + Transform.call(this, options); + var stream = this; + var decoder = this.decoder = new DecodeBuffer(options); + decoder.push = function(chunk) { + stream.push(chunk); + }; +} + +DecodeStream.prototype._transform = function(chunk, encoding, callback) { + this.decoder.write(chunk); + this.decoder.flush(); + if (callback) callback(); +}; + + +/***/ }), +/* 43 */ +/***/ (function(module, exports, __webpack_require__) { + +// ext.js + +// load both interfaces +__webpack_require__(32); +__webpack_require__(12); + +exports.createCodec = __webpack_require__(28).createCodec; + + +/***/ }), +/* 44 */ +/***/ (function(module, exports, __webpack_require__) { + +// codec.js + +// load both interfaces +__webpack_require__(32); +__webpack_require__(12); + +// @public +// msgpack.codec.preset + +exports.codec = { + preset: __webpack_require__(28).preset +}; + + +/***/ }), +/* 45 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = __webpack_require__(41); +class Buffered extends stream_1.Transform { + constructor() { + super({ + readableHighWaterMark: 10 * 1024 * 1024, + writableHighWaterMark: 10 * 1024 * 1024, + }); + this.chunks = null; + this.timer = null; + } + sendData() { + const { chunks } = this; + if (chunks) { + this.chunks = null; + const buf = Buffer.concat(chunks); + this.push(buf); + } + } + // eslint-disable-next-line consistent-return + _transform(chunk, _encoding, callback) { + const { chunks, timer } = this; + const MIN_SIZE = Buffer.poolSize; + if (timer) + clearTimeout(timer); + if (chunk.length < MIN_SIZE) { + if (!chunks) + return callback(null, chunk); + chunks.push(chunk); + this.sendData(); + callback(); + } + else { + if (!chunks) { + this.chunks = [chunk]; + } + else { + chunks.push(chunk); + } + this.timer = setTimeout(this.sendData.bind(this), 20); + callback(); + } + } + _flush(callback) { + const { chunks } = this; + if (chunks) { + this.chunks = null; + const buf = Buffer.concat(chunks); + callback(null, buf); + } + else { + callback(); + } + } +} +exports.default = Buffered; + + +/***/ }), +/* 46 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const Buffer_1 = __webpack_require__(47); +const Window_1 = __webpack_require__(50); +const Tabpage_1 = __webpack_require__(52); +var ExtType; +(function (ExtType) { + ExtType[ExtType["Buffer"] = 0] = "Buffer"; + ExtType[ExtType["Window"] = 1] = "Window"; + ExtType[ExtType["Tabpage"] = 2] = "Tabpage"; +})(ExtType = exports.ExtType || (exports.ExtType = {})); +exports.Metadata = [ + { + constructor: Buffer_1.Buffer, + name: 'Buffer', + prefix: 'nvim_buf_', + }, + { + constructor: Window_1.Window, + name: 'Window', + prefix: 'nvim_win_', + }, + { + constructor: Tabpage_1.Tabpage, + name: 'Tabpage', + prefix: 'nvim_tabpage_', + }, +]; + + +/***/ }), +/* 47 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const Base_1 = __webpack_require__(48); +const client_1 = __webpack_require__(7); +class Buffer extends Base_1.BaseApi { + constructor() { + super(...arguments); + this.prefix = 'nvim_buf_'; + } + get isAttached() { + return this.client.isAttached(this.id); + } + /** + * Attach to buffer to listen to buffer events + * @param sendBuffer Set to true if the initial notification should contain + * the whole buffer. If so, the first notification will be a + * `nvim_buf_lines_event`. Otherwise, the first notification will be + * a `nvim_buf_changedtick_event` + */ + attach(sendBuffer = false, options = {}) { + return __awaiter(this, void 0, void 0, function* () { + if (this.isAttached) + return true; + let res = false; + try { + res = yield this.request(`${this.prefix}attach`, [sendBuffer, options]); + } + catch (e) { + res = false; + } + if (res) { + this.client[client_1.ATTACH_BUFFER](this); + } + return this.isAttached; + }); + } + /** + * Detach from buffer to stop listening to buffer events + */ + detach() { + return __awaiter(this, void 0, void 0, function* () { + this.client[client_1.DETACH_BUFFER](this); + try { + yield this.request(`${this.prefix}detach`, []); + } + catch (e) { + // noop + } + }); + } + /** + * Get the bufnr of Buffer + */ + get id() { + return this.data; + } + /** Total number of lines in buffer */ + get length() { + return this.request(`${this.prefix}line_count`, []); + } + /** Get lines in buffer */ + get lines() { + return this.getLines(); + } + /** Gets a changed tick of a buffer */ + get changedtick() { + return this.request(`${this.prefix}get_changedtick`, []); + } + get commands() { + return this.getCommands(); + } + getCommands(options = {}) { + return this.request(`${this.prefix}get_commands`, [options]); + } + /** Get specific lines of buffer */ + getLines({ start, end, strictIndexing } = { start: 0, end: -1, strictIndexing: true }) { + const indexing = typeof strictIndexing === 'undefined' ? true : strictIndexing; + return this.request(`${this.prefix}get_lines`, [ + start, + end, + indexing, + ]); + } + /** Set lines of buffer given indeces */ + setLines(_lines, { start: _start, end: _end, strictIndexing } = { + strictIndexing: true, + }, notify = false) { + // TODO: Error checking + // if (typeof start === 'undefined' || typeof end === 'undefined') { + // } + const indexing = typeof strictIndexing === 'undefined' ? true : strictIndexing; + const lines = typeof _lines === 'string' ? [_lines] : _lines; + const end = typeof _end !== 'undefined' ? _end : _start + 1; + const method = notify ? 'notify' : 'request'; + return this[method](`${this.prefix}set_lines`, [ + _start, + end, + indexing, + lines, + ]); + } + /** + * Set virtual text for a line + * + * @public + * @param {number} src_id - Source group to use or 0 to use a new group, or -1 + * @param {number} line - Line to annotate with virtual text (zero-indexed) + * @param {Chunk[]} chunks - List with [text, hl_group] + * @param {{[index} opts + * @returns {Promise} + */ + setVirtualText(src_id, line, chunks, opts = {}) { + this.notify(`${this.prefix}set_virtual_text`, [ + src_id, + line, + chunks, + opts, + ]); + return Promise.resolve(src_id); + } + /** Insert lines at `start` index */ + insert(lines, start) { + return this.setLines(lines, { + start, + end: start, + strictIndexing: true, + }); + } + /** Replace lines starting at `start` index */ + replace(_lines, start) { + const lines = typeof _lines === 'string' ? [_lines] : _lines; + return this.setLines(lines, { + start, + end: start + lines.length, + strictIndexing: false, + }); + } + /** Remove lines at index */ + remove(start, end, strictIndexing = false) { + return this.setLines([], { start, end, strictIndexing }); + } + /** Append a string or list of lines to end of buffer */ + append(lines) { + return this.setLines(lines, { + start: -1, + end: -1, + strictIndexing: false, + }); + } + /** Get buffer name */ + get name() { + return this.request(`${this.prefix}get_name`, []); + } + /** Set current buffer name */ + setName(value) { + return this.request(`${this.prefix}set_name`, [value]); + } + /** Is current buffer valid */ + get valid() { + return this.request(`${this.prefix}is_valid`, []); + } + /** Get mark position given mark name */ + mark(name) { + return this.request(`${this.prefix}get_mark`, [name]); + } + // range(start, end) { + // """Return a `Range` object, which represents part of the Buffer.""" + // return Range(this, start, end) + // } + /** Gets keymap */ + getKeymap(mode) { + return this.request(`${this.prefix}get_keymap`, [mode]); + } + /** + * Checks if a buffer is valid and loaded. See |api-buffer| for + * more info about unloaded buffers. + */ + get loaded() { + return this.request(`${this.prefix}is_loaded`, []); + } + /** + * Returns the byte offset for a line. + * + * Line 1 (index=0) has offset 0. UTF-8 bytes are counted. EOL is + * one byte. 'fileformat' and 'fileencoding' are ignored. The + * line index just after the last line gives the total byte-count + * of the buffer. A final EOL byte is counted if it would be + * written, see 'eol'. + * + * Unlike |line2byte()|, throws error for out-of-bounds indexing. + * Returns -1 for unloaded buffer. + * + * @return {Number} Integer byte offset, or -1 for unloaded buffer. + */ + getOffset(index) { + return this.request(`${this.prefix}get_offset`, [index]); + } + /** + Adds a highlight to buffer. + + This can be used for plugins which dynamically generate + highlights to a buffer (like a semantic highlighter or + linter). The function adds a single highlight to a buffer. + Unlike matchaddpos() highlights follow changes to line + numbering (as lines are inserted/removed above the highlighted + line), like signs and marks do. + + "src_id" is useful for batch deletion/updating of a set of + highlights. When called with src_id = 0, an unique source id + is generated and returned. Succesive calls can pass in it as + "src_id" to add new highlights to the same source group. All + highlights in the same group can then be cleared with + nvim_buf_clear_highlight. If the highlight never will be + manually deleted pass in -1 for "src_id". + + If "hl_group" is the empty string no highlight is added, but a + new src_id is still returned. This is useful for an external + plugin to synchrounously request an unique src_id at + initialization, and later asynchronously add and clear + highlights in response to buffer changes. */ + addHighlight({ hlGroup: _hlGroup, line, colStart: _start, colEnd: _end, srcId: _srcId, }) { + const hlGroup = typeof _hlGroup !== 'undefined' ? _hlGroup : ''; + const colEnd = typeof _end !== 'undefined' ? _end : -1; + const colStart = typeof _start !== 'undefined' ? _start : -0; + const srcId = typeof _srcId !== 'undefined' ? _srcId : -1; + const method = hlGroup === '' ? 'request' : 'notify'; + let res = this[method](`${this.prefix}add_highlight`, [ + srcId, + hlGroup, + line, + colStart, + colEnd, + ]); + return method === 'request' ? res : Promise.resolve(null); + } + /** Clears highlights from a given source group and a range of + lines + To clear a source group in the entire buffer, pass in 1 and -1 + to lineStart and lineEnd respectively. */ + clearHighlight(args = {}) { + const defaults = { + srcId: -1, + lineStart: 0, + lineEnd: -1, + }; + const { srcId, lineStart, lineEnd } = Object.assign({}, defaults, args); + return this.notify(`${this.prefix}clear_highlight`, [ + srcId, + lineStart, + lineEnd, + ]); + } + clearNamespace(id, lineStart = 0, lineEnd = -1) { + return this.notify(`${this.prefix}clear_namespace`, [ + id, + lineStart, + lineEnd, + ]); + } + /** + * Listens to buffer for events + */ + listen(eventName, cb) { + if (!this.isAttached) { + throw new Error('buffer not attached'); + } + this.client.attachBufferEvent(this, eventName, cb); + return () => { + this.unlisten(eventName, cb); + }; + } + unlisten(eventName, cb) { + this.client.detachBufferEvent(this, eventName, cb); + } +} +exports.Buffer = Buffer; + + +/***/ }), +/* 48 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const events_1 = __webpack_require__(49); +const isVim = process.env.VIM_NODE_RPC == '1'; +// i.e. a plugin that detaches will affect all plugins registered on host +// const EXCLUDED = ['nvim_buf_attach', 'nvim_buf_detach'] +// Instead of dealing with multiple inheritance (or lackof), just extend EE +// Only the Neovim API class should use EE though +class BaseApi extends events_1.EventEmitter { + constructor({ transport, data, client, }) { + super(); + this.setTransport(transport); + this.data = data; + this.client = client; + } + setTransport(transport) { + this.transport = transport; + } + equals(other) { + try { + return String(this.data) === String(other.data); + } + catch (e) { + return false; + } + } + request(name, args = []) { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve, reject) => { + this.transport.request(name, this.getArgsByPrefix(args), (err, res) => { + if (err) { + reject(new Error(`request error ${name} - ${err[1]}`)); + } + else { + resolve(res); + } + }); + }); + }); + } + getArgsByPrefix(args) { + // Check if class is Neovim and if so, should not send `this` as first arg + if (this.prefix !== 'nvim_' && args[0] != this) { + let id = isVim ? this.data : this; + return [id, ...args]; + } + return args; + } + /** Retrieves a scoped variable depending on type (using `this.prefix`) */ + getVar(name) { + return this.request(`${this.prefix}get_var`, [name]).then(res => res, _err => { + return null; + }); + } + setVar(name, value, isNotify = false) { + if (isNotify) { + this.notify(`${this.prefix}set_var`, [name, value]); + return; + } + return this.request(`${this.prefix}set_var`, [name, value]); + } + /** Delete a scoped variable */ + deleteVar(name) { + this.notify(`${this.prefix}del_var`, [name]); + } + /** Retrieves a scoped option depending on type of `this` */ + getOption(name) { + return this.request(`${this.prefix}get_option`, [name]); + } + setOption(name, value, isNotify) { + if (isNotify) { + this.notify(`${this.prefix}set_option`, [name, value]); + return; + } + return this.request(`${this.prefix}set_option`, [name, value]); + } + /** `request` is basically the same except you can choose to wait forpromise to be resolved */ + notify(name, args = []) { + this.transport.notify(name, this.getArgsByPrefix(args)); + } +} +exports.BaseApi = BaseApi; + + +/***/ }), +/* 49 */ +/***/ (function(module, exports) { + +module.exports = require("events"); + +/***/ }), +/* 50 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const Base_1 = __webpack_require__(48); +const timers_1 = __webpack_require__(51); +class Window extends Base_1.BaseApi { + constructor() { + super(...arguments); + this.prefix = 'nvim_win_'; + } + /** + * The windowid that not change within a Vim session + */ + get id() { + return this.data; + } + /** Get current buffer of window */ + get buffer() { + return this.request(`${this.prefix}get_buf`, []); + } + /** Get the Tabpage that contains the window */ + get tabpage() { + return this.request(`${this.prefix}get_tabpage`, []); + } + /** Get cursor position */ + get cursor() { + return this.request(`${this.prefix}get_cursor`, []); + } + setCursor(pos, isNotify = false) { + let method = isNotify ? 'notify' : 'request'; + return this[method](`${this.prefix}set_cursor`, [pos]); + } + /** Get window height by number of rows */ + get height() { + return this.request(`${this.prefix}get_height`, []); + } + setHeight(height, isNotify = false) { + let method = isNotify ? 'notify' : 'request'; + return this[method](`${this.prefix}set_height`, [height]); + } + /** Get window width by number of columns */ + get width() { + return this.request(`${this.prefix}get_width`, []); + } + setWidth(width, isNotify = false) { + let method = isNotify ? 'notify' : 'request'; + return this[method](`${this.prefix}set_height`, [width]); + } + /** Get window position */ + get position() { + return this.request(`${this.prefix}get_position`, []); + } + /** 0-indexed, on-screen window position(row) in display cells. */ + get row() { + return this.request(`${this.prefix}get_position`, []).then(position => position[0]); + } + /** 0-indexed, on-screen window position(col) in display cells. */ + get col() { + return this.request(`${this.prefix}get_position`, []).then(position => position[1]); + } + /** Is window valid */ + get valid() { + return this.request(`${this.prefix}is_valid`, []); + } + /** Get window number */ + get number() { + return this.request(`${this.prefix}get_number`, []); + } + setConfig(options, isNotify) { + let method = isNotify ? 'notify' : 'request'; + return this[method](`${this.prefix}set_config`, [options]); + } + getConfig() { + return this.request(`${this.prefix}get_config`, []); + } + close(force, isNotify) { + if (isNotify) { + this.notify(`${this.prefix}close`, [force]); + let count = 0; + let interval = setInterval(() => { + if (count == 5) + return timers_1.clearInterval(interval); + this.request(`${this.prefix}is_valid`, []).then(valid => { + if (!valid) { + timers_1.clearInterval(interval); + } + else { + this.notify(`${this.prefix}close`, [force]); + } + }, () => { + timers_1.clearInterval(interval); + }); + count++; + }, 50); + return null; + } + return this.request(`${this.prefix}close`, [force]); + } +} +exports.Window = Window; + + +/***/ }), +/* 51 */ +/***/ (function(module, exports) { + +module.exports = require("timers"); + +/***/ }), +/* 52 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const Base_1 = __webpack_require__(48); +class Tabpage extends Base_1.BaseApi { + constructor() { + super(...arguments); + this.prefix = 'nvim_tabpage_'; + } + /** Returns all windows of tabpage */ + get windows() { + return this.request(`${this.prefix}list_wins`, []); + } + /** Gets the current window of tabpage */ + get window() { + return this.request(`${this.prefix}get_win`, []); + } + /** Is current tabpage valid */ + get valid() { + return this.request(`${this.prefix}is_valid`, []); + } + /** Tabpage number */ + get number() { + return this.request(`${this.prefix}get_number`, []); + } + /** Invalid */ + getOption() { + throw new Error('Tabpage does not have `getOption`'); + } + /** Invalid */ + setOption() { + throw new Error('Tabpage does not have `setOption`'); + } +} +exports.Tabpage = Tabpage; + + +/***/ }), +/* 53 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const events_1 = __webpack_require__(49); +const logger_1 = __webpack_require__(54); +const debug = process.env.NODE_CLIENT_LOG_LEVEL == 'debug'; +const logger = logger_1.createLogger('transport'); +class Transport extends events_1.EventEmitter { + constructor() { + super(...arguments); + this._paused = false; + this.paused = []; + } + debug(key, ...meta) { + if (!debug) + return; + logger.debug(key, ...meta); + } + debugMessage(msg) { + if (!debug) + return; + const msgType = msg[0]; + if (msgType == 0) { + logger.debug('receive request:', msg.slice(1)); + } + else if (msgType == 1) { + logger.debug('receive response:', msg.slice(1)); + } + else if (msgType == 2) { + logger.debug('receive notification:', msg.slice(1)); + } + else { + logger.debug('unknown message:', msg); + } + } + pauseNotification() { + this._paused = true; + } + resumeNotification(isNotify = false) { + this._paused = false; + let list = this.paused; + if (list.length) { + this.paused = []; + return new Promise((resolve, reject) => { + if (!isNotify) + return this.request('nvim_call_atomic', [list], (err, res) => { + if (err) + return reject(new Error(`call_atomic error: ${err[1]}`)); + resolve(res); + }); + this.notify('nvim_call_atomic', [list]); + resolve(); + }); + } + return isNotify ? null : Promise.resolve(); + } +} +exports.default = Transport; + + +/***/ }), +/* 54 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs_1 = __importDefault(__webpack_require__(55)); +const os_1 = __importDefault(__webpack_require__(56)); +const path_1 = __importDefault(__webpack_require__(57)); +function getLogFile() { + let file = process.env.NODE_CLIENT_LOG_FILE; + if (file) + return file; + let dir = process.env.XDG_RUNTIME_DIR; + if (dir) + return path_1.default.join(dir, 'node-client.log'); + return path_1.default.join(os_1.default.tmpdir(), `node-client-${process.pid}.log`); +} +const LOG_FILE_PATH = getLogFile(); +const level = process.env.NODE_CLIENT_LOG_LEVEL || 'info'; +let invalid = process.getuid && process.getuid() == 0; +if (!invalid) { + try { + fs_1.default.mkdirSync(path_1.default.dirname(LOG_FILE_PATH), { recursive: true }); + fs_1.default.writeFileSync(LOG_FILE_PATH, '', { encoding: 'utf8', mode: 0o666 }); + } + catch (_e) { + invalid = true; + } +} +function toObject(arg) { + if (arg == null) { + return arg; + } + if (Array.isArray(arg)) { + return arg.map(o => toObject(o)); + } + if (typeof arg == 'object' && typeof arg.prefix == 'string' && typeof arg.data == 'number') { + return '[' + arg.prefix + arg.data + ']'; + } + return arg; +} +function toString(arg) { + if (arg == null) + return String(arg); + if (typeof arg == 'object') + return JSON.stringify(arg, null, 2); + return String(arg); +} +const stream = invalid ? null : fs_1.default.createWriteStream(LOG_FILE_PATH, { encoding: 'utf8' }); +class Logger { + constructor(name) { + this.name = name; + } + getText(level, data, meta) { + let more = ''; + if (meta.length) { + let arr = toObject(meta); + more = ' ' + arr.map(o => toString(o)); + } + return `${new Date().toLocaleTimeString()} ${level.toUpperCase()} [${this.name}] - ${data}${more}\n`; + } + debug(data, ...meta) { + if (level != 'debug' || stream == null) + return; + stream.write(this.getText('debug', data, meta)); + } + info(data, ...meta) { + if (stream == null) + return; + stream.write(this.getText('info', data, meta)); + } + error(data, ...meta) { + if (stream == null) + return; + stream.write(this.getText('error', data, meta)); + } + trace(data, ...meta) { + if (level != 'trace' || stream == null) + return; + stream.write(this.getText('trace', data, meta)); + } +} +function createLogger(name) { + return new Logger(name); +} +exports.createLogger = createLogger; + + +/***/ }), +/* 55 */ +/***/ (function(module, exports) { + +module.exports = require("fs"); + +/***/ }), +/* 56 */ +/***/ (function(module, exports) { + +module.exports = require("os"); + +/***/ }), +/* 57 */ +/***/ (function(module, exports) { + +module.exports = require("path"); + +/***/ }), +/* 58 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const base_1 = __importDefault(__webpack_require__(53)); +const connection_1 = __importDefault(__webpack_require__(59)); +const request_1 = __importDefault(__webpack_require__(61)); +class VimTransport extends base_1.default { + constructor() { + super(); + this.pending = new Map(); + this.nextRequestId = 0; + this.attached = false; + this.notifyMethod = process.env.COC_NVIM == '1' ? 'coc#api#notify' : 'nvim#api#notify'; + } + attach(writer, reader, client) { + let connection = this.connection = new connection_1.default(reader, writer); + this.attached = true; + this.client = client; + connection.on('request', (id, obj) => { + let [method, args] = obj; + this.emit('request', method, args, this.createResponse(id)); + }); + connection.on('notification', (obj) => { + let [event, args] = obj; + this.emit('notification', event.toString(), args); + }); + connection.on('response', (id, obj) => { + let req = this.pending.get(id); + if (req) { + this.pending.delete(id); + let err = null; + let result = null; + if (!Array.isArray(obj)) { + err = obj; + } + else { + err = obj[0]; + result = obj[1]; + } + req.callback(this.client, err, result); + } + }); + } + detach() { + if (!this.attached) + return; + this.attached = false; + this.connection.dispose(); + } + /** + * Send request to vim + */ + request(method, args, cb) { + if (!this.attached) + return cb([0, 'transport disconnected']); + if (!this.client.hasFunction(method)) { + // tslint:disable-next-line: no-console + console.error(`method: ${method} not supported.`); + } + this.nextRequestId = this.nextRequestId - 1; + let req = new request_1.default(this.connection, cb, this.nextRequestId); + this.pending.set(this.nextRequestId, req); + req.request(method, args); + } + notify(method, args) { + if (!this.attached) + return; + if (!this.client.hasFunction(method)) { + // tslint:disable-next-line: no-console + console.error(`method: ${method} not supported.`); + } + if (this._paused) { + this.paused.push([method, args]); + return; + } + this.connection.call(this.notifyMethod, [method.slice(5), args]); + } + createResponse(requestId) { + let called = false; + let { connection } = this; + return { + send: (resp, isError) => { + if (called || !this.attached) + return; + called = true; + let err = null; + if (isError) + err = typeof resp === 'string' ? resp : resp.toString(); + connection.response(requestId, [err, isError ? null : resp]); + } + }; + } +} +exports.VimTransport = VimTransport; + + +/***/ }), +/* 59 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const events_1 = __importDefault(__webpack_require__(49)); +const readline_1 = __importDefault(__webpack_require__(60)); +const logger_1 = __webpack_require__(54); +const logger = logger_1.createLogger('connection'); +const debug = process.env.NODE_CLIENT_LOG_LEVEL == 'debug'; +class Connection extends events_1.default { + constructor(readable, writeable) { + super(); + this.readable = readable; + this.writeable = writeable; + const rl = readline_1.default.createInterface(this.readable); + rl.on('line', (line) => { + this.parseData(line); + }); + rl.on('close', () => { + logger.error('connection closed'); + process.exit(0); + }); + } + parseData(str) { + if (str.length == 0) + return; + let arr; + try { + arr = JSON.parse(str); + } + catch (e) { + // tslint:disable-next-line: no-console + console.error(`Invalid data from vim: ${str}`); + return; + } + // request, notification, response + let [id, obj] = arr; + logger.debug('received:', arr); + if (id > 0) { + this.emit('request', id, obj); + } + else if (id == 0) { + this.emit('notification', obj); + } + else { + // response for previous request + this.emit('response', id, obj); + } + } + response(requestId, data) { + this.send([requestId, data || null]); + } + notify(event, data) { + this.send([0, [event, data || null]]); + } + send(arr) { + if (debug) + logger.debug('send:', arr[0], arr.slice(1)); + try { + this.writeable.write(JSON.stringify(arr) + '\n'); + } + catch (e) { + logger.error('Send error:', arr); + } + } + redraw(force = false) { + this.send(['redraw', force ? 'force' : '']); + } + commmand(cmd) { + this.send(['ex', cmd]); + } + expr(expr) { + this.send(['expr', expr]); + } + call(func, args, requestId) { + if (!requestId) { + this.send(['call', func, args]); + return; + } + this.send(['call', func, args, requestId]); + } + dispose() { + this.removeAllListeners(); + } +} +exports.default = Connection; + + +/***/ }), +/* 60 */ +/***/ (function(module, exports) { + +module.exports = require("readline"); + +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const logger_1 = __webpack_require__(54); +const logger = logger_1.createLogger('request'); +const debug = process.env.NODE_CLIENT_LOG_LEVEL == 'debug'; +const func = process.env.COC_NVIM == '1' ? 'coc#api#call' : 'nvim#api#call'; +class Request { + constructor(connection, cb, id) { + this.connection = connection; + this.cb = cb; + this.id = id; + } + request(method, args = []) { + this.method = method; + this.args = args; + this.connection.call(func, [method.slice(5), args], this.id); + } + callback(client, err, result) { + let { method, cb } = this; + if (debug && err) { + logger.debug(`request ${this.method} error:`, err, this.args); + } + if (err) + return cb([0, err.toString()]); + switch (method) { + case 'nvim_list_wins': + case 'nvim_tabpage_list_wins': + return cb(null, result.map(o => client.createWindow(o))); + case 'nvim_tabpage_get_win': + case 'nvim_get_current_win': + case 'nvim_open_win': + return cb(null, client.createWindow(result)); + case 'nvim_list_bufs': + return cb(null, result.map(o => client.createBuffer(o))); + case 'nvim_win_get_buf': + case 'nvim_create_buf': + case 'nvim_get_current_buf': + return cb(null, client.createBuffer(result)); + case 'nvim_list_tabpages': + return cb(null, result.map(o => client.createTabpage(o))); + case 'nvim_get_current_tabpage': + return cb(null, client.createTabpage(result)); + default: + return cb(null, result); + } + } +} +exports.default = Request; + + +/***/ }), +/* 62 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const Base_1 = __webpack_require__(48); +const Buffer_1 = __webpack_require__(47); +const Tabpage_1 = __webpack_require__(52); +const Window_1 = __webpack_require__(50); +const isVim = process.env.VIM_NODE_RPC == '1'; +/** + * Neovim API + */ +class Neovim extends Base_1.BaseApi { + constructor() { + super(...arguments); + this.prefix = 'nvim_'; + this.Buffer = Buffer_1.Buffer; + this.Window = Window_1.Window; + this.Tabpage = Tabpage_1.Tabpage; + } + getArgs(args) { + if (!args) + return []; + if (Array.isArray(args)) + return args; + return [args]; + } + get apiInfo() { + return this.request(`${this.prefix}get_api_info`); + } + /** Get list of all buffers */ + get buffers() { + return this.request(`${this.prefix}list_bufs`); + } + /** Get current buffer */ + get buffer() { + return this.request(`${this.prefix}get_current_buf`); + } + /** Set current buffer */ + setBuffer(buffer) { + return __awaiter(this, void 0, void 0, function* () { + yield this.request(`${this.prefix}set_current_buf`, [buffer]); + }); + } + get chans() { + return this.request(`${this.prefix}list_chans`); + } + getChanInfo(chan) { + return this.request(`${this.prefix}get_chan_info`, [chan]); + } + createNamespace(name = "") { + return this.request(`${this.prefix}create_namespace`, [name]); + } + get namespaces() { + return this.request(`${this.prefix}get_namespaces`, [name]); + } + get commands() { + return this.getCommands(); + } + getCommands(options = {}) { + return this.request(`${this.prefix}get_commands`, [options]); + } + /** Get list of all tabpages */ + get tabpages() { + return this.request(`${this.prefix}list_tabpages`); + } + /** Get current tabpage */ + get tabpage() { + return this.request(`${this.prefix}get_current_tabpage`); + } + /** Set current tabpage */ + setTabpage(tabpage) { + return __awaiter(this, void 0, void 0, function* () { + yield this.request(`${this.prefix}set_current_tabpage`, [tabpage]); + }); + } + /** Get list of all windows */ + get windows() { + return this.getWindows(); + } + /** Get current window */ + get window() { + return this.request(`${this.prefix}get_current_win`); + } + /** Get list of all windows */ + getWindows() { + return this.request(`${this.prefix}list_wins`); + } + setWindow(win) { + return __awaiter(this, void 0, void 0, function* () { + // Throw error if win is not instance of Window? + yield this.request(`${this.prefix}set_current_win`, [win]); + }); + } + /** Get list of all runtime paths */ + get runtimePaths() { + return this.request(`${this.prefix}list_runtime_paths`); + } + /** Set current directory */ + setDirectory(dir) { + return this.request(`${this.prefix}set_current_dir`, [dir]); + } + /** Get current line. Always returns a Promise. */ + get line() { + return this.getLine(); + } + createNewBuffer(listed = false, scratch = false) { + return this.request(`${this.prefix}create_buf`, [listed, scratch]); + } + openFloatWindow(buffer, enter, options) { + return this.request(`${this.prefix}open_win`, [buffer, enter, options]); + } + getLine() { + return this.request(`${this.prefix}get_current_line`); + } + /** Set current line */ + setLine(line) { + return this.request(`${this.prefix}set_current_line`, [line]); + } + /** Gets keymap */ + getKeymap(mode) { + return this.request(`${this.prefix}get_keymap`, [mode]); + } + /** Gets current mode */ + get mode() { + return this.request(`${this.prefix}get_mode`); + } + /** Gets map of defined colors */ + get colorMap() { + return this.request(`${this.prefix}get_color_map`); + } + /** Get color by name */ + getColorByName(name) { + return this.request(`${this.prefix}get_color_by_name`, [name]); + } + /** Get highlight by name or id */ + getHighlight(nameOrId, isRgb = true) { + const functionName = typeof nameOrId === 'string' ? 'by_name' : 'by_id'; + return this.request(`${this.prefix}get_hl_${functionName}`, [ + nameOrId, + isRgb, + ]); + } + getHighlightByName(name, isRgb = true) { + return this.request(`${this.prefix}get_hl_by_name`, [name, isRgb]); + } + getHighlightById(id, isRgb = true) { + return this.request(`${this.prefix}get_hl_by_id`, [id, isRgb]); + } + /** Delete current line in buffer */ + deleteCurrentLine() { + return this.request(`${this.prefix}del_current_line`); + } + /** + * Evaluates a VimL expression (:help expression). Dictionaries + * and Lists are recursively expanded. On VimL error: Returns a + * generic error; v:errmsg is not updated. + * + */ + eval(expr) { + return this.request(`${this.prefix}eval`, [expr]); + } + /** + * Executes lua, it's possible neovim client does not support this + */ + lua(code, args = []) { + const _args = this.getArgs(args); + return this.request(`${this.prefix}execute_lua`, [code, _args]); + } + // Alias for `lua()` to be consistent with neovim API + executeLua(code, args = []) { + return this.lua(code, args); + } + callDictFunction(dict, fname, args = []) { + const _args = this.getArgs(args); + return this.request(`${this.prefix}call_dict_function`, [ + dict, + fname, + _args, + ]); + } + call(fname, args = [], isNotify) { + const _args = this.getArgs(args); + if (isNotify) { + this.notify(`${this.prefix}call_function`, [fname, _args]); + return null; + } + return this.request(`${this.prefix}call_function`, [fname, _args]); + } + callTimer(fname, args = [], isNotify) { + const _args = this.getArgs(args); + if (isNotify) { + this.notify(`${this.prefix}call_function`, ['coc#util#timer', [fname, _args]]); + return null; + } + if (isVim) { + this.notify(`${this.prefix}call_function`, ['coc#util#timer', [fname, _args]]); + return new Promise(resolve => { + setTimeout(() => { + resolve(null); + }, 20); + }); + } + return this.request(`${this.prefix}call_function`, ['coc#util#timer', [fname, _args]]); + } + callAsync(fname, args = []) { + const _args = this.getArgs(args); + return this.client.sendAsyncRequest(fname, _args); + } + /** Alias for `call` */ + callFunction(fname, args = []) { + return this.call(fname, args); + } + /** Call Atomic calls */ + callAtomic(calls) { + return this.request(`${this.prefix}call_atomic`, [calls]); + } + command(arg, isNotify) { + if (isNotify) { + this.notify(`${this.prefix}command`, [arg]); + return null; + } + return this.request(`${this.prefix}command`, [arg]); + } + /** Runs a command and returns output (synchronous?) */ + commandOutput(arg) { + return this.request(`${this.prefix}command_output`, [arg]); + } + /** Gets a v: variable */ + getVvar(name) { + return this.request(`${this.prefix}get_vvar`, [name]); + } + /** feedKeys */ + feedKeys(keys, mode, escapeCsi) { + return this.request(`${this.prefix}feedkeys`, [keys, mode, escapeCsi]); + } + /** Sends input keys */ + input(keys) { + return this.request(`${this.prefix}input`, [keys]); + } + /** + * Parse a VimL Expression + * + * TODO: return type, see :help + */ + parseExpression(expr, flags, highlight) { + return this.request(`${this.prefix}parse_expression`, [ + expr, + flags, + highlight, + ]); + } + getProc(pid) { + return this.request(`${this.prefix}get_proc`, [pid]); + } + getProcChildren(pid) { + return this.request(`${this.prefix}get_proc_children`, [pid]); + } + /** Replace term codes */ + replaceTermcodes(str, fromPart, doIt, special) { + return this.request(`${this.prefix}replace_termcodes`, [ + str, + fromPart, + doIt, + special, + ]); + } + /** Gets width of string */ + strWidth(str) { + return this.request(`${this.prefix}strwidth`, [str]); + } + /** Write to output buffer */ + outWrite(str) { + this.notify(`${this.prefix}out_write`, [str]); + } + outWriteLine(str) { + this.outWrite(`${str}\n`); + } + /** Write to error buffer */ + errWrite(str) { + this.notify(`${this.prefix}err_write`, [str]); + } + /** Write to error buffer */ + errWriteLine(str) { + this.notify(`${this.prefix}err_writeln`, [str]); + } + // TODO: add type + get uis() { + return this.request(`${this.prefix}list_uis`); + } + uiAttach(width, height, options) { + return this.request(`${this.prefix}ui_attach`, [width, height, options]); + } + uiDetach() { + return this.request(`${this.prefix}ui_detach`, []); + } + uiTryResize(width, height) { + return this.request(`${this.prefix}ui_try_resize`, [width, height]); + } + /** Set UI Option */ + uiSetOption(name, value) { + return this.request(`${this.prefix}ui_set_option`, [name, value]); + } + /** Subscribe to nvim event broadcasts */ + subscribe(event) { + return this.request(`${this.prefix}subscribe`, [event]); + } + /** Unsubscribe to nvim event broadcasts */ + unsubscribe(event) { + return this.request(`${this.prefix}unsubscribe`, [event]); + } + setClientInfo(name, version, type, methods, attributes) { + this.notify(`${this.prefix}set_client_info`, [ + name, + version, + type, + methods, + attributes, + ]); + } + /** Quit nvim */ + quit() { + return __awaiter(this, void 0, void 0, function* () { + this.command('qa!', true); + if (this.transport) { + this.transport.detach(); + } + }); + } +} +exports.Neovim = Neovim; + + +/***/ }), +/* 63 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var client_1 = __webpack_require__(7); +exports.Neovim = client_1.NeovimClient; +var client_2 = __webpack_require__(7); +exports.NeovimClient = client_2.NeovimClient; +var Buffer_1 = __webpack_require__(47); +exports.Buffer = Buffer_1.Buffer; +var Window_1 = __webpack_require__(50); +exports.Window = Window_1.Window; +var Tabpage_1 = __webpack_require__(52); +exports.Tabpage = Tabpage_1.Tabpage; + + +/***/ }), +/* 64 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @fileoverview log4js is a library to log in JavaScript in similar manner + * than in log4j for Java (but not really). + * + *

Example:

+ *
+ *  const logging = require('log4js');
+ *  const log = logging.getLogger('some-category');
+ *
+ *  //call the log
+ *  log.trace('trace me' );
+ * 
+ * + * NOTE: the authors below are the original browser-based log4js authors + * don't try to contact them about bugs in this version :) + * @author Stephan Strittmatter - http://jroller.com/page/stritti + * @author Seth Chisamore - http://www.chisamore.com + * @since 2005-05-20 + * Website: http://log4js.berlios.de + */ +const debug = __webpack_require__(65)("log4js:main"); +const fs = __webpack_require__(55); +const deepClone = __webpack_require__(73)({ proto: true }); +const configuration = __webpack_require__(74); +const layouts = __webpack_require__(75); +const levels = __webpack_require__(77); +const appenders = __webpack_require__(78); +const categories = __webpack_require__(145); +const Logger = __webpack_require__(146); +const clustering = __webpack_require__(79); +const connectLogger = __webpack_require__(147); + +let enabled = false; + +function sendLogEventToAppender(logEvent) { + if (!enabled) return; + debug("Received log event ", logEvent); + const categoryAppenders = categories.appendersForCategory( + logEvent.categoryName + ); + categoryAppenders.forEach(appender => { + appender(logEvent); + }); +} + +function loadConfigurationFile(filename) { + debug(`Loading configuration from ${filename}`); + try { + return JSON.parse(fs.readFileSync(filename, "utf8")); + } catch (e) { + throw new Error( + `Problem reading config from file "${filename}". Error was ${e.message}`, + e + ); + } +} + +function configure(configurationFileOrObject) { + let configObject = configurationFileOrObject; + + if (typeof configObject === "string") { + configObject = loadConfigurationFile(configurationFileOrObject); + } + debug(`Configuration is ${configObject}`); + + configuration.configure(deepClone(configObject)); + + clustering.onMessage(sendLogEventToAppender); + + enabled = true; + + // eslint-disable-next-line no-use-before-define + return log4js; +} + +/** + * Shutdown all log appenders. This will first disable all writing to appenders + * and then call the shutdown function each appender. + * + * @params {Function} cb - The callback to be invoked once all appenders have + * shutdown. If an error occurs, the callback will be given the error object + * as the first argument. + */ +function shutdown(cb) { + debug("Shutdown called. Disabling all log writing."); + // First, disable all writing to appenders. This prevents appenders from + // not being able to be drained because of run-away log writes. + enabled = false; + + // Call each of the shutdown functions in parallel + const appendersToCheck = Array.from(appenders.values()); + const shutdownFunctions = appendersToCheck.reduceRight( + (accum, next) => (next.shutdown ? accum + 1 : accum), + 0 + ); + let completed = 0; + let error; + + debug(`Found ${shutdownFunctions} appenders with shutdown functions.`); + function complete(err) { + error = error || err; + completed += 1; + debug(`Appender shutdowns complete: ${completed} / ${shutdownFunctions}`); + if (completed >= shutdownFunctions) { + debug("All shutdown functions completed."); + cb(error); + } + } + + if (shutdownFunctions === 0) { + debug("No appenders with shutdown functions found."); + return cb(); + } + + appendersToCheck.filter(a => a.shutdown).forEach(a => a.shutdown(complete)); + + return null; +} + +/** + * Get a logger instance. + * @static + * @param loggerCategoryName + * @return {Logger} instance of logger for the category + */ +function getLogger(category) { + if (!enabled) { + configure( + process.env.LOG4JS_CONFIG || { + appenders: { out: { type: "stdout" } }, + categories: { default: { appenders: ["out"], level: "OFF" } } + } + ); + } + return new Logger(category || "default"); +} + +/** + * @name log4js + * @namespace Log4js + * @property getLogger + * @property configure + * @property shutdown + */ +const log4js = { + getLogger, + configure, + shutdown, + connectLogger, + levels, + addLayout: layouts.addLayout +}; + +module.exports = log4js; + + +/***/ }), +/* 65 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * Detect Electron renderer / nwjs process, which is node, but we should + * treat as a browser. + */ + +if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) { + module.exports = __webpack_require__(66); +} else { + module.exports = __webpack_require__(69); +} + + +/***/ }), +/* 66 */ +/***/ (function(module, exports, __webpack_require__) { + +/* eslint-env browser */ + +/** + * This is the web browser implementation of `debug()`. + */ + +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = localstorage(); + +/** + * Colors. + */ + +exports.colors = [ + '#0000CC', + '#0000FF', + '#0033CC', + '#0033FF', + '#0066CC', + '#0066FF', + '#0099CC', + '#0099FF', + '#00CC00', + '#00CC33', + '#00CC66', + '#00CC99', + '#00CCCC', + '#00CCFF', + '#3300CC', + '#3300FF', + '#3333CC', + '#3333FF', + '#3366CC', + '#3366FF', + '#3399CC', + '#3399FF', + '#33CC00', + '#33CC33', + '#33CC66', + '#33CC99', + '#33CCCC', + '#33CCFF', + '#6600CC', + '#6600FF', + '#6633CC', + '#6633FF', + '#66CC00', + '#66CC33', + '#9900CC', + '#9900FF', + '#9933CC', + '#9933FF', + '#99CC00', + '#99CC33', + '#CC0000', + '#CC0033', + '#CC0066', + '#CC0099', + '#CC00CC', + '#CC00FF', + '#CC3300', + '#CC3333', + '#CC3366', + '#CC3399', + '#CC33CC', + '#CC33FF', + '#CC6600', + '#CC6633', + '#CC9900', + '#CC9933', + '#CCCC00', + '#CCCC33', + '#FF0000', + '#FF0033', + '#FF0066', + '#FF0099', + '#FF00CC', + '#FF00FF', + '#FF3300', + '#FF3333', + '#FF3366', + '#FF3399', + '#FF33CC', + '#FF33FF', + '#FF6600', + '#FF6633', + '#FF9900', + '#FF9933', + '#FFCC00', + '#FFCC33' +]; + +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +// eslint-disable-next-line complexity +function useColors() { + // NB: In an Electron preload script, document will be defined but not fully + // initialized. Since we know we're in Chrome, we'll just detect this case + // explicitly + if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { + return true; + } + + // Internet Explorer and Edge do not support colors. + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } + + // Is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || + // Is firebug? http://stackoverflow.com/a/398120/376773 + (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || + // Is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || + // Double check webkit in userAgent just in case we are in a worker + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); +} + +/** + * Colorize log arguments if enabled. + * + * @api public + */ + +function formatArgs(args) { + args[0] = (this.useColors ? '%c' : '') + + this.namespace + + (this.useColors ? ' %c' : ' ') + + args[0] + + (this.useColors ? '%c ' : ' ') + + '+' + module.exports.humanize(this.diff); + + if (!this.useColors) { + return; + } + + const c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit'); + + // The final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + let index = 0; + let lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, match => { + if (match === '%%') { + return; + } + index++; + if (match === '%c') { + // We only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + + args.splice(lastC, 0, c); +} + +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". + * + * @api public + */ +function log(...args) { + // This hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return typeof console === 'object' && + console.log && + console.log(...args); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ +function save(namespaces) { + try { + if (namespaces) { + exports.storage.setItem('debug', namespaces); + } else { + exports.storage.removeItem('debug'); + } + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ +function load() { + let r; + try { + r = exports.storage.getItem('debug'); + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; + } + + return r; +} + +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + +function localstorage() { + try { + // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context + // The Browser also has localStorage in the global context. + return localStorage; + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } +} + +module.exports = __webpack_require__(67)(exports); + +const {formatters} = module.exports; + +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +formatters.j = function (v) { + try { + return JSON.stringify(v); + } catch (error) { + return '[UnexpectedJSONParseError]: ' + error.message; + } +}; + + +/***/ }), +/* 67 */ +/***/ (function(module, exports, __webpack_require__) { + + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + */ + +function setup(env) { + createDebug.debug = createDebug; + createDebug.default = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = __webpack_require__(68); + + Object.keys(env).forEach(key => { + createDebug[key] = env[key]; + }); + + /** + * Active `debug` instances. + */ + createDebug.instances = []; + + /** + * The currently active debug mode names, and names to skip. + */ + + createDebug.names = []; + createDebug.skips = []; + + /** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". + */ + createDebug.formatters = {}; + + /** + * Selects a color for a debug namespace + * @param {String} namespace The namespace string for the for the debug instance to be colored + * @return {Number|String} An ANSI color code for the given namespace + * @api private + */ + function selectColor(namespace) { + let hash = 0; + + for (let i = 0; i < namespace.length; i++) { + hash = ((hash << 5) - hash) + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer + } + + return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; + } + createDebug.selectColor = selectColor; + + /** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + function createDebug(namespace) { + let prevTime; + + function debug(...args) { + // Disabled? + if (!debug.enabled) { + return; + } + + const self = debug; + + // Set `diff` timestamp + const curr = Number(new Date()); + const ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + + args[0] = createDebug.coerce(args[0]); + + if (typeof args[0] !== 'string') { + // Anything else let's inspect with %O + args.unshift('%O'); + } + + // Apply any `formatters` transformations + let index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { + // If we encounter an escaped % then don't increase the array index + if (match === '%%') { + return match; + } + index++; + const formatter = createDebug.formatters[format]; + if (typeof formatter === 'function') { + const val = args[index]; + match = formatter.call(self, val); + + // Now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + // Apply env-specific formatting (colors, etc.) + createDebug.formatArgs.call(self, args); + + const logFn = self.log || createDebug.log; + logFn.apply(self, args); + } + + debug.namespace = namespace; + debug.enabled = createDebug.enabled(namespace); + debug.useColors = createDebug.useColors(); + debug.color = selectColor(namespace); + debug.destroy = destroy; + debug.extend = extend; + // Debug.formatArgs = formatArgs; + // debug.rawLog = rawLog; + + // env-specific initialization logic for debug instances + if (typeof createDebug.init === 'function') { + createDebug.init(debug); + } + + createDebug.instances.push(debug); + + return debug; + } + + function destroy() { + const index = createDebug.instances.indexOf(this); + if (index !== -1) { + createDebug.instances.splice(index, 1); + return true; + } + return false; + } + + function extend(namespace, delimiter) { + const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); + newDebug.log = this.log; + return newDebug; + } + + /** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + function enable(namespaces) { + createDebug.save(namespaces); + + createDebug.names = []; + createDebug.skips = []; + + let i; + const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); + const len = split.length; + + for (i = 0; i < len; i++) { + if (!split[i]) { + // ignore empty strings + continue; + } + + namespaces = split[i].replace(/\*/g, '.*?'); + + if (namespaces[0] === '-') { + createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + createDebug.names.push(new RegExp('^' + namespaces + '$')); + } + } + + for (i = 0; i < createDebug.instances.length; i++) { + const instance = createDebug.instances[i]; + instance.enabled = createDebug.enabled(instance.namespace); + } + } + + /** + * Disable debug output. + * + * @return {String} namespaces + * @api public + */ + function disable() { + const namespaces = [ + ...createDebug.names.map(toNamespace), + ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace) + ].join(','); + createDebug.enable(''); + return namespaces; + } + + /** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + function enabled(name) { + if (name[name.length - 1] === '*') { + return true; + } + + let i; + let len; + + for (i = 0, len = createDebug.skips.length; i < len; i++) { + if (createDebug.skips[i].test(name)) { + return false; + } + } + + for (i = 0, len = createDebug.names.length; i < len; i++) { + if (createDebug.names[i].test(name)) { + return true; + } + } + + return false; + } + + /** + * Convert regexp to namespace + * + * @param {RegExp} regxep + * @return {String} namespace + * @api private + */ + function toNamespace(regexp) { + return regexp.toString() + .substring(2, regexp.toString().length - 2) + .replace(/\.\*\?$/, '*'); + } + + /** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + return val; + } + + createDebug.enable(createDebug.load()); + + return createDebug; +} + +module.exports = setup; + + +/***/ }), +/* 68 */ +/***/ (function(module, exports) { + +/** + * Helpers. + */ + +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var w = d * 7; +var y = d * 365.25; + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} [options] + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ + +module.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === 'string' && val.length > 0) { + return parse(val); + } else if (type === 'number' && isFinite(val)) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + 'val is not a non-empty string or a valid number. val=' + + JSON.stringify(val) + ); +}; + +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function parse(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'weeks': + case 'week': + case 'w': + return n * w; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; + } +} + +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtShort(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return Math.round(ms / d) + 'd'; + } + if (msAbs >= h) { + return Math.round(ms / h) + 'h'; + } + if (msAbs >= m) { + return Math.round(ms / m) + 'm'; + } + if (msAbs >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; +} + +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtLong(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return plural(ms, msAbs, d, 'day'); + } + if (msAbs >= h) { + return plural(ms, msAbs, h, 'hour'); + } + if (msAbs >= m) { + return plural(ms, msAbs, m, 'minute'); + } + if (msAbs >= s) { + return plural(ms, msAbs, s, 'second'); + } + return ms + ' ms'; +} + +/** + * Pluralization helper. + */ + +function plural(ms, msAbs, n, name) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); +} + + +/***/ }), +/* 69 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * Module dependencies. + */ + +const tty = __webpack_require__(70); +const util = __webpack_require__(40); + +/** + * This is the Node.js implementation of `debug()`. + */ + +exports.init = init; +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; + +/** + * Colors. + */ + +exports.colors = [6, 2, 3, 4, 5, 1]; + +try { + // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json) + // eslint-disable-next-line import/no-extraneous-dependencies + const supportsColor = __webpack_require__(71); + + if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { + exports.colors = [ + 20, + 21, + 26, + 27, + 32, + 33, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 56, + 57, + 62, + 63, + 68, + 69, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 92, + 93, + 98, + 99, + 112, + 113, + 128, + 129, + 134, + 135, + 148, + 149, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 178, + 179, + 184, + 185, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 214, + 215, + 220, + 221 + ]; + } +} catch (error) { + // Swallow - we only care if `supports-color` is available; it doesn't have to be. +} + +/** + * Build up the default `inspectOpts` object from the environment variables. + * + * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js + */ + +exports.inspectOpts = Object.keys(process.env).filter(key => { + return /^debug_/i.test(key); +}).reduce((obj, key) => { + // Camel-case + const prop = key + .substring(6) + .toLowerCase() + .replace(/_([a-z])/g, (_, k) => { + return k.toUpperCase(); + }); + + // Coerce string value into JS value + let val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) { + val = true; + } else if (/^(no|off|false|disabled)$/i.test(val)) { + val = false; + } else if (val === 'null') { + val = null; + } else { + val = Number(val); + } + + obj[prop] = val; + return obj; +}, {}); + +/** + * Is stdout a TTY? Colored output is enabled when `true`. + */ + +function useColors() { + return 'colors' in exports.inspectOpts ? + Boolean(exports.inspectOpts.colors) : + tty.isatty(process.stderr.fd); +} + +/** + * Adds ANSI color escape codes if enabled. + * + * @api public + */ + +function formatArgs(args) { + const {namespace: name, useColors} = this; + + if (useColors) { + const c = this.color; + const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c); + const prefix = ` ${colorCode};1m${name} \u001B[0m`; + + args[0] = prefix + args[0].split('\n').join('\n' + prefix); + args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m'); + } else { + args[0] = getDate() + name + ' ' + args[0]; + } +} + +function getDate() { + if (exports.inspectOpts.hideDate) { + return ''; + } + return new Date().toISOString() + ' '; +} + +/** + * Invokes `util.format()` with the specified arguments and writes to stderr. + */ + +function log(...args) { + return process.stderr.write(util.format(...args) + '\n'); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ +function save(namespaces) { + if (namespaces) { + process.env.DEBUG = namespaces; + } else { + // If you set a process.env field to null or undefined, it gets cast to the + // string 'null' or 'undefined'. Just delete instead. + delete process.env.DEBUG; + } +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + return process.env.DEBUG; +} + +/** + * Init logic for `debug` instances. + * + * Create a new `inspectOpts` object in case `useColors` is set + * differently for a particular `debug` instance. + */ + +function init(debug) { + debug.inspectOpts = {}; + + const keys = Object.keys(exports.inspectOpts); + for (let i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; + } +} + +module.exports = __webpack_require__(67)(exports); + +const {formatters} = module.exports; + +/** + * Map %o to `util.inspect()`, all on a single line. + */ + +formatters.o = function (v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts) + .replace(/\s*\n\s*/g, ' '); +}; + +/** + * Map %O to `util.inspect()`, allowing multiple lines if needed. + */ + +formatters.O = function (v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); +}; + + +/***/ }), +/* 70 */ +/***/ (function(module, exports) { + +module.exports = require("tty"); + +/***/ }), +/* 71 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const os = __webpack_require__(56); +const hasFlag = __webpack_require__(72); + +const {env} = process; + +let forceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false') || + hasFlag('color=never')) { + forceColor = 0; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + forceColor = 1; +} +if ('FORCE_COLOR' in env) { + if (env.FORCE_COLOR === true || env.FORCE_COLOR === 'true') { + forceColor = 1; + } else if (env.FORCE_COLOR === false || env.FORCE_COLOR === 'false') { + forceColor = 0; + } else { + forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3); + } +} + +function translateLevel(level) { + if (level === 0) { + return false; + } + + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; +} + +function supportsColor(stream) { + if (forceColor === 0) { + return 0; + } + + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } + + if (hasFlag('color=256')) { + return 2; + } + + if (stream && !stream.isTTY && forceColor === undefined) { + return 0; + } + + const min = forceColor || 0; + + if (env.TERM === 'dumb') { + return min; + } + + if (process.platform === 'win32') { + // Node.js 7.5.0 is the first version of Node.js to include a patch to + // libuv that enables 256 color output on Windows. Anything earlier and it + // won't work. However, here we target Node.js 8 at minimum as it is an LTS + // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows + // release that supports 256 colors. Windows 10 build 14931 is the first release + // that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(process.versions.node.split('.')[0]) >= 8 && + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } + + return 1; + } + + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } + + return min; + } + + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } + + if (env.COLORTERM === 'truecolor') { + return 3; + } + + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default + } + } + + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } + + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } + + if ('COLORTERM' in env) { + return 1; + } + + return min; +} + +function getSupportLevel(stream) { + const level = supportsColor(stream); + return translateLevel(level); +} + +module.exports = { + supportsColor: getSupportLevel, + stdout: getSupportLevel(process.stdout), + stderr: getSupportLevel(process.stderr) +}; + + +/***/ }), +/* 72 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = (flag, argv) => { + argv = argv || process.argv; + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); + const pos = argv.indexOf(prefix + flag); + const terminatorPos = argv.indexOf('--'); + return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); +}; + + +/***/ }), +/* 73 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = rfdc + +function rfdc (opts) { + opts = opts || {} + + if (opts.circles) return rfdcCircles(opts) + return opts.proto ? cloneProto : clone + + function cloneArray (a, fn) { + var keys = Object.keys(a) + var a2 = new Array(keys.length) + for (var i = 0; i < keys.length; i++) { + var k = keys[i] + var cur = a[k] + if (typeof cur !== 'object' || cur === null) { + a2[k] = cur + } else if (cur instanceof Date) { + a2[k] = new Date(cur) + } else { + a2[k] = fn(cur) + } + } + return a2 + } + + function clone (o) { + if (typeof o !== 'object' || o === null) return o + if (o instanceof Date) return new Date(o) + if (Array.isArray(o)) return cloneArray(o, clone) + var o2 = {} + for (var k in o) { + if (Object.hasOwnProperty.call(o, k) === false) continue + var cur = o[k] + if (typeof cur !== 'object' || cur === null) { + o2[k] = cur + } else if (cur instanceof Date) { + o2[k] = new Date(cur) + } else { + o2[k] = clone(cur) + } + } + return o2 + } + + function cloneProto (o) { + if (typeof o !== 'object' || o === null) return o + if (o instanceof Date) return new Date(o) + if (Array.isArray(o)) return cloneArray(o, cloneProto) + var o2 = {} + for (var k in o) { + var cur = o[k] + if (typeof cur !== 'object' || cur === null) { + o2[k] = cur + } else if (cur instanceof Date) { + o2[k] = new Date(cur) + } else { + o2[k] = cloneProto(cur) + } + } + return o2 + } +} + +function rfdcCircles (opts) { + var refs = [] + var refsNew = [] + + return opts.proto ? cloneProto : clone + + function cloneArray (a, fn) { + var keys = Object.keys(a) + var a2 = new Array(keys.length) + for (var i = 0; i < keys.length; i++) { + var k = keys[i] + var cur = a[k] + if (typeof cur !== 'object' || cur === null) { + a2[k] = cur + } else if (cur instanceof Date) { + a2[k] = new Date(cur) + } else { + var index = refs.indexOf(cur) + if (index !== -1) { + a2[k] = refsNew[index] + } else { + a2[k] = fn(cur) + } + } + } + return a2 + } + + function clone (o) { + if (typeof o !== 'object' || o === null) return o + if (o instanceof Date) return new Date(o) + if (Array.isArray(o)) return cloneArray(o, clone) + var o2 = {} + refs.push(o) + refsNew.push(o2) + for (var k in o) { + if (Object.hasOwnProperty.call(o, k) === false) continue + var cur = o[k] + if (typeof cur !== 'object' || cur === null) { + o2[k] = cur + } else if (cur instanceof Date) { + o2[k] = new Date(cur) + } else { + var i = refs.indexOf(cur) + if (i !== -1) { + o2[k] = refsNew[i] + } else { + o2[k] = clone(cur) + } + } + } + refs.pop() + refsNew.pop() + return o2 + } + + function cloneProto (o) { + if (typeof o !== 'object' || o === null) return o + if (o instanceof Date) return new Date(o) + if (Array.isArray(o)) return cloneArray(o, cloneProto) + var o2 = {} + refs.push(o) + refsNew.push(o2) + for (var k in o) { + var cur = o[k] + if (typeof cur !== 'object' || cur === null) { + o2[k] = cur + } else if (cur instanceof Date) { + o2[k] = new Date(cur) + } else { + var i = refs.indexOf(cur) + if (i !== -1) { + o2[k] = refsNew[i] + } else { + o2[k] = cloneProto(cur) + } + } + } + refs.pop() + refsNew.pop() + return o2 + } +} + + +/***/ }), +/* 74 */ +/***/ (function(module, exports, __webpack_require__) { + + + +const util = __webpack_require__(40); +const debug = __webpack_require__(65)('log4js:configuration'); + +const preProcessingListeners = []; +const listeners = []; + +const not = thing => !thing; + +const anObject = thing => thing && typeof thing === 'object' && !Array.isArray(thing); + +const validIdentifier = thing => /^[A-Za-z][A-Za-z0-9_]*$/g.test(thing); + +const anInteger = thing => thing && typeof thing === 'number' && Number.isInteger(thing); + +const addListener = (fn) => { + listeners.push(fn); + debug(`Added listener, now ${listeners.length} listeners`); +}; + +const addPreProcessingListener = (fn) => { + preProcessingListeners.push(fn); + debug(`Added pre-processing listener, now ${preProcessingListeners.length} listeners`); +}; + +const throwExceptionIf = (config, checks, message) => { + const tests = Array.isArray(checks) ? checks : [checks]; + tests.forEach((test) => { + if (test) { + throw new Error(`Problem with log4js configuration: (${util.inspect(config, { depth: 5 })})` + + ` - ${message}`); + } + }); +}; + +const configure = (candidate) => { + debug('New configuration to be validated: ', candidate); + throwExceptionIf(candidate, not(anObject(candidate)), 'must be an object.'); + + debug(`Calling pre-processing listeners (${preProcessingListeners.length})`); + preProcessingListeners.forEach(listener => listener(candidate)); + debug('Configuration pre-processing finished.'); + + debug(`Calling configuration listeners (${listeners.length})`); + listeners.forEach(listener => listener(candidate)); + debug('Configuration finished.'); +}; + +module.exports = { + configure, + addListener, + addPreProcessingListener, + throwExceptionIf, + anObject, + anInteger, + validIdentifier, + not +}; + + +/***/ }), +/* 75 */ +/***/ (function(module, exports, __webpack_require__) { + +const dateFormat = __webpack_require__(76); +const os = __webpack_require__(56); +const util = __webpack_require__(40); +const path = __webpack_require__(57); + +const styles = { + // styles + bold: [1, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + // grayscale + white: [37, 39], + grey: [90, 39], + black: [90, 39], + // colors + blue: [34, 39], + cyan: [36, 39], + green: [32, 39], + magenta: [35, 39], + red: [91, 39], + yellow: [33, 39] +}; + +function colorizeStart(style) { + return style ? `\x1B[${styles[style][0]}m` : ''; +} + +function colorizeEnd(style) { + return style ? `\x1B[${styles[style][1]}m` : ''; +} + +/** + * Taken from masylum's fork (https://github.com/masylum/log4js-node) + */ +function colorize(str, style) { + return colorizeStart(style) + str + colorizeEnd(style); +} + +function timestampLevelAndCategory(loggingEvent, colour) { + return colorize( + util.format( + '[%s] [%s] %s - ', + dateFormat.asString(loggingEvent.startTime), + loggingEvent.level.toString(), + loggingEvent.categoryName + ), + colour + ); +} + +/** + * BasicLayout is a simple layout for storing the logs. The logs are stored + * in following format: + *
+ * [startTime] [logLevel] categoryName - message\n
+ * 
+ * + * @author Stephan Strittmatter + */ +function basicLayout(loggingEvent) { + return timestampLevelAndCategory(loggingEvent) + util.format(...loggingEvent.data); +} + +/** + * colouredLayout - taken from masylum's fork. + * same as basicLayout, but with colours. + */ +function colouredLayout(loggingEvent) { + return timestampLevelAndCategory(loggingEvent, loggingEvent.level.colour) + util.format(...loggingEvent.data); +} + +function messagePassThroughLayout(loggingEvent) { + return util.format(...loggingEvent.data); +} + +function dummyLayout(loggingEvent) { + return loggingEvent.data[0]; +} + +/** + * PatternLayout + * Format for specifiers is %[padding].[truncation][field]{[format]} + * e.g. %5.10p - left pad the log level by 5 characters, up to a max of 10 + * Fields can be any of: + * - %r time in toLocaleTimeString format + * - %p log level + * - %c log category + * - %h hostname + * - %m log data + * - %d date in constious formats + * - %% % + * - %n newline + * - %z pid + * - %f filename + * - %l line number + * - %o column postion + * - %s call stack + * - %x{} add dynamic tokens to your log. Tokens are specified in the tokens parameter + * - %X{} add dynamic tokens to your log. Tokens are specified in logger context + * You can use %[ and %] to define a colored block. + * + * Tokens are specified as simple key:value objects. + * The key represents the token name whereas the value can be a string or function + * which is called to extract the value to put in the log message. If token is not + * found, it doesn't replace the field. + * + * A sample token would be: { 'pid' : function() { return process.pid; } } + * + * Takes a pattern string, array of tokens and returns a layout function. + * @return {Function} + * @param pattern + * @param tokens + * @param timezoneOffset + * + * @authors ['Stephan Strittmatter', 'Jan Schmidle'] + */ +function patternLayout(pattern, tokens) { + const TTCC_CONVERSION_PATTERN = '%r %p %c - %m%n'; + const regex = /%(-?[0-9]+)?(\.?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/; + + pattern = pattern || TTCC_CONVERSION_PATTERN; + + function categoryName(loggingEvent, specifier) { + let loggerName = loggingEvent.categoryName; + if (specifier) { + const precision = parseInt(specifier, 10); + const loggerNameBits = loggerName.split('.'); + if (precision < loggerNameBits.length) { + loggerName = loggerNameBits.slice(loggerNameBits.length - precision).join('.'); + } + } + return loggerName; + } + + function formatAsDate(loggingEvent, specifier) { + let format = dateFormat.ISO8601_FORMAT; + if (specifier) { + format = specifier; + // Pick up special cases + if (format === 'ISO8601') { + format = dateFormat.ISO8601_FORMAT; + } else if (format === 'ISO8601_WITH_TZ_OFFSET') { + format = dateFormat.ISO8601_WITH_TZ_OFFSET_FORMAT; + } else if (format === 'ABSOLUTE') { + format = dateFormat.ABSOLUTETIME_FORMAT; + } else if (format === 'DATE') { + format = dateFormat.DATETIME_FORMAT; + } + } + // Format the date + return dateFormat.asString(format, loggingEvent.startTime); + } + + function hostname() { + return os.hostname().toString(); + } + + function formatMessage(loggingEvent) { + return util.format(...loggingEvent.data); + } + + function endOfLine() { + return os.EOL; + } + + function logLevel(loggingEvent) { + return loggingEvent.level.toString(); + } + + function startTime(loggingEvent) { + return dateFormat.asString('hh:mm:ss', loggingEvent.startTime); + } + + function startColour(loggingEvent) { + return colorizeStart(loggingEvent.level.colour); + } + + function endColour(loggingEvent) { + return colorizeEnd(loggingEvent.level.colour); + } + + function percent() { + return '%'; + } + + function pid(loggingEvent) { + return loggingEvent && loggingEvent.pid ? loggingEvent.pid.toString() : process.pid.toString(); + } + + function clusterInfo() { + // this used to try to return the master and worker pids, + // but it would never have worked because master pid is not available to workers + // leaving this here to maintain compatibility for patterns + return pid(); + } + + function userDefined(loggingEvent, specifier) { + if (typeof tokens[specifier] !== 'undefined') { + return typeof tokens[specifier] === 'function' ? tokens[specifier](loggingEvent) : tokens[specifier]; + } + + return null; + } + + function contextDefined(loggingEvent, specifier) { + const resolver = loggingEvent.context[specifier]; + + if (typeof resolver !== 'undefined') { + return typeof resolver === 'function' ? resolver(loggingEvent) : resolver; + } + + return null; + } + + function fileName(loggingEvent, specifier) { + let filename = loggingEvent.fileName || ''; + if (specifier) { + const fileDepth = parseInt(specifier, 10); + const fileList = filename.split(path.sep); + if (fileList.length > fileDepth) { + filename = fileList.slice(-fileDepth).join(path.sep); + } + } + + return filename; + } + + function lineNumber(loggingEvent) { + return loggingEvent.lineNumber || ''; + } + + function columnNumber(loggingEvent) { + return loggingEvent.columnNumber || ''; + } + + function callStack(loggingEvent) { + return loggingEvent.callStack || ''; + } + + /* eslint quote-props:0 */ + const replacers = { + c: categoryName, + d: formatAsDate, + h: hostname, + m: formatMessage, + n: endOfLine, + p: logLevel, + r: startTime, + '[': startColour, + ']': endColour, + y: clusterInfo, + z: pid, + '%': percent, + x: userDefined, + X: contextDefined, + f: fileName, + l: lineNumber, + o: columnNumber, + s: callStack + }; + + function replaceToken(conversionCharacter, loggingEvent, specifier) { + return replacers[conversionCharacter](loggingEvent, specifier); + } + + function truncate(truncation, toTruncate) { + let len; + if (truncation) { + len = parseInt(truncation.substr(1), 10); + return toTruncate.substring(0, len); + } + + return toTruncate; + } + + function pad(padding, toPad) { + let len; + if (padding) { + if (padding.charAt(0) === '-') { + len = parseInt(padding.substr(1), 10); + // Right pad with spaces + while (toPad.length < len) { + toPad += ' '; + } + } else { + len = parseInt(padding, 10); + // Left pad with spaces + while (toPad.length < len) { + toPad = ` ${toPad}`; + } + } + } + return toPad; + } + + function truncateAndPad(toTruncAndPad, truncation, padding) { + let replacement = toTruncAndPad; + replacement = truncate(truncation, replacement); + replacement = pad(padding, replacement); + return replacement; + } + + return function (loggingEvent) { + let formattedString = ''; + let result; + let searchString = pattern; + + /* eslint no-cond-assign:0 */ + while ((result = regex.exec(searchString)) !== null) { + // const matchedString = result[0]; + const padding = result[1]; + const truncation = result[2]; + const conversionCharacter = result[3]; + const specifier = result[5]; + const text = result[6]; + + // Check if the pattern matched was just normal text + if (text) { + formattedString += text.toString(); + } else { + // Create a raw replacement string based on the conversion + // character and specifier + const replacement = replaceToken(conversionCharacter, loggingEvent, specifier); + formattedString += truncateAndPad(replacement, truncation, padding); + } + searchString = searchString.substr(result.index + result[0].length); + } + return formattedString; + }; +} + +const layoutMakers = { + messagePassThrough () { + return messagePassThroughLayout; + }, + basic () { + return basicLayout; + }, + colored () { + return colouredLayout; + }, + coloured () { + return colouredLayout; + }, + pattern (config) { + return patternLayout(config && config.pattern, config && config.tokens); + }, + dummy () { + return dummyLayout; + } +}; + +module.exports = { + basicLayout, + messagePassThroughLayout, + patternLayout, + colouredLayout, + coloredLayout: colouredLayout, + dummyLayout, + addLayout (name, serializerGenerator) { + layoutMakers[name] = serializerGenerator; + }, + layout (name, config) { + return layoutMakers[name] && layoutMakers[name](config); + } +}; + + +/***/ }), +/* 76 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function padWithZeros(vNumber, width) { + var numAsString = vNumber.toString(); + while (numAsString.length < width) { + numAsString = "0" + numAsString; + } + return numAsString; +} + +function addZero(vNumber) { + return padWithZeros(vNumber, 2); +} + +/** + * Formats the TimeOffset + * Thanks to http://www.svendtofte.com/code/date_format/ + * @private + */ +function offset(timezoneOffset) { + var os = Math.abs(timezoneOffset); + var h = String(Math.floor(os / 60)); + var m = String(os % 60); + if (h.length === 1) { + h = "0" + h; + } + if (m.length === 1) { + m = "0" + m; + } + return timezoneOffset < 0 ? "+" + h + m : "-" + h + m; +} + +function datePart(date, displayUTC, part) { + return displayUTC ? date["getUTC" + part]() : date["get" + part](); +} + +function asString(format, date) { + if (typeof format !== "string") { + date = format; + format = module.exports.ISO8601_FORMAT; + } + if (!date) { + date = module.exports.now(); + } + + var displayUTC = format.indexOf("O") > -1; + + var vDay = addZero(datePart(date, displayUTC, "Date")); + var vMonth = addZero(datePart(date, displayUTC, "Month") + 1); + var vYearLong = addZero(datePart(date, displayUTC, "FullYear")); + var vYearShort = addZero(vYearLong.substring(2, 4)); + var vYear = format.indexOf("yyyy") > -1 ? vYearLong : vYearShort; + var vHour = addZero(datePart(date, displayUTC, "Hours")); + var vMinute = addZero(datePart(date, displayUTC, "Minutes")); + var vSecond = addZero(datePart(date, displayUTC, "Seconds")); + var vMillisecond = padWithZeros( + datePart(date, displayUTC, "Milliseconds"), + 3 + ); + var vTimeZone = offset(date.getTimezoneOffset()); + var formatted = format + .replace(/dd/g, vDay) + .replace(/MM/g, vMonth) + .replace(/y{1,4}/g, vYear) + .replace(/hh/g, vHour) + .replace(/mm/g, vMinute) + .replace(/ss/g, vSecond) + .replace(/SSS/g, vMillisecond) + .replace(/O/g, vTimeZone); + return formatted; +} + +function extractDateParts(pattern, str, missingValuesDate) { + var matchers = [ + { + pattern: /y{1,4}/, + regexp: "\\d{1,4}", + fn: function(date, value) { + date.setFullYear(value); + } + }, + { + pattern: /MM/, + regexp: "\\d{1,2}", + fn: function(date, value) { + date.setMonth(value - 1); + } + }, + { + pattern: /dd/, + regexp: "\\d{1,2}", + fn: function(date, value) { + date.setDate(value); + } + }, + { + pattern: /hh/, + regexp: "\\d{1,2}", + fn: function(date, value) { + date.setHours(value); + } + }, + { + pattern: /mm/, + regexp: "\\d\\d", + fn: function(date, value) { + date.setMinutes(value); + } + }, + { + pattern: /ss/, + regexp: "\\d\\d", + fn: function(date, value) { + date.setSeconds(value); + } + }, + { + pattern: /SSS/, + regexp: "\\d\\d\\d", + fn: function(date, value) { + date.setMilliseconds(value); + } + }, + { + pattern: /O/, + regexp: "[+-]\\d{3,4}|Z", + fn: function(date, value) { + if (value === "Z") { + value = 0; + } + var offset = Math.abs(value); + var minutes = (offset % 100) + Math.floor(offset / 100) * 60; + date.setMinutes(date.getMinutes() + (value > 0 ? minutes : -minutes)); + } + } + ]; + + var parsedPattern = matchers.reduce( + function(p, m) { + if (m.pattern.test(p.regexp)) { + m.index = p.regexp.match(m.pattern).index; + p.regexp = p.regexp.replace(m.pattern, "(" + m.regexp + ")"); + } else { + m.index = -1; + } + return p; + }, + { regexp: pattern, index: [] } + ); + + var dateFns = matchers.filter(function(m) { + return m.index > -1; + }); + dateFns.sort(function(a, b) { + return a.index - b.index; + }); + + var matcher = new RegExp(parsedPattern.regexp); + var matches = matcher.exec(str); + if (matches) { + var date = missingValuesDate || module.exports.now(); + dateFns.forEach(function(f, i) { + f.fn(date, matches[i + 1]); + }); + return date; + } + + throw new Error( + "String '" + str + "' could not be parsed as '" + pattern + "'" + ); +} + +function parse(pattern, str, missingValuesDate) { + if (!pattern) { + throw new Error("pattern must be supplied"); + } + + return extractDateParts(pattern, str, missingValuesDate); +} + +/** + * Used for testing - replace this function with a fixed date. + */ +function now() { + return new Date(); +} + +module.exports = asString; +module.exports.asString = asString; +module.exports.parse = parse; +module.exports.now = now; +module.exports.ISO8601_FORMAT = "yyyy-MM-ddThh:mm:ss.SSS"; +module.exports.ISO8601_WITH_TZ_OFFSET_FORMAT = "yyyy-MM-ddThh:mm:ss.SSSO"; +module.exports.DATETIME_FORMAT = "dd MM yyyy hh:mm:ss.SSS"; +module.exports.ABSOLUTETIME_FORMAT = "hh:mm:ss.SSS"; + + +/***/ }), +/* 77 */ +/***/ (function(module, exports, __webpack_require__) { + + + +const configuration = __webpack_require__(74); + +const validColours = [ + 'white', 'grey', 'black', + 'blue', 'cyan', 'green', + 'magenta', 'red', 'yellow' +]; + +class Level { + constructor(level, levelStr, colour) { + this.level = level; + this.levelStr = levelStr; + this.colour = colour; + } + + toString() { + return this.levelStr; + } + + /** + * converts given String to corresponding Level + * @param {Level|String} sArg -- String value of Level OR Log4js.Level + * @param {Level} [defaultLevel] -- default Level, if no String representation + * @return {Level} + */ + static getLevel(sArg, defaultLevel) { + if (!sArg) { + return defaultLevel; + } + + if (sArg instanceof Level) { + return sArg; + } + + // a json-serialised level won't be an instance of Level (see issue #768) + if (sArg instanceof Object && sArg.levelStr) { + sArg = sArg.levelStr; + } + + return Level[sArg.toString().toUpperCase()] || defaultLevel; + } + + static addLevels(customLevels) { + if (customLevels) { + const levels = Object.keys(customLevels); + levels.forEach((l) => { + const levelStr = l.toUpperCase(); + Level[levelStr] = new Level( + customLevels[l].value, + levelStr, + customLevels[l].colour + ); + const existingLevelIndex = Level.levels.findIndex(lvl => lvl.levelStr === levelStr); + if (existingLevelIndex > -1) { + Level.levels[existingLevelIndex] = Level[levelStr]; + } else { + Level.levels.push(Level[levelStr]); + } + }); + Level.levels.sort((a, b) => a.level - b.level); + } + } + + + isLessThanOrEqualTo(otherLevel) { + if (typeof otherLevel === 'string') { + otherLevel = Level.getLevel(otherLevel); + } + return this.level <= otherLevel.level; + } + + isGreaterThanOrEqualTo(otherLevel) { + if (typeof otherLevel === 'string') { + otherLevel = Level.getLevel(otherLevel); + } + return this.level >= otherLevel.level; + } + + isEqualTo(otherLevel) { + if (typeof otherLevel === 'string') { + otherLevel = Level.getLevel(otherLevel); + } + return this.level === otherLevel.level; + } +} + +Level.levels = []; +Level.addLevels({ + ALL: { value: Number.MIN_VALUE, colour: 'grey' }, + TRACE: { value: 5000, colour: 'blue' }, + DEBUG: { value: 10000, colour: 'cyan' }, + INFO: { value: 20000, colour: 'green' }, + WARN: { value: 30000, colour: 'yellow' }, + ERROR: { value: 40000, colour: 'red' }, + FATAL: { value: 50000, colour: 'magenta' }, + MARK: { value: 9007199254740992, colour: 'grey' }, // 2^53 + OFF: { value: Number.MAX_VALUE, colour: 'grey' } +}); + +configuration.addListener((config) => { + const levelConfig = config.levels; + if (levelConfig) { + configuration.throwExceptionIf( + config, + configuration.not(configuration.anObject(levelConfig)), + 'levels must be an object' + ); + const newLevels = Object.keys(levelConfig); + newLevels.forEach((l) => { + configuration.throwExceptionIf( + config, + configuration.not(configuration.validIdentifier(l)), + `level name "${l}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)` + ); + configuration.throwExceptionIf( + config, + configuration.not(configuration.anObject(levelConfig[l])), + `level "${l}" must be an object` + ); + configuration.throwExceptionIf( + config, + configuration.not(levelConfig[l].value), + `level "${l}" must have a 'value' property` + ); + configuration.throwExceptionIf( + config, + configuration.not(configuration.anInteger(levelConfig[l].value)), + `level "${l}".value must have an integer value` + ); + configuration.throwExceptionIf( + config, + configuration.not(levelConfig[l].colour), + `level "${l}" must have a 'colour' property` + ); + configuration.throwExceptionIf( + config, + configuration.not(validColours.indexOf(levelConfig[l].colour) > -1), + `level "${l}".colour must be one of ${validColours.join(', ')}` + ); + }); + } +}); + +configuration.addListener((config) => { + Level.addLevels(config.levels); +}); + +module.exports = Level; + + +/***/ }), +/* 78 */ +/***/ (function(module, exports, __webpack_require__) { + +const path = __webpack_require__(57); +const debug = __webpack_require__(65)('log4js:appenders'); +const configuration = __webpack_require__(74); +const clustering = __webpack_require__(79); +const levels = __webpack_require__(77); +const layouts = __webpack_require__(75); +const adapters = __webpack_require__(83); + +// pre-load the core appenders so that webpack can find them +const coreAppenders = new Map(); +coreAppenders.set('console', __webpack_require__(84)); +coreAppenders.set('stdout', __webpack_require__(85)); +coreAppenders.set('stderr', __webpack_require__(86)); +coreAppenders.set('logLevelFilter', __webpack_require__(87)); +coreAppenders.set('categoryFilter', __webpack_require__(88)); +coreAppenders.set('noLogFilter', __webpack_require__(89)); +coreAppenders.set('file', __webpack_require__(90)); +coreAppenders.set('dateFile', __webpack_require__(143)); + +const appenders = new Map(); + +const tryLoading = (modulePath, config) => { + debug('Loading module from ', modulePath); + try { + return __webpack_require__(144)(modulePath); //eslint-disable-line + } catch (e) { + // if the module was found, and we still got an error, then raise it + configuration.throwExceptionIf( + config, + e.code !== 'MODULE_NOT_FOUND', + `appender "${modulePath}" could not be loaded (error was: ${e})` + ); + return undefined; + } +}; + +const loadAppenderModule = (type, config) => coreAppenders.get(type) + || tryLoading(`./${type}`, config) + || tryLoading(type, config) + || (__webpack_require__.c[__webpack_require__.s] && tryLoading(path.join(path.dirname(__webpack_require__.c[__webpack_require__.s].filename), type), config)) + || tryLoading(path.join(process.cwd(), type), config); + +const createAppender = (name, config) => { + const appenderConfig = config.appenders[name]; + const appenderModule = appenderConfig.type.configure + ? appenderConfig.type : loadAppenderModule(appenderConfig.type, config); + configuration.throwExceptionIf( + config, + configuration.not(appenderModule), + `appender "${name}" is not valid (type "${appenderConfig.type}" could not be found)` + ); + if (appenderModule.appender) { + debug(`DEPRECATION: Appender ${appenderConfig.type} exports an appender function.`); + } + if (appenderModule.shutdown) { + debug(`DEPRECATION: Appender ${appenderConfig.type} exports a shutdown function.`); + } + + debug(`${name}: clustering.isMaster ? ${clustering.isMaster()}`); + debug(`${name}: appenderModule is ${__webpack_require__(40).inspect(appenderModule)}`); // eslint-disable-line + return clustering.onlyOnMaster(() => { + debug(`calling appenderModule.configure for ${name} / ${appenderConfig.type}`); + return appenderModule.configure( + adapters.modifyConfig(appenderConfig), + layouts, + appender => appenders.get(appender), + levels + ); + }, () => {}); +}; + +const setup = (config) => { + appenders.clear(); + + Object.keys(config.appenders).forEach((name) => { + debug(`Creating appender ${name}`); + appenders.set(name, createAppender(name, config)); + }); +}; + +setup({ appenders: { out: { type: 'stdout' } } }); + +configuration.addListener((config) => { + configuration.throwExceptionIf( + config, + configuration.not(configuration.anObject(config.appenders)), + 'must have a property "appenders" of type object.' + ); + const appenderNames = Object.keys(config.appenders); + configuration.throwExceptionIf( + config, + configuration.not(appenderNames.length), + 'must define at least one appender.' + ); + + appenderNames.forEach((name) => { + configuration.throwExceptionIf( + config, + configuration.not(config.appenders[name].type), + `appender "${name}" is not valid (must be an object with property "type")` + ); + }); +}); + +configuration.addListener(setup); + +module.exports = appenders; + + +/***/ }), +/* 79 */ +/***/ (function(module, exports, __webpack_require__) { + +const debug = __webpack_require__(65)("log4js:clustering"); +const LoggingEvent = __webpack_require__(80); +const configuration = __webpack_require__(74); + +let disabled = false; +let cluster = null; +try { + cluster = __webpack_require__(82); //eslint-disable-line +} catch (e) { + debug("cluster module not present"); + disabled = true; +} + +const listeners = []; + +let pm2 = false; +let pm2InstanceVar = "NODE_APP_INSTANCE"; + +const isPM2Master = () => pm2 && process.env[pm2InstanceVar] === "0"; +const isMaster = () => disabled || cluster.isMaster || isPM2Master(); + +const sendToListeners = logEvent => { + listeners.forEach(l => l(logEvent)); +}; + +// in a multi-process node environment, worker loggers will use +// process.send +const receiver = (worker, message) => { + // prior to node v6, the worker parameter was not passed (args were message, handle) + debug("cluster message received from worker ", worker, ": ", message); + if (worker.topic && worker.data) { + message = worker; + worker = undefined; + } + if (message && message.topic && message.topic === "log4js:message") { + debug("received message: ", message.data); + const logEvent = LoggingEvent.deserialise(message.data); + sendToListeners(logEvent); + } +}; + +if (!disabled) { + configuration.addListener(config => { + // clear out the listeners, because configure has been called. + listeners.length = 0; + + ({ + pm2, + disableClustering: disabled, + pm2InstanceVar = "NODE_APP_INSTANCE" + } = config); + + debug(`clustering disabled ? ${disabled}`); + debug(`cluster.isMaster ? ${cluster && cluster.isMaster}`); + debug(`pm2 enabled ? ${pm2}`); + debug(`pm2InstanceVar = ${pm2InstanceVar}`); + debug(`process.env[${pm2InstanceVar}] = ${process.env[pm2InstanceVar]}`); + + // just in case configure is called after shutdown + if (pm2) { + process.removeListener("message", receiver); + } + if (cluster && cluster.removeListener) { + cluster.removeListener("message", receiver); + } + + if (disabled || config.disableClustering) { + debug("Not listening for cluster messages, because clustering disabled."); + } else if (isPM2Master()) { + // PM2 cluster support + // PM2 runs everything as workers - install pm2-intercom for this to work. + // we only want one of the app instances to write logs + debug("listening for PM2 broadcast messages"); + process.on("message", receiver); + } else if (cluster.isMaster) { + debug("listening for cluster messages"); + cluster.on("message", receiver); + } else { + debug("not listening for messages, because we are not a master process"); + } + }); +} + +module.exports = { + onlyOnMaster: (fn, notMaster) => (isMaster() ? fn() : notMaster), + isMaster, + send: msg => { + if (isMaster()) { + sendToListeners(msg); + } else { + if (!pm2) { + msg.cluster = { + workerId: cluster.worker.id, + worker: process.pid + }; + } + process.send({ topic: "log4js:message", data: msg.serialise() }); + } + }, + onMessage: listener => { + listeners.push(listener); + } +}; + + +/***/ }), +/* 80 */ +/***/ (function(module, exports, __webpack_require__) { + +const flatted = __webpack_require__(81); +const levels = __webpack_require__(77); + +/** + * @name LoggingEvent + * @namespace Log4js + */ +class LoggingEvent { + /** + * Models a logging event. + * @constructor + * @param {String} categoryName name of category + * @param {Log4js.Level} level level of message + * @param {Array} data objects to log + * @author Seth Chisamore + */ + constructor(categoryName, level, data, context, location) { + this.startTime = new Date(); + this.categoryName = categoryName; + this.data = data; + this.level = level; + this.context = Object.assign({}, context); + this.pid = process.pid; + + if (location) { + this.functionName = location.functionName; + this.fileName = location.fileName; + this.lineNumber = location.lineNumber; + this.columnNumber = location.columnNumber; + this.callStack = location.callStack; + } + } + + serialise() { + const logData = this.data.map((e) => { + // JSON.stringify(new Error('test')) returns {}, which is not really useful for us. + // The following allows us to serialize errors correctly. + if (e && e.message && e.stack) { + e = Object.assign({ message: e.message, stack: e.stack }, e); + } + return e; + }); + this.data = logData; + return flatted.stringify(this); + } + + static deserialise(serialised) { + let event; + try { + const rehydratedEvent = flatted.parse(serialised); + rehydratedEvent.data = rehydratedEvent.data.map((e) => { + if (e && e.message && e.stack) { + const fakeError = new Error(e); + Object.keys(e).forEach((key) => { fakeError[key] = e[key]; }); + e = fakeError; + } + return e; + }); + event = new LoggingEvent( + rehydratedEvent.categoryName, + levels.getLevel(rehydratedEvent.level.levelStr), + rehydratedEvent.data, + rehydratedEvent.context + ); + event.startTime = new Date(rehydratedEvent.startTime); + event.pid = rehydratedEvent.pid; + event.cluster = rehydratedEvent.cluster; + } catch (e) { + event = new LoggingEvent( + 'log4js', + levels.ERROR, + ['Unable to parse log:', serialised, 'because: ', e] + ); + } + + return event; + } +} + +module.exports = LoggingEvent; + + +/***/ }), +/* 81 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parse", function() { return parse; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stringify", function() { return stringify; }); +var Flatted = (function (Primitive, primitive) { + + /*! + * ISC License + * + * Copyright (c) 2018, Andrea Giammarchi, @WebReflection + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + + var Flatted = { + + parse: function parse(text, reviver) { + var input = JSON.parse(text, Primitives).map(primitives); + var value = input[0]; + var $ = reviver || noop; + var tmp = typeof value === 'object' && value ? + revive(input, new Set, value, $) : + value; + return $.call({'': tmp}, '', tmp); + }, + + stringify: function stringify(value, replacer, space) { + for (var + firstRun, + known = new Map, + input = [], + output = [], + $ = replacer && typeof replacer === typeof input ? + function (k, v) { + if (k === '' || -1 < replacer.indexOf(k)) return v; + } : + (replacer || noop), + i = +set(known, input, $.call({'': value}, '', value)), + replace = function (key, value) { + if (firstRun) { + firstRun = !firstRun; + return value; + // this was invoking twice each root object + // return i < 1 ? value : $.call(this, key, value); + } + var after = $.call(this, key, value); + switch (typeof after) { + case 'object': + if (after === null) return after; + case primitive: + return known.get(after) || set(known, input, after); + } + return after; + }; + i < input.length; i++ + ) { + firstRun = true; + output[i] = JSON.stringify(input[i], replace, space); + } + return '[' + output.join(',') + ']'; + } + + }; + + return Flatted; + + function noop(key, value) { + return value; + } + + function revive(input, parsed, output, $) { + return Object.keys(output).reduce( + function (output, key) { + var value = output[key]; + if (value instanceof Primitive) { + var tmp = input[value]; + if (typeof tmp === 'object' && !parsed.has(tmp)) { + parsed.add(tmp); + output[key] = $.call(output, key, revive(input, parsed, tmp, $)); + } else { + output[key] = $.call(output, key, tmp); + } + } else + output[key] = $.call(output, key, value); + return output; + }, + output + ); + } + + function set(known, input, value) { + var index = Primitive(input.push(value) - 1); + known.set(value, index); + return index; + } + + // the two kinds of primitives + // 1. the real one + // 2. the wrapped one + + function primitives(value) { + return value instanceof Primitive ? Primitive(value) : value; + } + + function Primitives(key, value) { + return typeof value === primitive ? new Primitive(value) : value; + } + +}(String, 'string')); +/* harmony default export */ __webpack_exports__["default"] = (Flatted); +var parse = Flatted.parse; +var stringify = Flatted.stringify; + + +/***/ }), +/* 82 */ +/***/ (function(module, exports) { + +module.exports = require("cluster"); + +/***/ }), +/* 83 */ +/***/ (function(module, exports) { + +function maxFileSizeUnitTransform(maxLogSize) { + if (typeof maxLogSize === 'number' && Number.isInteger(maxLogSize)) { + return maxLogSize; + } + + const units = { + K: 1024, + M: 1024 * 1024, + G: 1024 * 1024 * 1024, + }; + const validUnit = Object.keys(units); + const unit = maxLogSize.substr(maxLogSize.length - 1).toLocaleUpperCase(); + const value = maxLogSize.substring(0, maxLogSize.length - 1).trim(); + + if (validUnit.indexOf(unit) < 0 || !Number.isInteger(Number(value))) { + throw Error(`maxLogSize: "${maxLogSize}" is invalid`); + } else { + return value * units[unit]; + } +} + +function adapter(configAdapter, config) { + const newConfig = Object.assign({}, config); + Object.keys(configAdapter).forEach((key) => { + if (newConfig[key]) { + newConfig[key] = configAdapter[key](config[key]); + } + }); + return newConfig; +} + +function fileAppenderAdapter(config) { + const configAdapter = { + maxLogSize: maxFileSizeUnitTransform + }; + return adapter(configAdapter, config); +} + +const adapters = { + file: fileAppenderAdapter, + fileSync: fileAppenderAdapter +}; + +module.exports.modifyConfig = config => (adapters[config.type] ? adapters[config.type](config) : config); + + +/***/ }), +/* 84 */ +/***/ (function(module, exports) { + +// eslint-disable-next-line no-console +const consoleLog = console.log.bind(console); + +function consoleAppender(layout, timezoneOffset) { + return (loggingEvent) => { + consoleLog(layout(loggingEvent, timezoneOffset)); + }; +} + +function configure(config, layouts) { + let layout = layouts.colouredLayout; + if (config.layout) { + layout = layouts.layout(config.layout.type, config.layout); + } + return consoleAppender(layout, config.timezoneOffset); +} + +module.exports.configure = configure; + + +/***/ }), +/* 85 */ +/***/ (function(module, exports) { + + + +function stdoutAppender(layout, timezoneOffset) { + return (loggingEvent) => { + process.stdout.write(`${layout(loggingEvent, timezoneOffset)}\n`); + }; +} + +function configure(config, layouts) { + let layout = layouts.colouredLayout; + if (config.layout) { + layout = layouts.layout(config.layout.type, config.layout); + } + return stdoutAppender(layout, config.timezoneOffset); +} + +exports.configure = configure; + + +/***/ }), +/* 86 */ +/***/ (function(module, exports) { + + + +function stderrAppender(layout, timezoneOffset) { + return (loggingEvent) => { + process.stderr.write(`${layout(loggingEvent, timezoneOffset)}\n`); + }; +} + +function configure(config, layouts) { + let layout = layouts.colouredLayout; + if (config.layout) { + layout = layouts.layout(config.layout.type, config.layout); + } + return stderrAppender(layout, config.timezoneOffset); +} + +module.exports.configure = configure; + + +/***/ }), +/* 87 */ +/***/ (function(module, exports) { + +function logLevelFilter(minLevelString, maxLevelString, appender, levels) { + const minLevel = levels.getLevel(minLevelString); + const maxLevel = levels.getLevel(maxLevelString, levels.FATAL); + return (logEvent) => { + const eventLevel = logEvent.level; + if (eventLevel.isGreaterThanOrEqualTo(minLevel) && eventLevel.isLessThanOrEqualTo(maxLevel)) { + appender(logEvent); + } + }; +} + +function configure(config, layouts, findAppender, levels) { + const appender = findAppender(config.appender); + return logLevelFilter(config.level, config.maxLevel, appender, levels); +} + +module.exports.configure = configure; + + +/***/ }), +/* 88 */ +/***/ (function(module, exports, __webpack_require__) { + +const debug = __webpack_require__(65)('log4js:categoryFilter'); + +function categoryFilter(excludes, appender) { + if (typeof excludes === 'string') excludes = [excludes]; + return (logEvent) => { + debug(`Checking ${logEvent.categoryName} against ${excludes}`); + if (excludes.indexOf(logEvent.categoryName) === -1) { + debug('Not excluded, sending to appender'); + appender(logEvent); + } + }; +} + +function configure(config, layouts, findAppender) { + const appender = findAppender(config.appender); + return categoryFilter(config.exclude, appender); +} + +module.exports.configure = configure; + + +/***/ }), +/* 89 */ +/***/ (function(module, exports, __webpack_require__) { + + + +const debug = __webpack_require__(65)('log4js:noLogFilter'); + +/** + * The function removes empty or null regexp from the array + * @param {Array} regexp + * @returns {Array} a filtered string array with not empty or null regexp + */ +function removeNullOrEmptyRegexp(regexp) { + const filtered = regexp.filter(el => ((el != null) && (el !== ''))); + return filtered; +} + +/** + * Returns a function that will exclude the events in case they match + * with the regular expressions provided + * @param {string | Array} filters contains the regexp that will be used for the evaluation + * @param {*} appender + * @returns {function} + */ +function noLogFilter(filters, appender) { + return (logEvent) => { + debug(`Checking data: ${logEvent.data} against filters: ${filters}`); + if (typeof filters === 'string') { + filters = [filters]; + } + filters = removeNullOrEmptyRegexp(filters); + const regex = new RegExp(filters.join('|'), 'i'); + if (filters.length === 0 + || logEvent.data.findIndex(value => regex.test(value)) < 0) { + debug('Not excluded, sending to appender'); + appender(logEvent); + } + }; +} + +function configure(config, layouts, findAppender) { + const appender = findAppender(config.appender); + return noLogFilter(config.exclude, appender); +} + +module.exports.configure = configure; + + +/***/ }), +/* 90 */ +/***/ (function(module, exports, __webpack_require__) { + +const debug = __webpack_require__(65)('log4js:file'); +const path = __webpack_require__(57); +const streams = __webpack_require__(91); +const os = __webpack_require__(56); + +const eol = os.EOL || '\n'; + +function openTheStream(file, fileSize, numFiles, options) { + const stream = new streams.RollingFileStream( + file, + fileSize, + numFiles, + options + ); + stream.on('error', (err) => { + console.error('log4js.fileAppender - Writing to file %s, error happened ', file, err); //eslint-disable-line + }); + return stream; +} + + +/** + * File Appender writing the logs to a text file. Supports rolling of logs by size. + * + * @param file file log messages will be written to + * @param layout a function that takes a logEvent and returns a string + * (defaults to basicLayout). + * @param logSize - the maximum size (in bytes) for a log file, + * if not provided then logs won't be rotated. + * @param numBackups - the number of log files to keep after logSize + * has been reached (default 5) + * @param options - options to be passed to the underlying stream + * @param timezoneOffset - optional timezone offset in minutes (default system local) + */ +function fileAppender(file, layout, logSize, numBackups, options, timezoneOffset) { + file = path.normalize(file); + numBackups = numBackups === undefined ? 5 : numBackups; + // there has to be at least one backup if logSize has been specified + numBackups = numBackups === 0 ? 1 : numBackups; + + debug( + 'Creating file appender (', + file, ', ', + logSize, ', ', + numBackups, ', ', + options, ', ', + timezoneOffset, ')' + ); + + let writer = openTheStream(file, logSize, numBackups, options); + + const app = function (loggingEvent) { + writer.write(layout(loggingEvent, timezoneOffset) + eol, 'utf8'); + }; + + app.reopen = function () { + writer.end(() => { writer = openTheStream(file, logSize, numBackups, options); }); + }; + + app.sighupHandler = function () { + debug('SIGHUP handler called.'); + app.reopen(); + }; + + app.shutdown = function (complete) { + process.removeListener('SIGHUP', app.sighupHandler); + writer.end('', 'utf-8', complete); + }; + + // On SIGHUP, close and reopen all files. This allows this appender to work with + // logrotate. Note that if you are using logrotate, you should not set + // `logSize`. + process.on('SIGHUP', app.sighupHandler); + + return app; +} + +function configure(config, layouts) { + let layout = layouts.basicLayout; + if (config.layout) { + layout = layouts.layout(config.layout.type, config.layout); + } + + return fileAppender( + config.filename, + layout, + config.maxLogSize, + config.backups, + config, + config.timezoneOffset + ); +} + +module.exports.configure = configure; + + +/***/ }), +/* 91 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { + RollingFileWriteStream: __webpack_require__(92), + RollingFileStream: __webpack_require__(141), + DateRollingFileStream: __webpack_require__(142) +}; + + +/***/ }), +/* 92 */ +/***/ (function(module, exports, __webpack_require__) { + +const debug = __webpack_require__(65)("streamroller:RollingFileWriteStream"); +const fs = __webpack_require__(93); +const zlib = __webpack_require__(137); +const path = __webpack_require__(57); +const newNow = __webpack_require__(138); +const format = __webpack_require__(76); +const { Writable } = __webpack_require__(41); +const fileNameFormatter = __webpack_require__(139); +const fileNameParser = __webpack_require__(140); + +/** + * RollingFileWriteStream is mainly used when writing to a file rolling by date or size. + * RollingFileWriteStream inherits from stream.Writable + */ +class RollingFileWriteStream extends Writable { + /** + * Create a RollingFileWriteStream + * @constructor + * @param {string} filePath - The file path to write. + * @param {object} options - The extra options + * @param {number} options.numToKeep - The max numbers of files to keep. + * @param {number} options.maxSize - The maxSize one file can reach. Unit is Byte. + * This should be more than 1024. The default is Number.MAX_SAFE_INTEGER. + * @param {string} options.mode - The mode of the files. The default is '0644'. Refer to stream.writable for more. + * @param {string} options.flags - The default is 'a'. Refer to stream.flags for more. + * @param {boolean} options.compress - Whether to compress backup files. + * @param {boolean} options.keepFileExt - Whether to keep the file extension. + * @param {string} options.pattern - The date string pattern in the file name. + * @param {boolean} options.alwaysIncludePattern - Whether to add date to the name of the first file. + */ + constructor(filePath, options) { + debug(`constructor: creating RollingFileWriteStream. path=${filePath}`); + super(options); + this.options = this._parseOption(options); + this.fileObject = path.parse(filePath); + if (this.fileObject.dir === "") { + this.fileObject = path.parse(path.join(process.cwd(), filePath)); + } + this.fileFormatter = fileNameFormatter({ + file: this.fileObject, + alwaysIncludeDate: this.options.alwaysIncludePattern, + needsIndex: this.options.maxSize < Number.MAX_SAFE_INTEGER, + compress: this.options.compress, + keepFileExt: this.options.keepFileExt + }); + + this.fileNameParser = fileNameParser({ + file: this.fileObject, + keepFileExt: this.options.keepFileExt, + pattern: this.options.pattern + }); + + this.state = { + currentSize: 0 + }; + + if (this.options.pattern) { + this.state.currentDate = format(this.options.pattern, newNow()); + } + + this.filename = this.fileFormatter({ + index: 0, + date: this.state.currentDate + }); + if (["a", "a+", "as", "as+"].includes(this.options.flags)) { + this._setExistingSizeAndDate(); + } + + debug( + `constructor: create new file ${this.filename}, state=${JSON.stringify( + this.state + )}` + ); + this._renewWriteStream(); + } + + _setExistingSizeAndDate() { + try { + const stats = fs.statSync(this.filename); + this.state.currentSize = stats.size; + if (this.options.pattern) { + this.state.currentDate = format(this.options.pattern, stats.birthtime); + } + } catch (e) { + //file does not exist, that's fine - move along + return; + } + } + + _parseOption(rawOptions) { + const defaultOptions = { + maxSize: Number.MAX_SAFE_INTEGER, + numToKeep: Number.MAX_SAFE_INTEGER, + encoding: "utf8", + mode: parseInt("0644", 8), + flags: "a", + compress: false, + keepFileExt: false, + alwaysIncludePattern: false + }; + const options = Object.assign({}, defaultOptions, rawOptions); + if (options.maxSize <= 0) { + throw new Error(`options.maxSize (${options.maxSize}) should be > 0`); + } + if (options.numToKeep <= 0) { + throw new Error(`options.numToKeep (${options.numToKeep}) should be > 0`); + } + debug( + `_parseOption: creating stream with option=${JSON.stringify(options)}` + ); + return options; + } + + _final(callback) { + this.currentFileStream.end("", this.options.encoding, callback); + } + + _write(chunk, encoding, callback) { + this._shouldRoll().then(() => { + debug( + `_write: writing chunk. ` + + `file=${this.currentFileStream.path} ` + + `state=${JSON.stringify(this.state)} ` + + `chunk=${chunk}` + ); + this.currentFileStream.write(chunk, encoding, e => { + this.state.currentSize += chunk.length; + callback(e); + }); + }); + } + + async _shouldRoll() { + if (this._dateChanged() || this._tooBig()) { + debug( + `_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}` + ); + await this._roll(); + } + } + + _dateChanged() { + return ( + this.state.currentDate && + this.state.currentDate !== format(this.options.pattern, newNow()) + ); + } + + _tooBig() { + return this.state.currentSize >= this.options.maxSize; + } + + _roll() { + debug(`_roll: closing the current stream`); + return new Promise((resolve, reject) => { + this.currentFileStream.end("", this.options.encoding, () => { + this._moveOldFiles() + .then(resolve) + .catch(reject); + }); + }); + } + + async _moveOldFiles() { + const files = await this._getExistingFiles(); + const todaysFiles = this.state.currentDate + ? files.filter(f => f.date === this.state.currentDate) + : files; + for (let i = todaysFiles.length; i >= 0; i--) { + debug(`_moveOldFiles: i = ${i}`); + const sourceFilePath = this.fileFormatter({ + date: this.state.currentDate, + index: i + }); + const targetFilePath = this.fileFormatter({ + date: this.state.currentDate, + index: i + 1 + }); + + await moveAndMaybeCompressFile( + sourceFilePath, + targetFilePath, + this.options.compress && i === 0 + ); + } + + this.state.currentSize = 0; + this.state.currentDate = this.state.currentDate + ? format(this.options.pattern, newNow()) + : null; + debug( + `_moveOldFiles: finished rolling files. state=${JSON.stringify( + this.state + )}` + ); + this._renewWriteStream(); + // wait for the file to be open before cleaning up old ones, + // otherwise the daysToKeep calculations can be off + await new Promise((resolve, reject) => { + this.currentFileStream.write("", "utf8", () => { + this._clean() + .then(resolve) + .catch(reject); + }); + }); + } + + // Sorted from the oldest to the latest + async _getExistingFiles() { + const files = await fs.readdir(this.fileObject.dir).catch(() => []); + + debug(`_getExistingFiles: files=${files}`); + const existingFileDetails = files + .map(n => this.fileNameParser(n)) + .filter(n => n); + + const getKey = n => + (n.timestamp ? n.timestamp : newNow().getTime()) - n.index; + existingFileDetails.sort((a, b) => getKey(a) - getKey(b)); + + return existingFileDetails; + } + + _renewWriteStream() { + fs.ensureDirSync(this.fileObject.dir); + const filePath = this.fileFormatter({ + date: this.state.currentDate, + index: 0 + }); + const ops = { + flags: this.options.flags, + encoding: this.options.encoding, + mode: this.options.mode + }; + this.currentFileStream = fs.createWriteStream(filePath, ops); + this.currentFileStream.on("error", e => { + this.emit("error", e); + }); + } + + async _clean() { + const existingFileDetails = await this._getExistingFiles(); + debug( + `_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${existingFileDetails.length}` + ); + debug("_clean: existing files are: ", existingFileDetails); + if (this._tooManyFiles(existingFileDetails.length)) { + const fileNamesToRemove = existingFileDetails + .map(f => path.format({ dir: this.fileObject.dir, base: f.filename })) + .slice(0, existingFileDetails.length - this.options.numToKeep - 1); + await deleteFiles(fileNamesToRemove); + } + } + + _tooManyFiles(numFiles) { + return this.options.numToKeep > 0 && numFiles > this.options.numToKeep; + } +} + +const moveAndMaybeCompressFile = async ( + sourceFilePath, + targetFilePath, + needCompress +) => { + if (sourceFilePath === targetFilePath) { + debug( + `moveAndMaybeCompressFile: source and target are the same, not doing anything` + ); + return; + } + try { + await fs.access(sourceFilePath, fs.constants.W_OK | fs.constants.R_OK); + + debug( + `moveAndMaybeCompressFile: moving file from ${sourceFilePath} to ${targetFilePath} ${ + needCompress ? "with" : "without" + } compress` + ); + if (needCompress) { + await new Promise((resolve, reject) => { + fs.createReadStream(sourceFilePath) + .pipe(zlib.createGzip()) + .pipe(fs.createWriteStream(targetFilePath)) + .on("finish", () => { + debug( + `moveAndMaybeCompressFile: finished compressing ${targetFilePath}, deleting ${sourceFilePath}` + ); + fs.unlink(sourceFilePath) + .then(resolve) + .catch(reject); + }); + }); + } else { + debug( + `moveAndMaybeCompressFile: deleting file=${targetFilePath}, renaming ${sourceFilePath} to ${targetFilePath}` + ); + await fs.unlink(targetFilePath).catch(() => { + /* doesn't matter */ + }); + await fs.rename(sourceFilePath, targetFilePath); + } + } catch (e) { + debug( + `moveAndMaybeCompressFile: source file path does not exist. not moving. sourceFilePath=${sourceFilePath}` + ); + } +}; + +const deleteFiles = fileNames => { + debug(`deleteFiles: files to delete: ${fileNames}`); + return Promise.all(fileNames.map(f => fs.unlink(f))); +}; + +module.exports = RollingFileWriteStream; + + +/***/ }), +/* 93 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = Object.assign( + {}, + // Export promiseified graceful-fs: + __webpack_require__(94), + // Export extra methods: + __webpack_require__(102), + __webpack_require__(111), + __webpack_require__(114), + __webpack_require__(117), + __webpack_require__(123), + __webpack_require__(104), + __webpack_require__(132), + __webpack_require__(134), + __webpack_require__(136), + __webpack_require__(113), + __webpack_require__(115) +) + +// Export fs.promises as a getter property so that we don't trigger +// ExperimentalWarning before fs.promises is actually accessed. +const fs = __webpack_require__(55) +if (Object.getOwnPropertyDescriptor(fs, 'promises')) { + Object.defineProperty(module.exports, 'promises', { + get () { return fs.promises } + }) +} + + +/***/ }), +/* 94 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// This is adapted from https://github.com/normalize/mz +// Copyright (c) 2014-2016 Jonathan Ong me@jongleberry.com and Contributors +const u = __webpack_require__(95).fromCallback +const fs = __webpack_require__(96) + +const api = [ + 'access', + 'appendFile', + 'chmod', + 'chown', + 'close', + 'copyFile', + 'fchmod', + 'fchown', + 'fdatasync', + 'fstat', + 'fsync', + 'ftruncate', + 'futimes', + 'lchown', + 'lchmod', + 'link', + 'lstat', + 'mkdir', + 'mkdtemp', + 'open', + 'readFile', + 'readdir', + 'readlink', + 'realpath', + 'rename', + 'rmdir', + 'stat', + 'symlink', + 'truncate', + 'unlink', + 'utimes', + 'writeFile' +].filter(key => { + // Some commands are not available on some systems. Ex: + // fs.copyFile was added in Node.js v8.5.0 + // fs.mkdtemp was added in Node.js v5.10.0 + // fs.lchown is not available on at least some Linux + return typeof fs[key] === 'function' +}) + +// Export all keys: +Object.keys(fs).forEach(key => { + if (key === 'promises') { + // fs.promises is a getter property that triggers ExperimentalWarning + // Don't re-export it here, the getter is defined in "lib/index.js" + return + } + exports[key] = fs[key] +}) + +// Universalify async methods: +api.forEach(method => { + exports[method] = u(fs[method]) +}) + +// We differ from mz/fs in that we still ship the old, broken, fs.exists() +// since we are a drop-in replacement for the native module +exports.exists = function (filename, callback) { + if (typeof callback === 'function') { + return fs.exists(filename, callback) + } + return new Promise(resolve => { + return fs.exists(filename, resolve) + }) +} + +// fs.read() & fs.write need special treatment due to multiple callback args + +exports.read = function (fd, buffer, offset, length, position, callback) { + if (typeof callback === 'function') { + return fs.read(fd, buffer, offset, length, position, callback) + } + return new Promise((resolve, reject) => { + fs.read(fd, buffer, offset, length, position, (err, bytesRead, buffer) => { + if (err) return reject(err) + resolve({ bytesRead, buffer }) + }) + }) +} + +// Function signature can be +// fs.write(fd, buffer[, offset[, length[, position]]], callback) +// OR +// fs.write(fd, string[, position[, encoding]], callback) +// We need to handle both cases, so we use ...args +exports.write = function (fd, buffer, ...args) { + if (typeof args[args.length - 1] === 'function') { + return fs.write(fd, buffer, ...args) + } + + return new Promise((resolve, reject) => { + fs.write(fd, buffer, ...args, (err, bytesWritten, buffer) => { + if (err) return reject(err) + resolve({ bytesWritten, buffer }) + }) + }) +} + +// fs.realpath.native only available in Node v9.2+ +if (typeof fs.realpath.native === 'function') { + exports.realpath.native = u(fs.realpath.native) +} + + +/***/ }), +/* 95 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.fromCallback = function (fn) { + return Object.defineProperty(function () { + if (typeof arguments[arguments.length - 1] === 'function') fn.apply(this, arguments) + else { + return new Promise((resolve, reject) => { + arguments[arguments.length] = (err, res) => { + if (err) return reject(err) + resolve(res) + } + arguments.length++ + fn.apply(this, arguments) + }) + } + }, 'name', { value: fn.name }) +} + +exports.fromPromise = function (fn) { + return Object.defineProperty(function () { + const cb = arguments[arguments.length - 1] + if (typeof cb !== 'function') return fn.apply(this, arguments) + else fn.apply(this, arguments).then(r => cb(null, r), cb) + }, 'name', { value: fn.name }) +} + + +/***/ }), +/* 96 */ +/***/ (function(module, exports, __webpack_require__) { + +var fs = __webpack_require__(55) +var polyfills = __webpack_require__(97) +var legacy = __webpack_require__(99) +var clone = __webpack_require__(100) + +var util = __webpack_require__(40) + +/* istanbul ignore next - node 0.x polyfill */ +var gracefulQueue +var previousSymbol + +/* istanbul ignore else - node 0.x polyfill */ +if (typeof Symbol === 'function' && typeof Symbol.for === 'function') { + gracefulQueue = Symbol.for('graceful-fs.queue') + // This is used in testing by future versions + previousSymbol = Symbol.for('graceful-fs.previous') +} else { + gracefulQueue = '___graceful-fs.queue' + previousSymbol = '___graceful-fs.previous' +} + +function noop () {} + +var debug = noop +if (util.debuglog) + debug = util.debuglog('gfs4') +else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) + debug = function() { + var m = util.format.apply(util, arguments) + m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') + console.error(m) + } + +// Once time initialization +if (!global[gracefulQueue]) { + // This queue can be shared by multiple loaded instances + var queue = [] + Object.defineProperty(global, gracefulQueue, { + get: function() { + return queue + } + }) + + // Patch fs.close/closeSync to shared queue version, because we need + // to retry() whenever a close happens *anywhere* in the program. + // This is essential when multiple graceful-fs instances are + // in play at the same time. + fs.close = (function (fs$close) { + function close (fd, cb) { + return fs$close.call(fs, fd, function (err) { + // This function uses the graceful-fs shared queue + if (!err) { + retry() + } + + if (typeof cb === 'function') + cb.apply(this, arguments) + }) + } + + Object.defineProperty(close, previousSymbol, { + value: fs$close + }) + return close + })(fs.close) + + fs.closeSync = (function (fs$closeSync) { + function closeSync (fd) { + // This function uses the graceful-fs shared queue + fs$closeSync.apply(fs, arguments) + retry() + } + + Object.defineProperty(closeSync, previousSymbol, { + value: fs$closeSync + }) + return closeSync + })(fs.closeSync) + + if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { + process.on('exit', function() { + debug(global[gracefulQueue]) + __webpack_require__(101).equal(global[gracefulQueue].length, 0) + }) + } +} + +module.exports = patch(clone(fs)) +if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { + module.exports = patch(fs) + fs.__patched = true; +} + +function patch (fs) { + // Everything that references the open() function needs to be in here + polyfills(fs) + fs.gracefulify = patch + + fs.createReadStream = createReadStream + fs.createWriteStream = createWriteStream + var fs$readFile = fs.readFile + fs.readFile = readFile + function readFile (path, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$readFile(path, options, cb) + + function go$readFile (path, options, cb) { + return fs$readFile(path, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readFile, [path, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + var fs$writeFile = fs.writeFile + fs.writeFile = writeFile + function writeFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$writeFile(path, data, options, cb) + + function go$writeFile (path, data, options, cb) { + return fs$writeFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$writeFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + var fs$appendFile = fs.appendFile + if (fs$appendFile) + fs.appendFile = appendFile + function appendFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$appendFile(path, data, options, cb) + + function go$appendFile (path, data, options, cb) { + return fs$appendFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$appendFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + var fs$readdir = fs.readdir + fs.readdir = readdir + function readdir (path, options, cb) { + var args = [path] + if (typeof options !== 'function') { + args.push(options) + } else { + cb = options + } + args.push(go$readdir$cb) + + return go$readdir(args) + + function go$readdir$cb (err, files) { + if (files && files.sort) + files.sort() + + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readdir, [args]]) + + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + } + } + + function go$readdir (args) { + return fs$readdir.apply(fs, args) + } + + if (process.version.substr(0, 4) === 'v0.8') { + var legStreams = legacy(fs) + ReadStream = legStreams.ReadStream + WriteStream = legStreams.WriteStream + } + + var fs$ReadStream = fs.ReadStream + if (fs$ReadStream) { + ReadStream.prototype = Object.create(fs$ReadStream.prototype) + ReadStream.prototype.open = ReadStream$open + } + + var fs$WriteStream = fs.WriteStream + if (fs$WriteStream) { + WriteStream.prototype = Object.create(fs$WriteStream.prototype) + WriteStream.prototype.open = WriteStream$open + } + + Object.defineProperty(fs, 'ReadStream', { + get: function () { + return ReadStream + }, + set: function (val) { + ReadStream = val + }, + enumerable: true, + configurable: true + }) + Object.defineProperty(fs, 'WriteStream', { + get: function () { + return WriteStream + }, + set: function (val) { + WriteStream = val + }, + enumerable: true, + configurable: true + }) + + // legacy names + Object.defineProperty(fs, 'FileReadStream', { + get: function () { + return ReadStream + }, + set: function (val) { + ReadStream = val + }, + enumerable: true, + configurable: true + }) + Object.defineProperty(fs, 'FileWriteStream', { + get: function () { + return WriteStream + }, + set: function (val) { + WriteStream = val + }, + enumerable: true, + configurable: true + }) + + function ReadStream (path, options) { + if (this instanceof ReadStream) + return fs$ReadStream.apply(this, arguments), this + else + return ReadStream.apply(Object.create(ReadStream.prototype), arguments) + } + + function ReadStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + if (that.autoClose) + that.destroy() + + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + that.read() + } + }) + } + + function WriteStream (path, options) { + if (this instanceof WriteStream) + return fs$WriteStream.apply(this, arguments), this + else + return WriteStream.apply(Object.create(WriteStream.prototype), arguments) + } + + function WriteStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + that.destroy() + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + } + }) + } + + function createReadStream (path, options) { + return new fs.ReadStream(path, options) + } + + function createWriteStream (path, options) { + return new fs.WriteStream(path, options) + } + + var fs$open = fs.open + fs.open = open + function open (path, flags, mode, cb) { + if (typeof mode === 'function') + cb = mode, mode = null + + return go$open(path, flags, mode, cb) + + function go$open (path, flags, mode, cb) { + return fs$open(path, flags, mode, function (err, fd) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$open, [path, flags, mode, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + return fs +} + +function enqueue (elem) { + debug('ENQUEUE', elem[0].name, elem[1]) + global[gracefulQueue].push(elem) +} + +function retry () { + var elem = global[gracefulQueue].shift() + if (elem) { + debug('RETRY', elem[0].name, elem[1]) + elem[0].apply(null, elem[1]) + } +} + + +/***/ }), +/* 97 */ +/***/ (function(module, exports, __webpack_require__) { + +var constants = __webpack_require__(98) + +var origCwd = process.cwd +var cwd = null + +var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform + +process.cwd = function() { + if (!cwd) + cwd = origCwd.call(process) + return cwd +} +try { + process.cwd() +} catch (er) {} + +var chdir = process.chdir +process.chdir = function(d) { + cwd = null + chdir.call(process, d) +} + +module.exports = patch + +function patch (fs) { + // (re-)implement some things that are known busted or missing. + + // lchmod, broken prior to 0.6.2 + // back-port the fix here. + if (constants.hasOwnProperty('O_SYMLINK') && + process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { + patchLchmod(fs) + } + + // lutimes implementation, or no-op + if (!fs.lutimes) { + patchLutimes(fs) + } + + // https://github.com/isaacs/node-graceful-fs/issues/4 + // Chown should not fail on einval or eperm if non-root. + // It should not fail on enosys ever, as this just indicates + // that a fs doesn't support the intended operation. + + fs.chown = chownFix(fs.chown) + fs.fchown = chownFix(fs.fchown) + fs.lchown = chownFix(fs.lchown) + + fs.chmod = chmodFix(fs.chmod) + fs.fchmod = chmodFix(fs.fchmod) + fs.lchmod = chmodFix(fs.lchmod) + + fs.chownSync = chownFixSync(fs.chownSync) + fs.fchownSync = chownFixSync(fs.fchownSync) + fs.lchownSync = chownFixSync(fs.lchownSync) + + fs.chmodSync = chmodFixSync(fs.chmodSync) + fs.fchmodSync = chmodFixSync(fs.fchmodSync) + fs.lchmodSync = chmodFixSync(fs.lchmodSync) + + fs.stat = statFix(fs.stat) + fs.fstat = statFix(fs.fstat) + fs.lstat = statFix(fs.lstat) + + fs.statSync = statFixSync(fs.statSync) + fs.fstatSync = statFixSync(fs.fstatSync) + fs.lstatSync = statFixSync(fs.lstatSync) + + // if lchmod/lchown do not exist, then make them no-ops + if (!fs.lchmod) { + fs.lchmod = function (path, mode, cb) { + if (cb) process.nextTick(cb) + } + fs.lchmodSync = function () {} + } + if (!fs.lchown) { + fs.lchown = function (path, uid, gid, cb) { + if (cb) process.nextTick(cb) + } + fs.lchownSync = function () {} + } + + // on Windows, A/V software can lock the directory, causing this + // to fail with an EACCES or EPERM if the directory contains newly + // created files. Try again on failure, for up to 60 seconds. + + // Set the timeout this long because some Windows Anti-Virus, such as Parity + // bit9, may lock files for up to a minute, causing npm package install + // failures. Also, take care to yield the scheduler. Windows scheduling gives + // CPU to a busy looping process, which can cause the program causing the lock + // contention to be starved of CPU by node, so the contention doesn't resolve. + if (platform === "win32") { + fs.rename = (function (fs$rename) { return function (from, to, cb) { + var start = Date.now() + var backoff = 0; + fs$rename(from, to, function CB (er) { + if (er + && (er.code === "EACCES" || er.code === "EPERM") + && Date.now() - start < 60000) { + setTimeout(function() { + fs.stat(to, function (stater, st) { + if (stater && stater.code === "ENOENT") + fs$rename(from, to, CB); + else + cb(er) + }) + }, backoff) + if (backoff < 100) + backoff += 10; + return; + } + if (cb) cb(er) + }) + }})(fs.rename) + } + + // if read() returns EAGAIN, then just try it again. + fs.read = (function (fs$read) { + function read (fd, buffer, offset, length, position, callback_) { + var callback + if (callback_ && typeof callback_ === 'function') { + var eagCounter = 0 + callback = function (er, _, __) { + if (er && er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + } + callback_.apply(this, arguments) + } + } + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + } + + // This ensures `util.promisify` works as it does for native `fs.read`. + read.__proto__ = fs$read + return read + })(fs.read) + + fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { + var eagCounter = 0 + while (true) { + try { + return fs$readSync.call(fs, fd, buffer, offset, length, position) + } catch (er) { + if (er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + continue + } + throw er + } + } + }})(fs.readSync) + + function patchLchmod (fs) { + fs.lchmod = function (path, mode, callback) { + fs.open( path + , constants.O_WRONLY | constants.O_SYMLINK + , mode + , function (err, fd) { + if (err) { + if (callback) callback(err) + return + } + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + fs.fchmod(fd, mode, function (err) { + fs.close(fd, function(err2) { + if (callback) callback(err || err2) + }) + }) + }) + } + + fs.lchmodSync = function (path, mode) { + var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) + + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + var threw = true + var ret + try { + ret = fs.fchmodSync(fd, mode) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } + } + + function patchLutimes (fs) { + if (constants.hasOwnProperty("O_SYMLINK")) { + fs.lutimes = function (path, at, mt, cb) { + fs.open(path, constants.O_SYMLINK, function (er, fd) { + if (er) { + if (cb) cb(er) + return + } + fs.futimes(fd, at, mt, function (er) { + fs.close(fd, function (er2) { + if (cb) cb(er || er2) + }) + }) + }) + } + + fs.lutimesSync = function (path, at, mt) { + var fd = fs.openSync(path, constants.O_SYMLINK) + var ret + var threw = true + try { + ret = fs.futimesSync(fd, at, mt) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } + + } else { + fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } + fs.lutimesSync = function () {} + } + } + + function chmodFix (orig) { + if (!orig) return orig + return function (target, mode, cb) { + return orig.call(fs, target, mode, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } + } + + function chmodFixSync (orig) { + if (!orig) return orig + return function (target, mode) { + try { + return orig.call(fs, target, mode) + } catch (er) { + if (!chownErOk(er)) throw er + } + } + } + + + function chownFix (orig) { + if (!orig) return orig + return function (target, uid, gid, cb) { + return orig.call(fs, target, uid, gid, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } + } + + function chownFixSync (orig) { + if (!orig) return orig + return function (target, uid, gid) { + try { + return orig.call(fs, target, uid, gid) + } catch (er) { + if (!chownErOk(er)) throw er + } + } + } + + function statFix (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + function callback (er, stats) { + if (stats) { + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + } + if (cb) cb.apply(this, arguments) + } + return options ? orig.call(fs, target, options, callback) + : orig.call(fs, target, callback) + } + } + + function statFixSync (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, options) { + var stats = options ? orig.call(fs, target, options) + : orig.call(fs, target) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + return stats; + } + } + + // ENOSYS means that the fs doesn't support the op. Just ignore + // that, because it doesn't matter. + // + // if there's no getuid, or if getuid() is something other + // than 0, and the error is EINVAL or EPERM, then just ignore + // it. + // + // This specific case is a silent failure in cp, install, tar, + // and most other unix tools that manage permissions. + // + // When running as root, or if other types of errors are + // encountered, then it's strict. + function chownErOk (er) { + if (!er) + return true + + if (er.code === "ENOSYS") + return true + + var nonroot = !process.getuid || process.getuid() !== 0 + if (nonroot) { + if (er.code === "EINVAL" || er.code === "EPERM") + return true + } + + return false + } +} + + +/***/ }), +/* 98 */ +/***/ (function(module, exports) { + +module.exports = require("constants"); + +/***/ }), +/* 99 */ +/***/ (function(module, exports, __webpack_require__) { + +var Stream = __webpack_require__(41).Stream + +module.exports = legacy + +function legacy (fs) { + return { + ReadStream: ReadStream, + WriteStream: WriteStream + } + + function ReadStream (path, options) { + if (!(this instanceof ReadStream)) return new ReadStream(path, options); + + Stream.call(this); + + var self = this; + + this.path = path; + this.fd = null; + this.readable = true; + this.paused = false; + + this.flags = 'r'; + this.mode = 438; /*=0666*/ + this.bufferSize = 64 * 1024; + + options = options || {}; + + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + + if (this.encoding) this.setEncoding(this.encoding); + + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.end === undefined) { + this.end = Infinity; + } else if ('number' !== typeof this.end) { + throw TypeError('end must be a Number'); + } + + if (this.start > this.end) { + throw new Error('start must be <= end'); + } + + this.pos = this.start; + } + + if (this.fd !== null) { + process.nextTick(function() { + self._read(); + }); + return; + } + + fs.open(this.path, this.flags, this.mode, function (err, fd) { + if (err) { + self.emit('error', err); + self.readable = false; + return; + } + + self.fd = fd; + self.emit('open', fd); + self._read(); + }) + } + + function WriteStream (path, options) { + if (!(this instanceof WriteStream)) return new WriteStream(path, options); + + Stream.call(this); + + this.path = path; + this.fd = null; + this.writable = true; + + this.flags = 'w'; + this.encoding = 'binary'; + this.mode = 438; /*=0666*/ + this.bytesWritten = 0; + + options = options || {}; + + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.start < 0) { + throw new Error('start must be >= zero'); + } + + this.pos = this.start; + } + + this.busy = false; + this._queue = []; + + if (this.fd === null) { + this._open = fs.open; + this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); + this.flush(); + } + } +} + + +/***/ }), +/* 100 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = clone + +function clone (obj) { + if (obj === null || typeof obj !== 'object') + return obj + + if (obj instanceof Object) + var copy = { __proto__: obj.__proto__ } + else + var copy = Object.create(null) + + Object.getOwnPropertyNames(obj).forEach(function (key) { + Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) + }) + + return copy +} + + +/***/ }), +/* 101 */ +/***/ (function(module, exports) { + +module.exports = require("assert"); + +/***/ }), +/* 102 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = { + copySync: __webpack_require__(103) +} + + +/***/ }), +/* 103 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const fs = __webpack_require__(96) +const path = __webpack_require__(57) +const mkdirpSync = __webpack_require__(104).mkdirsSync +const utimesSync = __webpack_require__(108).utimesMillisSync +const stat = __webpack_require__(109) + +function copySync (src, dest, opts) { + if (typeof opts === 'function') { + opts = { filter: opts } + } + + opts = opts || {} + opts.clobber = 'clobber' in opts ? !!opts.clobber : true // default to true for now + opts.overwrite = 'overwrite' in opts ? !!opts.overwrite : opts.clobber // overwrite falls back to clobber + + // Warn about using preserveTimestamps on 32-bit node + if (opts.preserveTimestamps && process.arch === 'ia32') { + console.warn(`fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n + see https://github.com/jprichardson/node-fs-extra/issues/269`) + } + + const { srcStat, destStat } = stat.checkPathsSync(src, dest, 'copy') + stat.checkParentPathsSync(src, srcStat, dest, 'copy') + return handleFilterAndCopy(destStat, src, dest, opts) +} + +function handleFilterAndCopy (destStat, src, dest, opts) { + if (opts.filter && !opts.filter(src, dest)) return + const destParent = path.dirname(dest) + if (!fs.existsSync(destParent)) mkdirpSync(destParent) + return startCopy(destStat, src, dest, opts) +} + +function startCopy (destStat, src, dest, opts) { + if (opts.filter && !opts.filter(src, dest)) return + return getStats(destStat, src, dest, opts) +} + +function getStats (destStat, src, dest, opts) { + const statSync = opts.dereference ? fs.statSync : fs.lstatSync + const srcStat = statSync(src) + + if (srcStat.isDirectory()) return onDir(srcStat, destStat, src, dest, opts) + else if (srcStat.isFile() || + srcStat.isCharacterDevice() || + srcStat.isBlockDevice()) return onFile(srcStat, destStat, src, dest, opts) + else if (srcStat.isSymbolicLink()) return onLink(destStat, src, dest, opts) +} + +function onFile (srcStat, destStat, src, dest, opts) { + if (!destStat) return copyFile(srcStat, src, dest, opts) + return mayCopyFile(srcStat, src, dest, opts) +} + +function mayCopyFile (srcStat, src, dest, opts) { + if (opts.overwrite) { + fs.unlinkSync(dest) + return copyFile(srcStat, src, dest, opts) + } else if (opts.errorOnExist) { + throw new Error(`'${dest}' already exists`) + } +} + +function copyFile (srcStat, src, dest, opts) { + if (typeof fs.copyFileSync === 'function') { + fs.copyFileSync(src, dest) + fs.chmodSync(dest, srcStat.mode) + if (opts.preserveTimestamps) { + return utimesSync(dest, srcStat.atime, srcStat.mtime) + } + return + } + return copyFileFallback(srcStat, src, dest, opts) +} + +function copyFileFallback (srcStat, src, dest, opts) { + const BUF_LENGTH = 64 * 1024 + const _buff = __webpack_require__(110)(BUF_LENGTH) + + const fdr = fs.openSync(src, 'r') + const fdw = fs.openSync(dest, 'w', srcStat.mode) + let pos = 0 + + while (pos < srcStat.size) { + const bytesRead = fs.readSync(fdr, _buff, 0, BUF_LENGTH, pos) + fs.writeSync(fdw, _buff, 0, bytesRead) + pos += bytesRead + } + + if (opts.preserveTimestamps) fs.futimesSync(fdw, srcStat.atime, srcStat.mtime) + + fs.closeSync(fdr) + fs.closeSync(fdw) +} + +function onDir (srcStat, destStat, src, dest, opts) { + if (!destStat) return mkDirAndCopy(srcStat, src, dest, opts) + if (destStat && !destStat.isDirectory()) { + throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`) + } + return copyDir(src, dest, opts) +} + +function mkDirAndCopy (srcStat, src, dest, opts) { + fs.mkdirSync(dest) + copyDir(src, dest, opts) + return fs.chmodSync(dest, srcStat.mode) +} + +function copyDir (src, dest, opts) { + fs.readdirSync(src).forEach(item => copyDirItem(item, src, dest, opts)) +} + +function copyDirItem (item, src, dest, opts) { + const srcItem = path.join(src, item) + const destItem = path.join(dest, item) + const { destStat } = stat.checkPathsSync(srcItem, destItem, 'copy') + return startCopy(destStat, srcItem, destItem, opts) +} + +function onLink (destStat, src, dest, opts) { + let resolvedSrc = fs.readlinkSync(src) + if (opts.dereference) { + resolvedSrc = path.resolve(process.cwd(), resolvedSrc) + } + + if (!destStat) { + return fs.symlinkSync(resolvedSrc, dest) + } else { + let resolvedDest + try { + resolvedDest = fs.readlinkSync(dest) + } catch (err) { + // dest exists and is a regular file or directory, + // Windows may throw UNKNOWN error. If dest already exists, + // fs throws error anyway, so no need to guard against it here. + if (err.code === 'EINVAL' || err.code === 'UNKNOWN') return fs.symlinkSync(resolvedSrc, dest) + throw err + } + if (opts.dereference) { + resolvedDest = path.resolve(process.cwd(), resolvedDest) + } + if (stat.isSrcSubdir(resolvedSrc, resolvedDest)) { + throw new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`) + } + + // prevent copy if src is a subdir of dest since unlinking + // dest in this case would result in removing src contents + // and therefore a broken symlink would be created. + if (fs.statSync(dest).isDirectory() && stat.isSrcSubdir(resolvedDest, resolvedSrc)) { + throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`) + } + return copyLink(resolvedSrc, dest) + } +} + +function copyLink (resolvedSrc, dest) { + fs.unlinkSync(dest) + return fs.symlinkSync(resolvedSrc, dest) +} + +module.exports = copySync + + +/***/ }), +/* 104 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const u = __webpack_require__(95).fromCallback +const mkdirs = u(__webpack_require__(105)) +const mkdirsSync = __webpack_require__(107) + +module.exports = { + mkdirs, + mkdirsSync, + // alias + mkdirp: mkdirs, + mkdirpSync: mkdirsSync, + ensureDir: mkdirs, + ensureDirSync: mkdirsSync +} + + +/***/ }), +/* 105 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const fs = __webpack_require__(96) +const path = __webpack_require__(57) +const invalidWin32Path = __webpack_require__(106).invalidWin32Path + +const o777 = parseInt('0777', 8) + +function mkdirs (p, opts, callback, made) { + if (typeof opts === 'function') { + callback = opts + opts = {} + } else if (!opts || typeof opts !== 'object') { + opts = { mode: opts } + } + + if (process.platform === 'win32' && invalidWin32Path(p)) { + const errInval = new Error(p + ' contains invalid WIN32 path characters.') + errInval.code = 'EINVAL' + return callback(errInval) + } + + let mode = opts.mode + const xfs = opts.fs || fs + + if (mode === undefined) { + mode = o777 & (~process.umask()) + } + if (!made) made = null + + callback = callback || function () {} + p = path.resolve(p) + + xfs.mkdir(p, mode, er => { + if (!er) { + made = made || p + return callback(null, made) + } + switch (er.code) { + case 'ENOENT': + if (path.dirname(p) === p) return callback(er) + mkdirs(path.dirname(p), opts, (er, made) => { + if (er) callback(er, made) + else mkdirs(p, opts, callback, made) + }) + break + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + xfs.stat(p, (er2, stat) => { + // if the stat fails, then that's super weird. + // let the original error be the failure reason. + if (er2 || !stat.isDirectory()) callback(er, made) + else callback(null, made) + }) + break + } + }) +} + +module.exports = mkdirs + + +/***/ }), +/* 106 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const path = __webpack_require__(57) + +// get drive on windows +function getRootPath (p) { + p = path.normalize(path.resolve(p)).split(path.sep) + if (p.length > 0) return p[0] + return null +} + +// http://stackoverflow.com/a/62888/10333 contains more accurate +// TODO: expand to include the rest +const INVALID_PATH_CHARS = /[<>:"|?*]/ + +function invalidWin32Path (p) { + const rp = getRootPath(p) + p = p.replace(rp, '') + return INVALID_PATH_CHARS.test(p) +} + +module.exports = { + getRootPath, + invalidWin32Path +} + + +/***/ }), +/* 107 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const fs = __webpack_require__(96) +const path = __webpack_require__(57) +const invalidWin32Path = __webpack_require__(106).invalidWin32Path + +const o777 = parseInt('0777', 8) + +function mkdirsSync (p, opts, made) { + if (!opts || typeof opts !== 'object') { + opts = { mode: opts } + } + + let mode = opts.mode + const xfs = opts.fs || fs + + if (process.platform === 'win32' && invalidWin32Path(p)) { + const errInval = new Error(p + ' contains invalid WIN32 path characters.') + errInval.code = 'EINVAL' + throw errInval + } + + if (mode === undefined) { + mode = o777 & (~process.umask()) + } + if (!made) made = null + + p = path.resolve(p) + + try { + xfs.mkdirSync(p, mode) + made = made || p + } catch (err0) { + if (err0.code === 'ENOENT') { + if (path.dirname(p) === p) throw err0 + made = mkdirsSync(path.dirname(p), opts, made) + mkdirsSync(p, opts, made) + } else { + // In the case of any other error, just see if there's a dir there + // already. If so, then hooray! If not, then something is borked. + let stat + try { + stat = xfs.statSync(p) + } catch (err1) { + throw err0 + } + if (!stat.isDirectory()) throw err0 + } + } + + return made +} + +module.exports = mkdirsSync + + +/***/ }), +/* 108 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const fs = __webpack_require__(96) +const os = __webpack_require__(56) +const path = __webpack_require__(57) + +// HFS, ext{2,3}, FAT do not, Node.js v0.10 does not +function hasMillisResSync () { + let tmpfile = path.join('millis-test-sync' + Date.now().toString() + Math.random().toString().slice(2)) + tmpfile = path.join(os.tmpdir(), tmpfile) + + // 550 millis past UNIX epoch + const d = new Date(1435410243862) + fs.writeFileSync(tmpfile, 'https://github.com/jprichardson/node-fs-extra/pull/141') + const fd = fs.openSync(tmpfile, 'r+') + fs.futimesSync(fd, d, d) + fs.closeSync(fd) + return fs.statSync(tmpfile).mtime > 1435410243000 +} + +function hasMillisRes (callback) { + let tmpfile = path.join('millis-test' + Date.now().toString() + Math.random().toString().slice(2)) + tmpfile = path.join(os.tmpdir(), tmpfile) + + // 550 millis past UNIX epoch + const d = new Date(1435410243862) + fs.writeFile(tmpfile, 'https://github.com/jprichardson/node-fs-extra/pull/141', err => { + if (err) return callback(err) + fs.open(tmpfile, 'r+', (err, fd) => { + if (err) return callback(err) + fs.futimes(fd, d, d, err => { + if (err) return callback(err) + fs.close(fd, err => { + if (err) return callback(err) + fs.stat(tmpfile, (err, stats) => { + if (err) return callback(err) + callback(null, stats.mtime > 1435410243000) + }) + }) + }) + }) + }) +} + +function timeRemoveMillis (timestamp) { + if (typeof timestamp === 'number') { + return Math.floor(timestamp / 1000) * 1000 + } else if (timestamp instanceof Date) { + return new Date(Math.floor(timestamp.getTime() / 1000) * 1000) + } else { + throw new Error('fs-extra: timeRemoveMillis() unknown parameter type') + } +} + +function utimesMillis (path, atime, mtime, callback) { + // if (!HAS_MILLIS_RES) return fs.utimes(path, atime, mtime, callback) + fs.open(path, 'r+', (err, fd) => { + if (err) return callback(err) + fs.futimes(fd, atime, mtime, futimesErr => { + fs.close(fd, closeErr => { + if (callback) callback(futimesErr || closeErr) + }) + }) + }) +} + +function utimesMillisSync (path, atime, mtime) { + const fd = fs.openSync(path, 'r+') + fs.futimesSync(fd, atime, mtime) + return fs.closeSync(fd) +} + +module.exports = { + hasMillisRes, + hasMillisResSync, + timeRemoveMillis, + utimesMillis, + utimesMillisSync +} + + +/***/ }), +/* 109 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const fs = __webpack_require__(96) +const path = __webpack_require__(57) + +const NODE_VERSION_MAJOR_WITH_BIGINT = 10 +const NODE_VERSION_MINOR_WITH_BIGINT = 5 +const NODE_VERSION_PATCH_WITH_BIGINT = 0 +const nodeVersion = process.versions.node.split('.') +const nodeVersionMajor = Number.parseInt(nodeVersion[0], 10) +const nodeVersionMinor = Number.parseInt(nodeVersion[1], 10) +const nodeVersionPatch = Number.parseInt(nodeVersion[2], 10) + +function nodeSupportsBigInt () { + if (nodeVersionMajor > NODE_VERSION_MAJOR_WITH_BIGINT) { + return true + } else if (nodeVersionMajor === NODE_VERSION_MAJOR_WITH_BIGINT) { + if (nodeVersionMinor > NODE_VERSION_MINOR_WITH_BIGINT) { + return true + } else if (nodeVersionMinor === NODE_VERSION_MINOR_WITH_BIGINT) { + if (nodeVersionPatch >= NODE_VERSION_PATCH_WITH_BIGINT) { + return true + } + } + } + return false +} + +function getStats (src, dest, cb) { + if (nodeSupportsBigInt()) { + fs.stat(src, { bigint: true }, (err, srcStat) => { + if (err) return cb(err) + fs.stat(dest, { bigint: true }, (err, destStat) => { + if (err) { + if (err.code === 'ENOENT') return cb(null, { srcStat, destStat: null }) + return cb(err) + } + return cb(null, { srcStat, destStat }) + }) + }) + } else { + fs.stat(src, (err, srcStat) => { + if (err) return cb(err) + fs.stat(dest, (err, destStat) => { + if (err) { + if (err.code === 'ENOENT') return cb(null, { srcStat, destStat: null }) + return cb(err) + } + return cb(null, { srcStat, destStat }) + }) + }) + } +} + +function getStatsSync (src, dest) { + let srcStat, destStat + if (nodeSupportsBigInt()) { + srcStat = fs.statSync(src, { bigint: true }) + } else { + srcStat = fs.statSync(src) + } + try { + if (nodeSupportsBigInt()) { + destStat = fs.statSync(dest, { bigint: true }) + } else { + destStat = fs.statSync(dest) + } + } catch (err) { + if (err.code === 'ENOENT') return { srcStat, destStat: null } + throw err + } + return { srcStat, destStat } +} + +function checkPaths (src, dest, funcName, cb) { + getStats(src, dest, (err, stats) => { + if (err) return cb(err) + const { srcStat, destStat } = stats + if (destStat && destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev) { + return cb(new Error('Source and destination must not be the same.')) + } + if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { + return cb(new Error(errMsg(src, dest, funcName))) + } + return cb(null, { srcStat, destStat }) + }) +} + +function checkPathsSync (src, dest, funcName) { + const { srcStat, destStat } = getStatsSync(src, dest) + if (destStat && destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev) { + throw new Error('Source and destination must not be the same.') + } + if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { + throw new Error(errMsg(src, dest, funcName)) + } + return { srcStat, destStat } +} + +// recursively check if dest parent is a subdirectory of src. +// It works for all file types including symlinks since it +// checks the src and dest inodes. It starts from the deepest +// parent and stops once it reaches the src parent or the root path. +function checkParentPaths (src, srcStat, dest, funcName, cb) { + const srcParent = path.resolve(path.dirname(src)) + const destParent = path.resolve(path.dirname(dest)) + if (destParent === srcParent || destParent === path.parse(destParent).root) return cb() + if (nodeSupportsBigInt()) { + fs.stat(destParent, { bigint: true }, (err, destStat) => { + if (err) { + if (err.code === 'ENOENT') return cb() + return cb(err) + } + if (destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev) { + return cb(new Error(errMsg(src, dest, funcName))) + } + return checkParentPaths(src, srcStat, destParent, funcName, cb) + }) + } else { + fs.stat(destParent, (err, destStat) => { + if (err) { + if (err.code === 'ENOENT') return cb() + return cb(err) + } + if (destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev) { + return cb(new Error(errMsg(src, dest, funcName))) + } + return checkParentPaths(src, srcStat, destParent, funcName, cb) + }) + } +} + +function checkParentPathsSync (src, srcStat, dest, funcName) { + const srcParent = path.resolve(path.dirname(src)) + const destParent = path.resolve(path.dirname(dest)) + if (destParent === srcParent || destParent === path.parse(destParent).root) return + let destStat + try { + if (nodeSupportsBigInt()) { + destStat = fs.statSync(destParent, { bigint: true }) + } else { + destStat = fs.statSync(destParent) + } + } catch (err) { + if (err.code === 'ENOENT') return + throw err + } + if (destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev) { + throw new Error(errMsg(src, dest, funcName)) + } + return checkParentPathsSync(src, srcStat, destParent, funcName) +} + +// return true if dest is a subdir of src, otherwise false. +// It only checks the path strings. +function isSrcSubdir (src, dest) { + const srcArr = path.resolve(src).split(path.sep).filter(i => i) + const destArr = path.resolve(dest).split(path.sep).filter(i => i) + return srcArr.reduce((acc, cur, i) => acc && destArr[i] === cur, true) +} + +function errMsg (src, dest, funcName) { + return `Cannot ${funcName} '${src}' to a subdirectory of itself, '${dest}'.` +} + +module.exports = { + checkPaths, + checkPathsSync, + checkParentPaths, + checkParentPathsSync, + isSrcSubdir +} + + +/***/ }), +/* 110 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/* eslint-disable node/no-deprecated-api */ +module.exports = function (size) { + if (typeof Buffer.allocUnsafe === 'function') { + try { + return Buffer.allocUnsafe(size) + } catch (e) { + return new Buffer(size) + } + } + return new Buffer(size) +} + + +/***/ }), +/* 111 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const u = __webpack_require__(95).fromCallback +module.exports = { + copy: u(__webpack_require__(112)) +} + + +/***/ }), +/* 112 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const fs = __webpack_require__(96) +const path = __webpack_require__(57) +const mkdirp = __webpack_require__(104).mkdirs +const pathExists = __webpack_require__(113).pathExists +const utimes = __webpack_require__(108).utimesMillis +const stat = __webpack_require__(109) + +function copy (src, dest, opts, cb) { + if (typeof opts === 'function' && !cb) { + cb = opts + opts = {} + } else if (typeof opts === 'function') { + opts = { filter: opts } + } + + cb = cb || function () {} + opts = opts || {} + + opts.clobber = 'clobber' in opts ? !!opts.clobber : true // default to true for now + opts.overwrite = 'overwrite' in opts ? !!opts.overwrite : opts.clobber // overwrite falls back to clobber + + // Warn about using preserveTimestamps on 32-bit node + if (opts.preserveTimestamps && process.arch === 'ia32') { + console.warn(`fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n + see https://github.com/jprichardson/node-fs-extra/issues/269`) + } + + stat.checkPaths(src, dest, 'copy', (err, stats) => { + if (err) return cb(err) + const { srcStat, destStat } = stats + stat.checkParentPaths(src, srcStat, dest, 'copy', err => { + if (err) return cb(err) + if (opts.filter) return handleFilter(checkParentDir, destStat, src, dest, opts, cb) + return checkParentDir(destStat, src, dest, opts, cb) + }) + }) +} + +function checkParentDir (destStat, src, dest, opts, cb) { + const destParent = path.dirname(dest) + pathExists(destParent, (err, dirExists) => { + if (err) return cb(err) + if (dirExists) return startCopy(destStat, src, dest, opts, cb) + mkdirp(destParent, err => { + if (err) return cb(err) + return startCopy(destStat, src, dest, opts, cb) + }) + }) +} + +function handleFilter (onInclude, destStat, src, dest, opts, cb) { + Promise.resolve(opts.filter(src, dest)).then(include => { + if (include) return onInclude(destStat, src, dest, opts, cb) + return cb() + }, error => cb(error)) +} + +function startCopy (destStat, src, dest, opts, cb) { + if (opts.filter) return handleFilter(getStats, destStat, src, dest, opts, cb) + return getStats(destStat, src, dest, opts, cb) +} + +function getStats (destStat, src, dest, opts, cb) { + const stat = opts.dereference ? fs.stat : fs.lstat + stat(src, (err, srcStat) => { + if (err) return cb(err) + + if (srcStat.isDirectory()) return onDir(srcStat, destStat, src, dest, opts, cb) + else if (srcStat.isFile() || + srcStat.isCharacterDevice() || + srcStat.isBlockDevice()) return onFile(srcStat, destStat, src, dest, opts, cb) + else if (srcStat.isSymbolicLink()) return onLink(destStat, src, dest, opts, cb) + }) +} + +function onFile (srcStat, destStat, src, dest, opts, cb) { + if (!destStat) return copyFile(srcStat, src, dest, opts, cb) + return mayCopyFile(srcStat, src, dest, opts, cb) +} + +function mayCopyFile (srcStat, src, dest, opts, cb) { + if (opts.overwrite) { + fs.unlink(dest, err => { + if (err) return cb(err) + return copyFile(srcStat, src, dest, opts, cb) + }) + } else if (opts.errorOnExist) { + return cb(new Error(`'${dest}' already exists`)) + } else return cb() +} + +function copyFile (srcStat, src, dest, opts, cb) { + if (typeof fs.copyFile === 'function') { + return fs.copyFile(src, dest, err => { + if (err) return cb(err) + return setDestModeAndTimestamps(srcStat, dest, opts, cb) + }) + } + return copyFileFallback(srcStat, src, dest, opts, cb) +} + +function copyFileFallback (srcStat, src, dest, opts, cb) { + const rs = fs.createReadStream(src) + rs.on('error', err => cb(err)).once('open', () => { + const ws = fs.createWriteStream(dest, { mode: srcStat.mode }) + ws.on('error', err => cb(err)) + .on('open', () => rs.pipe(ws)) + .once('close', () => setDestModeAndTimestamps(srcStat, dest, opts, cb)) + }) +} + +function setDestModeAndTimestamps (srcStat, dest, opts, cb) { + fs.chmod(dest, srcStat.mode, err => { + if (err) return cb(err) + if (opts.preserveTimestamps) { + return utimes(dest, srcStat.atime, srcStat.mtime, cb) + } + return cb() + }) +} + +function onDir (srcStat, destStat, src, dest, opts, cb) { + if (!destStat) return mkDirAndCopy(srcStat, src, dest, opts, cb) + if (destStat && !destStat.isDirectory()) { + return cb(new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`)) + } + return copyDir(src, dest, opts, cb) +} + +function mkDirAndCopy (srcStat, src, dest, opts, cb) { + fs.mkdir(dest, err => { + if (err) return cb(err) + copyDir(src, dest, opts, err => { + if (err) return cb(err) + return fs.chmod(dest, srcStat.mode, cb) + }) + }) +} + +function copyDir (src, dest, opts, cb) { + fs.readdir(src, (err, items) => { + if (err) return cb(err) + return copyDirItems(items, src, dest, opts, cb) + }) +} + +function copyDirItems (items, src, dest, opts, cb) { + const item = items.pop() + if (!item) return cb() + return copyDirItem(items, item, src, dest, opts, cb) +} + +function copyDirItem (items, item, src, dest, opts, cb) { + const srcItem = path.join(src, item) + const destItem = path.join(dest, item) + stat.checkPaths(srcItem, destItem, 'copy', (err, stats) => { + if (err) return cb(err) + const { destStat } = stats + startCopy(destStat, srcItem, destItem, opts, err => { + if (err) return cb(err) + return copyDirItems(items, src, dest, opts, cb) + }) + }) +} + +function onLink (destStat, src, dest, opts, cb) { + fs.readlink(src, (err, resolvedSrc) => { + if (err) return cb(err) + if (opts.dereference) { + resolvedSrc = path.resolve(process.cwd(), resolvedSrc) + } + + if (!destStat) { + return fs.symlink(resolvedSrc, dest, cb) + } else { + fs.readlink(dest, (err, resolvedDest) => { + if (err) { + // dest exists and is a regular file or directory, + // Windows may throw UNKNOWN error. If dest already exists, + // fs throws error anyway, so no need to guard against it here. + if (err.code === 'EINVAL' || err.code === 'UNKNOWN') return fs.symlink(resolvedSrc, dest, cb) + return cb(err) + } + if (opts.dereference) { + resolvedDest = path.resolve(process.cwd(), resolvedDest) + } + if (stat.isSrcSubdir(resolvedSrc, resolvedDest)) { + return cb(new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`)) + } + + // do not copy if src is a subdir of dest since unlinking + // dest in this case would result in removing src contents + // and therefore a broken symlink would be created. + if (destStat.isDirectory() && stat.isSrcSubdir(resolvedDest, resolvedSrc)) { + return cb(new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`)) + } + return copyLink(resolvedSrc, dest, cb) + }) + } + }) +} + +function copyLink (resolvedSrc, dest, cb) { + fs.unlink(dest, err => { + if (err) return cb(err) + return fs.symlink(resolvedSrc, dest, cb) + }) +} + +module.exports = copy + + +/***/ }), +/* 113 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const u = __webpack_require__(95).fromPromise +const fs = __webpack_require__(94) + +function pathExists (path) { + return fs.access(path).then(() => true).catch(() => false) +} + +module.exports = { + pathExists: u(pathExists), + pathExistsSync: fs.existsSync +} + + +/***/ }), +/* 114 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const u = __webpack_require__(95).fromCallback +const fs = __webpack_require__(96) +const path = __webpack_require__(57) +const mkdir = __webpack_require__(104) +const remove = __webpack_require__(115) + +const emptyDir = u(function emptyDir (dir, callback) { + callback = callback || function () {} + fs.readdir(dir, (err, items) => { + if (err) return mkdir.mkdirs(dir, callback) + + items = items.map(item => path.join(dir, item)) + + deleteItem() + + function deleteItem () { + const item = items.pop() + if (!item) return callback() + remove.remove(item, err => { + if (err) return callback(err) + deleteItem() + }) + } + }) +}) + +function emptyDirSync (dir) { + let items + try { + items = fs.readdirSync(dir) + } catch (err) { + return mkdir.mkdirsSync(dir) + } + + items.forEach(item => { + item = path.join(dir, item) + remove.removeSync(item) + }) +} + +module.exports = { + emptyDirSync, + emptydirSync: emptyDirSync, + emptyDir, + emptydir: emptyDir +} + + +/***/ }), +/* 115 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const u = __webpack_require__(95).fromCallback +const rimraf = __webpack_require__(116) + +module.exports = { + remove: u(rimraf), + removeSync: rimraf.sync +} + + +/***/ }), +/* 116 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const fs = __webpack_require__(96) +const path = __webpack_require__(57) +const assert = __webpack_require__(101) + +const isWindows = (process.platform === 'win32') + +function defaults (options) { + const methods = [ + 'unlink', + 'chmod', + 'stat', + 'lstat', + 'rmdir', + 'readdir' + ] + methods.forEach(m => { + options[m] = options[m] || fs[m] + m = m + 'Sync' + options[m] = options[m] || fs[m] + }) + + options.maxBusyTries = options.maxBusyTries || 3 +} + +function rimraf (p, options, cb) { + let busyTries = 0 + + if (typeof options === 'function') { + cb = options + options = {} + } + + assert(p, 'rimraf: missing path') + assert.strictEqual(typeof p, 'string', 'rimraf: path should be a string') + assert.strictEqual(typeof cb, 'function', 'rimraf: callback function required') + assert(options, 'rimraf: invalid options argument provided') + assert.strictEqual(typeof options, 'object', 'rimraf: options should be object') + + defaults(options) + + rimraf_(p, options, function CB (er) { + if (er) { + if ((er.code === 'EBUSY' || er.code === 'ENOTEMPTY' || er.code === 'EPERM') && + busyTries < options.maxBusyTries) { + busyTries++ + const time = busyTries * 100 + // try again, with the same exact callback as this one. + return setTimeout(() => rimraf_(p, options, CB), time) + } + + // already gone + if (er.code === 'ENOENT') er = null + } + + cb(er) + }) +} + +// Two possible strategies. +// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR +// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR +// +// Both result in an extra syscall when you guess wrong. However, there +// are likely far more normal files in the world than directories. This +// is based on the assumption that a the average number of files per +// directory is >= 1. +// +// If anyone ever complains about this, then I guess the strategy could +// be made configurable somehow. But until then, YAGNI. +function rimraf_ (p, options, cb) { + assert(p) + assert(options) + assert(typeof cb === 'function') + + // sunos lets the root user unlink directories, which is... weird. + // so we have to lstat here and make sure it's not a dir. + options.lstat(p, (er, st) => { + if (er && er.code === 'ENOENT') { + return cb(null) + } + + // Windows can EPERM on stat. Life is suffering. + if (er && er.code === 'EPERM' && isWindows) { + return fixWinEPERM(p, options, er, cb) + } + + if (st && st.isDirectory()) { + return rmdir(p, options, er, cb) + } + + options.unlink(p, er => { + if (er) { + if (er.code === 'ENOENT') { + return cb(null) + } + if (er.code === 'EPERM') { + return (isWindows) + ? fixWinEPERM(p, options, er, cb) + : rmdir(p, options, er, cb) + } + if (er.code === 'EISDIR') { + return rmdir(p, options, er, cb) + } + } + return cb(er) + }) + }) +} + +function fixWinEPERM (p, options, er, cb) { + assert(p) + assert(options) + assert(typeof cb === 'function') + if (er) { + assert(er instanceof Error) + } + + options.chmod(p, 0o666, er2 => { + if (er2) { + cb(er2.code === 'ENOENT' ? null : er) + } else { + options.stat(p, (er3, stats) => { + if (er3) { + cb(er3.code === 'ENOENT' ? null : er) + } else if (stats.isDirectory()) { + rmdir(p, options, er, cb) + } else { + options.unlink(p, cb) + } + }) + } + }) +} + +function fixWinEPERMSync (p, options, er) { + let stats + + assert(p) + assert(options) + if (er) { + assert(er instanceof Error) + } + + try { + options.chmodSync(p, 0o666) + } catch (er2) { + if (er2.code === 'ENOENT') { + return + } else { + throw er + } + } + + try { + stats = options.statSync(p) + } catch (er3) { + if (er3.code === 'ENOENT') { + return + } else { + throw er + } + } + + if (stats.isDirectory()) { + rmdirSync(p, options, er) + } else { + options.unlinkSync(p) + } +} + +function rmdir (p, options, originalEr, cb) { + assert(p) + assert(options) + if (originalEr) { + assert(originalEr instanceof Error) + } + assert(typeof cb === 'function') + + // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) + // if we guessed wrong, and it's not a directory, then + // raise the original error. + options.rmdir(p, er => { + if (er && (er.code === 'ENOTEMPTY' || er.code === 'EEXIST' || er.code === 'EPERM')) { + rmkids(p, options, cb) + } else if (er && er.code === 'ENOTDIR') { + cb(originalEr) + } else { + cb(er) + } + }) +} + +function rmkids (p, options, cb) { + assert(p) + assert(options) + assert(typeof cb === 'function') + + options.readdir(p, (er, files) => { + if (er) return cb(er) + + let n = files.length + let errState + + if (n === 0) return options.rmdir(p, cb) + + files.forEach(f => { + rimraf(path.join(p, f), options, er => { + if (errState) { + return + } + if (er) return cb(errState = er) + if (--n === 0) { + options.rmdir(p, cb) + } + }) + }) + }) +} + +// this looks simpler, and is strictly *faster*, but will +// tie up the JavaScript thread and fail on excessively +// deep directory trees. +function rimrafSync (p, options) { + let st + + options = options || {} + defaults(options) + + assert(p, 'rimraf: missing path') + assert.strictEqual(typeof p, 'string', 'rimraf: path should be a string') + assert(options, 'rimraf: missing options') + assert.strictEqual(typeof options, 'object', 'rimraf: options should be object') + + try { + st = options.lstatSync(p) + } catch (er) { + if (er.code === 'ENOENT') { + return + } + + // Windows can EPERM on stat. Life is suffering. + if (er.code === 'EPERM' && isWindows) { + fixWinEPERMSync(p, options, er) + } + } + + try { + // sunos lets the root user unlink directories, which is... weird. + if (st && st.isDirectory()) { + rmdirSync(p, options, null) + } else { + options.unlinkSync(p) + } + } catch (er) { + if (er.code === 'ENOENT') { + return + } else if (er.code === 'EPERM') { + return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) + } else if (er.code !== 'EISDIR') { + throw er + } + rmdirSync(p, options, er) + } +} + +function rmdirSync (p, options, originalEr) { + assert(p) + assert(options) + if (originalEr) { + assert(originalEr instanceof Error) + } + + try { + options.rmdirSync(p) + } catch (er) { + if (er.code === 'ENOTDIR') { + throw originalEr + } else if (er.code === 'ENOTEMPTY' || er.code === 'EEXIST' || er.code === 'EPERM') { + rmkidsSync(p, options) + } else if (er.code !== 'ENOENT') { + throw er + } + } +} + +function rmkidsSync (p, options) { + assert(p) + assert(options) + options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options)) + + if (isWindows) { + // We only end up here once we got ENOTEMPTY at least once, and + // at this point, we are guaranteed to have removed all the kids. + // So, we know that it won't be ENOENT or ENOTDIR or anything else. + // try really hard to delete stuff on windows, because it has a + // PROFOUNDLY annoying habit of not closing handles promptly when + // files are deleted, resulting in spurious ENOTEMPTY errors. + const startTime = Date.now() + do { + try { + const ret = options.rmdirSync(p, options) + return ret + } catch (er) { } + } while (Date.now() - startTime < 500) // give up after 500ms + } else { + const ret = options.rmdirSync(p, options) + return ret + } +} + +module.exports = rimraf +rimraf.sync = rimrafSync + + +/***/ }), +/* 117 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const file = __webpack_require__(118) +const link = __webpack_require__(119) +const symlink = __webpack_require__(120) + +module.exports = { + // file + createFile: file.createFile, + createFileSync: file.createFileSync, + ensureFile: file.createFile, + ensureFileSync: file.createFileSync, + // link + createLink: link.createLink, + createLinkSync: link.createLinkSync, + ensureLink: link.createLink, + ensureLinkSync: link.createLinkSync, + // symlink + createSymlink: symlink.createSymlink, + createSymlinkSync: symlink.createSymlinkSync, + ensureSymlink: symlink.createSymlink, + ensureSymlinkSync: symlink.createSymlinkSync +} + + +/***/ }), +/* 118 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const u = __webpack_require__(95).fromCallback +const path = __webpack_require__(57) +const fs = __webpack_require__(96) +const mkdir = __webpack_require__(104) +const pathExists = __webpack_require__(113).pathExists + +function createFile (file, callback) { + function makeFile () { + fs.writeFile(file, '', err => { + if (err) return callback(err) + callback() + }) + } + + fs.stat(file, (err, stats) => { // eslint-disable-line handle-callback-err + if (!err && stats.isFile()) return callback() + const dir = path.dirname(file) + pathExists(dir, (err, dirExists) => { + if (err) return callback(err) + if (dirExists) return makeFile() + mkdir.mkdirs(dir, err => { + if (err) return callback(err) + makeFile() + }) + }) + }) +} + +function createFileSync (file) { + let stats + try { + stats = fs.statSync(file) + } catch (e) {} + if (stats && stats.isFile()) return + + const dir = path.dirname(file) + if (!fs.existsSync(dir)) { + mkdir.mkdirsSync(dir) + } + + fs.writeFileSync(file, '') +} + +module.exports = { + createFile: u(createFile), + createFileSync +} + + +/***/ }), +/* 119 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const u = __webpack_require__(95).fromCallback +const path = __webpack_require__(57) +const fs = __webpack_require__(96) +const mkdir = __webpack_require__(104) +const pathExists = __webpack_require__(113).pathExists + +function createLink (srcpath, dstpath, callback) { + function makeLink (srcpath, dstpath) { + fs.link(srcpath, dstpath, err => { + if (err) return callback(err) + callback(null) + }) + } + + pathExists(dstpath, (err, destinationExists) => { + if (err) return callback(err) + if (destinationExists) return callback(null) + fs.lstat(srcpath, (err) => { + if (err) { + err.message = err.message.replace('lstat', 'ensureLink') + return callback(err) + } + + const dir = path.dirname(dstpath) + pathExists(dir, (err, dirExists) => { + if (err) return callback(err) + if (dirExists) return makeLink(srcpath, dstpath) + mkdir.mkdirs(dir, err => { + if (err) return callback(err) + makeLink(srcpath, dstpath) + }) + }) + }) + }) +} + +function createLinkSync (srcpath, dstpath) { + const destinationExists = fs.existsSync(dstpath) + if (destinationExists) return undefined + + try { + fs.lstatSync(srcpath) + } catch (err) { + err.message = err.message.replace('lstat', 'ensureLink') + throw err + } + + const dir = path.dirname(dstpath) + const dirExists = fs.existsSync(dir) + if (dirExists) return fs.linkSync(srcpath, dstpath) + mkdir.mkdirsSync(dir) + + return fs.linkSync(srcpath, dstpath) +} + +module.exports = { + createLink: u(createLink), + createLinkSync +} + + +/***/ }), +/* 120 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const u = __webpack_require__(95).fromCallback +const path = __webpack_require__(57) +const fs = __webpack_require__(96) +const _mkdirs = __webpack_require__(104) +const mkdirs = _mkdirs.mkdirs +const mkdirsSync = _mkdirs.mkdirsSync + +const _symlinkPaths = __webpack_require__(121) +const symlinkPaths = _symlinkPaths.symlinkPaths +const symlinkPathsSync = _symlinkPaths.symlinkPathsSync + +const _symlinkType = __webpack_require__(122) +const symlinkType = _symlinkType.symlinkType +const symlinkTypeSync = _symlinkType.symlinkTypeSync + +const pathExists = __webpack_require__(113).pathExists + +function createSymlink (srcpath, dstpath, type, callback) { + callback = (typeof type === 'function') ? type : callback + type = (typeof type === 'function') ? false : type + + pathExists(dstpath, (err, destinationExists) => { + if (err) return callback(err) + if (destinationExists) return callback(null) + symlinkPaths(srcpath, dstpath, (err, relative) => { + if (err) return callback(err) + srcpath = relative.toDst + symlinkType(relative.toCwd, type, (err, type) => { + if (err) return callback(err) + const dir = path.dirname(dstpath) + pathExists(dir, (err, dirExists) => { + if (err) return callback(err) + if (dirExists) return fs.symlink(srcpath, dstpath, type, callback) + mkdirs(dir, err => { + if (err) return callback(err) + fs.symlink(srcpath, dstpath, type, callback) + }) + }) + }) + }) + }) +} + +function createSymlinkSync (srcpath, dstpath, type) { + const destinationExists = fs.existsSync(dstpath) + if (destinationExists) return undefined + + const relative = symlinkPathsSync(srcpath, dstpath) + srcpath = relative.toDst + type = symlinkTypeSync(relative.toCwd, type) + const dir = path.dirname(dstpath) + const exists = fs.existsSync(dir) + if (exists) return fs.symlinkSync(srcpath, dstpath, type) + mkdirsSync(dir) + return fs.symlinkSync(srcpath, dstpath, type) +} + +module.exports = { + createSymlink: u(createSymlink), + createSymlinkSync +} + + +/***/ }), +/* 121 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const path = __webpack_require__(57) +const fs = __webpack_require__(96) +const pathExists = __webpack_require__(113).pathExists + +/** + * Function that returns two types of paths, one relative to symlink, and one + * relative to the current working directory. Checks if path is absolute or + * relative. If the path is relative, this function checks if the path is + * relative to symlink or relative to current working directory. This is an + * initiative to find a smarter `srcpath` to supply when building symlinks. + * This allows you to determine which path to use out of one of three possible + * types of source paths. The first is an absolute path. This is detected by + * `path.isAbsolute()`. When an absolute path is provided, it is checked to + * see if it exists. If it does it's used, if not an error is returned + * (callback)/ thrown (sync). The other two options for `srcpath` are a + * relative url. By default Node's `fs.symlink` works by creating a symlink + * using `dstpath` and expects the `srcpath` to be relative to the newly + * created symlink. If you provide a `srcpath` that does not exist on the file + * system it results in a broken symlink. To minimize this, the function + * checks to see if the 'relative to symlink' source file exists, and if it + * does it will use it. If it does not, it checks if there's a file that + * exists that is relative to the current working directory, if does its used. + * This preserves the expectations of the original fs.symlink spec and adds + * the ability to pass in `relative to current working direcotry` paths. + */ + +function symlinkPaths (srcpath, dstpath, callback) { + if (path.isAbsolute(srcpath)) { + return fs.lstat(srcpath, (err) => { + if (err) { + err.message = err.message.replace('lstat', 'ensureSymlink') + return callback(err) + } + return callback(null, { + 'toCwd': srcpath, + 'toDst': srcpath + }) + }) + } else { + const dstdir = path.dirname(dstpath) + const relativeToDst = path.join(dstdir, srcpath) + return pathExists(relativeToDst, (err, exists) => { + if (err) return callback(err) + if (exists) { + return callback(null, { + 'toCwd': relativeToDst, + 'toDst': srcpath + }) + } else { + return fs.lstat(srcpath, (err) => { + if (err) { + err.message = err.message.replace('lstat', 'ensureSymlink') + return callback(err) + } + return callback(null, { + 'toCwd': srcpath, + 'toDst': path.relative(dstdir, srcpath) + }) + }) + } + }) + } +} + +function symlinkPathsSync (srcpath, dstpath) { + let exists + if (path.isAbsolute(srcpath)) { + exists = fs.existsSync(srcpath) + if (!exists) throw new Error('absolute srcpath does not exist') + return { + 'toCwd': srcpath, + 'toDst': srcpath + } + } else { + const dstdir = path.dirname(dstpath) + const relativeToDst = path.join(dstdir, srcpath) + exists = fs.existsSync(relativeToDst) + if (exists) { + return { + 'toCwd': relativeToDst, + 'toDst': srcpath + } + } else { + exists = fs.existsSync(srcpath) + if (!exists) throw new Error('relative srcpath does not exist') + return { + 'toCwd': srcpath, + 'toDst': path.relative(dstdir, srcpath) + } + } + } +} + +module.exports = { + symlinkPaths, + symlinkPathsSync +} + + +/***/ }), +/* 122 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const fs = __webpack_require__(96) + +function symlinkType (srcpath, type, callback) { + callback = (typeof type === 'function') ? type : callback + type = (typeof type === 'function') ? false : type + if (type) return callback(null, type) + fs.lstat(srcpath, (err, stats) => { + if (err) return callback(null, 'file') + type = (stats && stats.isDirectory()) ? 'dir' : 'file' + callback(null, type) + }) +} + +function symlinkTypeSync (srcpath, type) { + let stats + + if (type) return type + try { + stats = fs.lstatSync(srcpath) + } catch (e) { + return 'file' + } + return (stats && stats.isDirectory()) ? 'dir' : 'file' +} + +module.exports = { + symlinkType, + symlinkTypeSync +} + + +/***/ }), +/* 123 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const u = __webpack_require__(95).fromCallback +const jsonFile = __webpack_require__(124) + +jsonFile.outputJson = u(__webpack_require__(130)) +jsonFile.outputJsonSync = __webpack_require__(131) +// aliases +jsonFile.outputJSON = jsonFile.outputJson +jsonFile.outputJSONSync = jsonFile.outputJsonSync +jsonFile.writeJSON = jsonFile.writeJson +jsonFile.writeJSONSync = jsonFile.writeJsonSync +jsonFile.readJSON = jsonFile.readJson +jsonFile.readJSONSync = jsonFile.readJsonSync + +module.exports = jsonFile + + +/***/ }), +/* 124 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const u = __webpack_require__(95).fromCallback +const jsonFile = __webpack_require__(125) + +module.exports = { + // jsonfile exports + readJson: u(jsonFile.readFile), + readJsonSync: jsonFile.readFileSync, + writeJson: u(jsonFile.writeFile), + writeJsonSync: jsonFile.writeFileSync +} + + +/***/ }), +/* 125 */ +/***/ (function(module, exports, __webpack_require__) { + +var _fs +try { + _fs = __webpack_require__(126) +} catch (_) { + _fs = __webpack_require__(55) +} + +function readFile (file, options, callback) { + if (callback == null) { + callback = options + options = {} + } + + if (typeof options === 'string') { + options = {encoding: options} + } + + options = options || {} + var fs = options.fs || _fs + + var shouldThrow = true + if ('throws' in options) { + shouldThrow = options.throws + } + + fs.readFile(file, options, function (err, data) { + if (err) return callback(err) + + data = stripBom(data) + + var obj + try { + obj = JSON.parse(data, options ? options.reviver : null) + } catch (err2) { + if (shouldThrow) { + err2.message = file + ': ' + err2.message + return callback(err2) + } else { + return callback(null, null) + } + } + + callback(null, obj) + }) +} + +function readFileSync (file, options) { + options = options || {} + if (typeof options === 'string') { + options = {encoding: options} + } + + var fs = options.fs || _fs + + var shouldThrow = true + if ('throws' in options) { + shouldThrow = options.throws + } + + try { + var content = fs.readFileSync(file, options) + content = stripBom(content) + return JSON.parse(content, options.reviver) + } catch (err) { + if (shouldThrow) { + err.message = file + ': ' + err.message + throw err + } else { + return null + } + } +} + +function stringify (obj, options) { + var spaces + var EOL = '\n' + if (typeof options === 'object' && options !== null) { + if (options.spaces) { + spaces = options.spaces + } + if (options.EOL) { + EOL = options.EOL + } + } + + var str = JSON.stringify(obj, options ? options.replacer : null, spaces) + + return str.replace(/\n/g, EOL) + EOL +} + +function writeFile (file, obj, options, callback) { + if (callback == null) { + callback = options + options = {} + } + options = options || {} + var fs = options.fs || _fs + + var str = '' + try { + str = stringify(obj, options) + } catch (err) { + // Need to return whether a callback was passed or not + if (callback) callback(err, null) + return + } + + fs.writeFile(file, str, options, callback) +} + +function writeFileSync (file, obj, options) { + options = options || {} + var fs = options.fs || _fs + + var str = stringify(obj, options) + // not sure if fs.writeFileSync returns anything, but just in case + return fs.writeFileSync(file, str, options) +} + +function stripBom (content) { + // we do this because JSON.parse would convert it to a utf8 string if encoding wasn't specified + if (Buffer.isBuffer(content)) content = content.toString('utf8') + content = content.replace(/^\uFEFF/, '') + return content +} + +var jsonfile = { + readFile: readFile, + readFileSync: readFileSync, + writeFile: writeFile, + writeFileSync: writeFileSync +} + +module.exports = jsonfile + + +/***/ }), +/* 126 */ +/***/ (function(module, exports, __webpack_require__) { + +var fs = __webpack_require__(55) +var polyfills = __webpack_require__(127) +var legacy = __webpack_require__(128) +var clone = __webpack_require__(129) + +var queue = [] + +var util = __webpack_require__(40) + +function noop () {} + +var debug = noop +if (util.debuglog) + debug = util.debuglog('gfs4') +else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) + debug = function() { + var m = util.format.apply(util, arguments) + m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') + console.error(m) + } + +if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { + process.on('exit', function() { + debug(queue) + __webpack_require__(101).equal(queue.length, 0) + }) +} + +module.exports = patch(clone(fs)) +if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { + module.exports = patch(fs) + fs.__patched = true; +} + +// Always patch fs.close/closeSync, because we want to +// retry() whenever a close happens *anywhere* in the program. +// This is essential when multiple graceful-fs instances are +// in play at the same time. +module.exports.close = (function (fs$close) { return function (fd, cb) { + return fs$close.call(fs, fd, function (err) { + if (!err) + retry() + + if (typeof cb === 'function') + cb.apply(this, arguments) + }) +}})(fs.close) + +module.exports.closeSync = (function (fs$closeSync) { return function (fd) { + // Note that graceful-fs also retries when fs.closeSync() fails. + // Looks like a bug to me, although it's probably a harmless one. + var rval = fs$closeSync.apply(fs, arguments) + retry() + return rval +}})(fs.closeSync) + +// Only patch fs once, otherwise we'll run into a memory leak if +// graceful-fs is loaded multiple times, such as in test environments that +// reset the loaded modules between tests. +// We look for the string `graceful-fs` from the comment above. This +// way we are not adding any extra properties and it will detect if older +// versions of graceful-fs are installed. +if (!/\bgraceful-fs\b/.test(fs.closeSync.toString())) { + fs.closeSync = module.exports.closeSync; + fs.close = module.exports.close; +} + +function patch (fs) { + // Everything that references the open() function needs to be in here + polyfills(fs) + fs.gracefulify = patch + fs.FileReadStream = ReadStream; // Legacy name. + fs.FileWriteStream = WriteStream; // Legacy name. + fs.createReadStream = createReadStream + fs.createWriteStream = createWriteStream + var fs$readFile = fs.readFile + fs.readFile = readFile + function readFile (path, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$readFile(path, options, cb) + + function go$readFile (path, options, cb) { + return fs$readFile(path, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readFile, [path, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + var fs$writeFile = fs.writeFile + fs.writeFile = writeFile + function writeFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$writeFile(path, data, options, cb) + + function go$writeFile (path, data, options, cb) { + return fs$writeFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$writeFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + var fs$appendFile = fs.appendFile + if (fs$appendFile) + fs.appendFile = appendFile + function appendFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$appendFile(path, data, options, cb) + + function go$appendFile (path, data, options, cb) { + return fs$appendFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$appendFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + var fs$readdir = fs.readdir + fs.readdir = readdir + function readdir (path, options, cb) { + var args = [path] + if (typeof options !== 'function') { + args.push(options) + } else { + cb = options + } + args.push(go$readdir$cb) + + return go$readdir(args) + + function go$readdir$cb (err, files) { + if (files && files.sort) + files.sort() + + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readdir, [args]]) + + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + } + } + + function go$readdir (args) { + return fs$readdir.apply(fs, args) + } + + if (process.version.substr(0, 4) === 'v0.8') { + var legStreams = legacy(fs) + ReadStream = legStreams.ReadStream + WriteStream = legStreams.WriteStream + } + + var fs$ReadStream = fs.ReadStream + if (fs$ReadStream) { + ReadStream.prototype = Object.create(fs$ReadStream.prototype) + ReadStream.prototype.open = ReadStream$open + } + + var fs$WriteStream = fs.WriteStream + if (fs$WriteStream) { + WriteStream.prototype = Object.create(fs$WriteStream.prototype) + WriteStream.prototype.open = WriteStream$open + } + + fs.ReadStream = ReadStream + fs.WriteStream = WriteStream + + function ReadStream (path, options) { + if (this instanceof ReadStream) + return fs$ReadStream.apply(this, arguments), this + else + return ReadStream.apply(Object.create(ReadStream.prototype), arguments) + } + + function ReadStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + if (that.autoClose) + that.destroy() + + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + that.read() + } + }) + } + + function WriteStream (path, options) { + if (this instanceof WriteStream) + return fs$WriteStream.apply(this, arguments), this + else + return WriteStream.apply(Object.create(WriteStream.prototype), arguments) + } + + function WriteStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + that.destroy() + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + } + }) + } + + function createReadStream (path, options) { + return new ReadStream(path, options) + } + + function createWriteStream (path, options) { + return new WriteStream(path, options) + } + + var fs$open = fs.open + fs.open = open + function open (path, flags, mode, cb) { + if (typeof mode === 'function') + cb = mode, mode = null + + return go$open(path, flags, mode, cb) + + function go$open (path, flags, mode, cb) { + return fs$open(path, flags, mode, function (err, fd) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$open, [path, flags, mode, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + return fs +} + +function enqueue (elem) { + debug('ENQUEUE', elem[0].name, elem[1]) + queue.push(elem) +} + +function retry () { + var elem = queue.shift() + if (elem) { + debug('RETRY', elem[0].name, elem[1]) + elem[0].apply(null, elem[1]) + } +} + + +/***/ }), +/* 127 */ +/***/ (function(module, exports, __webpack_require__) { + +var constants = __webpack_require__(98) + +var origCwd = process.cwd +var cwd = null + +var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform + +process.cwd = function() { + if (!cwd) + cwd = origCwd.call(process) + return cwd +} +try { + process.cwd() +} catch (er) {} + +var chdir = process.chdir +process.chdir = function(d) { + cwd = null + chdir.call(process, d) +} + +module.exports = patch + +function patch (fs) { + // (re-)implement some things that are known busted or missing. + + // lchmod, broken prior to 0.6.2 + // back-port the fix here. + if (constants.hasOwnProperty('O_SYMLINK') && + process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { + patchLchmod(fs) + } + + // lutimes implementation, or no-op + if (!fs.lutimes) { + patchLutimes(fs) + } + + // https://github.com/isaacs/node-graceful-fs/issues/4 + // Chown should not fail on einval or eperm if non-root. + // It should not fail on enosys ever, as this just indicates + // that a fs doesn't support the intended operation. + + fs.chown = chownFix(fs.chown) + fs.fchown = chownFix(fs.fchown) + fs.lchown = chownFix(fs.lchown) + + fs.chmod = chmodFix(fs.chmod) + fs.fchmod = chmodFix(fs.fchmod) + fs.lchmod = chmodFix(fs.lchmod) + + fs.chownSync = chownFixSync(fs.chownSync) + fs.fchownSync = chownFixSync(fs.fchownSync) + fs.lchownSync = chownFixSync(fs.lchownSync) + + fs.chmodSync = chmodFixSync(fs.chmodSync) + fs.fchmodSync = chmodFixSync(fs.fchmodSync) + fs.lchmodSync = chmodFixSync(fs.lchmodSync) + + fs.stat = statFix(fs.stat) + fs.fstat = statFix(fs.fstat) + fs.lstat = statFix(fs.lstat) + + fs.statSync = statFixSync(fs.statSync) + fs.fstatSync = statFixSync(fs.fstatSync) + fs.lstatSync = statFixSync(fs.lstatSync) + + // if lchmod/lchown do not exist, then make them no-ops + if (!fs.lchmod) { + fs.lchmod = function (path, mode, cb) { + if (cb) process.nextTick(cb) + } + fs.lchmodSync = function () {} + } + if (!fs.lchown) { + fs.lchown = function (path, uid, gid, cb) { + if (cb) process.nextTick(cb) + } + fs.lchownSync = function () {} + } + + // on Windows, A/V software can lock the directory, causing this + // to fail with an EACCES or EPERM if the directory contains newly + // created files. Try again on failure, for up to 60 seconds. + + // Set the timeout this long because some Windows Anti-Virus, such as Parity + // bit9, may lock files for up to a minute, causing npm package install + // failures. Also, take care to yield the scheduler. Windows scheduling gives + // CPU to a busy looping process, which can cause the program causing the lock + // contention to be starved of CPU by node, so the contention doesn't resolve. + if (platform === "win32") { + fs.rename = (function (fs$rename) { return function (from, to, cb) { + var start = Date.now() + var backoff = 0; + fs$rename(from, to, function CB (er) { + if (er + && (er.code === "EACCES" || er.code === "EPERM") + && Date.now() - start < 60000) { + setTimeout(function() { + fs.stat(to, function (stater, st) { + if (stater && stater.code === "ENOENT") + fs$rename(from, to, CB); + else + cb(er) + }) + }, backoff) + if (backoff < 100) + backoff += 10; + return; + } + if (cb) cb(er) + }) + }})(fs.rename) + } + + // if read() returns EAGAIN, then just try it again. + fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) { + var callback + if (callback_ && typeof callback_ === 'function') { + var eagCounter = 0 + callback = function (er, _, __) { + if (er && er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + } + callback_.apply(this, arguments) + } + } + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + }})(fs.read) + + fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { + var eagCounter = 0 + while (true) { + try { + return fs$readSync.call(fs, fd, buffer, offset, length, position) + } catch (er) { + if (er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + continue + } + throw er + } + } + }})(fs.readSync) + + function patchLchmod (fs) { + fs.lchmod = function (path, mode, callback) { + fs.open( path + , constants.O_WRONLY | constants.O_SYMLINK + , mode + , function (err, fd) { + if (err) { + if (callback) callback(err) + return + } + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + fs.fchmod(fd, mode, function (err) { + fs.close(fd, function(err2) { + if (callback) callback(err || err2) + }) + }) + }) + } + + fs.lchmodSync = function (path, mode) { + var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) + + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + var threw = true + var ret + try { + ret = fs.fchmodSync(fd, mode) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } + } + + function patchLutimes (fs) { + if (constants.hasOwnProperty("O_SYMLINK")) { + fs.lutimes = function (path, at, mt, cb) { + fs.open(path, constants.O_SYMLINK, function (er, fd) { + if (er) { + if (cb) cb(er) + return + } + fs.futimes(fd, at, mt, function (er) { + fs.close(fd, function (er2) { + if (cb) cb(er || er2) + }) + }) + }) + } + + fs.lutimesSync = function (path, at, mt) { + var fd = fs.openSync(path, constants.O_SYMLINK) + var ret + var threw = true + try { + ret = fs.futimesSync(fd, at, mt) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } + + } else { + fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } + fs.lutimesSync = function () {} + } + } + + function chmodFix (orig) { + if (!orig) return orig + return function (target, mode, cb) { + return orig.call(fs, target, mode, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } + } + + function chmodFixSync (orig) { + if (!orig) return orig + return function (target, mode) { + try { + return orig.call(fs, target, mode) + } catch (er) { + if (!chownErOk(er)) throw er + } + } + } + + + function chownFix (orig) { + if (!orig) return orig + return function (target, uid, gid, cb) { + return orig.call(fs, target, uid, gid, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } + } + + function chownFixSync (orig) { + if (!orig) return orig + return function (target, uid, gid) { + try { + return orig.call(fs, target, uid, gid) + } catch (er) { + if (!chownErOk(er)) throw er + } + } + } + + + function statFix (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, cb) { + return orig.call(fs, target, function (er, stats) { + if (!stats) return cb.apply(this, arguments) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + if (cb) cb.apply(this, arguments) + }) + } + } + + function statFixSync (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target) { + var stats = orig.call(fs, target) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + return stats; + } + } + + // ENOSYS means that the fs doesn't support the op. Just ignore + // that, because it doesn't matter. + // + // if there's no getuid, or if getuid() is something other + // than 0, and the error is EINVAL or EPERM, then just ignore + // it. + // + // This specific case is a silent failure in cp, install, tar, + // and most other unix tools that manage permissions. + // + // When running as root, or if other types of errors are + // encountered, then it's strict. + function chownErOk (er) { + if (!er) + return true + + if (er.code === "ENOSYS") + return true + + var nonroot = !process.getuid || process.getuid() !== 0 + if (nonroot) { + if (er.code === "EINVAL" || er.code === "EPERM") + return true + } + + return false + } +} + + +/***/ }), +/* 128 */ +/***/ (function(module, exports, __webpack_require__) { + +var Stream = __webpack_require__(41).Stream + +module.exports = legacy + +function legacy (fs) { + return { + ReadStream: ReadStream, + WriteStream: WriteStream + } + + function ReadStream (path, options) { + if (!(this instanceof ReadStream)) return new ReadStream(path, options); + + Stream.call(this); + + var self = this; + + this.path = path; + this.fd = null; + this.readable = true; + this.paused = false; + + this.flags = 'r'; + this.mode = 438; /*=0666*/ + this.bufferSize = 64 * 1024; + + options = options || {}; + + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + + if (this.encoding) this.setEncoding(this.encoding); + + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.end === undefined) { + this.end = Infinity; + } else if ('number' !== typeof this.end) { + throw TypeError('end must be a Number'); + } + + if (this.start > this.end) { + throw new Error('start must be <= end'); + } + + this.pos = this.start; + } + + if (this.fd !== null) { + process.nextTick(function() { + self._read(); + }); + return; + } + + fs.open(this.path, this.flags, this.mode, function (err, fd) { + if (err) { + self.emit('error', err); + self.readable = false; + return; + } + + self.fd = fd; + self.emit('open', fd); + self._read(); + }) + } + + function WriteStream (path, options) { + if (!(this instanceof WriteStream)) return new WriteStream(path, options); + + Stream.call(this); + + this.path = path; + this.fd = null; + this.writable = true; + + this.flags = 'w'; + this.encoding = 'binary'; + this.mode = 438; /*=0666*/ + this.bytesWritten = 0; + + options = options || {}; + + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.start < 0) { + throw new Error('start must be >= zero'); + } + + this.pos = this.start; + } + + this.busy = false; + this._queue = []; + + if (this.fd === null) { + this._open = fs.open; + this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); + this.flush(); + } + } +} + + +/***/ }), +/* 129 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = clone + +function clone (obj) { + if (obj === null || typeof obj !== 'object') + return obj + + if (obj instanceof Object) + var copy = { __proto__: obj.__proto__ } + else + var copy = Object.create(null) + + Object.getOwnPropertyNames(obj).forEach(function (key) { + Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) + }) + + return copy +} + + +/***/ }), +/* 130 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const path = __webpack_require__(57) +const mkdir = __webpack_require__(104) +const pathExists = __webpack_require__(113).pathExists +const jsonFile = __webpack_require__(124) + +function outputJson (file, data, options, callback) { + if (typeof options === 'function') { + callback = options + options = {} + } + + const dir = path.dirname(file) + + pathExists(dir, (err, itDoes) => { + if (err) return callback(err) + if (itDoes) return jsonFile.writeJson(file, data, options, callback) + + mkdir.mkdirs(dir, err => { + if (err) return callback(err) + jsonFile.writeJson(file, data, options, callback) + }) + }) +} + +module.exports = outputJson + + +/***/ }), +/* 131 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const fs = __webpack_require__(96) +const path = __webpack_require__(57) +const mkdir = __webpack_require__(104) +const jsonFile = __webpack_require__(124) + +function outputJsonSync (file, data, options) { + const dir = path.dirname(file) + + if (!fs.existsSync(dir)) { + mkdir.mkdirsSync(dir) + } + + jsonFile.writeJsonSync(file, data, options) +} + +module.exports = outputJsonSync + + +/***/ }), +/* 132 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = { + moveSync: __webpack_require__(133) +} + + +/***/ }), +/* 133 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const fs = __webpack_require__(96) +const path = __webpack_require__(57) +const copySync = __webpack_require__(102).copySync +const removeSync = __webpack_require__(115).removeSync +const mkdirpSync = __webpack_require__(104).mkdirpSync +const stat = __webpack_require__(109) + +function moveSync (src, dest, opts) { + opts = opts || {} + const overwrite = opts.overwrite || opts.clobber || false + + const { srcStat } = stat.checkPathsSync(src, dest, 'move') + stat.checkParentPathsSync(src, srcStat, dest, 'move') + mkdirpSync(path.dirname(dest)) + return doRename(src, dest, overwrite) +} + +function doRename (src, dest, overwrite) { + if (overwrite) { + removeSync(dest) + return rename(src, dest, overwrite) + } + if (fs.existsSync(dest)) throw new Error('dest already exists.') + return rename(src, dest, overwrite) +} + +function rename (src, dest, overwrite) { + try { + fs.renameSync(src, dest) + } catch (err) { + if (err.code !== 'EXDEV') throw err + return moveAcrossDevice(src, dest, overwrite) + } +} + +function moveAcrossDevice (src, dest, overwrite) { + const opts = { + overwrite, + errorOnExist: true + } + copySync(src, dest, opts) + return removeSync(src) +} + +module.exports = moveSync + + +/***/ }), +/* 134 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const u = __webpack_require__(95).fromCallback +module.exports = { + move: u(__webpack_require__(135)) +} + + +/***/ }), +/* 135 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const fs = __webpack_require__(96) +const path = __webpack_require__(57) +const copy = __webpack_require__(111).copy +const remove = __webpack_require__(115).remove +const mkdirp = __webpack_require__(104).mkdirp +const pathExists = __webpack_require__(113).pathExists +const stat = __webpack_require__(109) + +function move (src, dest, opts, cb) { + if (typeof opts === 'function') { + cb = opts + opts = {} + } + + const overwrite = opts.overwrite || opts.clobber || false + + stat.checkPaths(src, dest, 'move', (err, stats) => { + if (err) return cb(err) + const { srcStat } = stats + stat.checkParentPaths(src, srcStat, dest, 'move', err => { + if (err) return cb(err) + mkdirp(path.dirname(dest), err => { + if (err) return cb(err) + return doRename(src, dest, overwrite, cb) + }) + }) + }) +} + +function doRename (src, dest, overwrite, cb) { + if (overwrite) { + return remove(dest, err => { + if (err) return cb(err) + return rename(src, dest, overwrite, cb) + }) + } + pathExists(dest, (err, destExists) => { + if (err) return cb(err) + if (destExists) return cb(new Error('dest already exists.')) + return rename(src, dest, overwrite, cb) + }) +} + +function rename (src, dest, overwrite, cb) { + fs.rename(src, dest, err => { + if (!err) return cb() + if (err.code !== 'EXDEV') return cb(err) + return moveAcrossDevice(src, dest, overwrite, cb) + }) +} + +function moveAcrossDevice (src, dest, overwrite, cb) { + const opts = { + overwrite, + errorOnExist: true + } + copy(src, dest, opts, err => { + if (err) return cb(err) + return remove(src, cb) + }) +} + +module.exports = move + + +/***/ }), +/* 136 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const u = __webpack_require__(95).fromCallback +const fs = __webpack_require__(96) +const path = __webpack_require__(57) +const mkdir = __webpack_require__(104) +const pathExists = __webpack_require__(113).pathExists + +function outputFile (file, data, encoding, callback) { + if (typeof encoding === 'function') { + callback = encoding + encoding = 'utf8' + } + + const dir = path.dirname(file) + pathExists(dir, (err, itDoes) => { + if (err) return callback(err) + if (itDoes) return fs.writeFile(file, data, encoding, callback) + + mkdir.mkdirs(dir, err => { + if (err) return callback(err) + + fs.writeFile(file, data, encoding, callback) + }) + }) +} + +function outputFileSync (file, ...args) { + const dir = path.dirname(file) + if (fs.existsSync(dir)) { + return fs.writeFileSync(file, ...args) + } + mkdir.mkdirsSync(dir) + fs.writeFileSync(file, ...args) +} + +module.exports = { + outputFile: u(outputFile), + outputFileSync +} + + +/***/ }), +/* 137 */ +/***/ (function(module, exports) { + +module.exports = require("zlib"); + +/***/ }), +/* 138 */ +/***/ (function(module, exports) { + +// allows us to inject a mock date in tests +module.exports = () => new Date(); + + +/***/ }), +/* 139 */ +/***/ (function(module, exports, __webpack_require__) { + +const debug = __webpack_require__(65)("streamroller:fileNameFormatter"); +const path = __webpack_require__(57); +const FILENAME_SEP = "."; +const ZIP_EXT = ".gz"; + +module.exports = ({ + file, + keepFileExt, + needsIndex, + alwaysIncludeDate, + compress +}) => { + const dirAndName = path.join(file.dir, file.name); + + const ext = f => f + file.ext; + + const index = (f, i, d) => + (needsIndex || !d) && i ? f + FILENAME_SEP + i : f; + + const date = (f, i, d) => { + return (i > 0 || alwaysIncludeDate) && d ? f + FILENAME_SEP + d : f; + }; + + const gzip = (f, i) => (i && compress ? f + ZIP_EXT : f); + + const parts = keepFileExt + ? [date, index, ext, gzip] + : [ext, date, index, gzip]; + + return ({ date, index }) => { + debug(`_formatFileName: date=${date}, index=${index}`); + return parts.reduce( + (filename, part) => part(filename, index, date), + dirAndName + ); + }; +}; + + +/***/ }), +/* 140 */ +/***/ (function(module, exports, __webpack_require__) { + +const debug = __webpack_require__(65)("streamroller:fileNameParser"); +const FILENAME_SEP = "."; +const ZIP_EXT = ".gz"; +const format = __webpack_require__(76); + +module.exports = ({ file, keepFileExt, pattern }) => { + // All these functions take two arguments: f, the filename, and p, the result placeholder + // They return the filename with any matching parts removed. + // The "zip" function, for instance, removes the ".gz" part of the filename (if present) + const zip = (f, p) => { + if (f.endsWith(ZIP_EXT)) { + debug("it is gzipped"); + p.isCompressed = true; + return f.slice(0, -1 * ZIP_EXT.length); + } + return f; + }; + + const extAtEnd = f => { + if (f.startsWith(file.name) && f.endsWith(file.ext)) { + debug("it starts and ends with the right things"); + return f.slice(file.name.length + 1, -1 * file.ext.length); + } + return f; + }; + + const extInMiddle = f => { + if (f.startsWith(file.base)) { + debug("it starts with the right things"); + return f.slice(file.base.length + 1); + } + return f; + }; + + const dateAndIndex = (f, p) => { + const items = f.split(FILENAME_SEP); + let indexStr = items[items.length - 1]; + debug("items: ", items, ", indexStr: ", indexStr); + let dateStr = f; + if (indexStr !== undefined && indexStr.match(/^\d+$/)) { + dateStr = f.slice(0, -1 * (indexStr.length + 1)); + debug(`dateStr is ${dateStr}`); + } else { + indexStr = "0"; + } + + try { + // Two arguments for new Date() are intentional. This will set other date + // components to minimal values in the current timezone instead of UTC, + // as new Date(0) will do. + const date = format.parse(pattern, dateStr, new Date(0, 0)); + p.index = parseInt(indexStr, 10); + p.date = dateStr; + p.timestamp = date.getTime(); + return ""; + } catch (e) { + //not a valid date, don't panic. + debug(`Problem parsing ${dateStr} as ${pattern}, error was: `, e); + return f; + } + }; + + const index = (f, p) => { + if (f.match(/^\d+$/)) { + debug("it has an index"); + p.index = parseInt(f, 10); + return ""; + } + return f; + }; + + let parts = [ + zip, + keepFileExt ? extAtEnd : extInMiddle, + pattern ? dateAndIndex : index + ]; + + return filename => { + let result = { filename, index: 0, isCompressed: false }; + // pass the filename through each of the file part parsers + let whatsLeftOver = parts.reduce( + (remains, part) => part(remains, result), + filename + ); + // if there's anything left after parsing, then it wasn't a valid filename + return whatsLeftOver ? null : result; + }; +}; + + +/***/ }), +/* 141 */ +/***/ (function(module, exports, __webpack_require__) { + +const RollingFileWriteStream = __webpack_require__(92); + +// just to adapt the previous version +class RollingFileStream extends RollingFileWriteStream { + constructor(filename, size, backups, options) { + if (!options) { + options = {}; + } + if (size) { + options.maxSize = size; + } + if (!backups) { + backups = 1; + } + options.numToKeep = backups; + super(filename, options); + this.backups = this.options.numToKeep; + this.size = this.options.maxSize; + } + + get theStream() { + return this.currentFileStream; + } + +} + +module.exports = RollingFileStream; + + +/***/ }), +/* 142 */ +/***/ (function(module, exports, __webpack_require__) { + +const RollingFileWriteStream = __webpack_require__(92); + +// just to adapt the previous version +class DateRollingFileStream extends RollingFileWriteStream { + constructor(filename, pattern, options) { + if (pattern && typeof(pattern) === 'object') { + options = pattern; + pattern = null; + } + if (!options) { + options = {}; + } + if (!pattern) { + pattern = 'yyyy-MM-dd'; + } + if (options.daysToKeep) { + options.numToKeep = options.daysToKeep; + } + if (pattern.startsWith('.')) { + pattern = pattern.substring(1); + } + options.pattern = pattern; + super(filename, options); + this.mode = this.options.mode; + } + + get theStream() { + return this.currentFileStream; + } + +} + +module.exports = DateRollingFileStream; + + +/***/ }), +/* 143 */ +/***/ (function(module, exports, __webpack_require__) { + +const streams = __webpack_require__(91); +const os = __webpack_require__(56); + +const eol = os.EOL || '\n'; + +/** + * File appender that rolls files according to a date pattern. + * @filename base filename. + * @pattern the format that will be added to the end of filename when rolling, + * also used to check when to roll files - defaults to '.yyyy-MM-dd' + * @layout layout function for log messages - defaults to basicLayout + * @timezoneOffset optional timezone offset in minutes - defaults to system local + */ +function appender( + filename, + pattern, + layout, + options, + timezoneOffset +) { + // the options for file appender use maxLogSize, but the docs say any file appender + // options should work for dateFile as well. + options.maxSize = options.maxLogSize; + + const logFile = new streams.DateRollingFileStream( + filename, + pattern, + options + ); + + const app = function (logEvent) { + logFile.write(layout(logEvent, timezoneOffset) + eol, 'utf8'); + }; + + app.shutdown = function (complete) { + logFile.write('', 'utf-8', () => { + logFile.end(complete); + }); + }; + + return app; +} + +function configure(config, layouts) { + let layout = layouts.basicLayout; + + if (config.layout) { + layout = layouts.layout(config.layout.type, config.layout); + } + + if (!config.alwaysIncludePattern) { + config.alwaysIncludePattern = false; + } + + return appender( + config.filename, + config.pattern, + layout, + config, + config.timezoneOffset + ); +} + +module.exports.configure = configure; + + +/***/ }), +/* 144 */ +/***/ (function(module, exports) { + +function webpackEmptyContext(req) { + var e = new Error("Cannot find module '" + req + "'"); + e.code = 'MODULE_NOT_FOUND'; + throw e; +} +webpackEmptyContext.keys = function() { return []; }; +webpackEmptyContext.resolve = webpackEmptyContext; +module.exports = webpackEmptyContext; +webpackEmptyContext.id = 144; + +/***/ }), +/* 145 */ +/***/ (function(module, exports, __webpack_require__) { + +const debug = __webpack_require__(65)('log4js:categories'); +const configuration = __webpack_require__(74); +const levels = __webpack_require__(77); +const appenders = __webpack_require__(78); + +const categories = new Map(); + +/** + * Add inherited config to this category. That includes extra appenders from parent, + * and level, if none is set on this category. + * This is recursive, so each parent also gets loaded with inherited appenders. + * Inheritance is blocked if a category has inherit=false + * @param {any} config + * @param {any} category the child category + * @param {string} categoryName dotted path to category + * @return {void} + */ +function inheritFromParent(config, category, categoryName) { + if (category.inherit === false) return; + const lastDotIndex = categoryName.lastIndexOf('.'); + if (lastDotIndex < 0) return; // category is not a child + const parentCategoryName = categoryName.substring(0, lastDotIndex); + let parentCategory = config.categories[parentCategoryName]; + + + if (!parentCategory) { + // parent is missing, so implicitly create it, so that it can inherit from its parents + parentCategory = { inherit: true, appenders: [] }; + } + + // make sure parent has had its inheritance taken care of before pulling its properties to this child + inheritFromParent(config, parentCategory, parentCategoryName); + + // if the parent is not in the config (because we just created it above), + // and it inherited a valid configuration, add it to config.categories + if (!config.categories[parentCategoryName] + && parentCategory.appenders + && parentCategory.appenders.length + && parentCategory.level) { + config.categories[parentCategoryName] = parentCategory; + } + + category.appenders = category.appenders || []; + category.level = category.level || parentCategory.level; + + // merge in appenders from parent (parent is already holding its inherited appenders) + parentCategory.appenders.forEach((ap) => { + if (!category.appenders.includes(ap)) { + category.appenders.push(ap); + } + }); + category.parent = parentCategory; +} + + +/** + * Walk all categories in the config, and pull down any configuration from parent to child. + * This includes inherited appenders, and level, where level is not set. + * Inheritance is skipped where a category has inherit=false. + * @param {any} config + */ +function addCategoryInheritance(config) { + if (!config.categories) return; + const categoryNames = Object.keys(config.categories); + categoryNames.forEach((name) => { + const category = config.categories[name]; + // add inherited appenders and level to this category + inheritFromParent(config, category, name); + }); +} + +configuration.addPreProcessingListener(config => addCategoryInheritance(config)); + +configuration.addListener((config) => { + configuration.throwExceptionIf( + config, + configuration.not(configuration.anObject(config.categories)), + 'must have a property "categories" of type object.' + ); + + const categoryNames = Object.keys(config.categories); + configuration.throwExceptionIf( + config, + configuration.not(categoryNames.length), + 'must define at least one category.' + ); + + categoryNames.forEach((name) => { + const category = config.categories[name]; + configuration.throwExceptionIf( + config, + [ + configuration.not(category.appenders), + configuration.not(category.level) + ], + `category "${name}" is not valid (must be an object with properties "appenders" and "level")` + ); + + configuration.throwExceptionIf( + config, + configuration.not(Array.isArray(category.appenders)), + `category "${name}" is not valid (appenders must be an array of appender names)` + ); + + configuration.throwExceptionIf( + config, + configuration.not(category.appenders.length), + `category "${name}" is not valid (appenders must contain at least one appender name)` + ); + + if (Object.prototype.hasOwnProperty.call(category, 'enableCallStack')) { + configuration.throwExceptionIf( + config, + typeof category.enableCallStack !== 'boolean', + `category "${name}" is not valid (enableCallStack must be boolean type)` + ); + } + + category.appenders.forEach((appender) => { + configuration.throwExceptionIf( + config, + configuration.not(appenders.get(appender)), + `category "${name}" is not valid (appender "${appender}" is not defined)` + ); + }); + + configuration.throwExceptionIf( + config, + configuration.not(levels.getLevel(category.level)), + `category "${name}" is not valid (level "${category.level}" not recognised;` + + ` valid levels are ${levels.levels.join(', ')})` + ); + }); + + configuration.throwExceptionIf( + config, + configuration.not(config.categories.default), + 'must define a "default" category.' + ); +}); + +const setup = (config) => { + categories.clear(); + + const categoryNames = Object.keys(config.categories); + categoryNames.forEach((name) => { + const category = config.categories[name]; + const categoryAppenders = []; + category.appenders.forEach((appender) => { + categoryAppenders.push(appenders.get(appender)); + debug(`Creating category ${name}`); + categories.set( + name, + { + appenders: categoryAppenders, + level: levels.getLevel(category.level), + enableCallStack: category.enableCallStack || false + } + ); + }); + }); +}; + +setup({ categories: { default: { appenders: ['out'], level: 'OFF' } } }); +configuration.addListener(setup); + +const configForCategory = (category) => { + debug(`configForCategory: searching for config for ${category}`); + if (categories.has(category)) { + debug(`configForCategory: ${category} exists in config, returning it`); + return categories.get(category); + } + if (category.indexOf('.') > 0) { + debug(`configForCategory: ${category} has hierarchy, searching for parents`); + return configForCategory(category.substring(0, category.lastIndexOf('.'))); + } + debug('configForCategory: returning config for default category'); + return configForCategory('default'); +}; + +const appendersForCategory = category => configForCategory(category).appenders; +const getLevelForCategory = category => configForCategory(category).level; + +const setLevelForCategory = (category, level) => { + let categoryConfig = categories.get(category); + debug(`setLevelForCategory: found ${categoryConfig} for ${category}`); + if (!categoryConfig) { + const sourceCategoryConfig = configForCategory(category); + debug('setLevelForCategory: no config found for category, ' + + `found ${sourceCategoryConfig} for parents of ${category}`); + categoryConfig = { appenders: sourceCategoryConfig.appenders }; + } + categoryConfig.level = level; + categories.set(category, categoryConfig); +}; + +const getEnableCallStackForCategory = category => configForCategory(category).enableCallStack === true; +const setEnableCallStackForCategory = (category, useCallStack) => { + configForCategory(category).enableCallStack = useCallStack; +}; + +module.exports = { + appendersForCategory, + getLevelForCategory, + setLevelForCategory, + getEnableCallStackForCategory, + setEnableCallStackForCategory, +}; + + +/***/ }), +/* 146 */ +/***/ (function(module, exports, __webpack_require__) { + +/* eslint no-underscore-dangle:0 */ +const debug = __webpack_require__(65)("log4js:logger"); +const LoggingEvent = __webpack_require__(80); +const levels = __webpack_require__(77); +const clustering = __webpack_require__(79); +const categories = __webpack_require__(145); +const configuration = __webpack_require__(74); + +const stackReg = /at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/; +function defaultParseCallStack(data, skipIdx = 4) { + const stacklines = data.stack.split("\n").slice(skipIdx); + const lineMatch = stackReg.exec(stacklines[0]); + if (lineMatch && lineMatch.length === 6) { + return { + functionName: lineMatch[1], + fileName: lineMatch[2], + lineNumber: parseInt(lineMatch[3], 10), + columnNumber: parseInt(lineMatch[4], 10), + callStack: stacklines.join("\n") + }; + } + return null; +} + +/** + * Logger to log messages. + * use {@see log4js#getLogger(String)} to get an instance. + * + * @name Logger + * @namespace Log4js + * @param name name of category to log to + * @param level - the loglevel for the category + * @param dispatch - the function which will receive the logevents + * + * @author Stephan Strittmatter + */ +class Logger { + constructor(name) { + if (!name) { + throw new Error("No category provided."); + } + this.category = name; + this.context = {}; + this.parseCallStack = defaultParseCallStack; + debug(`Logger created (${this.category}, ${this.level})`); + } + + get level() { + return levels.getLevel( + categories.getLevelForCategory(this.category), + levels.TRACE + ); + } + + set level(level) { + categories.setLevelForCategory( + this.category, + levels.getLevel(level, this.level) + ); + } + + get useCallStack() { + return categories.getEnableCallStackForCategory(this.category); + } + + set useCallStack(bool) { + categories.setEnableCallStackForCategory(this.category, bool === true); + } + + log(level, ...args) { + const logLevel = levels.getLevel(level, levels.INFO); + if (this.isLevelEnabled(logLevel)) { + this._log(logLevel, args); + } + } + + isLevelEnabled(otherLevel) { + return this.level.isLessThanOrEqualTo(otherLevel); + } + + _log(level, data) { + debug(`sending log data (${level}) to appenders`); + const loggingEvent = new LoggingEvent( + this.category, + level, + data, + this.context, + this.useCallStack && this.parseCallStack(new Error()) + ); + clustering.send(loggingEvent); + } + + addContext(key, value) { + this.context[key] = value; + } + + removeContext(key) { + delete this.context[key]; + } + + clearContext() { + this.context = {}; + } + + setParseCallStackFunction(parseFunction) { + this.parseCallStack = parseFunction; + } +} + +function addLevelMethods(target) { + const level = levels.getLevel(target); + + const levelStrLower = level.toString().toLowerCase(); + const levelMethod = levelStrLower.replace(/_([a-z])/g, g => + g[1].toUpperCase() + ); + const isLevelMethod = levelMethod[0].toUpperCase() + levelMethod.slice(1); + + Logger.prototype[`is${isLevelMethod}Enabled`] = function() { + return this.isLevelEnabled(level); + }; + + Logger.prototype[levelMethod] = function(...args) { + this.log(level, ...args); + }; +} + +levels.levels.forEach(addLevelMethods); + +configuration.addListener(() => { + levels.levels.forEach(addLevelMethods); +}); + +module.exports = Logger; + + +/***/ }), +/* 147 */ +/***/ (function(module, exports, __webpack_require__) { + +/* eslint-disable no-plusplus */ + +const levels = __webpack_require__(77); + +const DEFAULT_FORMAT = + ":remote-addr - -" + + ' ":method :url HTTP/:http-version"' + + ' :status :content-length ":referrer"' + + ' ":user-agent"'; + +/** + * Return request url path, + * adding this function prevents the Cyclomatic Complexity, + * for the assemble_tokens function at low, to pass the tests. + * + * @param {IncomingMessage} req + * @return {String} + * @api private + */ +function getUrl(req) { + return req.originalUrl || req.url; +} + +/** + * Adds custom {token, replacement} objects to defaults, + * overwriting the defaults if any tokens clash + * + * @param {IncomingMessage} req + * @param {ServerResponse} res + * @param {Array} customTokens + * [{ token: string-or-regexp, replacement: string-or-replace-function }] + * @return {Array} + */ +function assembleTokens(req, res, customTokens) { + const arrayUniqueTokens = array => { + const a = array.concat(); + for (let i = 0; i < a.length; ++i) { + for (let j = i + 1; j < a.length; ++j) { + // not === because token can be regexp object + /* eslint eqeqeq:0 */ + if (a[i].token == a[j].token) { + a.splice(j--, 1); + } + } + } + return a; + }; + + const defaultTokens = []; + defaultTokens.push({ token: ":url", replacement: getUrl(req) }); + defaultTokens.push({ token: ":protocol", replacement: req.protocol }); + defaultTokens.push({ token: ":hostname", replacement: req.hostname }); + defaultTokens.push({ token: ":method", replacement: req.method }); + defaultTokens.push({ + token: ":status", + replacement: res.__statusCode || res.statusCode + }); + defaultTokens.push({ + token: ":response-time", + replacement: res.responseTime + }); + defaultTokens.push({ token: ":date", replacement: new Date().toUTCString() }); + defaultTokens.push({ + token: ":referrer", + replacement: req.headers.referer || req.headers.referrer || "" + }); + defaultTokens.push({ + token: ":http-version", + replacement: `${req.httpVersionMajor}.${req.httpVersionMinor}` + }); + defaultTokens.push({ + token: ":remote-addr", + replacement: + req.headers["x-forwarded-for"] || + req.ip || + req._remoteAddress || + (req.socket && + (req.socket.remoteAddress || + (req.socket.socket && req.socket.socket.remoteAddress))) + }); + defaultTokens.push({ + token: ":user-agent", + replacement: req.headers["user-agent"] + }); + defaultTokens.push({ + token: ":content-length", + replacement: + res.getHeader("content-length") || + (res.__headers && res.__headers["Content-Length"]) || + "-" + }); + defaultTokens.push({ + token: /:req\[([^\]]+)]/g, + replacement(_, field) { + return req.headers[field.toLowerCase()]; + } + }); + defaultTokens.push({ + token: /:res\[([^\]]+)]/g, + replacement(_, field) { + return ( + res.getHeader(field.toLowerCase()) || + (res.__headers && res.__headers[field]) + ); + } + }); + + return arrayUniqueTokens(customTokens.concat(defaultTokens)); +} + +/** + * Return formatted log line. + * + * @param {String} str + * @param {Array} tokens + * @return {String} + * @api private + */ +function format(str, tokens) { + for (let i = 0; i < tokens.length; i++) { + str = str.replace(tokens[i].token, tokens[i].replacement); + } + return str; +} + +/** + * Return RegExp Object about nolog + * + * @param {String|Array} nolog + * @return {RegExp} + * @api private + * + * syntax + * 1. String + * 1.1 "\\.gif" + * NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.gif?fuga + * LOGGING http://example.com/hoge.agif + * 1.2 in "\\.gif|\\.jpg$" + * NOT LOGGING http://example.com/hoge.gif and + * http://example.com/hoge.gif?fuga and http://example.com/hoge.jpg?fuga + * LOGGING http://example.com/hoge.agif, + * http://example.com/hoge.ajpg and http://example.com/hoge.jpg?hoge + * 1.3 in "\\.(gif|jpe?g|png)$" + * NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.jpeg + * LOGGING http://example.com/hoge.gif?uid=2 and http://example.com/hoge.jpg?pid=3 + * 2. RegExp + * 2.1 in /\.(gif|jpe?g|png)$/ + * SAME AS 1.3 + * 3. Array + * 3.1 ["\\.jpg$", "\\.png", "\\.gif"] + * SAME AS "\\.jpg|\\.png|\\.gif" + */ +function createNoLogCondition(nolog) { + let regexp = null; + + if (nolog instanceof RegExp) { + regexp = nolog; + } + + if (typeof nolog === "string") { + regexp = new RegExp(nolog); + } + + if (Array.isArray(nolog)) { + // convert to strings + const regexpsAsStrings = nolog.map(reg => (reg.source ? reg.source : reg)); + regexp = new RegExp(regexpsAsStrings.join("|")); + } + + return regexp; +} + +/** + * Allows users to define rules around status codes to assign them to a specific + * logging level. + * There are two types of rules: + * - RANGE: matches a code within a certain range + * E.g. { 'from': 200, 'to': 299, 'level': 'info' } + * - CONTAINS: matches a code to a set of expected codes + * E.g. { 'codes': [200, 203], 'level': 'debug' } + * Note*: Rules are respected only in order of prescendence. + * + * @param {Number} statusCode + * @param {Level} currentLevel + * @param {Object} ruleSet + * @return {Level} + * @api private + */ +function matchRules(statusCode, currentLevel, ruleSet) { + let level = currentLevel; + + if (ruleSet) { + const matchedRule = ruleSet.find(rule => { + let ruleMatched = false; + if (rule.from && rule.to) { + ruleMatched = statusCode >= rule.from && statusCode <= rule.to; + } else { + ruleMatched = rule.codes.indexOf(statusCode) !== -1; + } + return ruleMatched; + }); + if (matchedRule) { + level = levels.getLevel(matchedRule.level, level); + } + } + return level; +} + +/** + * Log requests with the given `options` or a `format` string. + * + * Options: + * + * - `format` Format string, see below for tokens + * - `level` A log4js levels instance. Supports also 'auto' + * - `nolog` A string or RegExp to exclude target logs + * - `statusRules` A array of rules for setting specific logging levels base on status codes + * - `context` Whether to add a response of express to the context + * + * Tokens: + * + * - `:req[header]` ex: `:req[Accept]` + * - `:res[header]` ex: `:res[Content-Length]` + * - `:http-version` + * - `:response-time` + * - `:remote-addr` + * - `:date` + * - `:method` + * - `:url` + * - `:referrer` + * - `:user-agent` + * - `:status` + * + * @return {Function} + * @param logger4js + * @param options + * @api public + */ +module.exports = function getLogger(logger4js, options) { + /* eslint no-underscore-dangle:0 */ + if (typeof options === "string" || typeof options === "function") { + options = { format: options }; + } else { + options = options || {}; + } + + const thisLogger = logger4js; + let level = levels.getLevel(options.level, levels.INFO); + const fmt = options.format || DEFAULT_FORMAT; + const nolog = createNoLogCondition(options.nolog); + + return (req, res, next) => { + // mount safety + if (req._logging) return next(); + + // nologs + if (nolog && nolog.test(req.originalUrl)) return next(); + + if (thisLogger.isLevelEnabled(level) || options.level === "auto") { + const start = new Date(); + const { writeHead } = res; + + // flag as logging + req._logging = true; + + // proxy for statusCode. + res.writeHead = (code, headers) => { + res.writeHead = writeHead; + res.writeHead(code, headers); + + res.__statusCode = code; + res.__headers = headers || {}; + }; + + // hook on end request to emit the log entry of the HTTP request. + res.on("finish", () => { + res.responseTime = new Date() - start; + // status code response level handling + if (res.statusCode && options.level === "auto") { + level = levels.INFO; + if (res.statusCode >= 300) level = levels.WARN; + if (res.statusCode >= 400) level = levels.ERROR; + } + level = matchRules(res.statusCode, level, options.statusRules); + + const combinedTokens = assembleTokens(req, res, options.tokens || []); + + if (options.context) thisLogger.addContext("res", res); + if (typeof fmt === "function") { + const line = fmt(req, res, str => format(str, combinedTokens)); + if (line) thisLogger.log(level, line); + } else { + thisLogger.log(level, format(fmt, combinedTokens)); + } + if (options.context) thisLogger.removeContext("res"); + }); + } + + // ensure next gets always called + return next(); + }; +}; + + +/***/ }), +/* 148 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const util_1 = __webpack_require__(174); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('events'); +class Events { + constructor() { + this.handlers = new Map(); + this.insertMode = false; + } + get cursor() { + return this._cursor; + } + async fire(event, args) { + logger.debug('Event:', event, args); + let handlers = this.handlers.get(event); + if (event == 'InsertEnter') { + this.insertMode = true; + } + else if (event == 'InsertLeave') { + this.insertMode = false; + } + else if (!this.insertMode && (event == 'CursorHoldI' || event == 'CursorMovedI')) { + this.insertMode = true; + await this.fire('InsertEnter', [args[0]]); + } + else if (this.insertMode && (event == 'CursorHold' || event == 'CursorMoved')) { + this.insertMode = false; + await this.fire('InsertLeave', [args[0]]); + } + if (event == 'CursorMoved' || event == 'CursorMovedI') { + this._cursor = { + bufnr: args[0], + lnum: args[1][0], + col: args[1][1], + insert: event == 'CursorMovedI' + }; + } + if (handlers) { + try { + await Promise.all(handlers.map(fn => { + return Promise.resolve(fn.apply(null, args)); + })); + } + catch (e) { + logger.error(`Error on ${event}: `, e.stack); + workspace_1.default.showMessage(`Error on ${event}: ${e.message} `, 'error'); + } + } + } + on(event, handler, thisArg, disposables) { + if (Array.isArray(event)) { + let disposables = []; + for (let ev of event) { + disposables.push(this.on(ev, handler, thisArg, disposables)); + } + return vscode_languageserver_protocol_1.Disposable.create(() => { + util_1.disposeAll(disposables); + }); + } + else { + let arr = this.handlers.get(event) || []; + arr.push(handler.bind(thisArg || null)); + this.handlers.set(event, arr); + let disposable = vscode_languageserver_protocol_1.Disposable.create(() => { + let idx = arr.indexOf(handler); + if (idx !== -1) { + arr.splice(idx, 1); + } + }); + if (disposables) { + disposables.push(disposable); + } + return disposable; + } + } +} +exports.default = new Events(); +//# sourceMappingURL=events.js.map + +/***/ }), +/* 149 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_jsonrpc_1 = __webpack_require__(150); +exports.ErrorCodes = vscode_jsonrpc_1.ErrorCodes; +exports.ResponseError = vscode_jsonrpc_1.ResponseError; +exports.CancellationToken = vscode_jsonrpc_1.CancellationToken; +exports.CancellationTokenSource = vscode_jsonrpc_1.CancellationTokenSource; +exports.Disposable = vscode_jsonrpc_1.Disposable; +exports.Event = vscode_jsonrpc_1.Event; +exports.Emitter = vscode_jsonrpc_1.Emitter; +exports.Trace = vscode_jsonrpc_1.Trace; +exports.TraceFormat = vscode_jsonrpc_1.TraceFormat; +exports.SetTraceNotification = vscode_jsonrpc_1.SetTraceNotification; +exports.LogTraceNotification = vscode_jsonrpc_1.LogTraceNotification; +exports.RequestType = vscode_jsonrpc_1.RequestType; +exports.RequestType0 = vscode_jsonrpc_1.RequestType0; +exports.NotificationType = vscode_jsonrpc_1.NotificationType; +exports.NotificationType0 = vscode_jsonrpc_1.NotificationType0; +exports.MessageReader = vscode_jsonrpc_1.MessageReader; +exports.MessageWriter = vscode_jsonrpc_1.MessageWriter; +exports.ConnectionStrategy = vscode_jsonrpc_1.ConnectionStrategy; +exports.StreamMessageReader = vscode_jsonrpc_1.StreamMessageReader; +exports.StreamMessageWriter = vscode_jsonrpc_1.StreamMessageWriter; +exports.IPCMessageReader = vscode_jsonrpc_1.IPCMessageReader; +exports.IPCMessageWriter = vscode_jsonrpc_1.IPCMessageWriter; +exports.createClientPipeTransport = vscode_jsonrpc_1.createClientPipeTransport; +exports.createServerPipeTransport = vscode_jsonrpc_1.createServerPipeTransport; +exports.generateRandomPipeName = vscode_jsonrpc_1.generateRandomPipeName; +exports.createClientSocketTransport = vscode_jsonrpc_1.createClientSocketTransport; +exports.createServerSocketTransport = vscode_jsonrpc_1.createServerSocketTransport; +__export(__webpack_require__(161)); +__export(__webpack_require__(162)); +const callHierarchy = __webpack_require__(172); +const progress = __webpack_require__(173); +var Proposed; +(function (Proposed) { + let CallHierarchyRequest; + (function (CallHierarchyRequest) { + CallHierarchyRequest.type = callHierarchy.CallHierarchyRequest.type; + })(CallHierarchyRequest = Proposed.CallHierarchyRequest || (Proposed.CallHierarchyRequest = {})); + let CallHierarchyDirection; + (function (CallHierarchyDirection) { + CallHierarchyDirection.CallsFrom = callHierarchy.CallHierarchyDirection.CallsFrom; + CallHierarchyDirection.CallsTo = callHierarchy.CallHierarchyDirection.CallsTo; + })(CallHierarchyDirection = Proposed.CallHierarchyDirection || (Proposed.CallHierarchyDirection = {})); + let ProgressStartNotification; + (function (ProgressStartNotification) { + ProgressStartNotification.type = progress.ProgressStartNotification.type; + })(ProgressStartNotification = Proposed.ProgressStartNotification || (Proposed.ProgressStartNotification = {})); + let ProgressReportNotification; + (function (ProgressReportNotification) { + ProgressReportNotification.type = progress.ProgressReportNotification.type; + })(ProgressReportNotification = Proposed.ProgressReportNotification || (Proposed.ProgressReportNotification = {})); + let ProgressDoneNotification; + (function (ProgressDoneNotification) { + ProgressDoneNotification.type = progress.ProgressDoneNotification.type; + })(ProgressDoneNotification = Proposed.ProgressDoneNotification || (Proposed.ProgressDoneNotification = {})); + let ProgressCancelNotification; + (function (ProgressCancelNotification) { + ProgressCancelNotification.type = progress.ProgressCancelNotification.type; + })(ProgressCancelNotification = Proposed.ProgressCancelNotification || (Proposed.ProgressCancelNotification = {})); +})(Proposed = exports.Proposed || (exports.Proposed = {})); +function createProtocolConnection(reader, writer, logger, strategy) { + return vscode_jsonrpc_1.createMessageConnection(reader, writer, logger, strategy); +} +exports.createProtocolConnection = createProtocolConnection; + + +/***/ }), +/* 150 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ +/// + +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +Object.defineProperty(exports, "__esModule", { value: true }); +const Is = __webpack_require__(151); +const messages_1 = __webpack_require__(152); +exports.RequestType = messages_1.RequestType; +exports.RequestType0 = messages_1.RequestType0; +exports.RequestType1 = messages_1.RequestType1; +exports.RequestType2 = messages_1.RequestType2; +exports.RequestType3 = messages_1.RequestType3; +exports.RequestType4 = messages_1.RequestType4; +exports.RequestType5 = messages_1.RequestType5; +exports.RequestType6 = messages_1.RequestType6; +exports.RequestType7 = messages_1.RequestType7; +exports.RequestType8 = messages_1.RequestType8; +exports.RequestType9 = messages_1.RequestType9; +exports.ResponseError = messages_1.ResponseError; +exports.ErrorCodes = messages_1.ErrorCodes; +exports.NotificationType = messages_1.NotificationType; +exports.NotificationType0 = messages_1.NotificationType0; +exports.NotificationType1 = messages_1.NotificationType1; +exports.NotificationType2 = messages_1.NotificationType2; +exports.NotificationType3 = messages_1.NotificationType3; +exports.NotificationType4 = messages_1.NotificationType4; +exports.NotificationType5 = messages_1.NotificationType5; +exports.NotificationType6 = messages_1.NotificationType6; +exports.NotificationType7 = messages_1.NotificationType7; +exports.NotificationType8 = messages_1.NotificationType8; +exports.NotificationType9 = messages_1.NotificationType9; +const messageReader_1 = __webpack_require__(153); +exports.MessageReader = messageReader_1.MessageReader; +exports.StreamMessageReader = messageReader_1.StreamMessageReader; +exports.IPCMessageReader = messageReader_1.IPCMessageReader; +exports.SocketMessageReader = messageReader_1.SocketMessageReader; +const messageWriter_1 = __webpack_require__(155); +exports.MessageWriter = messageWriter_1.MessageWriter; +exports.StreamMessageWriter = messageWriter_1.StreamMessageWriter; +exports.IPCMessageWriter = messageWriter_1.IPCMessageWriter; +exports.SocketMessageWriter = messageWriter_1.SocketMessageWriter; +const events_1 = __webpack_require__(154); +exports.Disposable = events_1.Disposable; +exports.Event = events_1.Event; +exports.Emitter = events_1.Emitter; +const cancellation_1 = __webpack_require__(156); +exports.CancellationTokenSource = cancellation_1.CancellationTokenSource; +exports.CancellationToken = cancellation_1.CancellationToken; +const linkedMap_1 = __webpack_require__(157); +__export(__webpack_require__(158)); +__export(__webpack_require__(160)); +var CancelNotification; +(function (CancelNotification) { + CancelNotification.type = new messages_1.NotificationType('$/cancelRequest'); +})(CancelNotification || (CancelNotification = {})); +exports.NullLogger = Object.freeze({ + error: () => { }, + warn: () => { }, + info: () => { }, + log: () => { } +}); +var Trace; +(function (Trace) { + Trace[Trace["Off"] = 0] = "Off"; + Trace[Trace["Messages"] = 1] = "Messages"; + Trace[Trace["Verbose"] = 2] = "Verbose"; +})(Trace = exports.Trace || (exports.Trace = {})); +(function (Trace) { + function fromString(value) { + value = value.toLowerCase(); + switch (value) { + case 'off': + return Trace.Off; + case 'messages': + return Trace.Messages; + case 'verbose': + return Trace.Verbose; + default: + return Trace.Off; + } + } + Trace.fromString = fromString; + function toString(value) { + switch (value) { + case Trace.Off: + return 'off'; + case Trace.Messages: + return 'messages'; + case Trace.Verbose: + return 'verbose'; + default: + return 'off'; + } + } + Trace.toString = toString; +})(Trace = exports.Trace || (exports.Trace = {})); +var TraceFormat; +(function (TraceFormat) { + TraceFormat["Text"] = "text"; + TraceFormat["JSON"] = "json"; +})(TraceFormat = exports.TraceFormat || (exports.TraceFormat = {})); +(function (TraceFormat) { + function fromString(value) { + value = value.toLowerCase(); + if (value === 'json') { + return TraceFormat.JSON; + } + else { + return TraceFormat.Text; + } + } + TraceFormat.fromString = fromString; +})(TraceFormat = exports.TraceFormat || (exports.TraceFormat = {})); +var SetTraceNotification; +(function (SetTraceNotification) { + SetTraceNotification.type = new messages_1.NotificationType('$/setTraceNotification'); +})(SetTraceNotification = exports.SetTraceNotification || (exports.SetTraceNotification = {})); +var LogTraceNotification; +(function (LogTraceNotification) { + LogTraceNotification.type = new messages_1.NotificationType('$/logTraceNotification'); +})(LogTraceNotification = exports.LogTraceNotification || (exports.LogTraceNotification = {})); +var ConnectionErrors; +(function (ConnectionErrors) { + /** + * The connection is closed. + */ + ConnectionErrors[ConnectionErrors["Closed"] = 1] = "Closed"; + /** + * The connection got disposed. + */ + ConnectionErrors[ConnectionErrors["Disposed"] = 2] = "Disposed"; + /** + * The connection is already in listening mode. + */ + ConnectionErrors[ConnectionErrors["AlreadyListening"] = 3] = "AlreadyListening"; +})(ConnectionErrors = exports.ConnectionErrors || (exports.ConnectionErrors = {})); +class ConnectionError extends Error { + constructor(code, message) { + super(message); + this.code = code; + Object.setPrototypeOf(this, ConnectionError.prototype); + } +} +exports.ConnectionError = ConnectionError; +var ConnectionStrategy; +(function (ConnectionStrategy) { + function is(value) { + let candidate = value; + return candidate && Is.func(candidate.cancelUndispatched); + } + ConnectionStrategy.is = is; +})(ConnectionStrategy = exports.ConnectionStrategy || (exports.ConnectionStrategy = {})); +var ConnectionState; +(function (ConnectionState) { + ConnectionState[ConnectionState["New"] = 1] = "New"; + ConnectionState[ConnectionState["Listening"] = 2] = "Listening"; + ConnectionState[ConnectionState["Closed"] = 3] = "Closed"; + ConnectionState[ConnectionState["Disposed"] = 4] = "Disposed"; +})(ConnectionState || (ConnectionState = {})); +function _createMessageConnection(messageReader, messageWriter, logger, strategy) { + let sequenceNumber = 0; + let notificationSquenceNumber = 0; + let unknownResponseSquenceNumber = 0; + const version = '2.0'; + let starRequestHandler = undefined; + let requestHandlers = Object.create(null); + let starNotificationHandler = undefined; + let notificationHandlers = Object.create(null); + let timer; + let messageQueue = new linkedMap_1.LinkedMap(); + let responsePromises = Object.create(null); + let requestTokens = Object.create(null); + let trace = Trace.Off; + let traceFormat = TraceFormat.Text; + let tracer; + let state = ConnectionState.New; + let errorEmitter = new events_1.Emitter(); + let closeEmitter = new events_1.Emitter(); + let unhandledNotificationEmitter = new events_1.Emitter(); + let disposeEmitter = new events_1.Emitter(); + function createRequestQueueKey(id) { + return 'req-' + id.toString(); + } + function createResponseQueueKey(id) { + if (id === null) { + return 'res-unknown-' + (++unknownResponseSquenceNumber).toString(); + } + else { + return 'res-' + id.toString(); + } + } + function createNotificationQueueKey() { + return 'not-' + (++notificationSquenceNumber).toString(); + } + function addMessageToQueue(queue, message) { + if (messages_1.isRequestMessage(message)) { + queue.set(createRequestQueueKey(message.id), message); + } + else if (messages_1.isResponseMessage(message)) { + queue.set(createResponseQueueKey(message.id), message); + } + else { + queue.set(createNotificationQueueKey(), message); + } + } + function cancelUndispatched(_message) { + return undefined; + } + function isListening() { + return state === ConnectionState.Listening; + } + function isClosed() { + return state === ConnectionState.Closed; + } + function isDisposed() { + return state === ConnectionState.Disposed; + } + function closeHandler() { + if (state === ConnectionState.New || state === ConnectionState.Listening) { + state = ConnectionState.Closed; + closeEmitter.fire(undefined); + } + // If the connection is disposed don't sent close events. + } + ; + function readErrorHandler(error) { + errorEmitter.fire([error, undefined, undefined]); + } + function writeErrorHandler(data) { + errorEmitter.fire(data); + } + messageReader.onClose(closeHandler); + messageReader.onError(readErrorHandler); + messageWriter.onClose(closeHandler); + messageWriter.onError(writeErrorHandler); + function triggerMessageQueue() { + if (timer || messageQueue.size === 0) { + return; + } + timer = setImmediate(() => { + timer = undefined; + processMessageQueue(); + }); + } + function processMessageQueue() { + if (messageQueue.size === 0) { + return; + } + let message = messageQueue.shift(); + try { + if (messages_1.isRequestMessage(message)) { + handleRequest(message); + } + else if (messages_1.isNotificationMessage(message)) { + handleNotification(message); + } + else if (messages_1.isResponseMessage(message)) { + handleResponse(message); + } + else { + handleInvalidMessage(message); + } + } + finally { + triggerMessageQueue(); + } + } + let callback = (message) => { + try { + // We have received a cancellation message. Check if the message is still in the queue + // and cancel it if allowed to do so. + if (messages_1.isNotificationMessage(message) && message.method === CancelNotification.type.method) { + let key = createRequestQueueKey(message.params.id); + let toCancel = messageQueue.get(key); + if (messages_1.isRequestMessage(toCancel)) { + let response = strategy && strategy.cancelUndispatched ? strategy.cancelUndispatched(toCancel, cancelUndispatched) : cancelUndispatched(toCancel); + if (response && (response.error !== void 0 || response.result !== void 0)) { + messageQueue.delete(key); + response.id = toCancel.id; + traceSendingResponse(response, message.method, Date.now()); + messageWriter.write(response); + return; + } + } + } + addMessageToQueue(messageQueue, message); + } + finally { + triggerMessageQueue(); + } + }; + function handleRequest(requestMessage) { + if (isDisposed()) { + // we return here silently since we fired an event when the + // connection got disposed. + return; + } + function reply(resultOrError, method, startTime) { + let message = { + jsonrpc: version, + id: requestMessage.id + }; + if (resultOrError instanceof messages_1.ResponseError) { + message.error = resultOrError.toJson(); + } + else { + message.result = resultOrError === void 0 ? null : resultOrError; + } + traceSendingResponse(message, method, startTime); + messageWriter.write(message); + } + function replyError(error, method, startTime) { + let message = { + jsonrpc: version, + id: requestMessage.id, + error: error.toJson() + }; + traceSendingResponse(message, method, startTime); + messageWriter.write(message); + } + function replySuccess(result, method, startTime) { + // The JSON RPC defines that a response must either have a result or an error + // So we can't treat undefined as a valid response result. + if (result === void 0) { + result = null; + } + let message = { + jsonrpc: version, + id: requestMessage.id, + result: result + }; + traceSendingResponse(message, method, startTime); + messageWriter.write(message); + } + traceReceivedRequest(requestMessage); + let element = requestHandlers[requestMessage.method]; + let type; + let requestHandler; + if (element) { + type = element.type; + requestHandler = element.handler; + } + let startTime = Date.now(); + if (requestHandler || starRequestHandler) { + let cancellationSource = new cancellation_1.CancellationTokenSource(); + let tokenKey = String(requestMessage.id); + requestTokens[tokenKey] = cancellationSource; + try { + let handlerResult; + if (requestMessage.params === void 0 || (type !== void 0 && type.numberOfParams === 0)) { + handlerResult = requestHandler + ? requestHandler(cancellationSource.token) + : starRequestHandler(requestMessage.method, cancellationSource.token); + } + else if (Is.array(requestMessage.params) && (type === void 0 || type.numberOfParams > 1)) { + handlerResult = requestHandler + ? requestHandler(...requestMessage.params, cancellationSource.token) + : starRequestHandler(requestMessage.method, ...requestMessage.params, cancellationSource.token); + } + else { + handlerResult = requestHandler + ? requestHandler(requestMessage.params, cancellationSource.token) + : starRequestHandler(requestMessage.method, requestMessage.params, cancellationSource.token); + } + let promise = handlerResult; + if (!handlerResult) { + delete requestTokens[tokenKey]; + replySuccess(handlerResult, requestMessage.method, startTime); + } + else if (promise.then) { + promise.then((resultOrError) => { + delete requestTokens[tokenKey]; + reply(resultOrError, requestMessage.method, startTime); + }, error => { + delete requestTokens[tokenKey]; + if (error instanceof messages_1.ResponseError) { + replyError(error, requestMessage.method, startTime); + } + else if (error && Is.string(error.message)) { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`), requestMessage.method, startTime); + } + else { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`), requestMessage.method, startTime); + } + }); + } + else { + delete requestTokens[tokenKey]; + reply(handlerResult, requestMessage.method, startTime); + } + } + catch (error) { + delete requestTokens[tokenKey]; + if (error instanceof messages_1.ResponseError) { + reply(error, requestMessage.method, startTime); + } + else if (error && Is.string(error.message)) { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`), requestMessage.method, startTime); + } + else { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`), requestMessage.method, startTime); + } + } + } + else { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.MethodNotFound, `Unhandled method ${requestMessage.method}`), requestMessage.method, startTime); + } + } + function handleResponse(responseMessage) { + if (isDisposed()) { + // See handle request. + return; + } + if (responseMessage.id === null) { + if (responseMessage.error) { + logger.error(`Received response message without id: Error is: \n${JSON.stringify(responseMessage.error, undefined, 4)}`); + } + else { + logger.error(`Received response message without id. No further error information provided.`); + } + } + else { + let key = String(responseMessage.id); + let responsePromise = responsePromises[key]; + traceReceivedResponse(responseMessage, responsePromise); + if (responsePromise) { + delete responsePromises[key]; + try { + if (responseMessage.error) { + let error = responseMessage.error; + responsePromise.reject(new messages_1.ResponseError(error.code, error.message, error.data)); + } + else if (responseMessage.result !== void 0) { + responsePromise.resolve(responseMessage.result); + } + else { + throw new Error('Should never happen.'); + } + } + catch (error) { + if (error.message) { + logger.error(`Response handler '${responsePromise.method}' failed with message: ${error.message}`); + } + else { + logger.error(`Response handler '${responsePromise.method}' failed unexpectedly.`); + } + } + } + } + } + function handleNotification(message) { + if (isDisposed()) { + // See handle request. + return; + } + let type = undefined; + let notificationHandler; + if (message.method === CancelNotification.type.method) { + notificationHandler = (params) => { + let id = params.id; + let source = requestTokens[String(id)]; + if (source) { + source.cancel(); + } + }; + } + else { + let element = notificationHandlers[message.method]; + if (element) { + notificationHandler = element.handler; + type = element.type; + } + } + if (notificationHandler || starNotificationHandler) { + try { + traceReceivedNotification(message); + if (message.params === void 0 || (type !== void 0 && type.numberOfParams === 0)) { + notificationHandler ? notificationHandler() : starNotificationHandler(message.method); + } + else if (Is.array(message.params) && (type === void 0 || type.numberOfParams > 1)) { + notificationHandler ? notificationHandler(...message.params) : starNotificationHandler(message.method, ...message.params); + } + else { + notificationHandler ? notificationHandler(message.params) : starNotificationHandler(message.method, message.params); + } + } + catch (error) { + if (error.message) { + logger.error(`Notification handler '${message.method}' failed with message: ${error.message}`); + } + else { + logger.error(`Notification handler '${message.method}' failed unexpectedly.`); + } + } + } + else { + unhandledNotificationEmitter.fire(message); + } + } + function handleInvalidMessage(message) { + if (!message) { + logger.error('Received empty message.'); + return; + } + logger.error(`Received message which is neither a response nor a notification message:\n${JSON.stringify(message, null, 4)}`); + // Test whether we find an id to reject the promise + let responseMessage = message; + if (Is.string(responseMessage.id) || Is.number(responseMessage.id)) { + let key = String(responseMessage.id); + let responseHandler = responsePromises[key]; + if (responseHandler) { + responseHandler.reject(new Error('The received response has neither a result nor an error property.')); + } + } + } + function traceSendingRequest(message) { + if (trace === Trace.Off || !tracer) { + return; + } + if (traceFormat === TraceFormat.Text) { + let data = undefined; + if (trace === Trace.Verbose && message.params) { + data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`; + } + tracer.log(`Sending request '${message.method} - (${message.id})'.`, data); + } + else { + logLSPMessage('send-request', message); + } + } + function traceSendingNotification(message) { + if (trace === Trace.Off || !tracer) { + return; + } + if (traceFormat === TraceFormat.Text) { + let data = undefined; + if (trace === Trace.Verbose) { + if (message.params) { + data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`; + } + else { + data = 'No parameters provided.\n\n'; + } + } + tracer.log(`Sending notification '${message.method}'.`, data); + } + else { + logLSPMessage('send-notification', message); + } + } + function traceSendingResponse(message, method, startTime) { + if (trace === Trace.Off || !tracer) { + return; + } + if (traceFormat === TraceFormat.Text) { + let data = undefined; + if (trace === Trace.Verbose) { + if (message.error && message.error.data) { + data = `Error data: ${JSON.stringify(message.error.data, null, 4)}\n\n`; + } + else { + if (message.result) { + data = `Result: ${JSON.stringify(message.result, null, 4)}\n\n`; + } + else if (message.error === void 0) { + data = 'No result returned.\n\n'; + } + } + } + tracer.log(`Sending response '${method} - (${message.id})'. Processing request took ${Date.now() - startTime}ms`, data); + } + else { + logLSPMessage('send-response', message); + } + } + function traceReceivedRequest(message) { + if (trace === Trace.Off || !tracer) { + return; + } + if (traceFormat === TraceFormat.Text) { + let data = undefined; + if (trace === Trace.Verbose && message.params) { + data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`; + } + tracer.log(`Received request '${message.method} - (${message.id})'.`, data); + } + else { + logLSPMessage('receive-request', message); + } + } + function traceReceivedNotification(message) { + if (trace === Trace.Off || !tracer || message.method === LogTraceNotification.type.method) { + return; + } + if (traceFormat === TraceFormat.Text) { + let data = undefined; + if (trace === Trace.Verbose) { + if (message.params) { + data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`; + } + else { + data = 'No parameters provided.\n\n'; + } + } + tracer.log(`Received notification '${message.method}'.`, data); + } + else { + logLSPMessage('receive-notification', message); + } + } + function traceReceivedResponse(message, responsePromise) { + if (trace === Trace.Off || !tracer) { + return; + } + if (traceFormat === TraceFormat.Text) { + let data = undefined; + if (trace === Trace.Verbose) { + if (message.error && message.error.data) { + data = `Error data: ${JSON.stringify(message.error.data, null, 4)}\n\n`; + } + else { + if (message.result) { + data = `Result: ${JSON.stringify(message.result, null, 4)}\n\n`; + } + else if (message.error === void 0) { + data = 'No result returned.\n\n'; + } + } + } + if (responsePromise) { + let error = message.error ? ` Request failed: ${message.error.message} (${message.error.code}).` : ''; + tracer.log(`Received response '${responsePromise.method} - (${message.id})' in ${Date.now() - responsePromise.timerStart}ms.${error}`, data); + } + else { + tracer.log(`Received response ${message.id} without active response promise.`, data); + } + } + else { + logLSPMessage('receive-response', message); + } + } + function logLSPMessage(type, message) { + if (!tracer || trace === Trace.Off) { + return; + } + const lspMessage = { + isLSPMessage: true, + type, + message, + timestamp: Date.now() + }; + tracer.log(lspMessage); + } + function throwIfClosedOrDisposed() { + if (isClosed()) { + throw new ConnectionError(ConnectionErrors.Closed, 'Connection is closed.'); + } + if (isDisposed()) { + throw new ConnectionError(ConnectionErrors.Disposed, 'Connection is disposed.'); + } + } + function throwIfListening() { + if (isListening()) { + throw new ConnectionError(ConnectionErrors.AlreadyListening, 'Connection is already listening'); + } + } + function throwIfNotListening() { + if (!isListening()) { + throw new Error('Call listen() first.'); + } + } + function undefinedToNull(param) { + if (param === void 0) { + return null; + } + else { + return param; + } + } + function computeMessageParams(type, params) { + let result; + let numberOfParams = type.numberOfParams; + switch (numberOfParams) { + case 0: + result = null; + break; + case 1: + result = undefinedToNull(params[0]); + break; + default: + result = []; + for (let i = 0; i < params.length && i < numberOfParams; i++) { + result.push(undefinedToNull(params[i])); + } + if (params.length < numberOfParams) { + for (let i = params.length; i < numberOfParams; i++) { + result.push(null); + } + } + break; + } + return result; + } + let connection = { + sendNotification: (type, ...params) => { + throwIfClosedOrDisposed(); + let method; + let messageParams; + if (Is.string(type)) { + method = type; + switch (params.length) { + case 0: + messageParams = null; + break; + case 1: + messageParams = params[0]; + break; + default: + messageParams = params; + break; + } + } + else { + method = type.method; + messageParams = computeMessageParams(type, params); + } + let notificationMessage = { + jsonrpc: version, + method: method, + params: messageParams + }; + traceSendingNotification(notificationMessage); + messageWriter.write(notificationMessage); + }, + onNotification: (type, handler) => { + throwIfClosedOrDisposed(); + if (Is.func(type)) { + starNotificationHandler = type; + } + else if (handler) { + if (Is.string(type)) { + notificationHandlers[type] = { type: undefined, handler }; + } + else { + notificationHandlers[type.method] = { type, handler }; + } + } + }, + sendRequest: (type, ...params) => { + throwIfClosedOrDisposed(); + throwIfNotListening(); + let method; + let messageParams; + let token = undefined; + if (Is.string(type)) { + method = type; + switch (params.length) { + case 0: + messageParams = null; + break; + case 1: + // The cancellation token is optional so it can also be undefined. + if (cancellation_1.CancellationToken.is(params[0])) { + messageParams = null; + token = params[0]; + } + else { + messageParams = undefinedToNull(params[0]); + } + break; + default: + const last = params.length - 1; + if (cancellation_1.CancellationToken.is(params[last])) { + token = params[last]; + if (params.length === 2) { + messageParams = undefinedToNull(params[0]); + } + else { + messageParams = params.slice(0, last).map(value => undefinedToNull(value)); + } + } + else { + messageParams = params.map(value => undefinedToNull(value)); + } + break; + } + } + else { + method = type.method; + messageParams = computeMessageParams(type, params); + let numberOfParams = type.numberOfParams; + token = cancellation_1.CancellationToken.is(params[numberOfParams]) ? params[numberOfParams] : undefined; + } + let id = sequenceNumber++; + let result = new Promise((resolve, reject) => { + let requestMessage = { + jsonrpc: version, + id: id, + method: method, + params: messageParams + }; + let responsePromise = { method: method, timerStart: Date.now(), resolve, reject }; + traceSendingRequest(requestMessage); + try { + messageWriter.write(requestMessage); + } + catch (e) { + // Writing the message failed. So we need to reject the promise. + responsePromise.reject(new messages_1.ResponseError(messages_1.ErrorCodes.MessageWriteError, e.message ? e.message : 'Unknown reason')); + responsePromise = null; + } + if (responsePromise) { + responsePromises[String(id)] = responsePromise; + } + }); + if (token) { + token.onCancellationRequested(() => { + connection.sendNotification(CancelNotification.type, { id }); + }); + } + return result; + }, + onRequest: (type, handler) => { + throwIfClosedOrDisposed(); + if (Is.func(type)) { + starRequestHandler = type; + } + else if (handler) { + if (Is.string(type)) { + requestHandlers[type] = { type: undefined, handler }; + } + else { + requestHandlers[type.method] = { type, handler }; + } + } + }, + trace: (_value, _tracer, sendNotificationOrTraceOptions) => { + let _sendNotification = false; + let _traceFormat = TraceFormat.Text; + if (sendNotificationOrTraceOptions !== void 0) { + if (Is.boolean(sendNotificationOrTraceOptions)) { + _sendNotification = sendNotificationOrTraceOptions; + } + else { + _sendNotification = sendNotificationOrTraceOptions.sendNotification || false; + _traceFormat = sendNotificationOrTraceOptions.traceFormat || TraceFormat.Text; + } + } + trace = _value; + traceFormat = _traceFormat; + if (trace === Trace.Off) { + tracer = undefined; + } + else { + tracer = _tracer; + } + if (_sendNotification && !isClosed() && !isDisposed()) { + connection.sendNotification(SetTraceNotification.type, { value: Trace.toString(_value) }); + } + }, + onError: errorEmitter.event, + onClose: closeEmitter.event, + onUnhandledNotification: unhandledNotificationEmitter.event, + onDispose: disposeEmitter.event, + dispose: () => { + if (isDisposed()) { + return; + } + state = ConnectionState.Disposed; + disposeEmitter.fire(undefined); + let error = new Error('Connection got disposed.'); + Object.keys(responsePromises).forEach((key) => { + responsePromises[key].reject(error); + }); + responsePromises = Object.create(null); + requestTokens = Object.create(null); + messageQueue = new linkedMap_1.LinkedMap(); + // Test for backwards compatibility + if (Is.func(messageWriter.dispose)) { + messageWriter.dispose(); + } + if (Is.func(messageReader.dispose)) { + messageReader.dispose(); + } + }, + listen: () => { + throwIfClosedOrDisposed(); + throwIfListening(); + state = ConnectionState.Listening; + messageReader.listen(callback); + }, + inspect: () => { + console.log("inspect"); + } + }; + connection.onNotification(LogTraceNotification.type, (params) => { + if (trace === Trace.Off || !tracer) { + return; + } + tracer.log(params.message, trace === Trace.Verbose ? params.verbose : undefined); + }); + return connection; +} +function isMessageReader(value) { + return value.listen !== void 0 && value.read === void 0; +} +function isMessageWriter(value) { + return value.write !== void 0 && value.end === void 0; +} +function createMessageConnection(input, output, logger, strategy) { + if (!logger) { + logger = exports.NullLogger; + } + let reader = isMessageReader(input) ? input : new messageReader_1.StreamMessageReader(input); + let writer = isMessageWriter(output) ? output : new messageWriter_1.StreamMessageWriter(output); + return _createMessageConnection(reader, writer, logger, strategy); +} +exports.createMessageConnection = createMessageConnection; + + +/***/ }), +/* 151 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +function boolean(value) { + return value === true || value === false; +} +exports.boolean = boolean; +function string(value) { + return typeof value === 'string' || value instanceof String; +} +exports.string = string; +function number(value) { + return typeof value === 'number' || value instanceof Number; +} +exports.number = number; +function error(value) { + return value instanceof Error; +} +exports.error = error; +function func(value) { + return typeof value === 'function'; +} +exports.func = func; +function array(value) { + return Array.isArray(value); +} +exports.array = array; +function stringArray(value) { + return array(value) && value.every(elem => string(elem)); +} +exports.stringArray = stringArray; + + +/***/ }), +/* 152 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const is = __webpack_require__(151); +/** + * Predefined error codes. + */ +var ErrorCodes; +(function (ErrorCodes) { + // Defined by JSON RPC + ErrorCodes.ParseError = -32700; + ErrorCodes.InvalidRequest = -32600; + ErrorCodes.MethodNotFound = -32601; + ErrorCodes.InvalidParams = -32602; + ErrorCodes.InternalError = -32603; + ErrorCodes.serverErrorStart = -32099; + ErrorCodes.serverErrorEnd = -32000; + ErrorCodes.ServerNotInitialized = -32002; + ErrorCodes.UnknownErrorCode = -32001; + // Defined by the protocol. + ErrorCodes.RequestCancelled = -32800; + ErrorCodes.ContentModified = -32801; + // Defined by VSCode library. + ErrorCodes.MessageWriteError = 1; + ErrorCodes.MessageReadError = 2; +})(ErrorCodes = exports.ErrorCodes || (exports.ErrorCodes = {})); +/** + * An error object return in a response in case a request + * has failed. + */ +class ResponseError extends Error { + constructor(code, message, data) { + super(message); + this.code = is.number(code) ? code : ErrorCodes.UnknownErrorCode; + this.data = data; + Object.setPrototypeOf(this, ResponseError.prototype); + } + toJson() { + return { + code: this.code, + message: this.message, + data: this.data, + }; + } +} +exports.ResponseError = ResponseError; +/** + * An abstract implementation of a MessageType. + */ +class AbstractMessageType { + constructor(_method, _numberOfParams) { + this._method = _method; + this._numberOfParams = _numberOfParams; + } + get method() { + return this._method; + } + get numberOfParams() { + return this._numberOfParams; + } +} +exports.AbstractMessageType = AbstractMessageType; +/** + * Classes to type request response pairs + */ +class RequestType0 extends AbstractMessageType { + constructor(method) { + super(method, 0); + this._ = undefined; + } +} +exports.RequestType0 = RequestType0; +class RequestType extends AbstractMessageType { + constructor(method) { + super(method, 1); + this._ = undefined; + } +} +exports.RequestType = RequestType; +class RequestType1 extends AbstractMessageType { + constructor(method) { + super(method, 1); + this._ = undefined; + } +} +exports.RequestType1 = RequestType1; +class RequestType2 extends AbstractMessageType { + constructor(method) { + super(method, 2); + this._ = undefined; + } +} +exports.RequestType2 = RequestType2; +class RequestType3 extends AbstractMessageType { + constructor(method) { + super(method, 3); + this._ = undefined; + } +} +exports.RequestType3 = RequestType3; +class RequestType4 extends AbstractMessageType { + constructor(method) { + super(method, 4); + this._ = undefined; + } +} +exports.RequestType4 = RequestType4; +class RequestType5 extends AbstractMessageType { + constructor(method) { + super(method, 5); + this._ = undefined; + } +} +exports.RequestType5 = RequestType5; +class RequestType6 extends AbstractMessageType { + constructor(method) { + super(method, 6); + this._ = undefined; + } +} +exports.RequestType6 = RequestType6; +class RequestType7 extends AbstractMessageType { + constructor(method) { + super(method, 7); + this._ = undefined; + } +} +exports.RequestType7 = RequestType7; +class RequestType8 extends AbstractMessageType { + constructor(method) { + super(method, 8); + this._ = undefined; + } +} +exports.RequestType8 = RequestType8; +class RequestType9 extends AbstractMessageType { + constructor(method) { + super(method, 9); + this._ = undefined; + } +} +exports.RequestType9 = RequestType9; +class NotificationType extends AbstractMessageType { + constructor(method) { + super(method, 1); + this._ = undefined; + } +} +exports.NotificationType = NotificationType; +class NotificationType0 extends AbstractMessageType { + constructor(method) { + super(method, 0); + this._ = undefined; + } +} +exports.NotificationType0 = NotificationType0; +class NotificationType1 extends AbstractMessageType { + constructor(method) { + super(method, 1); + this._ = undefined; + } +} +exports.NotificationType1 = NotificationType1; +class NotificationType2 extends AbstractMessageType { + constructor(method) { + super(method, 2); + this._ = undefined; + } +} +exports.NotificationType2 = NotificationType2; +class NotificationType3 extends AbstractMessageType { + constructor(method) { + super(method, 3); + this._ = undefined; + } +} +exports.NotificationType3 = NotificationType3; +class NotificationType4 extends AbstractMessageType { + constructor(method) { + super(method, 4); + this._ = undefined; + } +} +exports.NotificationType4 = NotificationType4; +class NotificationType5 extends AbstractMessageType { + constructor(method) { + super(method, 5); + this._ = undefined; + } +} +exports.NotificationType5 = NotificationType5; +class NotificationType6 extends AbstractMessageType { + constructor(method) { + super(method, 6); + this._ = undefined; + } +} +exports.NotificationType6 = NotificationType6; +class NotificationType7 extends AbstractMessageType { + constructor(method) { + super(method, 7); + this._ = undefined; + } +} +exports.NotificationType7 = NotificationType7; +class NotificationType8 extends AbstractMessageType { + constructor(method) { + super(method, 8); + this._ = undefined; + } +} +exports.NotificationType8 = NotificationType8; +class NotificationType9 extends AbstractMessageType { + constructor(method) { + super(method, 9); + this._ = undefined; + } +} +exports.NotificationType9 = NotificationType9; +/** + * Tests if the given message is a request message + */ +function isRequestMessage(message) { + let candidate = message; + return candidate && is.string(candidate.method) && (is.string(candidate.id) || is.number(candidate.id)); +} +exports.isRequestMessage = isRequestMessage; +/** + * Tests if the given message is a notification message + */ +function isNotificationMessage(message) { + let candidate = message; + return candidate && is.string(candidate.method) && message.id === void 0; +} +exports.isNotificationMessage = isNotificationMessage; +/** + * Tests if the given message is a response message + */ +function isResponseMessage(message) { + let candidate = message; + return candidate && (candidate.result !== void 0 || !!candidate.error) && (is.string(candidate.id) || is.number(candidate.id) || candidate.id === null); +} +exports.isResponseMessage = isResponseMessage; + + +/***/ }), +/* 153 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const events_1 = __webpack_require__(154); +const Is = __webpack_require__(151); +let DefaultSize = 8192; +let CR = Buffer.from('\r', 'ascii')[0]; +let LF = Buffer.from('\n', 'ascii')[0]; +let CRLF = '\r\n'; +class MessageBuffer { + constructor(encoding = 'utf8') { + this.encoding = encoding; + this.index = 0; + this.buffer = Buffer.allocUnsafe(DefaultSize); + } + append(chunk) { + var toAppend = chunk; + if (typeof (chunk) === 'string') { + var str = chunk; + var bufferLen = Buffer.byteLength(str, this.encoding); + toAppend = Buffer.allocUnsafe(bufferLen); + toAppend.write(str, 0, bufferLen, this.encoding); + } + if (this.buffer.length - this.index >= toAppend.length) { + toAppend.copy(this.buffer, this.index, 0, toAppend.length); + } + else { + var newSize = (Math.ceil((this.index + toAppend.length) / DefaultSize) + 1) * DefaultSize; + if (this.index === 0) { + this.buffer = Buffer.allocUnsafe(newSize); + toAppend.copy(this.buffer, 0, 0, toAppend.length); + } + else { + this.buffer = Buffer.concat([this.buffer.slice(0, this.index), toAppend], newSize); + } + } + this.index += toAppend.length; + } + tryReadHeaders() { + let result = undefined; + let current = 0; + while (current + 3 < this.index && (this.buffer[current] !== CR || this.buffer[current + 1] !== LF || this.buffer[current + 2] !== CR || this.buffer[current + 3] !== LF)) { + current++; + } + // No header / body separator found (e.g CRLFCRLF) + if (current + 3 >= this.index) { + return result; + } + result = Object.create(null); + let headers = this.buffer.toString('ascii', 0, current).split(CRLF); + headers.forEach((header) => { + let index = header.indexOf(':'); + if (index === -1) { + throw new Error('Message header must separate key and value using :'); + } + let key = header.substr(0, index); + let value = header.substr(index + 1).trim(); + result[key] = value; + }); + let nextStart = current + 4; + this.buffer = this.buffer.slice(nextStart); + this.index = this.index - nextStart; + return result; + } + tryReadContent(length) { + if (this.index < length) { + return null; + } + let result = this.buffer.toString(this.encoding, 0, length); + let nextStart = length; + this.buffer.copy(this.buffer, 0, nextStart); + this.index = this.index - nextStart; + return result; + } + get numberOfBytes() { + return this.index; + } +} +var MessageReader; +(function (MessageReader) { + function is(value) { + let candidate = value; + return candidate && Is.func(candidate.listen) && Is.func(candidate.dispose) && + Is.func(candidate.onError) && Is.func(candidate.onClose) && Is.func(candidate.onPartialMessage); + } + MessageReader.is = is; +})(MessageReader = exports.MessageReader || (exports.MessageReader = {})); +class AbstractMessageReader { + constructor() { + this.errorEmitter = new events_1.Emitter(); + this.closeEmitter = new events_1.Emitter(); + this.partialMessageEmitter = new events_1.Emitter(); + } + dispose() { + this.errorEmitter.dispose(); + this.closeEmitter.dispose(); + } + get onError() { + return this.errorEmitter.event; + } + fireError(error) { + this.errorEmitter.fire(this.asError(error)); + } + get onClose() { + return this.closeEmitter.event; + } + fireClose() { + this.closeEmitter.fire(undefined); + } + get onPartialMessage() { + return this.partialMessageEmitter.event; + } + firePartialMessage(info) { + this.partialMessageEmitter.fire(info); + } + asError(error) { + if (error instanceof Error) { + return error; + } + else { + return new Error(`Reader received error. Reason: ${Is.string(error.message) ? error.message : 'unknown'}`); + } + } +} +exports.AbstractMessageReader = AbstractMessageReader; +class StreamMessageReader extends AbstractMessageReader { + constructor(readable, encoding = 'utf8') { + super(); + this.readable = readable; + this.buffer = new MessageBuffer(encoding); + this._partialMessageTimeout = 10000; + } + set partialMessageTimeout(timeout) { + this._partialMessageTimeout = timeout; + } + get partialMessageTimeout() { + return this._partialMessageTimeout; + } + listen(callback) { + this.nextMessageLength = -1; + this.messageToken = 0; + this.partialMessageTimer = undefined; + this.callback = callback; + this.readable.on('data', (data) => { + this.onData(data); + }); + this.readable.on('error', (error) => this.fireError(error)); + this.readable.on('close', () => this.fireClose()); + } + onData(data) { + this.buffer.append(data); + while (true) { + if (this.nextMessageLength === -1) { + let headers = this.buffer.tryReadHeaders(); + if (!headers) { + return; + } + let contentLength = headers['Content-Length']; + if (!contentLength) { + throw new Error('Header must provide a Content-Length property.'); + } + let length = parseInt(contentLength); + if (isNaN(length)) { + throw new Error('Content-Length value must be a number.'); + } + this.nextMessageLength = length; + // Take the encoding form the header. For compatibility + // treat both utf-8 and utf8 as node utf8 + } + var msg = this.buffer.tryReadContent(this.nextMessageLength); + if (msg === null) { + /** We haven't received the full message yet. */ + this.setPartialMessageTimer(); + return; + } + this.clearPartialMessageTimer(); + this.nextMessageLength = -1; + this.messageToken++; + var json = JSON.parse(msg); + this.callback(json); + } + } + clearPartialMessageTimer() { + if (this.partialMessageTimer) { + clearTimeout(this.partialMessageTimer); + this.partialMessageTimer = undefined; + } + } + setPartialMessageTimer() { + this.clearPartialMessageTimer(); + if (this._partialMessageTimeout <= 0) { + return; + } + this.partialMessageTimer = setTimeout((token, timeout) => { + this.partialMessageTimer = undefined; + if (token === this.messageToken) { + this.firePartialMessage({ messageToken: token, waitingTime: timeout }); + this.setPartialMessageTimer(); + } + }, this._partialMessageTimeout, this.messageToken, this._partialMessageTimeout); + } +} +exports.StreamMessageReader = StreamMessageReader; +class IPCMessageReader extends AbstractMessageReader { + constructor(process) { + super(); + this.process = process; + let eventEmitter = this.process; + eventEmitter.on('error', (error) => this.fireError(error)); + eventEmitter.on('close', () => this.fireClose()); + } + listen(callback) { + this.process.on('message', callback); + } +} +exports.IPCMessageReader = IPCMessageReader; +class SocketMessageReader extends StreamMessageReader { + constructor(socket, encoding = 'utf-8') { + super(socket, encoding); + } +} +exports.SocketMessageReader = SocketMessageReader; + + +/***/ }), +/* 154 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +var Disposable; +(function (Disposable) { + function create(func) { + return { + dispose: func + }; + } + Disposable.create = create; +})(Disposable = exports.Disposable || (exports.Disposable = {})); +var Event; +(function (Event) { + const _disposable = { dispose() { } }; + Event.None = function () { return _disposable; }; +})(Event = exports.Event || (exports.Event = {})); +class CallbackList { + add(callback, context = null, bucket) { + if (!this._callbacks) { + this._callbacks = []; + this._contexts = []; + } + this._callbacks.push(callback); + this._contexts.push(context); + if (Array.isArray(bucket)) { + bucket.push({ dispose: () => this.remove(callback, context) }); + } + } + remove(callback, context = null) { + if (!this._callbacks) { + return; + } + var foundCallbackWithDifferentContext = false; + for (var i = 0, len = this._callbacks.length; i < len; i++) { + if (this._callbacks[i] === callback) { + if (this._contexts[i] === context) { + // callback & context match => remove it + this._callbacks.splice(i, 1); + this._contexts.splice(i, 1); + return; + } + else { + foundCallbackWithDifferentContext = true; + } + } + } + if (foundCallbackWithDifferentContext) { + throw new Error('When adding a listener with a context, you should remove it with the same context'); + } + } + invoke(...args) { + if (!this._callbacks) { + return []; + } + var ret = [], callbacks = this._callbacks.slice(0), contexts = this._contexts.slice(0); + for (var i = 0, len = callbacks.length; i < len; i++) { + try { + ret.push(callbacks[i].apply(contexts[i], args)); + } + catch (e) { + console.error(e); + } + } + return ret; + } + isEmpty() { + return !this._callbacks || this._callbacks.length === 0; + } + dispose() { + this._callbacks = undefined; + this._contexts = undefined; + } +} +class Emitter { + constructor(_options) { + this._options = _options; + } + /** + * For the public to allow to subscribe + * to events from this Emitter + */ + get event() { + if (!this._event) { + this._event = (listener, thisArgs, disposables) => { + if (!this._callbacks) { + this._callbacks = new CallbackList(); + } + if (this._options && this._options.onFirstListenerAdd && this._callbacks.isEmpty()) { + this._options.onFirstListenerAdd(this); + } + this._callbacks.add(listener, thisArgs); + let result; + result = { + dispose: () => { + this._callbacks.remove(listener, thisArgs); + result.dispose = Emitter._noop; + if (this._options && this._options.onLastListenerRemove && this._callbacks.isEmpty()) { + this._options.onLastListenerRemove(this); + } + } + }; + if (Array.isArray(disposables)) { + disposables.push(result); + } + return result; + }; + } + return this._event; + } + /** + * To be kept private to fire an event to + * subscribers + */ + fire(event) { + if (this._callbacks) { + this._callbacks.invoke.call(this._callbacks, event); + } + } + dispose() { + if (this._callbacks) { + this._callbacks.dispose(); + this._callbacks = undefined; + } + } +} +Emitter._noop = function () { }; +exports.Emitter = Emitter; + + +/***/ }), +/* 155 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const events_1 = __webpack_require__(154); +const Is = __webpack_require__(151); +let ContentLength = 'Content-Length: '; +let CRLF = '\r\n'; +var MessageWriter; +(function (MessageWriter) { + function is(value) { + let candidate = value; + return candidate && Is.func(candidate.dispose) && Is.func(candidate.onClose) && + Is.func(candidate.onError) && Is.func(candidate.write); + } + MessageWriter.is = is; +})(MessageWriter = exports.MessageWriter || (exports.MessageWriter = {})); +class AbstractMessageWriter { + constructor() { + this.errorEmitter = new events_1.Emitter(); + this.closeEmitter = new events_1.Emitter(); + } + dispose() { + this.errorEmitter.dispose(); + this.closeEmitter.dispose(); + } + get onError() { + return this.errorEmitter.event; + } + fireError(error, message, count) { + this.errorEmitter.fire([this.asError(error), message, count]); + } + get onClose() { + return this.closeEmitter.event; + } + fireClose() { + this.closeEmitter.fire(undefined); + } + asError(error) { + if (error instanceof Error) { + return error; + } + else { + return new Error(`Writer received error. Reason: ${Is.string(error.message) ? error.message : 'unknown'}`); + } + } +} +exports.AbstractMessageWriter = AbstractMessageWriter; +class StreamMessageWriter extends AbstractMessageWriter { + constructor(writable, encoding = 'utf8') { + super(); + this.writable = writable; + this.encoding = encoding; + this.errorCount = 0; + this.writable.on('error', (error) => this.fireError(error)); + this.writable.on('close', () => this.fireClose()); + } + write(msg) { + let json = JSON.stringify(msg); + let contentLength = Buffer.byteLength(json, this.encoding); + let headers = [ + ContentLength, contentLength.toString(), CRLF, + CRLF + ]; + try { + // Header must be written in ASCII encoding + this.writable.write(headers.join(''), 'ascii'); + // Now write the content. This can be written in any encoding + this.writable.write(json, this.encoding); + this.errorCount = 0; + } + catch (error) { + this.errorCount++; + this.fireError(error, msg, this.errorCount); + } + } +} +exports.StreamMessageWriter = StreamMessageWriter; +class IPCMessageWriter extends AbstractMessageWriter { + constructor(process) { + super(); + this.process = process; + this.errorCount = 0; + this.queue = []; + this.sending = false; + let eventEmitter = this.process; + eventEmitter.on('error', (error) => this.fireError(error)); + eventEmitter.on('close', () => this.fireClose); + } + write(msg) { + if (!this.sending && this.queue.length === 0) { + // See https://github.com/nodejs/node/issues/7657 + this.doWriteMessage(msg); + } + else { + this.queue.push(msg); + } + } + doWriteMessage(msg) { + try { + if (this.process.send) { + this.sending = true; + this.process.send(msg, undefined, undefined, (error) => { + this.sending = false; + if (error) { + this.errorCount++; + this.fireError(error, msg, this.errorCount); + } + else { + this.errorCount = 0; + } + if (this.queue.length > 0) { + this.doWriteMessage(this.queue.shift()); + } + }); + } + } + catch (error) { + this.errorCount++; + this.fireError(error, msg, this.errorCount); + } + } +} +exports.IPCMessageWriter = IPCMessageWriter; +class SocketMessageWriter extends AbstractMessageWriter { + constructor(socket, encoding = 'utf8') { + super(); + this.socket = socket; + this.queue = []; + this.sending = false; + this.encoding = encoding; + this.errorCount = 0; + this.socket.on('error', (error) => this.fireError(error)); + this.socket.on('close', () => this.fireClose()); + } + dispose() { + super.dispose(); + this.socket.destroy(); + } + write(msg) { + if (!this.sending && this.queue.length === 0) { + // See https://github.com/nodejs/node/issues/7657 + this.doWriteMessage(msg); + } + else { + this.queue.push(msg); + } + } + doWriteMessage(msg) { + let json = JSON.stringify(msg); + let contentLength = Buffer.byteLength(json, this.encoding); + let headers = [ + ContentLength, contentLength.toString(), CRLF, + CRLF + ]; + try { + // Header must be written in ASCII encoding + this.sending = true; + this.socket.write(headers.join(''), 'ascii', (error) => { + if (error) { + this.handleError(error, msg); + } + try { + // Now write the content. This can be written in any encoding + this.socket.write(json, this.encoding, (error) => { + this.sending = false; + if (error) { + this.handleError(error, msg); + } + else { + this.errorCount = 0; + } + if (this.queue.length > 0) { + this.doWriteMessage(this.queue.shift()); + } + }); + } + catch (error) { + this.handleError(error, msg); + } + }); + } + catch (error) { + this.handleError(error, msg); + } + } + handleError(error, msg) { + this.errorCount++; + this.fireError(error, msg, this.errorCount); + } +} +exports.SocketMessageWriter = SocketMessageWriter; + + +/***/ }), +/* 156 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +Object.defineProperty(exports, "__esModule", { value: true }); +const events_1 = __webpack_require__(154); +const Is = __webpack_require__(151); +var CancellationToken; +(function (CancellationToken) { + CancellationToken.None = Object.freeze({ + isCancellationRequested: false, + onCancellationRequested: events_1.Event.None + }); + CancellationToken.Cancelled = Object.freeze({ + isCancellationRequested: true, + onCancellationRequested: events_1.Event.None + }); + function is(value) { + let candidate = value; + return candidate && (candidate === CancellationToken.None + || candidate === CancellationToken.Cancelled + || (Is.boolean(candidate.isCancellationRequested) && !!candidate.onCancellationRequested)); + } + CancellationToken.is = is; +})(CancellationToken = exports.CancellationToken || (exports.CancellationToken = {})); +const shortcutEvent = Object.freeze(function (callback, context) { + let handle = setTimeout(callback.bind(context), 0); + return { dispose() { clearTimeout(handle); } }; +}); +class MutableToken { + constructor() { + this._isCancelled = false; + } + cancel() { + if (!this._isCancelled) { + this._isCancelled = true; + if (this._emitter) { + this._emitter.fire(undefined); + this.dispose(); + } + } + } + get isCancellationRequested() { + return this._isCancelled; + } + get onCancellationRequested() { + if (this._isCancelled) { + return shortcutEvent; + } + if (!this._emitter) { + this._emitter = new events_1.Emitter(); + } + return this._emitter.event; + } + dispose() { + if (this._emitter) { + this._emitter.dispose(); + this._emitter = undefined; + } + } +} +class CancellationTokenSource { + get token() { + if (!this._token) { + // be lazy and create the token only when + // actually needed + this._token = new MutableToken(); + } + return this._token; + } + cancel() { + if (!this._token) { + // save an object by returning the default + // cancelled token when cancellation happens + // before someone asks for the token + this._token = CancellationToken.Cancelled; + } + else { + this._token.cancel(); + } + } + dispose() { + if (!this._token) { + // ensure to initialize with an empty token if we had none + this._token = CancellationToken.None; + } + else if (this._token instanceof MutableToken) { + // actually dispose + this._token.dispose(); + } + } +} +exports.CancellationTokenSource = CancellationTokenSource; + + +/***/ }), +/* 157 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +var Touch; +(function (Touch) { + Touch.None = 0; + Touch.First = 1; + Touch.Last = 2; +})(Touch = exports.Touch || (exports.Touch = {})); +class LinkedMap { + constructor() { + this._map = new Map(); + this._head = undefined; + this._tail = undefined; + this._size = 0; + } + clear() { + this._map.clear(); + this._head = undefined; + this._tail = undefined; + this._size = 0; + } + isEmpty() { + return !this._head && !this._tail; + } + get size() { + return this._size; + } + has(key) { + return this._map.has(key); + } + get(key) { + const item = this._map.get(key); + if (!item) { + return undefined; + } + return item.value; + } + set(key, value, touch = Touch.None) { + let item = this._map.get(key); + if (item) { + item.value = value; + if (touch !== Touch.None) { + this.touch(item, touch); + } + } + else { + item = { key, value, next: undefined, previous: undefined }; + switch (touch) { + case Touch.None: + this.addItemLast(item); + break; + case Touch.First: + this.addItemFirst(item); + break; + case Touch.Last: + this.addItemLast(item); + break; + default: + this.addItemLast(item); + break; + } + this._map.set(key, item); + this._size++; + } + } + delete(key) { + const item = this._map.get(key); + if (!item) { + return false; + } + this._map.delete(key); + this.removeItem(item); + this._size--; + return true; + } + shift() { + if (!this._head && !this._tail) { + return undefined; + } + if (!this._head || !this._tail) { + throw new Error('Invalid list'); + } + const item = this._head; + this._map.delete(item.key); + this.removeItem(item); + this._size--; + return item.value; + } + forEach(callbackfn, thisArg) { + let current = this._head; + while (current) { + if (thisArg) { + callbackfn.bind(thisArg)(current.value, current.key, this); + } + else { + callbackfn(current.value, current.key, this); + } + current = current.next; + } + } + forEachReverse(callbackfn, thisArg) { + let current = this._tail; + while (current) { + if (thisArg) { + callbackfn.bind(thisArg)(current.value, current.key, this); + } + else { + callbackfn(current.value, current.key, this); + } + current = current.previous; + } + } + values() { + let result = []; + let current = this._head; + while (current) { + result.push(current.value); + current = current.next; + } + return result; + } + keys() { + let result = []; + let current = this._head; + while (current) { + result.push(current.key); + current = current.next; + } + return result; + } + /* JSON RPC run on es5 which has no Symbol.iterator + public keys(): IterableIterator { + let current = this._head; + let iterator: IterableIterator = { + [Symbol.iterator]() { + return iterator; + }, + next():IteratorResult { + if (current) { + let result = { value: current.key, done: false }; + current = current.next; + return result; + } else { + return { value: undefined, done: true }; + } + } + }; + return iterator; + } + + public values(): IterableIterator { + let current = this._head; + let iterator: IterableIterator = { + [Symbol.iterator]() { + return iterator; + }, + next():IteratorResult { + if (current) { + let result = { value: current.value, done: false }; + current = current.next; + return result; + } else { + return { value: undefined, done: true }; + } + } + }; + return iterator; + } + */ + addItemFirst(item) { + // First time Insert + if (!this._head && !this._tail) { + this._tail = item; + } + else if (!this._head) { + throw new Error('Invalid list'); + } + else { + item.next = this._head; + this._head.previous = item; + } + this._head = item; + } + addItemLast(item) { + // First time Insert + if (!this._head && !this._tail) { + this._head = item; + } + else if (!this._tail) { + throw new Error('Invalid list'); + } + else { + item.previous = this._tail; + this._tail.next = item; + } + this._tail = item; + } + removeItem(item) { + if (item === this._head && item === this._tail) { + this._head = undefined; + this._tail = undefined; + } + else if (item === this._head) { + this._head = item.next; + } + else if (item === this._tail) { + this._tail = item.previous; + } + else { + const next = item.next; + const previous = item.previous; + if (!next || !previous) { + throw new Error('Invalid list'); + } + next.previous = previous; + previous.next = next; + } + } + touch(item, touch) { + if (!this._head || !this._tail) { + throw new Error('Invalid list'); + } + if ((touch !== Touch.First && touch !== Touch.Last)) { + return; + } + if (touch === Touch.First) { + if (item === this._head) { + return; + } + const next = item.next; + const previous = item.previous; + // Unlink the item + if (item === this._tail) { + // previous must be defined since item was not head but is tail + // So there are more than on item in the map + previous.next = undefined; + this._tail = previous; + } + else { + // Both next and previous are not undefined since item was neither head nor tail. + next.previous = previous; + previous.next = next; + } + // Insert the node at head + item.previous = undefined; + item.next = this._head; + this._head.previous = item; + this._head = item; + } + else if (touch === Touch.Last) { + if (item === this._tail) { + return; + } + const next = item.next; + const previous = item.previous; + // Unlink the item. + if (item === this._head) { + // next must be defined since item was not tail but is head + // So there are more than on item in the map + next.previous = undefined; + this._head = next; + } + else { + // Both next and previous are not undefined since item was neither head nor tail. + next.previous = previous; + previous.next = next; + } + item.next = undefined; + item.previous = this._tail; + this._tail.next = item; + this._tail = item; + } + } +} +exports.LinkedMap = LinkedMap; + + +/***/ }), +/* 158 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const path_1 = __webpack_require__(57); +const os_1 = __webpack_require__(56); +const crypto_1 = __webpack_require__(159); +const net_1 = __webpack_require__(6); +const messageReader_1 = __webpack_require__(153); +const messageWriter_1 = __webpack_require__(155); +function generateRandomPipeName() { + const randomSuffix = crypto_1.randomBytes(21).toString('hex'); + if (process.platform === 'win32') { + return `\\\\.\\pipe\\vscode-jsonrpc-${randomSuffix}-sock`; + } + else { + // Mac/Unix: use socket file + return path_1.join(os_1.tmpdir(), `vscode-${randomSuffix}.sock`); + } +} +exports.generateRandomPipeName = generateRandomPipeName; +function createClientPipeTransport(pipeName, encoding = 'utf-8') { + let connectResolve; + let connected = new Promise((resolve, _reject) => { + connectResolve = resolve; + }); + return new Promise((resolve, reject) => { + let server = net_1.createServer((socket) => { + server.close(); + connectResolve([ + new messageReader_1.SocketMessageReader(socket, encoding), + new messageWriter_1.SocketMessageWriter(socket, encoding) + ]); + }); + server.on('error', reject); + server.listen(pipeName, () => { + server.removeListener('error', reject); + resolve({ + onConnected: () => { return connected; } + }); + }); + }); +} +exports.createClientPipeTransport = createClientPipeTransport; +function createServerPipeTransport(pipeName, encoding = 'utf-8') { + const socket = net_1.createConnection(pipeName); + return [ + new messageReader_1.SocketMessageReader(socket, encoding), + new messageWriter_1.SocketMessageWriter(socket, encoding) + ]; +} +exports.createServerPipeTransport = createServerPipeTransport; + + +/***/ }), +/* 159 */ +/***/ (function(module, exports) { + +module.exports = require("crypto"); + +/***/ }), +/* 160 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const net_1 = __webpack_require__(6); +const messageReader_1 = __webpack_require__(153); +const messageWriter_1 = __webpack_require__(155); +function createClientSocketTransport(port, encoding = 'utf-8') { + let connectResolve; + let connected = new Promise((resolve, _reject) => { + connectResolve = resolve; + }); + return new Promise((resolve, reject) => { + let server = net_1.createServer((socket) => { + server.close(); + connectResolve([ + new messageReader_1.SocketMessageReader(socket, encoding), + new messageWriter_1.SocketMessageWriter(socket, encoding) + ]); + }); + server.on('error', reject); + server.listen(port, '127.0.0.1', () => { + server.removeListener('error', reject); + resolve({ + onConnected: () => { return connected; } + }); + }); + }); +} +exports.createClientSocketTransport = createClientSocketTransport; +function createServerSocketTransport(port, encoding = 'utf-8') { + const socket = net_1.createConnection(port, '127.0.0.1'); + return [ + new messageReader_1.SocketMessageReader(socket, encoding), + new messageWriter_1.SocketMessageWriter(socket, encoding) + ]; +} +exports.createServerSocketTransport = createServerSocketTransport; + + +/***/ }), +/* 161 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Position", function() { return Position; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Range", function() { return Range; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Location", function() { return Location; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LocationLink", function() { return LocationLink; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Color", function() { return Color; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorInformation", function() { return ColorInformation; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorPresentation", function() { return ColorPresentation; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FoldingRangeKind", function() { return FoldingRangeKind; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FoldingRange", function() { return FoldingRange; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DiagnosticRelatedInformation", function() { return DiagnosticRelatedInformation; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DiagnosticSeverity", function() { return DiagnosticSeverity; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DiagnosticTag", function() { return DiagnosticTag; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Diagnostic", function() { return Diagnostic; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Command", function() { return Command; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextEdit", function() { return TextEdit; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextDocumentEdit", function() { return TextDocumentEdit; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CreateFile", function() { return CreateFile; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RenameFile", function() { return RenameFile; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DeleteFile", function() { return DeleteFile; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WorkspaceEdit", function() { return WorkspaceEdit; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WorkspaceChange", function() { return WorkspaceChange; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextDocumentIdentifier", function() { return TextDocumentIdentifier; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VersionedTextDocumentIdentifier", function() { return VersionedTextDocumentIdentifier; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextDocumentItem", function() { return TextDocumentItem; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MarkupKind", function() { return MarkupKind; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MarkupContent", function() { return MarkupContent; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CompletionItemKind", function() { return CompletionItemKind; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InsertTextFormat", function() { return InsertTextFormat; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CompletionItem", function() { return CompletionItem; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CompletionList", function() { return CompletionList; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MarkedString", function() { return MarkedString; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Hover", function() { return Hover; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParameterInformation", function() { return ParameterInformation; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SignatureInformation", function() { return SignatureInformation; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DocumentHighlightKind", function() { return DocumentHighlightKind; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DocumentHighlight", function() { return DocumentHighlight; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SymbolKind", function() { return SymbolKind; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SymbolInformation", function() { return SymbolInformation; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DocumentSymbol", function() { return DocumentSymbol; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CodeActionKind", function() { return CodeActionKind; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CodeActionContext", function() { return CodeActionContext; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CodeAction", function() { return CodeAction; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CodeLens", function() { return CodeLens; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FormattingOptions", function() { return FormattingOptions; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DocumentLink", function() { return DocumentLink; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SelectionRange", function() { return SelectionRange; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EOL", function() { return EOL; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextDocument", function() { return TextDocument; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextDocumentSaveReason", function() { return TextDocumentSaveReason; }); +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +/** + * The Position namespace provides helper functions to work with + * [Position](#Position) literals. + */ +var Position; +(function (Position) { + /** + * Creates a new Position literal from the given line and character. + * @param line The position's line. + * @param character The position's character. + */ + function create(line, character) { + return { line: line, character: character }; + } + Position.create = create; + /** + * Checks whether the given liternal conforms to the [Position](#Position) interface. + */ + function is(value) { + var candidate = value; + return Is.objectLiteral(candidate) && Is.number(candidate.line) && Is.number(candidate.character); + } + Position.is = is; +})(Position || (Position = {})); +/** + * The Range namespace provides helper functions to work with + * [Range](#Range) literals. + */ +var Range; +(function (Range) { + function create(one, two, three, four) { + if (Is.number(one) && Is.number(two) && Is.number(three) && Is.number(four)) { + return { start: Position.create(one, two), end: Position.create(three, four) }; + } + else if (Position.is(one) && Position.is(two)) { + return { start: one, end: two }; + } + else { + throw new Error("Range#create called with invalid arguments[" + one + ", " + two + ", " + three + ", " + four + "]"); + } + } + Range.create = create; + /** + * Checks whether the given literal conforms to the [Range](#Range) interface. + */ + function is(value) { + var candidate = value; + return Is.objectLiteral(candidate) && Position.is(candidate.start) && Position.is(candidate.end); + } + Range.is = is; +})(Range || (Range = {})); +/** + * The Location namespace provides helper functions to work with + * [Location](#Location) literals. + */ +var Location; +(function (Location) { + /** + * Creates a Location literal. + * @param uri The location's uri. + * @param range The location's range. + */ + function create(uri, range) { + return { uri: uri, range: range }; + } + Location.create = create; + /** + * Checks whether the given literal conforms to the [Location](#Location) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) && Range.is(candidate.range) && (Is.string(candidate.uri) || Is.undefined(candidate.uri)); + } + Location.is = is; +})(Location || (Location = {})); +/** + * The LocationLink namespace provides helper functions to work with + * [LocationLink](#LocationLink) literals. + */ +var LocationLink; +(function (LocationLink) { + /** + * Creates a LocationLink literal. + * @param targetUri The definition's uri. + * @param targetRange The full range of the definition. + * @param targetSelectionRange The span of the symbol definition at the target. + * @param originSelectionRange The span of the symbol being defined in the originating source file. + */ + function create(targetUri, targetRange, targetSelectionRange, originSelectionRange) { + return { targetUri: targetUri, targetRange: targetRange, targetSelectionRange: targetSelectionRange, originSelectionRange: originSelectionRange }; + } + LocationLink.create = create; + /** + * Checks whether the given literal conforms to the [LocationLink](#LocationLink) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) && Range.is(candidate.targetRange) && Is.string(candidate.targetUri) + && (Range.is(candidate.targetSelectionRange) || Is.undefined(candidate.targetSelectionRange)) + && (Range.is(candidate.originSelectionRange) || Is.undefined(candidate.originSelectionRange)); + } + LocationLink.is = is; +})(LocationLink || (LocationLink = {})); +/** + * The Color namespace provides helper functions to work with + * [Color](#Color) literals. + */ +var Color; +(function (Color) { + /** + * Creates a new Color literal. + */ + function create(red, green, blue, alpha) { + return { + red: red, + green: green, + blue: blue, + alpha: alpha, + }; + } + Color.create = create; + /** + * Checks whether the given literal conforms to the [Color](#Color) interface. + */ + function is(value) { + var candidate = value; + return Is.number(candidate.red) + && Is.number(candidate.green) + && Is.number(candidate.blue) + && Is.number(candidate.alpha); + } + Color.is = is; +})(Color || (Color = {})); +/** + * The ColorInformation namespace provides helper functions to work with + * [ColorInformation](#ColorInformation) literals. + */ +var ColorInformation; +(function (ColorInformation) { + /** + * Creates a new ColorInformation literal. + */ + function create(range, color) { + return { + range: range, + color: color, + }; + } + ColorInformation.create = create; + /** + * Checks whether the given literal conforms to the [ColorInformation](#ColorInformation) interface. + */ + function is(value) { + var candidate = value; + return Range.is(candidate.range) && Color.is(candidate.color); + } + ColorInformation.is = is; +})(ColorInformation || (ColorInformation = {})); +/** + * The Color namespace provides helper functions to work with + * [ColorPresentation](#ColorPresentation) literals. + */ +var ColorPresentation; +(function (ColorPresentation) { + /** + * Creates a new ColorInformation literal. + */ + function create(label, textEdit, additionalTextEdits) { + return { + label: label, + textEdit: textEdit, + additionalTextEdits: additionalTextEdits, + }; + } + ColorPresentation.create = create; + /** + * Checks whether the given literal conforms to the [ColorInformation](#ColorInformation) interface. + */ + function is(value) { + var candidate = value; + return Is.string(candidate.label) + && (Is.undefined(candidate.textEdit) || TextEdit.is(candidate)) + && (Is.undefined(candidate.additionalTextEdits) || Is.typedArray(candidate.additionalTextEdits, TextEdit.is)); + } + ColorPresentation.is = is; +})(ColorPresentation || (ColorPresentation = {})); +/** + * Enum of known range kinds + */ +var FoldingRangeKind; +(function (FoldingRangeKind) { + /** + * Folding range for a comment + */ + FoldingRangeKind["Comment"] = "comment"; + /** + * Folding range for a imports or includes + */ + FoldingRangeKind["Imports"] = "imports"; + /** + * Folding range for a region (e.g. `#region`) + */ + FoldingRangeKind["Region"] = "region"; +})(FoldingRangeKind || (FoldingRangeKind = {})); +/** + * The folding range namespace provides helper functions to work with + * [FoldingRange](#FoldingRange) literals. + */ +var FoldingRange; +(function (FoldingRange) { + /** + * Creates a new FoldingRange literal. + */ + function create(startLine, endLine, startCharacter, endCharacter, kind) { + var result = { + startLine: startLine, + endLine: endLine + }; + if (Is.defined(startCharacter)) { + result.startCharacter = startCharacter; + } + if (Is.defined(endCharacter)) { + result.endCharacter = endCharacter; + } + if (Is.defined(kind)) { + result.kind = kind; + } + return result; + } + FoldingRange.create = create; + /** + * Checks whether the given literal conforms to the [FoldingRange](#FoldingRange) interface. + */ + function is(value) { + var candidate = value; + return Is.number(candidate.startLine) && Is.number(candidate.startLine) + && (Is.undefined(candidate.startCharacter) || Is.number(candidate.startCharacter)) + && (Is.undefined(candidate.endCharacter) || Is.number(candidate.endCharacter)) + && (Is.undefined(candidate.kind) || Is.string(candidate.kind)); + } + FoldingRange.is = is; +})(FoldingRange || (FoldingRange = {})); +/** + * The DiagnosticRelatedInformation namespace provides helper functions to work with + * [DiagnosticRelatedInformation](#DiagnosticRelatedInformation) literals. + */ +var DiagnosticRelatedInformation; +(function (DiagnosticRelatedInformation) { + /** + * Creates a new DiagnosticRelatedInformation literal. + */ + function create(location, message) { + return { + location: location, + message: message + }; + } + DiagnosticRelatedInformation.create = create; + /** + * Checks whether the given literal conforms to the [DiagnosticRelatedInformation](#DiagnosticRelatedInformation) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) && Location.is(candidate.location) && Is.string(candidate.message); + } + DiagnosticRelatedInformation.is = is; +})(DiagnosticRelatedInformation || (DiagnosticRelatedInformation = {})); +/** + * The diagnostic's severity. + */ +var DiagnosticSeverity; +(function (DiagnosticSeverity) { + /** + * Reports an error. + */ + DiagnosticSeverity.Error = 1; + /** + * Reports a warning. + */ + DiagnosticSeverity.Warning = 2; + /** + * Reports an information. + */ + DiagnosticSeverity.Information = 3; + /** + * Reports a hint. + */ + DiagnosticSeverity.Hint = 4; +})(DiagnosticSeverity || (DiagnosticSeverity = {})); +var DiagnosticTag; +(function (DiagnosticTag) { + /** + * Unused or unnecessary code. + * + * Clients are allowed to render diagnostics with this tag faded out instead of having + * an error squiggle. + */ + DiagnosticTag.Unnecessary = 1; +})(DiagnosticTag || (DiagnosticTag = {})); +/** + * The Diagnostic namespace provides helper functions to work with + * [Diagnostic](#Diagnostic) literals. + */ +var Diagnostic; +(function (Diagnostic) { + /** + * Creates a new Diagnostic literal. + */ + function create(range, message, severity, code, source, relatedInformation) { + var result = { range: range, message: message }; + if (Is.defined(severity)) { + result.severity = severity; + } + if (Is.defined(code)) { + result.code = code; + } + if (Is.defined(source)) { + result.source = source; + } + if (Is.defined(relatedInformation)) { + result.relatedInformation = relatedInformation; + } + return result; + } + Diagnostic.create = create; + /** + * Checks whether the given literal conforms to the [Diagnostic](#Diagnostic) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) + && Range.is(candidate.range) + && Is.string(candidate.message) + && (Is.number(candidate.severity) || Is.undefined(candidate.severity)) + && (Is.number(candidate.code) || Is.string(candidate.code) || Is.undefined(candidate.code)) + && (Is.string(candidate.source) || Is.undefined(candidate.source)) + && (Is.undefined(candidate.relatedInformation) || Is.typedArray(candidate.relatedInformation, DiagnosticRelatedInformation.is)); + } + Diagnostic.is = is; +})(Diagnostic || (Diagnostic = {})); +/** + * The Command namespace provides helper functions to work with + * [Command](#Command) literals. + */ +var Command; +(function (Command) { + /** + * Creates a new Command literal. + */ + function create(title, command) { + var args = []; + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + var result = { title: title, command: command }; + if (Is.defined(args) && args.length > 0) { + result.arguments = args; + } + return result; + } + Command.create = create; + /** + * Checks whether the given literal conforms to the [Command](#Command) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) && Is.string(candidate.title) && Is.string(candidate.command); + } + Command.is = is; +})(Command || (Command = {})); +/** + * The TextEdit namespace provides helper function to create replace, + * insert and delete edits more easily. + */ +var TextEdit; +(function (TextEdit) { + /** + * Creates a replace text edit. + * @param range The range of text to be replaced. + * @param newText The new text. + */ + function replace(range, newText) { + return { range: range, newText: newText }; + } + TextEdit.replace = replace; + /** + * Creates a insert text edit. + * @param position The position to insert the text at. + * @param newText The text to be inserted. + */ + function insert(position, newText) { + return { range: { start: position, end: position }, newText: newText }; + } + TextEdit.insert = insert; + /** + * Creates a delete text edit. + * @param range The range of text to be deleted. + */ + function del(range) { + return { range: range, newText: '' }; + } + TextEdit.del = del; + function is(value) { + var candidate = value; + return Is.objectLiteral(candidate) + && Is.string(candidate.newText) + && Range.is(candidate.range); + } + TextEdit.is = is; +})(TextEdit || (TextEdit = {})); +/** + * The TextDocumentEdit namespace provides helper function to create + * an edit that manipulates a text document. + */ +var TextDocumentEdit; +(function (TextDocumentEdit) { + /** + * Creates a new `TextDocumentEdit` + */ + function create(textDocument, edits) { + return { textDocument: textDocument, edits: edits }; + } + TextDocumentEdit.create = create; + function is(value) { + var candidate = value; + return Is.defined(candidate) + && VersionedTextDocumentIdentifier.is(candidate.textDocument) + && Array.isArray(candidate.edits); + } + TextDocumentEdit.is = is; +})(TextDocumentEdit || (TextDocumentEdit = {})); +var CreateFile; +(function (CreateFile) { + function create(uri, options) { + var result = { + kind: 'create', + uri: uri + }; + if (options !== void 0 && (options.overwrite !== void 0 || options.ignoreIfExists !== void 0)) { + result.options = options; + } + return result; + } + CreateFile.create = create; + function is(value) { + var candidate = value; + return candidate && candidate.kind === 'create' && Is.string(candidate.uri) && + (candidate.options === void 0 || + ((candidate.options.overwrite === void 0 || Is.boolean(candidate.options.overwrite)) && (candidate.options.ignoreIfExists === void 0 || Is.boolean(candidate.options.ignoreIfExists)))); + } + CreateFile.is = is; +})(CreateFile || (CreateFile = {})); +var RenameFile; +(function (RenameFile) { + function create(oldUri, newUri, options) { + var result = { + kind: 'rename', + oldUri: oldUri, + newUri: newUri + }; + if (options !== void 0 && (options.overwrite !== void 0 || options.ignoreIfExists !== void 0)) { + result.options = options; + } + return result; + } + RenameFile.create = create; + function is(value) { + var candidate = value; + return candidate && candidate.kind === 'rename' && Is.string(candidate.oldUri) && Is.string(candidate.newUri) && + (candidate.options === void 0 || + ((candidate.options.overwrite === void 0 || Is.boolean(candidate.options.overwrite)) && (candidate.options.ignoreIfExists === void 0 || Is.boolean(candidate.options.ignoreIfExists)))); + } + RenameFile.is = is; +})(RenameFile || (RenameFile = {})); +var DeleteFile; +(function (DeleteFile) { + function create(uri, options) { + var result = { + kind: 'delete', + uri: uri + }; + if (options !== void 0 && (options.recursive !== void 0 || options.ignoreIfNotExists !== void 0)) { + result.options = options; + } + return result; + } + DeleteFile.create = create; + function is(value) { + var candidate = value; + return candidate && candidate.kind === 'delete' && Is.string(candidate.uri) && + (candidate.options === void 0 || + ((candidate.options.recursive === void 0 || Is.boolean(candidate.options.recursive)) && (candidate.options.ignoreIfNotExists === void 0 || Is.boolean(candidate.options.ignoreIfNotExists)))); + } + DeleteFile.is = is; +})(DeleteFile || (DeleteFile = {})); +var WorkspaceEdit; +(function (WorkspaceEdit) { + function is(value) { + var candidate = value; + return candidate && + (candidate.changes !== void 0 || candidate.documentChanges !== void 0) && + (candidate.documentChanges === void 0 || candidate.documentChanges.every(function (change) { + if (Is.string(change.kind)) { + return CreateFile.is(change) || RenameFile.is(change) || DeleteFile.is(change); + } + else { + return TextDocumentEdit.is(change); + } + })); + } + WorkspaceEdit.is = is; +})(WorkspaceEdit || (WorkspaceEdit = {})); +var TextEditChangeImpl = /** @class */ (function () { + function TextEditChangeImpl(edits) { + this.edits = edits; + } + TextEditChangeImpl.prototype.insert = function (position, newText) { + this.edits.push(TextEdit.insert(position, newText)); + }; + TextEditChangeImpl.prototype.replace = function (range, newText) { + this.edits.push(TextEdit.replace(range, newText)); + }; + TextEditChangeImpl.prototype.delete = function (range) { + this.edits.push(TextEdit.del(range)); + }; + TextEditChangeImpl.prototype.add = function (edit) { + this.edits.push(edit); + }; + TextEditChangeImpl.prototype.all = function () { + return this.edits; + }; + TextEditChangeImpl.prototype.clear = function () { + this.edits.splice(0, this.edits.length); + }; + return TextEditChangeImpl; +}()); +/** + * A workspace change helps constructing changes to a workspace. + */ +var WorkspaceChange = /** @class */ (function () { + function WorkspaceChange(workspaceEdit) { + var _this = this; + this._textEditChanges = Object.create(null); + if (workspaceEdit) { + this._workspaceEdit = workspaceEdit; + if (workspaceEdit.documentChanges) { + workspaceEdit.documentChanges.forEach(function (change) { + if (TextDocumentEdit.is(change)) { + var textEditChange = new TextEditChangeImpl(change.edits); + _this._textEditChanges[change.textDocument.uri] = textEditChange; + } + }); + } + else if (workspaceEdit.changes) { + Object.keys(workspaceEdit.changes).forEach(function (key) { + var textEditChange = new TextEditChangeImpl(workspaceEdit.changes[key]); + _this._textEditChanges[key] = textEditChange; + }); + } + } + } + Object.defineProperty(WorkspaceChange.prototype, "edit", { + /** + * Returns the underlying [WorkspaceEdit](#WorkspaceEdit) literal + * use to be returned from a workspace edit operation like rename. + */ + get: function () { + return this._workspaceEdit; + }, + enumerable: true, + configurable: true + }); + WorkspaceChange.prototype.getTextEditChange = function (key) { + if (VersionedTextDocumentIdentifier.is(key)) { + if (!this._workspaceEdit) { + this._workspaceEdit = { + documentChanges: [] + }; + } + if (!this._workspaceEdit.documentChanges) { + throw new Error('Workspace edit is not configured for document changes.'); + } + var textDocument = key; + var result = this._textEditChanges[textDocument.uri]; + if (!result) { + var edits = []; + var textDocumentEdit = { + textDocument: textDocument, + edits: edits + }; + this._workspaceEdit.documentChanges.push(textDocumentEdit); + result = new TextEditChangeImpl(edits); + this._textEditChanges[textDocument.uri] = result; + } + return result; + } + else { + if (!this._workspaceEdit) { + this._workspaceEdit = { + changes: Object.create(null) + }; + } + if (!this._workspaceEdit.changes) { + throw new Error('Workspace edit is not configured for normal text edit changes.'); + } + var result = this._textEditChanges[key]; + if (!result) { + var edits = []; + this._workspaceEdit.changes[key] = edits; + result = new TextEditChangeImpl(edits); + this._textEditChanges[key] = result; + } + return result; + } + }; + WorkspaceChange.prototype.createFile = function (uri, options) { + this.checkDocumentChanges(); + this._workspaceEdit.documentChanges.push(CreateFile.create(uri, options)); + }; + WorkspaceChange.prototype.renameFile = function (oldUri, newUri, options) { + this.checkDocumentChanges(); + this._workspaceEdit.documentChanges.push(RenameFile.create(oldUri, newUri, options)); + }; + WorkspaceChange.prototype.deleteFile = function (uri, options) { + this.checkDocumentChanges(); + this._workspaceEdit.documentChanges.push(DeleteFile.create(uri, options)); + }; + WorkspaceChange.prototype.checkDocumentChanges = function () { + if (!this._workspaceEdit || !this._workspaceEdit.documentChanges) { + throw new Error('Workspace edit is not configured for document changes.'); + } + }; + return WorkspaceChange; +}()); + +/** + * The TextDocumentIdentifier namespace provides helper functions to work with + * [TextDocumentIdentifier](#TextDocumentIdentifier) literals. + */ +var TextDocumentIdentifier; +(function (TextDocumentIdentifier) { + /** + * Creates a new TextDocumentIdentifier literal. + * @param uri The document's uri. + */ + function create(uri) { + return { uri: uri }; + } + TextDocumentIdentifier.create = create; + /** + * Checks whether the given literal conforms to the [TextDocumentIdentifier](#TextDocumentIdentifier) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) && Is.string(candidate.uri); + } + TextDocumentIdentifier.is = is; +})(TextDocumentIdentifier || (TextDocumentIdentifier = {})); +/** + * The VersionedTextDocumentIdentifier namespace provides helper functions to work with + * [VersionedTextDocumentIdentifier](#VersionedTextDocumentIdentifier) literals. + */ +var VersionedTextDocumentIdentifier; +(function (VersionedTextDocumentIdentifier) { + /** + * Creates a new VersionedTextDocumentIdentifier literal. + * @param uri The document's uri. + * @param uri The document's text. + */ + function create(uri, version) { + return { uri: uri, version: version }; + } + VersionedTextDocumentIdentifier.create = create; + /** + * Checks whether the given literal conforms to the [VersionedTextDocumentIdentifier](#VersionedTextDocumentIdentifier) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) && Is.string(candidate.uri) && (candidate.version === null || Is.number(candidate.version)); + } + VersionedTextDocumentIdentifier.is = is; +})(VersionedTextDocumentIdentifier || (VersionedTextDocumentIdentifier = {})); +/** + * The TextDocumentItem namespace provides helper functions to work with + * [TextDocumentItem](#TextDocumentItem) literals. + */ +var TextDocumentItem; +(function (TextDocumentItem) { + /** + * Creates a new TextDocumentItem literal. + * @param uri The document's uri. + * @param languageId The document's language identifier. + * @param version The document's version number. + * @param text The document's text. + */ + function create(uri, languageId, version, text) { + return { uri: uri, languageId: languageId, version: version, text: text }; + } + TextDocumentItem.create = create; + /** + * Checks whether the given literal conforms to the [TextDocumentItem](#TextDocumentItem) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) && Is.string(candidate.uri) && Is.string(candidate.languageId) && Is.number(candidate.version) && Is.string(candidate.text); + } + TextDocumentItem.is = is; +})(TextDocumentItem || (TextDocumentItem = {})); +/** + * Describes the content type that a client supports in various + * result literals like `Hover`, `ParameterInfo` or `CompletionItem`. + * + * Please note that `MarkupKinds` must not start with a `$`. This kinds + * are reserved for internal usage. + */ +var MarkupKind; +(function (MarkupKind) { + /** + * Plain text is supported as a content format + */ + MarkupKind.PlainText = 'plaintext'; + /** + * Markdown is supported as a content format + */ + MarkupKind.Markdown = 'markdown'; +})(MarkupKind || (MarkupKind = {})); +(function (MarkupKind) { + /** + * Checks whether the given value is a value of the [MarkupKind](#MarkupKind) type. + */ + function is(value) { + var candidate = value; + return candidate === MarkupKind.PlainText || candidate === MarkupKind.Markdown; + } + MarkupKind.is = is; +})(MarkupKind || (MarkupKind = {})); +var MarkupContent; +(function (MarkupContent) { + /** + * Checks whether the given value conforms to the [MarkupContent](#MarkupContent) interface. + */ + function is(value) { + var candidate = value; + return Is.objectLiteral(value) && MarkupKind.is(candidate.kind) && Is.string(candidate.value); + } + MarkupContent.is = is; +})(MarkupContent || (MarkupContent = {})); +/** + * The kind of a completion entry. + */ +var CompletionItemKind; +(function (CompletionItemKind) { + CompletionItemKind.Text = 1; + CompletionItemKind.Method = 2; + CompletionItemKind.Function = 3; + CompletionItemKind.Constructor = 4; + CompletionItemKind.Field = 5; + CompletionItemKind.Variable = 6; + CompletionItemKind.Class = 7; + CompletionItemKind.Interface = 8; + CompletionItemKind.Module = 9; + CompletionItemKind.Property = 10; + CompletionItemKind.Unit = 11; + CompletionItemKind.Value = 12; + CompletionItemKind.Enum = 13; + CompletionItemKind.Keyword = 14; + CompletionItemKind.Snippet = 15; + CompletionItemKind.Color = 16; + CompletionItemKind.File = 17; + CompletionItemKind.Reference = 18; + CompletionItemKind.Folder = 19; + CompletionItemKind.EnumMember = 20; + CompletionItemKind.Constant = 21; + CompletionItemKind.Struct = 22; + CompletionItemKind.Event = 23; + CompletionItemKind.Operator = 24; + CompletionItemKind.TypeParameter = 25; +})(CompletionItemKind || (CompletionItemKind = {})); +/** + * Defines whether the insert text in a completion item should be interpreted as + * plain text or a snippet. + */ +var InsertTextFormat; +(function (InsertTextFormat) { + /** + * The primary text to be inserted is treated as a plain string. + */ + InsertTextFormat.PlainText = 1; + /** + * The primary text to be inserted is treated as a snippet. + * + * A snippet can define tab stops and placeholders with `$1`, `$2` + * and `${3:foo}`. `$0` defines the final tab stop, it defaults to + * the end of the snippet. Placeholders with equal identifiers are linked, + * that is typing in one will update others too. + * + * See also: https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md + */ + InsertTextFormat.Snippet = 2; +})(InsertTextFormat || (InsertTextFormat = {})); +/** + * The CompletionItem namespace provides functions to deal with + * completion items. + */ +var CompletionItem; +(function (CompletionItem) { + /** + * Create a completion item and seed it with a label. + * @param label The completion item's label + */ + function create(label) { + return { label: label }; + } + CompletionItem.create = create; +})(CompletionItem || (CompletionItem = {})); +/** + * The CompletionList namespace provides functions to deal with + * completion lists. + */ +var CompletionList; +(function (CompletionList) { + /** + * Creates a new completion list. + * + * @param items The completion items. + * @param isIncomplete The list is not complete. + */ + function create(items, isIncomplete) { + return { items: items ? items : [], isIncomplete: !!isIncomplete }; + } + CompletionList.create = create; +})(CompletionList || (CompletionList = {})); +var MarkedString; +(function (MarkedString) { + /** + * Creates a marked string from plain text. + * + * @param plainText The plain text. + */ + function fromPlainText(plainText) { + return plainText.replace(/[\\`*_{}[\]()#+\-.!]/g, "\\$&"); // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash + } + MarkedString.fromPlainText = fromPlainText; + /** + * Checks whether the given value conforms to the [MarkedString](#MarkedString) type. + */ + function is(value) { + var candidate = value; + return Is.string(candidate) || (Is.objectLiteral(candidate) && Is.string(candidate.language) && Is.string(candidate.value)); + } + MarkedString.is = is; +})(MarkedString || (MarkedString = {})); +var Hover; +(function (Hover) { + /** + * Checks whether the given value conforms to the [Hover](#Hover) interface. + */ + function is(value) { + var candidate = value; + return !!candidate && Is.objectLiteral(candidate) && (MarkupContent.is(candidate.contents) || + MarkedString.is(candidate.contents) || + Is.typedArray(candidate.contents, MarkedString.is)) && (value.range === void 0 || Range.is(value.range)); + } + Hover.is = is; +})(Hover || (Hover = {})); +/** + * The ParameterInformation namespace provides helper functions to work with + * [ParameterInformation](#ParameterInformation) literals. + */ +var ParameterInformation; +(function (ParameterInformation) { + /** + * Creates a new parameter information literal. + * + * @param label A label string. + * @param documentation A doc string. + */ + function create(label, documentation) { + return documentation ? { label: label, documentation: documentation } : { label: label }; + } + ParameterInformation.create = create; + ; +})(ParameterInformation || (ParameterInformation = {})); +/** + * The SignatureInformation namespace provides helper functions to work with + * [SignatureInformation](#SignatureInformation) literals. + */ +var SignatureInformation; +(function (SignatureInformation) { + function create(label, documentation) { + var parameters = []; + for (var _i = 2; _i < arguments.length; _i++) { + parameters[_i - 2] = arguments[_i]; + } + var result = { label: label }; + if (Is.defined(documentation)) { + result.documentation = documentation; + } + if (Is.defined(parameters)) { + result.parameters = parameters; + } + else { + result.parameters = []; + } + return result; + } + SignatureInformation.create = create; +})(SignatureInformation || (SignatureInformation = {})); +/** + * A document highlight kind. + */ +var DocumentHighlightKind; +(function (DocumentHighlightKind) { + /** + * A textual occurrence. + */ + DocumentHighlightKind.Text = 1; + /** + * Read-access of a symbol, like reading a variable. + */ + DocumentHighlightKind.Read = 2; + /** + * Write-access of a symbol, like writing to a variable. + */ + DocumentHighlightKind.Write = 3; +})(DocumentHighlightKind || (DocumentHighlightKind = {})); +/** + * DocumentHighlight namespace to provide helper functions to work with + * [DocumentHighlight](#DocumentHighlight) literals. + */ +var DocumentHighlight; +(function (DocumentHighlight) { + /** + * Create a DocumentHighlight object. + * @param range The range the highlight applies to. + */ + function create(range, kind) { + var result = { range: range }; + if (Is.number(kind)) { + result.kind = kind; + } + return result; + } + DocumentHighlight.create = create; +})(DocumentHighlight || (DocumentHighlight = {})); +/** + * A symbol kind. + */ +var SymbolKind; +(function (SymbolKind) { + SymbolKind.File = 1; + SymbolKind.Module = 2; + SymbolKind.Namespace = 3; + SymbolKind.Package = 4; + SymbolKind.Class = 5; + SymbolKind.Method = 6; + SymbolKind.Property = 7; + SymbolKind.Field = 8; + SymbolKind.Constructor = 9; + SymbolKind.Enum = 10; + SymbolKind.Interface = 11; + SymbolKind.Function = 12; + SymbolKind.Variable = 13; + SymbolKind.Constant = 14; + SymbolKind.String = 15; + SymbolKind.Number = 16; + SymbolKind.Boolean = 17; + SymbolKind.Array = 18; + SymbolKind.Object = 19; + SymbolKind.Key = 20; + SymbolKind.Null = 21; + SymbolKind.EnumMember = 22; + SymbolKind.Struct = 23; + SymbolKind.Event = 24; + SymbolKind.Operator = 25; + SymbolKind.TypeParameter = 26; +})(SymbolKind || (SymbolKind = {})); +var SymbolInformation; +(function (SymbolInformation) { + /** + * Creates a new symbol information literal. + * + * @param name The name of the symbol. + * @param kind The kind of the symbol. + * @param range The range of the location of the symbol. + * @param uri The resource of the location of symbol, defaults to the current document. + * @param containerName The name of the symbol containing the symbol. + */ + function create(name, kind, range, uri, containerName) { + var result = { + name: name, + kind: kind, + location: { uri: uri, range: range } + }; + if (containerName) { + result.containerName = containerName; + } + return result; + } + SymbolInformation.create = create; +})(SymbolInformation || (SymbolInformation = {})); +/** + * Represents programming constructs like variables, classes, interfaces etc. + * that appear in a document. Document symbols can be hierarchical and they + * have two ranges: one that encloses its definition and one that points to + * its most interesting range, e.g. the range of an identifier. + */ +var DocumentSymbol = /** @class */ (function () { + function DocumentSymbol() { + } + return DocumentSymbol; +}()); + +(function (DocumentSymbol) { + /** + * Creates a new symbol information literal. + * + * @param name The name of the symbol. + * @param detail The detail of the symbol. + * @param kind The kind of the symbol. + * @param range The range of the symbol. + * @param selectionRange The selectionRange of the symbol. + * @param children Children of the symbol. + */ + function create(name, detail, kind, range, selectionRange, children) { + var result = { + name: name, + detail: detail, + kind: kind, + range: range, + selectionRange: selectionRange + }; + if (children !== void 0) { + result.children = children; + } + return result; + } + DocumentSymbol.create = create; + /** + * Checks whether the given literal conforms to the [DocumentSymbol](#DocumentSymbol) interface. + */ + function is(value) { + var candidate = value; + return candidate && + Is.string(candidate.name) && Is.number(candidate.kind) && + Range.is(candidate.range) && Range.is(candidate.selectionRange) && + (candidate.detail === void 0 || Is.string(candidate.detail)) && + (candidate.deprecated === void 0 || Is.boolean(candidate.deprecated)) && + (candidate.children === void 0 || Array.isArray(candidate.children)); + } + DocumentSymbol.is = is; +})(DocumentSymbol || (DocumentSymbol = {})); +/** + * A set of predefined code action kinds + */ +var CodeActionKind; +(function (CodeActionKind) { + /** + * Base kind for quickfix actions: 'quickfix' + */ + CodeActionKind.QuickFix = 'quickfix'; + /** + * Base kind for refactoring actions: 'refactor' + */ + CodeActionKind.Refactor = 'refactor'; + /** + * Base kind for refactoring extraction actions: 'refactor.extract' + * + * Example extract actions: + * + * - Extract method + * - Extract function + * - Extract variable + * - Extract interface from class + * - ... + */ + CodeActionKind.RefactorExtract = 'refactor.extract'; + /** + * Base kind for refactoring inline actions: 'refactor.inline' + * + * Example inline actions: + * + * - Inline function + * - Inline variable + * - Inline constant + * - ... + */ + CodeActionKind.RefactorInline = 'refactor.inline'; + /** + * Base kind for refactoring rewrite actions: 'refactor.rewrite' + * + * Example rewrite actions: + * + * - Convert JavaScript function to class + * - Add or remove parameter + * - Encapsulate field + * - Make method static + * - Move method to base class + * - ... + */ + CodeActionKind.RefactorRewrite = 'refactor.rewrite'; + /** + * Base kind for source actions: `source` + * + * Source code actions apply to the entire file. + */ + CodeActionKind.Source = 'source'; + /** + * Base kind for an organize imports source action: `source.organizeImports` + */ + CodeActionKind.SourceOrganizeImports = 'source.organizeImports'; +})(CodeActionKind || (CodeActionKind = {})); +/** + * The CodeActionContext namespace provides helper functions to work with + * [CodeActionContext](#CodeActionContext) literals. + */ +var CodeActionContext; +(function (CodeActionContext) { + /** + * Creates a new CodeActionContext literal. + */ + function create(diagnostics, only) { + var result = { diagnostics: diagnostics }; + if (only !== void 0 && only !== null) { + result.only = only; + } + return result; + } + CodeActionContext.create = create; + /** + * Checks whether the given literal conforms to the [CodeActionContext](#CodeActionContext) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) && Is.typedArray(candidate.diagnostics, Diagnostic.is) && (candidate.only === void 0 || Is.typedArray(candidate.only, Is.string)); + } + CodeActionContext.is = is; +})(CodeActionContext || (CodeActionContext = {})); +var CodeAction; +(function (CodeAction) { + function create(title, commandOrEdit, kind) { + var result = { title: title }; + if (Command.is(commandOrEdit)) { + result.command = commandOrEdit; + } + else { + result.edit = commandOrEdit; + } + if (kind !== void null) { + result.kind = kind; + } + return result; + } + CodeAction.create = create; + function is(value) { + var candidate = value; + return candidate && Is.string(candidate.title) && + (candidate.diagnostics === void 0 || Is.typedArray(candidate.diagnostics, Diagnostic.is)) && + (candidate.kind === void 0 || Is.string(candidate.kind)) && + (candidate.edit !== void 0 || candidate.command !== void 0) && + (candidate.command === void 0 || Command.is(candidate.command)) && + (candidate.edit === void 0 || WorkspaceEdit.is(candidate.edit)); + } + CodeAction.is = is; +})(CodeAction || (CodeAction = {})); +/** + * The CodeLens namespace provides helper functions to work with + * [CodeLens](#CodeLens) literals. + */ +var CodeLens; +(function (CodeLens) { + /** + * Creates a new CodeLens literal. + */ + function create(range, data) { + var result = { range: range }; + if (Is.defined(data)) + result.data = data; + return result; + } + CodeLens.create = create; + /** + * Checks whether the given literal conforms to the [CodeLens](#CodeLens) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) && Range.is(candidate.range) && (Is.undefined(candidate.command) || Command.is(candidate.command)); + } + CodeLens.is = is; +})(CodeLens || (CodeLens = {})); +/** + * The FormattingOptions namespace provides helper functions to work with + * [FormattingOptions](#FormattingOptions) literals. + */ +var FormattingOptions; +(function (FormattingOptions) { + /** + * Creates a new FormattingOptions literal. + */ + function create(tabSize, insertSpaces) { + return { tabSize: tabSize, insertSpaces: insertSpaces }; + } + FormattingOptions.create = create; + /** + * Checks whether the given literal conforms to the [FormattingOptions](#FormattingOptions) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) && Is.number(candidate.tabSize) && Is.boolean(candidate.insertSpaces); + } + FormattingOptions.is = is; +})(FormattingOptions || (FormattingOptions = {})); +/** + * A document link is a range in a text document that links to an internal or external resource, like another + * text document or a web site. + */ +var DocumentLink = /** @class */ (function () { + function DocumentLink() { + } + return DocumentLink; +}()); + +/** + * The DocumentLink namespace provides helper functions to work with + * [DocumentLink](#DocumentLink) literals. + */ +(function (DocumentLink) { + /** + * Creates a new DocumentLink literal. + */ + function create(range, target, data) { + return { range: range, target: target, data: data }; + } + DocumentLink.create = create; + /** + * Checks whether the given literal conforms to the [DocumentLink](#DocumentLink) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) && Range.is(candidate.range) && (Is.undefined(candidate.target) || Is.string(candidate.target)); + } + DocumentLink.is = is; +})(DocumentLink || (DocumentLink = {})); +/** + * The SelectionRange namespace provides helper function to work with + * SelectionRange literals. + */ +var SelectionRange; +(function (SelectionRange) { + /** + * Creates a new SelectionRange + * @param range the range. + * @param parent an optional parent. + */ + function create(range, parent) { + return { range: range, parent: parent }; + } + SelectionRange.create = create; + function is(value) { + var candidate = value; + return candidate !== undefined && Range.is(candidate.range) && (candidate.parent === undefined || SelectionRange.is(candidate.parent)); + } + SelectionRange.is = is; +})(SelectionRange || (SelectionRange = {})); +var EOL = ['\n', '\r\n', '\r']; +var TextDocument; +(function (TextDocument) { + /** + * Creates a new ITextDocument literal from the given uri and content. + * @param uri The document's uri. + * @param languageId The document's language Id. + * @param content The document's content. + */ + function create(uri, languageId, version, content) { + return new FullTextDocument(uri, languageId, version, content); + } + TextDocument.create = create; + /** + * Checks whether the given literal conforms to the [ITextDocument](#ITextDocument) interface. + */ + function is(value) { + var candidate = value; + return Is.defined(candidate) && Is.string(candidate.uri) && (Is.undefined(candidate.languageId) || Is.string(candidate.languageId)) && Is.number(candidate.lineCount) + && Is.func(candidate.getText) && Is.func(candidate.positionAt) && Is.func(candidate.offsetAt) ? true : false; + } + TextDocument.is = is; + function applyEdits(document, edits) { + var text = document.getText(); + var sortedEdits = mergeSort(edits, function (a, b) { + var diff = a.range.start.line - b.range.start.line; + if (diff === 0) { + return a.range.start.character - b.range.start.character; + } + return diff; + }); + var lastModifiedOffset = text.length; + for (var i = sortedEdits.length - 1; i >= 0; i--) { + var e = sortedEdits[i]; + var startOffset = document.offsetAt(e.range.start); + var endOffset = document.offsetAt(e.range.end); + if (endOffset <= lastModifiedOffset) { + text = text.substring(0, startOffset) + e.newText + text.substring(endOffset, text.length); + } + else { + throw new Error('Overlapping edit'); + } + lastModifiedOffset = startOffset; + } + return text; + } + TextDocument.applyEdits = applyEdits; + function mergeSort(data, compare) { + if (data.length <= 1) { + // sorted + return data; + } + var p = (data.length / 2) | 0; + var left = data.slice(0, p); + var right = data.slice(p); + mergeSort(left, compare); + mergeSort(right, compare); + var leftIdx = 0; + var rightIdx = 0; + var i = 0; + while (leftIdx < left.length && rightIdx < right.length) { + var ret = compare(left[leftIdx], right[rightIdx]); + if (ret <= 0) { + // smaller_equal -> take left to preserve order + data[i++] = left[leftIdx++]; + } + else { + // greater -> take right + data[i++] = right[rightIdx++]; + } + } + while (leftIdx < left.length) { + data[i++] = left[leftIdx++]; + } + while (rightIdx < right.length) { + data[i++] = right[rightIdx++]; + } + return data; + } +})(TextDocument || (TextDocument = {})); +/** + * Represents reasons why a text document is saved. + */ +var TextDocumentSaveReason; +(function (TextDocumentSaveReason) { + /** + * Manually triggered, e.g. by the user pressing save, by starting debugging, + * or by an API call. + */ + TextDocumentSaveReason.Manual = 1; + /** + * Automatic after a delay. + */ + TextDocumentSaveReason.AfterDelay = 2; + /** + * When the editor lost focus. + */ + TextDocumentSaveReason.FocusOut = 3; +})(TextDocumentSaveReason || (TextDocumentSaveReason = {})); +var FullTextDocument = /** @class */ (function () { + function FullTextDocument(uri, languageId, version, content) { + this._uri = uri; + this._languageId = languageId; + this._version = version; + this._content = content; + this._lineOffsets = null; + } + Object.defineProperty(FullTextDocument.prototype, "uri", { + get: function () { + return this._uri; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(FullTextDocument.prototype, "languageId", { + get: function () { + return this._languageId; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(FullTextDocument.prototype, "version", { + get: function () { + return this._version; + }, + enumerable: true, + configurable: true + }); + FullTextDocument.prototype.getText = function (range) { + if (range) { + var start = this.offsetAt(range.start); + var end = this.offsetAt(range.end); + return this._content.substring(start, end); + } + return this._content; + }; + FullTextDocument.prototype.update = function (event, version) { + this._content = event.text; + this._version = version; + this._lineOffsets = null; + }; + FullTextDocument.prototype.getLineOffsets = function () { + if (this._lineOffsets === null) { + var lineOffsets = []; + var text = this._content; + var isLineStart = true; + for (var i = 0; i < text.length; i++) { + if (isLineStart) { + lineOffsets.push(i); + isLineStart = false; + } + var ch = text.charAt(i); + isLineStart = (ch === '\r' || ch === '\n'); + if (ch === '\r' && i + 1 < text.length && text.charAt(i + 1) === '\n') { + i++; + } + } + if (isLineStart && text.length > 0) { + lineOffsets.push(text.length); + } + this._lineOffsets = lineOffsets; + } + return this._lineOffsets; + }; + FullTextDocument.prototype.positionAt = function (offset) { + offset = Math.max(Math.min(offset, this._content.length), 0); + var lineOffsets = this.getLineOffsets(); + var low = 0, high = lineOffsets.length; + if (high === 0) { + return Position.create(0, offset); + } + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (lineOffsets[mid] > offset) { + high = mid; + } + else { + low = mid + 1; + } + } + // low is the least x for which the line offset is larger than the current offset + // or array.length if no line offset is larger than the current offset + var line = low - 1; + return Position.create(line, offset - lineOffsets[line]); + }; + FullTextDocument.prototype.offsetAt = function (position) { + var lineOffsets = this.getLineOffsets(); + if (position.line >= lineOffsets.length) { + return this._content.length; + } + else if (position.line < 0) { + return 0; + } + var lineOffset = lineOffsets[position.line]; + var nextLineOffset = (position.line + 1 < lineOffsets.length) ? lineOffsets[position.line + 1] : this._content.length; + return Math.max(Math.min(lineOffset + position.character, nextLineOffset), lineOffset); + }; + Object.defineProperty(FullTextDocument.prototype, "lineCount", { + get: function () { + return this.getLineOffsets().length; + }, + enumerable: true, + configurable: true + }); + return FullTextDocument; +}()); +var Is; +(function (Is) { + var toString = Object.prototype.toString; + function defined(value) { + return typeof value !== 'undefined'; + } + Is.defined = defined; + function undefined(value) { + return typeof value === 'undefined'; + } + Is.undefined = undefined; + function boolean(value) { + return value === true || value === false; + } + Is.boolean = boolean; + function string(value) { + return toString.call(value) === '[object String]'; + } + Is.string = string; + function number(value) { + return toString.call(value) === '[object Number]'; + } + Is.number = number; + function func(value) { + return toString.call(value) === '[object Function]'; + } + Is.func = func; + function objectLiteral(value) { + // Strictly speaking class instances pass this check as well. Since the LSP + // doesn't use classes we ignore this for now. If we do we need to add something + // like this: `Object.getPrototypeOf(Object.getPrototypeOf(x)) === null` + return value !== null && typeof value === 'object'; + } + Is.objectLiteral = objectLiteral; + function typedArray(value, check) { + return Array.isArray(value) && value.every(check); + } + Is.typedArray = typedArray; +})(Is || (Is = {})); + + +/***/ }), +/* 162 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const Is = __webpack_require__(163); +const vscode_jsonrpc_1 = __webpack_require__(150); +const protocol_implementation_1 = __webpack_require__(164); +exports.ImplementationRequest = protocol_implementation_1.ImplementationRequest; +const protocol_typeDefinition_1 = __webpack_require__(165); +exports.TypeDefinitionRequest = protocol_typeDefinition_1.TypeDefinitionRequest; +const protocol_workspaceFolders_1 = __webpack_require__(166); +exports.WorkspaceFoldersRequest = protocol_workspaceFolders_1.WorkspaceFoldersRequest; +exports.DidChangeWorkspaceFoldersNotification = protocol_workspaceFolders_1.DidChangeWorkspaceFoldersNotification; +const protocol_configuration_1 = __webpack_require__(167); +exports.ConfigurationRequest = protocol_configuration_1.ConfigurationRequest; +const protocol_colorProvider_1 = __webpack_require__(168); +exports.DocumentColorRequest = protocol_colorProvider_1.DocumentColorRequest; +exports.ColorPresentationRequest = protocol_colorProvider_1.ColorPresentationRequest; +const protocol_foldingRange_1 = __webpack_require__(169); +exports.FoldingRangeRequest = protocol_foldingRange_1.FoldingRangeRequest; +const protocol_declaration_1 = __webpack_require__(170); +exports.DeclarationRequest = protocol_declaration_1.DeclarationRequest; +const protocol_selectionRange_1 = __webpack_require__(171); +exports.SelectionRangeRequest = protocol_selectionRange_1.SelectionRangeRequest; +// @ts-ignore: to avoid inlining LocatioLink as dynamic import +let __noDynamicImport; +var DocumentFilter; +(function (DocumentFilter) { + function is(value) { + let candidate = value; + return Is.string(candidate.language) || Is.string(candidate.scheme) || Is.string(candidate.pattern); + } + DocumentFilter.is = is; +})(DocumentFilter = exports.DocumentFilter || (exports.DocumentFilter = {})); +/** + * The `client/registerCapability` request is sent from the server to the client to register a new capability + * handler on the client side. + */ +var RegistrationRequest; +(function (RegistrationRequest) { + RegistrationRequest.type = new vscode_jsonrpc_1.RequestType('client/registerCapability'); +})(RegistrationRequest = exports.RegistrationRequest || (exports.RegistrationRequest = {})); +/** + * The `client/unregisterCapability` request is sent from the server to the client to unregister a previously registered capability + * handler on the client side. + */ +var UnregistrationRequest; +(function (UnregistrationRequest) { + UnregistrationRequest.type = new vscode_jsonrpc_1.RequestType('client/unregisterCapability'); +})(UnregistrationRequest = exports.UnregistrationRequest || (exports.UnregistrationRequest = {})); +var ResourceOperationKind; +(function (ResourceOperationKind) { + /** + * Supports creating new files and folders. + */ + ResourceOperationKind.Create = 'create'; + /** + * Supports renaming existing files and folders. + */ + ResourceOperationKind.Rename = 'rename'; + /** + * Supports deleting existing files and folders. + */ + ResourceOperationKind.Delete = 'delete'; +})(ResourceOperationKind = exports.ResourceOperationKind || (exports.ResourceOperationKind = {})); +var FailureHandlingKind; +(function (FailureHandlingKind) { + /** + * Applying the workspace change is simply aborted if one of the changes provided + * fails. All operations executed before the failing operation stay executed. + */ + FailureHandlingKind.Abort = 'abort'; + /** + * All operations are executed transactional. That means they either all + * succeed or no changes at all are applied to the workspace. + */ + FailureHandlingKind.Transactional = 'transactional'; + /** + * If the workspace edit contains only textual file changes they are executed transactional. + * If resource changes (create, rename or delete file) are part of the change the failure + * handling startegy is abort. + */ + FailureHandlingKind.TextOnlyTransactional = 'textOnlyTransactional'; + /** + * The client tries to undo the operations already executed. But there is no + * guaruntee that this is succeeding. + */ + FailureHandlingKind.Undo = 'undo'; +})(FailureHandlingKind = exports.FailureHandlingKind || (exports.FailureHandlingKind = {})); +/** + * Defines how the host (editor) should sync + * document changes to the language server. + */ +var TextDocumentSyncKind; +(function (TextDocumentSyncKind) { + /** + * Documents should not be synced at all. + */ + TextDocumentSyncKind.None = 0; + /** + * Documents are synced by always sending the full content + * of the document. + */ + TextDocumentSyncKind.Full = 1; + /** + * Documents are synced by sending the full content on open. + * After that only incremental updates to the document are + * send. + */ + TextDocumentSyncKind.Incremental = 2; +})(TextDocumentSyncKind = exports.TextDocumentSyncKind || (exports.TextDocumentSyncKind = {})); +/** + * The initialize request is sent from the client to the server. + * It is sent once as the request after starting up the server. + * The requests parameter is of type [InitializeParams](#InitializeParams) + * the response if of type [InitializeResult](#InitializeResult) of a Thenable that + * resolves to such. + */ +var InitializeRequest; +(function (InitializeRequest) { + InitializeRequest.type = new vscode_jsonrpc_1.RequestType('initialize'); +})(InitializeRequest = exports.InitializeRequest || (exports.InitializeRequest = {})); +/** + * Known error codes for an `InitializeError`; + */ +var InitializeError; +(function (InitializeError) { + /** + * If the protocol version provided by the client can't be handled by the server. + * @deprecated This initialize error got replaced by client capabilities. There is + * no version handshake in version 3.0x + */ + InitializeError.unknownProtocolVersion = 1; +})(InitializeError = exports.InitializeError || (exports.InitializeError = {})); +/** + * The intialized notification is sent from the client to the + * server after the client is fully initialized and the server + * is allowed to send requests from the server to the client. + */ +var InitializedNotification; +(function (InitializedNotification) { + InitializedNotification.type = new vscode_jsonrpc_1.NotificationType('initialized'); +})(InitializedNotification = exports.InitializedNotification || (exports.InitializedNotification = {})); +//---- Shutdown Method ---- +/** + * A shutdown request is sent from the client to the server. + * It is sent once when the client decides to shutdown the + * server. The only notification that is sent after a shutdown request + * is the exit event. + */ +var ShutdownRequest; +(function (ShutdownRequest) { + ShutdownRequest.type = new vscode_jsonrpc_1.RequestType0('shutdown'); +})(ShutdownRequest = exports.ShutdownRequest || (exports.ShutdownRequest = {})); +//---- Exit Notification ---- +/** + * The exit event is sent from the client to the server to + * ask the server to exit its process. + */ +var ExitNotification; +(function (ExitNotification) { + ExitNotification.type = new vscode_jsonrpc_1.NotificationType0('exit'); +})(ExitNotification = exports.ExitNotification || (exports.ExitNotification = {})); +//---- Configuration notification ---- +/** + * The configuration change notification is sent from the client to the server + * when the client's configuration has changed. The notification contains + * the changed configuration as defined by the language client. + */ +var DidChangeConfigurationNotification; +(function (DidChangeConfigurationNotification) { + DidChangeConfigurationNotification.type = new vscode_jsonrpc_1.NotificationType('workspace/didChangeConfiguration'); +})(DidChangeConfigurationNotification = exports.DidChangeConfigurationNotification || (exports.DidChangeConfigurationNotification = {})); +//---- Message show and log notifications ---- +/** + * The message type + */ +var MessageType; +(function (MessageType) { + /** + * An error message. + */ + MessageType.Error = 1; + /** + * A warning message. + */ + MessageType.Warning = 2; + /** + * An information message. + */ + MessageType.Info = 3; + /** + * A log message. + */ + MessageType.Log = 4; +})(MessageType = exports.MessageType || (exports.MessageType = {})); +/** + * The show message notification is sent from a server to a client to ask + * the client to display a particular message in the user interface. + */ +var ShowMessageNotification; +(function (ShowMessageNotification) { + ShowMessageNotification.type = new vscode_jsonrpc_1.NotificationType('window/showMessage'); +})(ShowMessageNotification = exports.ShowMessageNotification || (exports.ShowMessageNotification = {})); +/** + * The show message request is sent from the server to the client to show a message + * and a set of options actions to the user. + */ +var ShowMessageRequest; +(function (ShowMessageRequest) { + ShowMessageRequest.type = new vscode_jsonrpc_1.RequestType('window/showMessageRequest'); +})(ShowMessageRequest = exports.ShowMessageRequest || (exports.ShowMessageRequest = {})); +/** + * The log message notification is sent from the server to the client to ask + * the client to log a particular message. + */ +var LogMessageNotification; +(function (LogMessageNotification) { + LogMessageNotification.type = new vscode_jsonrpc_1.NotificationType('window/logMessage'); +})(LogMessageNotification = exports.LogMessageNotification || (exports.LogMessageNotification = {})); +//---- Telemetry notification +/** + * The telemetry event notification is sent from the server to the client to ask + * the client to log telemetry data. + */ +var TelemetryEventNotification; +(function (TelemetryEventNotification) { + TelemetryEventNotification.type = new vscode_jsonrpc_1.NotificationType('telemetry/event'); +})(TelemetryEventNotification = exports.TelemetryEventNotification || (exports.TelemetryEventNotification = {})); +/** + * The document open notification is sent from the client to the server to signal + * newly opened text documents. The document's truth is now managed by the client + * and the server must not try to read the document's truth using the document's + * uri. Open in this sense means it is managed by the client. It doesn't necessarily + * mean that its content is presented in an editor. An open notification must not + * be sent more than once without a corresponding close notification send before. + * This means open and close notification must be balanced and the max open count + * is one. + */ +var DidOpenTextDocumentNotification; +(function (DidOpenTextDocumentNotification) { + DidOpenTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/didOpen'); +})(DidOpenTextDocumentNotification = exports.DidOpenTextDocumentNotification || (exports.DidOpenTextDocumentNotification = {})); +/** + * The document change notification is sent from the client to the server to signal + * changes to a text document. + */ +var DidChangeTextDocumentNotification; +(function (DidChangeTextDocumentNotification) { + DidChangeTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/didChange'); +})(DidChangeTextDocumentNotification = exports.DidChangeTextDocumentNotification || (exports.DidChangeTextDocumentNotification = {})); +/** + * The document close notification is sent from the client to the server when + * the document got closed in the client. The document's truth now exists where + * the document's uri points to (e.g. if the document's uri is a file uri the + * truth now exists on disk). As with the open notification the close notification + * is about managing the document's content. Receiving a close notification + * doesn't mean that the document was open in an editor before. A close + * notification requires a previous open notification to be sent. + */ +var DidCloseTextDocumentNotification; +(function (DidCloseTextDocumentNotification) { + DidCloseTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/didClose'); +})(DidCloseTextDocumentNotification = exports.DidCloseTextDocumentNotification || (exports.DidCloseTextDocumentNotification = {})); +/** + * The document save notification is sent from the client to the server when + * the document got saved in the client. + */ +var DidSaveTextDocumentNotification; +(function (DidSaveTextDocumentNotification) { + DidSaveTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/didSave'); +})(DidSaveTextDocumentNotification = exports.DidSaveTextDocumentNotification || (exports.DidSaveTextDocumentNotification = {})); +/** + * A document will save notification is sent from the client to the server before + * the document is actually saved. + */ +var WillSaveTextDocumentNotification; +(function (WillSaveTextDocumentNotification) { + WillSaveTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/willSave'); +})(WillSaveTextDocumentNotification = exports.WillSaveTextDocumentNotification || (exports.WillSaveTextDocumentNotification = {})); +/** + * A document will save request is sent from the client to the server before + * the document is actually saved. The request can return an array of TextEdits + * which will be applied to the text document before it is saved. Please note that + * clients might drop results if computing the text edits took too long or if a + * server constantly fails on this request. This is done to keep the save fast and + * reliable. + */ +var WillSaveTextDocumentWaitUntilRequest; +(function (WillSaveTextDocumentWaitUntilRequest) { + WillSaveTextDocumentWaitUntilRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/willSaveWaitUntil'); +})(WillSaveTextDocumentWaitUntilRequest = exports.WillSaveTextDocumentWaitUntilRequest || (exports.WillSaveTextDocumentWaitUntilRequest = {})); +//---- File eventing ---- +/** + * The watched files notification is sent from the client to the server when + * the client detects changes to file watched by the language client. + */ +var DidChangeWatchedFilesNotification; +(function (DidChangeWatchedFilesNotification) { + DidChangeWatchedFilesNotification.type = new vscode_jsonrpc_1.NotificationType('workspace/didChangeWatchedFiles'); +})(DidChangeWatchedFilesNotification = exports.DidChangeWatchedFilesNotification || (exports.DidChangeWatchedFilesNotification = {})); +/** + * The file event type + */ +var FileChangeType; +(function (FileChangeType) { + /** + * The file got created. + */ + FileChangeType.Created = 1; + /** + * The file got changed. + */ + FileChangeType.Changed = 2; + /** + * The file got deleted. + */ + FileChangeType.Deleted = 3; +})(FileChangeType = exports.FileChangeType || (exports.FileChangeType = {})); +var WatchKind; +(function (WatchKind) { + /** + * Interested in create events. + */ + WatchKind.Create = 1; + /** + * Interested in change events + */ + WatchKind.Change = 2; + /** + * Interested in delete events + */ + WatchKind.Delete = 4; +})(WatchKind = exports.WatchKind || (exports.WatchKind = {})); +//---- Diagnostic notification ---- +/** + * Diagnostics notification are sent from the server to the client to signal + * results of validation runs. + */ +var PublishDiagnosticsNotification; +(function (PublishDiagnosticsNotification) { + PublishDiagnosticsNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/publishDiagnostics'); +})(PublishDiagnosticsNotification = exports.PublishDiagnosticsNotification || (exports.PublishDiagnosticsNotification = {})); +/** + * How a completion was triggered + */ +var CompletionTriggerKind; +(function (CompletionTriggerKind) { + /** + * Completion was triggered by typing an identifier (24x7 code + * complete), manual invocation (e.g Ctrl+Space) or via API. + */ + CompletionTriggerKind.Invoked = 1; + /** + * Completion was triggered by a trigger character specified by + * the `triggerCharacters` properties of the `CompletionRegistrationOptions`. + */ + CompletionTriggerKind.TriggerCharacter = 2; + /** + * Completion was re-triggered as current completion list is incomplete + */ + CompletionTriggerKind.TriggerForIncompleteCompletions = 3; +})(CompletionTriggerKind = exports.CompletionTriggerKind || (exports.CompletionTriggerKind = {})); +/** + * Request to request completion at a given text document position. The request's + * parameter is of type [TextDocumentPosition](#TextDocumentPosition) the response + * is of type [CompletionItem[]](#CompletionItem) or [CompletionList](#CompletionList) + * or a Thenable that resolves to such. + * + * The request can delay the computation of the [`detail`](#CompletionItem.detail) + * and [`documentation`](#CompletionItem.documentation) properties to the `completionItem/resolve` + * request. However, properties that are needed for the initial sorting and filtering, like `sortText`, + * `filterText`, `insertText`, and `textEdit`, must not be changed during resolve. + */ +var CompletionRequest; +(function (CompletionRequest) { + CompletionRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/completion'); +})(CompletionRequest = exports.CompletionRequest || (exports.CompletionRequest = {})); +/** + * Request to resolve additional information for a given completion item.The request's + * parameter is of type [CompletionItem](#CompletionItem) the response + * is of type [CompletionItem](#CompletionItem) or a Thenable that resolves to such. + */ +var CompletionResolveRequest; +(function (CompletionResolveRequest) { + CompletionResolveRequest.type = new vscode_jsonrpc_1.RequestType('completionItem/resolve'); +})(CompletionResolveRequest = exports.CompletionResolveRequest || (exports.CompletionResolveRequest = {})); +//---- Hover Support ------------------------------- +/** + * Request to request hover information at a given text document position. The request's + * parameter is of type [TextDocumentPosition](#TextDocumentPosition) the response is of + * type [Hover](#Hover) or a Thenable that resolves to such. + */ +var HoverRequest; +(function (HoverRequest) { + HoverRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/hover'); +})(HoverRequest = exports.HoverRequest || (exports.HoverRequest = {})); +var SignatureHelpRequest; +(function (SignatureHelpRequest) { + SignatureHelpRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/signatureHelp'); +})(SignatureHelpRequest = exports.SignatureHelpRequest || (exports.SignatureHelpRequest = {})); +//---- Goto Definition ------------------------------------- +/** + * A request to resolve the definition location of a symbol at a given text + * document position. The request's parameter is of type [TextDocumentPosition] + * (#TextDocumentPosition) the response is of either type [Definition](#Definition) + * or a typed array of [DefinitionLink](#DefinitionLink) or a Thenable that resolves + * to such. + */ +var DefinitionRequest; +(function (DefinitionRequest) { + DefinitionRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/definition'); +})(DefinitionRequest = exports.DefinitionRequest || (exports.DefinitionRequest = {})); +/** + * A request to resolve project-wide references for the symbol denoted + * by the given text document position. The request's parameter is of + * type [ReferenceParams](#ReferenceParams) the response is of type + * [Location[]](#Location) or a Thenable that resolves to such. + */ +var ReferencesRequest; +(function (ReferencesRequest) { + ReferencesRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/references'); +})(ReferencesRequest = exports.ReferencesRequest || (exports.ReferencesRequest = {})); +//---- Document Highlight ---------------------------------- +/** + * Request to resolve a [DocumentHighlight](#DocumentHighlight) for a given + * text document position. The request's parameter is of type [TextDocumentPosition] + * (#TextDocumentPosition) the request response is of type [DocumentHighlight[]] + * (#DocumentHighlight) or a Thenable that resolves to such. + */ +var DocumentHighlightRequest; +(function (DocumentHighlightRequest) { + DocumentHighlightRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/documentHighlight'); +})(DocumentHighlightRequest = exports.DocumentHighlightRequest || (exports.DocumentHighlightRequest = {})); +//---- Document Symbol Provider --------------------------- +/** + * A request to list all symbols found in a given text document. The request's + * parameter is of type [TextDocumentIdentifier](#TextDocumentIdentifier) the + * response is of type [SymbolInformation[]](#SymbolInformation) or a Thenable + * that resolves to such. + */ +var DocumentSymbolRequest; +(function (DocumentSymbolRequest) { + DocumentSymbolRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/documentSymbol'); +})(DocumentSymbolRequest = exports.DocumentSymbolRequest || (exports.DocumentSymbolRequest = {})); +//---- Workspace Symbol Provider --------------------------- +/** + * A request to list project-wide symbols matching the query string given + * by the [WorkspaceSymbolParams](#WorkspaceSymbolParams). The response is + * of type [SymbolInformation[]](#SymbolInformation) or a Thenable that + * resolves to such. + */ +var WorkspaceSymbolRequest; +(function (WorkspaceSymbolRequest) { + WorkspaceSymbolRequest.type = new vscode_jsonrpc_1.RequestType('workspace/symbol'); +})(WorkspaceSymbolRequest = exports.WorkspaceSymbolRequest || (exports.WorkspaceSymbolRequest = {})); +/** + * A request to provide commands for the given text document and range. + */ +var CodeActionRequest; +(function (CodeActionRequest) { + CodeActionRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/codeAction'); +})(CodeActionRequest = exports.CodeActionRequest || (exports.CodeActionRequest = {})); +/** + * A request to provide code lens for the given text document. + */ +var CodeLensRequest; +(function (CodeLensRequest) { + CodeLensRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/codeLens'); +})(CodeLensRequest = exports.CodeLensRequest || (exports.CodeLensRequest = {})); +/** + * A request to resolve a command for a given code lens. + */ +var CodeLensResolveRequest; +(function (CodeLensResolveRequest) { + CodeLensResolveRequest.type = new vscode_jsonrpc_1.RequestType('codeLens/resolve'); +})(CodeLensResolveRequest = exports.CodeLensResolveRequest || (exports.CodeLensResolveRequest = {})); +/** + * A request to to format a whole document. + */ +var DocumentFormattingRequest; +(function (DocumentFormattingRequest) { + DocumentFormattingRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/formatting'); +})(DocumentFormattingRequest = exports.DocumentFormattingRequest || (exports.DocumentFormattingRequest = {})); +/** + * A request to to format a range in a document. + */ +var DocumentRangeFormattingRequest; +(function (DocumentRangeFormattingRequest) { + DocumentRangeFormattingRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/rangeFormatting'); +})(DocumentRangeFormattingRequest = exports.DocumentRangeFormattingRequest || (exports.DocumentRangeFormattingRequest = {})); +/** + * A request to format a document on type. + */ +var DocumentOnTypeFormattingRequest; +(function (DocumentOnTypeFormattingRequest) { + DocumentOnTypeFormattingRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/onTypeFormatting'); +})(DocumentOnTypeFormattingRequest = exports.DocumentOnTypeFormattingRequest || (exports.DocumentOnTypeFormattingRequest = {})); +/** + * A request to rename a symbol. + */ +var RenameRequest; +(function (RenameRequest) { + RenameRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/rename'); +})(RenameRequest = exports.RenameRequest || (exports.RenameRequest = {})); +/** + * A request to test and perform the setup necessary for a rename. + */ +var PrepareRenameRequest; +(function (PrepareRenameRequest) { + PrepareRenameRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/prepareRename'); +})(PrepareRenameRequest = exports.PrepareRenameRequest || (exports.PrepareRenameRequest = {})); +/** + * A request to provide document links + */ +var DocumentLinkRequest; +(function (DocumentLinkRequest) { + DocumentLinkRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/documentLink'); +})(DocumentLinkRequest = exports.DocumentLinkRequest || (exports.DocumentLinkRequest = {})); +/** + * Request to resolve additional information for a given document link. The request's + * parameter is of type [DocumentLink](#DocumentLink) the response + * is of type [DocumentLink](#DocumentLink) or a Thenable that resolves to such. + */ +var DocumentLinkResolveRequest; +(function (DocumentLinkResolveRequest) { + DocumentLinkResolveRequest.type = new vscode_jsonrpc_1.RequestType('documentLink/resolve'); +})(DocumentLinkResolveRequest = exports.DocumentLinkResolveRequest || (exports.DocumentLinkResolveRequest = {})); +/** + * A request send from the client to the server to execute a command. The request might return + * a workspace edit which the client will apply to the workspace. + */ +var ExecuteCommandRequest; +(function (ExecuteCommandRequest) { + ExecuteCommandRequest.type = new vscode_jsonrpc_1.RequestType('workspace/executeCommand'); +})(ExecuteCommandRequest = exports.ExecuteCommandRequest || (exports.ExecuteCommandRequest = {})); +/** + * A request sent from the server to the client to modified certain resources. + */ +var ApplyWorkspaceEditRequest; +(function (ApplyWorkspaceEditRequest) { + ApplyWorkspaceEditRequest.type = new vscode_jsonrpc_1.RequestType('workspace/applyEdit'); +})(ApplyWorkspaceEditRequest = exports.ApplyWorkspaceEditRequest || (exports.ApplyWorkspaceEditRequest = {})); + + +/***/ }), +/* 163 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +function boolean(value) { + return value === true || value === false; +} +exports.boolean = boolean; +function string(value) { + return typeof value === 'string' || value instanceof String; +} +exports.string = string; +function number(value) { + return typeof value === 'number' || value instanceof Number; +} +exports.number = number; +function error(value) { + return value instanceof Error; +} +exports.error = error; +function func(value) { + return typeof value === 'function'; +} +exports.func = func; +function array(value) { + return Array.isArray(value); +} +exports.array = array; +function stringArray(value) { + return array(value) && value.every(elem => string(elem)); +} +exports.stringArray = stringArray; +function typedArray(value, check) { + return Array.isArray(value) && value.every(check); +} +exports.typedArray = typedArray; +function thenable(value) { + return value && func(value.then); +} +exports.thenable = thenable; + + +/***/ }), +/* 164 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_jsonrpc_1 = __webpack_require__(150); +// @ts-ignore: to avoid inlining LocatioLink as dynamic import +let __noDynamicImport; +/** + * A request to resolve the implementation locations of a symbol at a given text + * document position. The request's parameter is of type [TextDocumentPositioParams] + * (#TextDocumentPositionParams) the response is of type [Definition](#Definition) or a + * Thenable that resolves to such. + */ +var ImplementationRequest; +(function (ImplementationRequest) { + ImplementationRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/implementation'); +})(ImplementationRequest = exports.ImplementationRequest || (exports.ImplementationRequest = {})); + + +/***/ }), +/* 165 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_jsonrpc_1 = __webpack_require__(150); +// @ts-ignore: to avoid inlining LocatioLink as dynamic import +let __noDynamicImport; +/** + * A request to resolve the type definition locations of a symbol at a given text + * document position. The request's parameter is of type [TextDocumentPositioParams] + * (#TextDocumentPositionParams) the response is of type [Definition](#Definition) or a + * Thenable that resolves to such. + */ +var TypeDefinitionRequest; +(function (TypeDefinitionRequest) { + TypeDefinitionRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/typeDefinition'); +})(TypeDefinitionRequest = exports.TypeDefinitionRequest || (exports.TypeDefinitionRequest = {})); + + +/***/ }), +/* 166 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_jsonrpc_1 = __webpack_require__(150); +/** + * The `workspace/workspaceFolders` is sent from the server to the client to fetch the open workspace folders. + */ +var WorkspaceFoldersRequest; +(function (WorkspaceFoldersRequest) { + WorkspaceFoldersRequest.type = new vscode_jsonrpc_1.RequestType0('workspace/workspaceFolders'); +})(WorkspaceFoldersRequest = exports.WorkspaceFoldersRequest || (exports.WorkspaceFoldersRequest = {})); +/** + * The `workspace/didChangeWorkspaceFolders` notification is sent from the client to the server when the workspace + * folder configuration changes. + */ +var DidChangeWorkspaceFoldersNotification; +(function (DidChangeWorkspaceFoldersNotification) { + DidChangeWorkspaceFoldersNotification.type = new vscode_jsonrpc_1.NotificationType('workspace/didChangeWorkspaceFolders'); +})(DidChangeWorkspaceFoldersNotification = exports.DidChangeWorkspaceFoldersNotification || (exports.DidChangeWorkspaceFoldersNotification = {})); + + +/***/ }), +/* 167 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_jsonrpc_1 = __webpack_require__(150); +/** + * The 'workspace/configuration' request is sent from the server to the client to fetch a certain + * configuration setting. + * + * This pull model replaces the old push model were the client signaled configuration change via an + * event. If the server still needs to react to configuration changes (since the server caches the + * result of `workspace/configuration` requests) the server should register for an empty configuration + * change event and empty the cache if such an event is received. + */ +var ConfigurationRequest; +(function (ConfigurationRequest) { + ConfigurationRequest.type = new vscode_jsonrpc_1.RequestType('workspace/configuration'); +})(ConfigurationRequest = exports.ConfigurationRequest || (exports.ConfigurationRequest = {})); + + +/***/ }), +/* 168 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_jsonrpc_1 = __webpack_require__(150); +/** + * A request to list all color symbols found in a given text document. The request's + * parameter is of type [DocumentColorParams](#DocumentColorParams) the + * response is of type [ColorInformation[]](#ColorInformation) or a Thenable + * that resolves to such. + */ +var DocumentColorRequest; +(function (DocumentColorRequest) { + DocumentColorRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/documentColor'); +})(DocumentColorRequest = exports.DocumentColorRequest || (exports.DocumentColorRequest = {})); +/** + * A request to list all presentation for a color. The request's + * parameter is of type [ColorPresentationParams](#ColorPresentationParams) the + * response is of type [ColorInformation[]](#ColorInformation) or a Thenable + * that resolves to such. + */ +var ColorPresentationRequest; +(function (ColorPresentationRequest) { + ColorPresentationRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/colorPresentation'); +})(ColorPresentationRequest = exports.ColorPresentationRequest || (exports.ColorPresentationRequest = {})); + + +/***/ }), +/* 169 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_jsonrpc_1 = __webpack_require__(150); +/** + * Enum of known range kinds + */ +var FoldingRangeKind; +(function (FoldingRangeKind) { + /** + * Folding range for a comment + */ + FoldingRangeKind["Comment"] = "comment"; + /** + * Folding range for a imports or includes + */ + FoldingRangeKind["Imports"] = "imports"; + /** + * Folding range for a region (e.g. `#region`) + */ + FoldingRangeKind["Region"] = "region"; +})(FoldingRangeKind = exports.FoldingRangeKind || (exports.FoldingRangeKind = {})); +/** + * A request to provide folding ranges in a document. The request's + * parameter is of type [FoldingRangeParams](#FoldingRangeParams), the + * response is of type [FoldingRangeList](#FoldingRangeList) or a Thenable + * that resolves to such. + */ +var FoldingRangeRequest; +(function (FoldingRangeRequest) { + FoldingRangeRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/foldingRange'); +})(FoldingRangeRequest = exports.FoldingRangeRequest || (exports.FoldingRangeRequest = {})); + + +/***/ }), +/* 170 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_jsonrpc_1 = __webpack_require__(150); +// @ts-ignore: to avoid inlining LocatioLink as dynamic import +let __noDynamicImport; +/** + * A request to resolve the type definition locations of a symbol at a given text + * document position. The request's parameter is of type [TextDocumentPositioParams] + * (#TextDocumentPositionParams) the response is of type [Declaration](#Declaration) + * or a typed array of [DeclarationLink](#DeclarationLink) or a Thenable that resolves + * to such. + */ +var DeclarationRequest; +(function (DeclarationRequest) { + DeclarationRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/declaration'); +})(DeclarationRequest = exports.DeclarationRequest || (exports.DeclarationRequest = {})); + + +/***/ }), +/* 171 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_jsonrpc_1 = __webpack_require__(150); +/** + * A request to provide selection ranges in a document. The request's + * parameter is of type [SelectionRangeParams](#SelectionRangeParams), the + * response is of type [SelectionRange[]](#SelectionRange[]) or a Thenable + * that resolves to such. + */ +var SelectionRangeRequest; +(function (SelectionRangeRequest) { + SelectionRangeRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/selectionRange'); +})(SelectionRangeRequest = exports.SelectionRangeRequest || (exports.SelectionRangeRequest = {})); + + +/***/ }), +/* 172 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) TypeFox and others. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_jsonrpc_1 = __webpack_require__(150); +/** + * The direction of a call hierarchy request. + */ +var CallHierarchyDirection; +(function (CallHierarchyDirection) { + /** + * The callers + */ + CallHierarchyDirection.CallsFrom = 1; + /** + * The callees + */ + CallHierarchyDirection.CallsTo = 2; +})(CallHierarchyDirection = exports.CallHierarchyDirection || (exports.CallHierarchyDirection = {})); +/** + * Request to provide the call hierarchy at a given text document position. + * + * The request's parameter is of type [CallHierarchyParams](#CallHierarchyParams). The response + * is of type [CallHierarchyCall[]](#CallHierarchyCall) or a Thenable that resolves to such. + * + * Evaluates the symbol defined (or referenced) at the given position, and returns all incoming or outgoing calls to the symbol(s). + */ +var CallHierarchyRequest; +(function (CallHierarchyRequest) { + CallHierarchyRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/callHierarchy'); +})(CallHierarchyRequest = exports.CallHierarchyRequest || (exports.CallHierarchyRequest = {})); + + +/***/ }), +/* 173 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_jsonrpc_1 = __webpack_require__(150); +/** + * The `window/progress/start` notification is sent from the server to the client + * to initiate a progress. + */ +var ProgressStartNotification; +(function (ProgressStartNotification) { + ProgressStartNotification.type = new vscode_jsonrpc_1.NotificationType('window/progress/start'); +})(ProgressStartNotification = exports.ProgressStartNotification || (exports.ProgressStartNotification = {})); +/** + * The `window/progress/report` notification is sent from the server to the client + * to initiate a progress. + */ +var ProgressReportNotification; +(function (ProgressReportNotification) { + ProgressReportNotification.type = new vscode_jsonrpc_1.NotificationType('window/progress/report'); +})(ProgressReportNotification = exports.ProgressReportNotification || (exports.ProgressReportNotification = {})); +/** + * The `window/progress/done` notification is sent from the server to the client + * to initiate a progress. + */ +var ProgressDoneNotification; +(function (ProgressDoneNotification) { + ProgressDoneNotification.type = new vscode_jsonrpc_1.NotificationType('window/progress/done'); +})(ProgressDoneNotification = exports.ProgressDoneNotification || (exports.ProgressDoneNotification = {})); +/** + * The `window/progress/cancel` notification is sent client to the server to cancel a progress + * initiated on the server side. + */ +var ProgressCancelNotification; +(function (ProgressCancelNotification) { + ProgressCancelNotification.type = new vscode_jsonrpc_1.NotificationType('window/progress/cancel'); +})(ProgressCancelNotification = exports.ProgressCancelNotification || (exports.ProgressCancelNotification = {})); + + +/***/ }), +/* 174 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const child_process_1 = __webpack_require__(175); +const debounce_1 = tslib_1.__importDefault(__webpack_require__(176)); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const isuri_1 = tslib_1.__importDefault(__webpack_require__(177)); +const mkdirp_1 = tslib_1.__importDefault(__webpack_require__(179)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const vscode_uri_1 = __webpack_require__(180); +const which_1 = tslib_1.__importDefault(__webpack_require__(181)); +const platform = tslib_1.__importStar(__webpack_require__(185)); +exports.platform = platform; +const logger = __webpack_require__(186)('util-index'); +const prefix = '[coc.nvim] '; +function escapeSingleQuote(str) { + return str.replace(/'/g, "''"); +} +exports.escapeSingleQuote = escapeSingleQuote; +function echoErr(nvim, msg) { + echoMsg(nvim, prefix + msg, 'Error'); // tslint:disable-line +} +exports.echoErr = echoErr; +function echoWarning(nvim, msg) { + echoMsg(nvim, prefix + msg, 'WarningMsg'); // tslint:disable-line +} +exports.echoWarning = echoWarning; +function echoMessage(nvim, msg) { + echoMsg(nvim, prefix + msg, 'MoreMsg'); // tslint:disable-line +} +exports.echoMessage = echoMessage; +function wait(ms) { + return new Promise(resolve => { + setTimeout(() => { + resolve(); + }, ms); + }); +} +exports.wait = wait; +function echoMsg(nvim, msg, hl) { + let method = process.env.VIM_NODE_RPC == '1' ? 'callTimer' : 'call'; + nvim[method]('coc#util#echo_messages', [hl, msg.split('\n')], true); +} +function getUri(fullpath, id, buftype, isCygwin) { + if (!fullpath) + return `untitled:${id}`; + if (platform.isWindows && !isCygwin) + fullpath = path_1.default.win32.normalize(fullpath); + if (path_1.default.isAbsolute(fullpath)) + return vscode_uri_1.URI.file(fullpath).toString(); + if (isuri_1.default.isValid(fullpath)) + return vscode_uri_1.URI.parse(fullpath).toString(); + if (buftype != '') + return `${buftype}:${id}`; + return `unknown:${id}`; +} +exports.getUri = getUri; +function disposeAll(disposables) { + while (disposables.length) { + const item = disposables.pop(); + if (item) { + item.dispose(); + } + } +} +exports.disposeAll = disposeAll; +function executable(command) { + try { + which_1.default.sync(command); + } + catch (e) { + return false; + } + return true; +} +exports.executable = executable; +function runCommand(cmd, opts = {}, timeout) { + if (!platform.isWindows) { + opts.shell = opts.shell || process.env.SHELL; + } + return new Promise((resolve, reject) => { + let timer; + if (timeout) { + timer = setTimeout(() => { + reject(new Error(`timeout after ${timeout}s`)); + }, timeout * 1000); + } + child_process_1.exec(cmd, opts, (err, stdout, stderr) => { + if (timer) + clearTimeout(timer); + if (err) { + reject(new Error(`exited with ${err.code}\n${err}\n${stderr}`)); + return; + } + resolve(stdout); + }); + }); +} +exports.runCommand = runCommand; +function watchFile(filepath, onChange) { + let callback = debounce_1.default(onChange, 100); + try { + let watcher = fs_1.default.watch(filepath, { + persistent: true, + recursive: false, + encoding: 'utf8' + }, () => { + callback(); + }); + return vscode_languageserver_protocol_1.Disposable.create(() => { + watcher.close(); + }); + } + catch (e) { + return vscode_languageserver_protocol_1.Disposable.create(() => { + // noop + }); + } +} +exports.watchFile = watchFile; +function isRunning(pid) { + try { + let res = process.kill(pid, 0); + return res == true; + } + catch (e) { + return e.code === 'EPERM'; + } +} +exports.isRunning = isRunning; +function getKeymapModifier(mode) { + if (mode == 'o' || mode == 'x' || mode == 'v') + return ''; + if (mode == 'n') + return ''; + if (mode == 'i') + return ''; + if (mode == 's') + return ''; + return ''; +} +exports.getKeymapModifier = getKeymapModifier; +async function mkdirp(path, mode) { + return new Promise(resolve => { + mkdirp_1.default(path, { mode }, err => { + if (err) + return resolve(false); + resolve(true); + }); + }); +} +exports.mkdirp = mkdirp; +// consider textDocument without version to be valid +function isDocumentEdit(edit) { + if (edit == null) + return false; + if (!vscode_languageserver_protocol_1.TextDocumentIdentifier.is(edit.textDocument)) + return false; + if (!Array.isArray(edit.edits)) + return false; + return true; +} +exports.isDocumentEdit = isDocumentEdit; +function concurrent(fns, limit = Infinity) { + if (fns.length == 0) + return Promise.resolve([]); + return new Promise((resolve, rejrect) => { + let remain = fns.slice(); + let results = []; + let next = () => { + if (remain.length == 0) { + return resolve(results); + } + let list = remain.splice(0, limit); + Promise.all(list.map(fn => fn())).then(res => { + results.push(...res); + next(); + }, rejrect); + }; + next(); + }); +} +exports.concurrent = concurrent; +//# sourceMappingURL=index.js.map + +/***/ }), +/* 175 */ +/***/ (function(module, exports) { + +module.exports = require("child_process"); + +/***/ }), +/* 176 */ +/***/ (function(module, exports) { + +/** + * Returns a function, that, as long as it continues to be invoked, will not + * be triggered. The function will be called after it stops being called for + * N milliseconds. If `immediate` is passed, trigger the function on the + * leading edge, instead of the trailing. The function also has a property 'clear' + * that is a function which will clear the timer to prevent previously scheduled executions. + * + * @source underscore.js + * @see http://unscriptable.com/2009/03/20/debouncing-javascript-methods/ + * @param {Function} function to wrap + * @param {Number} timeout in ms (`100`) + * @param {Boolean} whether to execute at the beginning (`false`) + * @api public + */ +function debounce(func, wait, immediate){ + var timeout, args, context, timestamp, result; + if (null == wait) wait = 100; + + function later() { + var last = Date.now() - timestamp; + + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + context = args = null; + } + } + }; + + var debounced = function(){ + context = this; + args = arguments; + timestamp = Date.now(); + var callNow = immediate && !timeout; + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + + debounced.clear = function() { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + }; + + debounced.flush = function() { + if (timeout) { + result = func.apply(context, args); + context = args = null; + + clearTimeout(timeout); + timeout = null; + } + }; + + return debounced; +}; + +// Adds compatibility for ES modules +debounce.debounce = debounce; + +module.exports = debounce; + + +/***/ }), +/* 177 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var rfc3986 = __webpack_require__(178); + +// See: https://github.com/hapijs/hoek/blob/f62961d3d07aca68ab11480893e6e80a421914b4/lib/index.js#L783-L787 +function escapeRegex(string) { + // Escape ^$.*+-?=!:|\/()[]{}, + return string.replace(/[\^\$\.\*\+\-\?\=\!\:\|\\\/\(\)\[\]\{\}\,]/g, '\\$&'); +} + +var internals = { + Uri: { + createUriRegex: function (options) { + options = options || {}; + + if (typeof options !== 'object' || Array.isArray(options)) { + throw new Error('options must be an object'); + } + + var customScheme = ''; + + // If we were passed a scheme, use it instead of the generic one + if (options.scheme) { + if (!Array.isArray(options.scheme)) { + options.scheme = [options.scheme]; + } + + if (options.scheme.length <= 0) { + throw new Error('scheme must have at least 1 scheme specified'); + } + + for (var i = 0; i < options.scheme.length; ++i) { + var currentScheme = options.scheme[i]; + + if (!(currentScheme instanceof RegExp || typeof currentScheme === 'string')) { + throw new Error('scheme must only contain Regular Expressions or Strings'); + } + + // Add OR separators if a value already exists + customScheme = customScheme + (customScheme ? '|' : ''); + + // If someone wants to match HTTP or HTTPS for example then we need to support both RegExp and String so we don't escape their pattern unknowingly. + if (currentScheme instanceof RegExp) { + customScheme = customScheme + currentScheme.source; + } else { + if (!/[a-zA-Z][a-zA-Z0-9+-\.]*/.test(currentScheme)) { + throw new Error('scheme at position ' + i + ' must be a valid scheme'); + } + customScheme = customScheme + escapeRegex(currentScheme); + } + } + + } + + // Have to put this in a non-capturing group to handle the OR statements + var scheme = '(?:' + (customScheme || rfc3986.scheme) + ')'; + + /** + * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] + * + * OR + * + * relative-ref = relative-part [ "?" query ] [ "#" fragment ] + */ + return new RegExp('^(?:' + scheme + ':' + rfc3986.hierPart + ')(?:\\?' + rfc3986.query + ')?(?:#' + rfc3986.fragment + ')?$'); + }, + uriRegex: new RegExp(rfc3986.uri) + } +}; + +internals.Uri.isValid = function (val) { + return internals.Uri.uriRegex.test(val); +}; + +module.exports = { + createUriRegex: internals.Uri.createUriRegex, + + uriRegex: internals.Uri.uriRegex, + isValid: internals.Uri.isValid +}; + +/***/ }), +/* 178 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// Load modules + +// Delcare internals + +var internals = { + rfc3986: {} +}; + +internals.generate = function () { + + /** + * elements separated by forward slash ("/") are alternatives. + */ + var or = '|'; + + /** + * DIGIT = %x30-39 ; 0-9 + */ + var digit = '0-9'; + var digitOnly = '[' + digit + ']'; + + /** + * ALPHA = %x41-5A / %x61-7A ; A-Z / a-z + */ + var alpha = 'a-zA-Z'; + var alphaOnly = '[' + alpha + ']'; + + /** + * cidr = DIGIT ; 0-9 + * / %x31-32 DIGIT ; 10-29 + * / "3" %x30-32 ; 30-32 + */ + internals.rfc3986.cidr = digitOnly + or + '[1-2]' + digitOnly + or + '3' + '[0-2]'; + + /** + * HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" + */ + var hexDigit = digit + 'A-Fa-f'; + var hexDigitOnly = '[' + hexDigit + ']'; + + /** + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + */ + var unreserved = alpha + digit + '-\\._~'; + + /** + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" + */ + var subDelims = '!\\$&\'\\(\\)\\*\\+,;='; + + /** + * pct-encoded = "%" HEXDIG HEXDIG + */ + var pctEncoded = '%' + hexDigit; + + /** + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + */ + var pchar = unreserved + pctEncoded + subDelims + ':@'; + var pcharOnly = '[' + pchar + ']'; + + /** + * Rule to support zero-padded addresses. + */ + var zeroPad = '0?'; + + /** + * dec-octet = DIGIT ; 0-9 + * / %x31-39 DIGIT ; 10-99 + * / "1" 2DIGIT ; 100-199 + * / "2" %x30-34 DIGIT ; 200-249 + * / "25" %x30-35 ; 250-255 + */ + var decOctect = '(?:' + zeroPad + zeroPad + digitOnly + or + zeroPad + '[1-9]' + digitOnly + or + '1' + digitOnly + digitOnly + or + '2' + '[0-4]' + digitOnly + or + '25' + '[0-5])'; + + /** + * IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet + */ + internals.rfc3986.IPv4address = '(?:' + decOctect + '\\.){3}' + decOctect; + + /** + * h16 = 1*4HEXDIG ; 16 bits of address represented in hexadecimal + * ls32 = ( h16 ":" h16 ) / IPv4address ; least-significant 32 bits of address + * IPv6address = 6( h16 ":" ) ls32 + * / "::" 5( h16 ":" ) ls32 + * / [ h16 ] "::" 4( h16 ":" ) ls32 + * / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 + * / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 + * / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 + * / [ *4( h16 ":" ) h16 ] "::" ls32 + * / [ *5( h16 ":" ) h16 ] "::" h16 + * / [ *6( h16 ":" ) h16 ] "::" + */ + var h16 = hexDigitOnly + '{1,4}'; + var ls32 = '(?:' + h16 + ':' + h16 + '|' + internals.rfc3986.IPv4address + ')'; + var IPv6SixHex = '(?:' + h16 + ':){6}' + ls32; + var IPv6FiveHex = '::(?:' + h16 + ':){5}' + ls32; + var IPv6FourHex = '(?:' + h16 + ')?::(?:' + h16 + ':){4}' + ls32; + var IPv6ThreeHex = '(?:(?:' + h16 + ':){0,1}' + h16 + ')?::(?:' + h16 + ':){3}' + ls32; + var IPv6TwoHex = '(?:(?:' + h16 + ':){0,2}' + h16 + ')?::(?:' + h16 + ':){2}' + ls32; + var IPv6OneHex = '(?:(?:' + h16 + ':){0,3}' + h16 + ')?::' + h16 + ':' + ls32; + var IPv6NoneHex = '(?:(?:' + h16 + ':){0,4}' + h16 + ')?::' + ls32; + var IPv6NoneHex2 = '(?:(?:' + h16 + ':){0,5}' + h16 + ')?::' + h16; + var IPv6NoneHex3 = '(?:(?:' + h16 + ':){0,6}' + h16 + ')?::'; + internals.rfc3986.IPv6address = '(?:' + IPv6SixHex + or + IPv6FiveHex + or + IPv6FourHex + or + IPv6ThreeHex + or + IPv6TwoHex + or + IPv6OneHex + or + IPv6NoneHex + or + IPv6NoneHex2 + or + IPv6NoneHex3 + ')'; + + /** + * IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) + */ + internals.rfc3986.IPvFuture = 'v' + hexDigitOnly + '+\\.[' + unreserved + subDelims + ':]+'; + + /** + * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + */ + internals.rfc3986.scheme = alphaOnly + '[' + alpha + digit + '+-\\.]*'; + + /** + * userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) + */ + var userinfo = '[' + unreserved + pctEncoded + subDelims + ':]*'; + + /** + * IP-literal = "[" ( IPv6address / IPvFuture ) "]" + */ + internals.rfc3986.IPLiteral = '\\[(?:' + internals.rfc3986.IPv6address + or + internals.rfc3986.IPvFuture + ')\\]'; + + /** + * reg-name = *( unreserved / pct-encoded / sub-delims ) + */ + var regName = '[' + unreserved + pctEncoded + subDelims + ']{0,255}'; + + /** + * host = IP-literal / IPv4address / reg-name + */ + var host = '(?:' + internals.rfc3986.IPLiteral + or + internals.rfc3986.IPv4address + or + regName + ')'; + + /** + * port = *DIGIT + */ + var port = digitOnly + '*'; + + /** + * authority = [ userinfo "@" ] host [ ":" port ] + */ + var authority = '(?:' + userinfo + '@)?' + host + '(?::' + port + ')?'; + + /** + * segment = *pchar + * segment-nz = 1*pchar + * path = path-abempty ; begins with "/" or is empty + * / path-absolute ; begins with "/" but not "//" + * / path-noscheme ; begins with a non-colon segment + * / path-rootless ; begins with a segment + * / path-empty ; zero characters + * path-abempty = *( "/" segment ) + * path-absolute = "/" [ segment-nz *( "/" segment ) ] + * path-rootless = segment-nz *( "/" segment ) + */ + var segment = pcharOnly + '*'; + var segmentNz = pcharOnly + '+'; + var pathAbEmpty = '(?:\\/' + segment + ')*'; + var pathAbsolute = '\\/(?:' + segmentNz + pathAbEmpty + ')?'; + var pathRootless = segmentNz + pathAbEmpty; + + /** + * hier-part = "//" authority path + */ + internals.rfc3986.hierPart = '(?:' + '(?:\\/\\/' + authority + pathAbEmpty + ')' + or + pathAbsolute + or + pathRootless + ')'; + + /** + * query = *( pchar / "/" / "?" ) + */ + internals.rfc3986.query = '[' + pchar + '\\/\\?]*(?=#|$)'; //Finish matching either at the fragment part or end of the line. + + /** + * fragment = *( pchar / "/" / "?" ) + */ + internals.rfc3986.fragment = '[' + pchar + '\\/\\?]*'; + + /** + * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] + * + * OR + * + * relative-ref = relative-part [ "?" query ] [ "#" fragment ] + */ + internals.rfc3986.uri = '^(?:' + internals.rfc3986.scheme + ':' + internals.rfc3986.hierPart + ')(?:\\?' + internals.rfc3986.query + ')?' + '(?:#' + internals.rfc3986.fragment + ')?$'; +}; + +internals.generate(); + +module.exports = internals.rfc3986; + +/***/ }), +/* 179 */ +/***/ (function(module, exports, __webpack_require__) { + +var path = __webpack_require__(57); +var fs = __webpack_require__(55); +var _0777 = parseInt('0777', 8); + +module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + +function mkdirP (p, opts, f, made) { + if (typeof opts === 'function') { + f = opts; + opts = {}; + } + else if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = _0777 & (~process.umask()); + } + if (!made) made = null; + + var cb = f || function () {}; + p = path.resolve(p); + + xfs.mkdir(p, mode, function (er) { + if (!er) { + made = made || p; + return cb(null, made); + } + switch (er.code) { + case 'ENOENT': + mkdirP(path.dirname(p), opts, function (er, made) { + if (er) cb(er, made); + else mkdirP(p, opts, cb, made); + }); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + xfs.stat(p, function (er2, stat) { + // if the stat fails, then that's super weird. + // let the original error be the failure reason. + if (er2 || !stat.isDirectory()) cb(er, made) + else cb(null, made); + }); + break; + } + }); +} + +mkdirP.sync = function sync (p, opts, made) { + if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = _0777 & (~process.umask()); + } + if (!made) made = null; + + p = path.resolve(p); + + try { + xfs.mkdirSync(p, mode); + made = made || p; + } + catch (err0) { + switch (err0.code) { + case 'ENOENT' : + made = sync(path.dirname(p), opts, made); + sync(p, opts, made); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + var stat; + try { + stat = xfs.statSync(p); + } + catch (err1) { + throw err0; + } + if (!stat.isDirectory()) throw err0; + break; + } + } + + return made; +}; + + +/***/ }), +/* 180 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setUriThrowOnMissingScheme", function() { return setUriThrowOnMissingScheme; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "URI", function() { return URI; }); +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +var __extends = (undefined && undefined.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var isWindows; +if (typeof process === 'object') { + isWindows = process.platform === 'win32'; +} +else if (typeof navigator === 'object') { + var userAgent = navigator.userAgent; + isWindows = userAgent.indexOf('Windows') >= 0; +} +//#endregion +var _schemePattern = /^\w[\w\d+.-]*$/; +var _singleSlashStart = /^\//; +var _doubleSlashStart = /^\/\//; +var _throwOnMissingSchema = true; +/** + * @internal + */ +function setUriThrowOnMissingScheme(value) { + var old = _throwOnMissingSchema; + _throwOnMissingSchema = value; + return old; +} +function _validateUri(ret, _strict) { + // scheme, must be set + if (!ret.scheme) { + if (_strict || _throwOnMissingSchema) { + throw new Error("[UriError]: Scheme is missing: {scheme: \"\", authority: \"" + ret.authority + "\", path: \"" + ret.path + "\", query: \"" + ret.query + "\", fragment: \"" + ret.fragment + "\"}"); + } + else { + // console.warn(`[UriError]: Scheme is missing: {scheme: "", authority: "${ret.authority}", path: "${ret.path}", query: "${ret.query}", fragment: "${ret.fragment}"}`); + } + } + // scheme, https://tools.ietf.org/html/rfc3986#section-3.1 + // ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + if (ret.scheme && !_schemePattern.test(ret.scheme)) { + throw new Error('[UriError]: Scheme contains illegal characters.'); + } + // path, http://tools.ietf.org/html/rfc3986#section-3.3 + // If a URI contains an authority component, then the path component + // must either be empty or begin with a slash ("/") character. If a URI + // does not contain an authority component, then the path cannot begin + // with two slash characters ("//"). + if (ret.path) { + if (ret.authority) { + if (!_singleSlashStart.test(ret.path)) { + throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character'); + } + } + else { + if (_doubleSlashStart.test(ret.path)) { + throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")'); + } + } + } +} +// for a while we allowed uris *without* schemes and this is the migration +// for them, e.g. an uri without scheme and without strict-mode warns and falls +// back to the file-scheme. that should cause the least carnage and still be a +// clear warning +function _schemeFix(scheme, _strict) { + if (_strict || _throwOnMissingSchema) { + return scheme || _empty; + } + if (!scheme) { + // console.trace('BAD uri lacks scheme, falling back to file-scheme.'); + scheme = 'file'; + } + return scheme; +} +// implements a bit of https://tools.ietf.org/html/rfc3986#section-5 +function _referenceResolution(scheme, path) { + // the slash-character is our 'default base' as we don't + // support constructing URIs relative to other URIs. This + // also means that we alter and potentially break paths. + // see https://tools.ietf.org/html/rfc3986#section-5.1.4 + switch (scheme) { + case 'https': + case 'http': + case 'file': + if (!path) { + path = _slash; + } + else if (path[0] !== _slash) { + path = _slash + path; + } + break; + } + return path; +} +var _empty = ''; +var _slash = '/'; +var _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/; +/** + * Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986. + * This class is a simple parser which creates the basic component parts + * (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation + * and encoding. + * + * foo://example.com:8042/over/there?name=ferret#nose + * \_/ \______________/\_________/ \_________/ \__/ + * | | | | | + * scheme authority path query fragment + * | _____________________|__ + * / \ / \ + * urn:example:animal:ferret:nose + */ +var URI = (function () { + /** + * @internal + */ + function URI(schemeOrData, authority, path, query, fragment, _strict) { + if (_strict === void 0) { _strict = false; } + if (typeof schemeOrData === 'object') { + this.scheme = schemeOrData.scheme || _empty; + this.authority = schemeOrData.authority || _empty; + this.path = schemeOrData.path || _empty; + this.query = schemeOrData.query || _empty; + this.fragment = schemeOrData.fragment || _empty; + // no validation because it's this URI + // that creates uri components. + // _validateUri(this); + } + else { + this.scheme = _schemeFix(schemeOrData, _strict); + this.authority = authority || _empty; + this.path = _referenceResolution(this.scheme, path || _empty); + this.query = query || _empty; + this.fragment = fragment || _empty; + _validateUri(this, _strict); + } + } + URI.isUri = function (thing) { + if (thing instanceof URI) { + return true; + } + if (!thing) { + return false; + } + return typeof thing.authority === 'string' + && typeof thing.fragment === 'string' + && typeof thing.path === 'string' + && typeof thing.query === 'string' + && typeof thing.scheme === 'string' + && typeof thing.fsPath === 'function' + && typeof thing.with === 'function' + && typeof thing.toString === 'function'; + }; + Object.defineProperty(URI.prototype, "fsPath", { + // ---- filesystem path ----------------------- + /** + * Returns a string representing the corresponding file system path of this URI. + * Will handle UNC paths, normalizes windows drive letters to lower-case, and uses the + * platform specific path separator. + * + * * Will *not* validate the path for invalid characters and semantics. + * * Will *not* look at the scheme of this URI. + * * The result shall *not* be used for display purposes but for accessing a file on disk. + * + * + * The *difference* to `URI#path` is the use of the platform specific separator and the handling + * of UNC paths. See the below sample of a file-uri with an authority (UNC path). + * + * ```ts + const u = URI.parse('file://server/c$/folder/file.txt') + u.authority === 'server' + u.path === '/shares/c$/file.txt' + u.fsPath === '\\server\c$\folder\file.txt' + ``` + * + * Using `URI#path` to read a file (using fs-apis) would not be enough because parts of the path, + * namely the server name, would be missing. Therefore `URI#fsPath` exists - it's sugar to ease working + * with URIs that represent files on disk (`file` scheme). + */ + get: function () { + // if (this.scheme !== 'file') { + // console.warn(`[UriError] calling fsPath with scheme ${this.scheme}`); + // } + return _makeFsPath(this); + }, + enumerable: true, + configurable: true + }); + // ---- modify to new ------------------------- + URI.prototype.with = function (change) { + if (!change) { + return this; + } + var scheme = change.scheme, authority = change.authority, path = change.path, query = change.query, fragment = change.fragment; + if (scheme === undefined) { + scheme = this.scheme; + } + else if (scheme === null) { + scheme = _empty; + } + if (authority === undefined) { + authority = this.authority; + } + else if (authority === null) { + authority = _empty; + } + if (path === undefined) { + path = this.path; + } + else if (path === null) { + path = _empty; + } + if (query === undefined) { + query = this.query; + } + else if (query === null) { + query = _empty; + } + if (fragment === undefined) { + fragment = this.fragment; + } + else if (fragment === null) { + fragment = _empty; + } + if (scheme === this.scheme + && authority === this.authority + && path === this.path + && query === this.query + && fragment === this.fragment) { + return this; + } + return new _URI(scheme, authority, path, query, fragment); + }; + // ---- parse & validate ------------------------ + /** + * Creates a new URI from a string, e.g. `http://www.msft.com/some/path`, + * `file:///usr/home`, or `scheme:with/path`. + * + * @param value A string which represents an URI (see `URI#toString`). + */ + URI.parse = function (value, _strict) { + if (_strict === void 0) { _strict = false; } + var match = _regexp.exec(value); + if (!match) { + return new _URI(_empty, _empty, _empty, _empty, _empty); + } + return new _URI(match[2] || _empty, decodeURIComponent(match[4] || _empty), decodeURIComponent(match[5] || _empty), decodeURIComponent(match[7] || _empty), decodeURIComponent(match[9] || _empty), _strict); + }; + /** + * Creates a new URI from a file system path, e.g. `c:\my\files`, + * `/usr/home`, or `\\server\share\some\path`. + * + * The *difference* between `URI#parse` and `URI#file` is that the latter treats the argument + * as path, not as stringified-uri. E.g. `URI.file(path)` is **not the same as** + * `URI.parse('file://' + path)` because the path might contain characters that are + * interpreted (# and ?). See the following sample: + * ```ts + const good = URI.file('/coding/c#/project1'); + good.scheme === 'file'; + good.path === '/coding/c#/project1'; + good.fragment === ''; + const bad = URI.parse('file://' + '/coding/c#/project1'); + bad.scheme === 'file'; + bad.path === '/coding/c'; // path is now broken + bad.fragment === '/project1'; + ``` + * + * @param path A file system path (see `URI#fsPath`) + */ + URI.file = function (path) { + var authority = _empty; + // normalize to fwd-slashes on windows, + // on other systems bwd-slashes are valid + // filename character, eg /f\oo/ba\r.txt + if (isWindows) { + path = path.replace(/\\/g, _slash); + } + // check for authority as used in UNC shares + // or use the path as given + if (path[0] === _slash && path[1] === _slash) { + var idx = path.indexOf(_slash, 2); + if (idx === -1) { + authority = path.substring(2); + path = _slash; + } + else { + authority = path.substring(2, idx); + path = path.substring(idx) || _slash; + } + } + return new _URI('file', authority, path, _empty, _empty); + }; + URI.from = function (components) { + return new _URI(components.scheme, components.authority, components.path, components.query, components.fragment); + }; + // ---- printing/externalize --------------------------- + /** + * Creates a string representation for this URI. It's guaranteed that calling + * `URI.parse` with the result of this function creates an URI which is equal + * to this URI. + * + * * The result shall *not* be used for display purposes but for externalization or transport. + * * The result will be encoded using the percentage encoding and encoding happens mostly + * ignore the scheme-specific encoding rules. + * + * @param skipEncoding Do not encode the result, default is `false` + */ + URI.prototype.toString = function (skipEncoding) { + if (skipEncoding === void 0) { skipEncoding = false; } + return _asFormatted(this, skipEncoding); + }; + URI.prototype.toJSON = function () { + return this; + }; + URI.revive = function (data) { + if (!data) { + return data; + } + else if (data instanceof URI) { + return data; + } + else { + var result = new _URI(data); + result._formatted = data.external; + result._fsPath = data._sep === _pathSepMarker ? data.fsPath : null; + return result; + } + }; + return URI; +}()); + +var _pathSepMarker = isWindows ? 1 : undefined; +// tslint:disable-next-line:class-name +var _URI = (function (_super) { + __extends(_URI, _super); + function _URI() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this._formatted = null; + _this._fsPath = null; + return _this; + } + Object.defineProperty(_URI.prototype, "fsPath", { + get: function () { + if (!this._fsPath) { + this._fsPath = _makeFsPath(this); + } + return this._fsPath; + }, + enumerable: true, + configurable: true + }); + _URI.prototype.toString = function (skipEncoding) { + if (skipEncoding === void 0) { skipEncoding = false; } + if (!skipEncoding) { + if (!this._formatted) { + this._formatted = _asFormatted(this, false); + } + return this._formatted; + } + else { + // we don't cache that + return _asFormatted(this, true); + } + }; + _URI.prototype.toJSON = function () { + var res = { + $mid: 1 + }; + // cached state + if (this._fsPath) { + res.fsPath = this._fsPath; + res._sep = _pathSepMarker; + } + if (this._formatted) { + res.external = this._formatted; + } + // uri components + if (this.path) { + res.path = this.path; + } + if (this.scheme) { + res.scheme = this.scheme; + } + if (this.authority) { + res.authority = this.authority; + } + if (this.query) { + res.query = this.query; + } + if (this.fragment) { + res.fragment = this.fragment; + } + return res; + }; + return _URI; +}(URI)); +// reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2 +var encodeTable = (_a = {}, + _a[58 /* Colon */] = '%3A', + _a[47 /* Slash */] = '%2F', + _a[63 /* QuestionMark */] = '%3F', + _a[35 /* Hash */] = '%23', + _a[91 /* OpenSquareBracket */] = '%5B', + _a[93 /* CloseSquareBracket */] = '%5D', + _a[64 /* AtSign */] = '%40', + _a[33 /* ExclamationMark */] = '%21', + _a[36 /* DollarSign */] = '%24', + _a[38 /* Ampersand */] = '%26', + _a[39 /* SingleQuote */] = '%27', + _a[40 /* OpenParen */] = '%28', + _a[41 /* CloseParen */] = '%29', + _a[42 /* Asterisk */] = '%2A', + _a[43 /* Plus */] = '%2B', + _a[44 /* Comma */] = '%2C', + _a[59 /* Semicolon */] = '%3B', + _a[61 /* Equals */] = '%3D', + _a[32 /* Space */] = '%20', + _a); +function encodeURIComponentFast(uriComponent, allowSlash) { + var res = undefined; + var nativeEncodePos = -1; + for (var pos = 0; pos < uriComponent.length; pos++) { + var code = uriComponent.charCodeAt(pos); + // unreserved characters: https://tools.ietf.org/html/rfc3986#section-2.3 + if ((code >= 97 /* a */ && code <= 122 /* z */) + || (code >= 65 /* A */ && code <= 90 /* Z */) + || (code >= 48 /* Digit0 */ && code <= 57 /* Digit9 */) + || code === 45 /* Dash */ + || code === 46 /* Period */ + || code === 95 /* Underline */ + || code === 126 /* Tilde */ + || (allowSlash && code === 47 /* Slash */)) { + // check if we are delaying native encode + if (nativeEncodePos !== -1) { + res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos)); + nativeEncodePos = -1; + } + // check if we write into a new string (by default we try to return the param) + if (res !== undefined) { + res += uriComponent.charAt(pos); + } + } + else { + // encoding needed, we need to allocate a new string + if (res === undefined) { + res = uriComponent.substr(0, pos); + } + // check with default table first + var escaped = encodeTable[code]; + if (escaped !== undefined) { + // check if we are delaying native encode + if (nativeEncodePos !== -1) { + res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos)); + nativeEncodePos = -1; + } + // append escaped variant to result + res += escaped; + } + else if (nativeEncodePos === -1) { + // use native encode only when needed + nativeEncodePos = pos; + } + } + } + if (nativeEncodePos !== -1) { + res += encodeURIComponent(uriComponent.substring(nativeEncodePos)); + } + return res !== undefined ? res : uriComponent; +} +function encodeURIComponentMinimal(path) { + var res = undefined; + for (var pos = 0; pos < path.length; pos++) { + var code = path.charCodeAt(pos); + if (code === 35 /* Hash */ || code === 63 /* QuestionMark */) { + if (res === undefined) { + res = path.substr(0, pos); + } + res += encodeTable[code]; + } + else { + if (res !== undefined) { + res += path[pos]; + } + } + } + return res !== undefined ? res : path; +} +/** + * Compute `fsPath` for the given uri + */ +function _makeFsPath(uri) { + var value; + if (uri.authority && uri.path.length > 1 && uri.scheme === 'file') { + // unc path: file://shares/c$/far/boo + value = "//" + uri.authority + uri.path; + } + else if (uri.path.charCodeAt(0) === 47 /* Slash */ + && (uri.path.charCodeAt(1) >= 65 /* A */ && uri.path.charCodeAt(1) <= 90 /* Z */ || uri.path.charCodeAt(1) >= 97 /* a */ && uri.path.charCodeAt(1) <= 122 /* z */) + && uri.path.charCodeAt(2) === 58 /* Colon */) { + // windows drive letter: file:///c:/far/boo + value = uri.path[1].toLowerCase() + uri.path.substr(2); + } + else { + // other path + value = uri.path; + } + if (isWindows) { + value = value.replace(/\//g, '\\'); + } + return value; +} +/** + * Create the external version of a uri + */ +function _asFormatted(uri, skipEncoding) { + var encoder = !skipEncoding + ? encodeURIComponentFast + : encodeURIComponentMinimal; + var res = ''; + var scheme = uri.scheme, authority = uri.authority, path = uri.path, query = uri.query, fragment = uri.fragment; + if (scheme) { + res += scheme; + res += ':'; + } + if (authority || scheme === 'file') { + res += _slash; + res += _slash; + } + if (authority) { + var idx = authority.indexOf('@'); + if (idx !== -1) { + // @ + var userinfo = authority.substr(0, idx); + authority = authority.substr(idx + 1); + idx = userinfo.indexOf(':'); + if (idx === -1) { + res += encoder(userinfo, false); + } + else { + // :@ + res += encoder(userinfo.substr(0, idx), false); + res += ':'; + res += encoder(userinfo.substr(idx + 1), false); + } + res += '@'; + } + authority = authority.toLowerCase(); + idx = authority.indexOf(':'); + if (idx === -1) { + res += encoder(authority, false); + } + else { + // : + res += encoder(authority.substr(0, idx), false); + res += authority.substr(idx); + } + } + if (path) { + // lower-case windows drive letters in /C:/fff or C:/fff + if (path.length >= 3 && path.charCodeAt(0) === 47 /* Slash */ && path.charCodeAt(2) === 58 /* Colon */) { + var code = path.charCodeAt(1); + if (code >= 65 /* A */ && code <= 90 /* Z */) { + path = "/" + String.fromCharCode(code + 32) + ":" + path.substr(3); // "/c:".length === 3 + } + } + else if (path.length >= 2 && path.charCodeAt(1) === 58 /* Colon */) { + var code = path.charCodeAt(0); + if (code >= 65 /* A */ && code <= 90 /* Z */) { + path = String.fromCharCode(code + 32) + ":" + path.substr(2); // "/c:".length === 3 + } + } + // encode the rest of the path + res += encoder(path, true); + } + if (query) { + res += '?'; + res += encoder(query, false); + } + if (fragment) { + res += '#'; + res += !skipEncoding ? encodeURIComponentFast(fragment, false) : fragment; + } + return res; +} +var _a; + + +/***/ }), +/* 181 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = which +which.sync = whichSync + +var isWindows = process.platform === 'win32' || + process.env.OSTYPE === 'cygwin' || + process.env.OSTYPE === 'msys' + +var path = __webpack_require__(57) +var COLON = isWindows ? ';' : ':' +var isexe = __webpack_require__(182) + +function getNotFoundError (cmd) { + var er = new Error('not found: ' + cmd) + er.code = 'ENOENT' + + return er +} + +function getPathInfo (cmd, opt) { + var colon = opt.colon || COLON + var pathEnv = opt.path || process.env.PATH || '' + var pathExt = [''] + + pathEnv = pathEnv.split(colon) + + var pathExtExe = '' + if (isWindows) { + pathEnv.unshift(process.cwd()) + pathExtExe = (opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM') + pathExt = pathExtExe.split(colon) + + + // Always test the cmd itself first. isexe will check to make sure + // it's found in the pathExt set. + if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') + pathExt.unshift('') + } + + // If it has a slash, then we don't bother searching the pathenv. + // just check the file itself, and that's it. + if (cmd.match(/\//) || isWindows && cmd.match(/\\/)) + pathEnv = [''] + + return { + env: pathEnv, + ext: pathExt, + extExe: pathExtExe + } +} + +function which (cmd, opt, cb) { + if (typeof opt === 'function') { + cb = opt + opt = {} + } + + var info = getPathInfo(cmd, opt) + var pathEnv = info.env + var pathExt = info.ext + var pathExtExe = info.extExe + var found = [] + + ;(function F (i, l) { + if (i === l) { + if (opt.all && found.length) + return cb(null, found) + else + return cb(getNotFoundError(cmd)) + } + + var pathPart = pathEnv[i] + if (pathPart.charAt(0) === '"' && pathPart.slice(-1) === '"') + pathPart = pathPart.slice(1, -1) + + var p = path.join(pathPart, cmd) + if (!pathPart && (/^\.[\\\/]/).test(cmd)) { + p = cmd.slice(0, 2) + p + } + ;(function E (ii, ll) { + if (ii === ll) return F(i + 1, l) + var ext = pathExt[ii] + isexe(p + ext, { pathExt: pathExtExe }, function (er, is) { + if (!er && is) { + if (opt.all) + found.push(p + ext) + else + return cb(null, p + ext) + } + return E(ii + 1, ll) + }) + })(0, pathExt.length) + })(0, pathEnv.length) +} + +function whichSync (cmd, opt) { + opt = opt || {} + + var info = getPathInfo(cmd, opt) + var pathEnv = info.env + var pathExt = info.ext + var pathExtExe = info.extExe + var found = [] + + for (var i = 0, l = pathEnv.length; i < l; i ++) { + var pathPart = pathEnv[i] + if (pathPart.charAt(0) === '"' && pathPart.slice(-1) === '"') + pathPart = pathPart.slice(1, -1) + + var p = path.join(pathPart, cmd) + if (!pathPart && /^\.[\\\/]/.test(cmd)) { + p = cmd.slice(0, 2) + p + } + for (var j = 0, ll = pathExt.length; j < ll; j ++) { + var cur = p + pathExt[j] + var is + try { + is = isexe.sync(cur, { pathExt: pathExtExe }) + if (is) { + if (opt.all) + found.push(cur) + else + return cur + } + } catch (ex) {} + } + } + + if (opt.all && found.length) + return found + + if (opt.nothrow) + return null + + throw getNotFoundError(cmd) +} + + +/***/ }), +/* 182 */ +/***/ (function(module, exports, __webpack_require__) { + +var fs = __webpack_require__(55) +var core +if (process.platform === 'win32' || global.TESTING_WINDOWS) { + core = __webpack_require__(183) +} else { + core = __webpack_require__(184) +} + +module.exports = isexe +isexe.sync = sync + +function isexe (path, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} + } + + if (!cb) { + if (typeof Promise !== 'function') { + throw new TypeError('callback not provided') + } + + return new Promise(function (resolve, reject) { + isexe(path, options || {}, function (er, is) { + if (er) { + reject(er) + } else { + resolve(is) + } + }) + }) + } + + core(path, options || {}, function (er, is) { + // ignore EACCES because that just means we aren't allowed to run it + if (er) { + if (er.code === 'EACCES' || options && options.ignoreErrors) { + er = null + is = false + } + } + cb(er, is) + }) +} + +function sync (path, options) { + // my kingdom for a filtered catch + try { + return core.sync(path, options || {}) + } catch (er) { + if (options && options.ignoreErrors || er.code === 'EACCES') { + return false + } else { + throw er + } + } +} + + +/***/ }), +/* 183 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = isexe +isexe.sync = sync + +var fs = __webpack_require__(55) + +function checkPathExt (path, options) { + var pathext = options.pathExt !== undefined ? + options.pathExt : process.env.PATHEXT + + if (!pathext) { + return true + } + + pathext = pathext.split(';') + if (pathext.indexOf('') !== -1) { + return true + } + for (var i = 0; i < pathext.length; i++) { + var p = pathext[i].toLowerCase() + if (p && path.substr(-p.length).toLowerCase() === p) { + return true + } + } + return false +} + +function checkStat (stat, path, options) { + if (!stat.isSymbolicLink() && !stat.isFile()) { + return false + } + return checkPathExt(path, options) +} + +function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, path, options)) + }) +} + +function sync (path, options) { + return checkStat(fs.statSync(path), path, options) +} + + +/***/ }), +/* 184 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = isexe +isexe.sync = sync + +var fs = __webpack_require__(55) + +function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, options)) + }) +} + +function sync (path, options) { + return checkStat(fs.statSync(path), options) +} + +function checkStat (stat, options) { + return stat.isFile() && checkMode(stat, options) +} + +function checkMode (stat, options) { + var mod = stat.mode + var uid = stat.uid + var gid = stat.gid + + var myUid = options.uid !== undefined ? + options.uid : process.getuid && process.getuid() + var myGid = options.gid !== undefined ? + options.gid : process.getgid && process.getgid() + + var u = parseInt('100', 8) + var g = parseInt('010', 8) + var o = parseInt('001', 8) + var ug = u | g + + var ret = (mod & o) || + (mod & g) && gid === myGid || + (mod & u) && uid === myUid || + (mod & ug) && myUid === 0 + + return ret +} + + +/***/ }), +/* 185 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +let _isWindows = false; +let _isMacintosh = false; +let _isLinux = false; +let _isNative = false; +let _isWeb = false; +exports.language = 'en'; +// OS detection +if (typeof process === 'object' && + typeof process.nextTick === 'function' && + typeof process.platform === 'string') { + _isWindows = process.platform === 'win32'; + _isMacintosh = process.platform === 'darwin'; + _isLinux = process.platform === 'linux'; + _isNative = true; +} +var Platform; +(function (Platform) { + Platform[Platform["Web"] = 0] = "Web"; + Platform[Platform["Mac"] = 1] = "Mac"; + Platform[Platform["Linux"] = 2] = "Linux"; + Platform[Platform["Windows"] = 3] = "Windows"; +})(Platform = exports.Platform || (exports.Platform = {})); +let _platform = Platform.Web; +if (_isNative) { + if (_isMacintosh) { + _platform = Platform.Mac; + } + else if (_isWindows) { + _platform = Platform.Windows; + } + else if (_isLinux) { + _platform = Platform.Linux; + } +} +exports.isWindows = _isWindows; +exports.isMacintosh = _isMacintosh; +exports.isLinux = _isLinux; +exports.isNative = _isNative; +exports.isWeb = _isWeb; +exports.platform = _platform; +const _globals = typeof self === 'object' + ? self + : typeof global === 'object' + ? global + : {}; +exports.globals = _globals; +exports.OS = _isMacintosh + ? 2 /* Macintosh */ + : _isWindows + ? 1 /* Windows */ + : 3 /* Linux */; +//# sourceMappingURL=platform.js.map + +/***/ }), +/* 186 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const log4js_1 = tslib_1.__importDefault(__webpack_require__(64)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const os_1 = tslib_1.__importDefault(__webpack_require__(56)); +function getLogFile() { + let file = process.env.NVIM_COC_LOG_FILE; + if (file) + return file; + let dir = process.env.XDG_RUNTIME_DIR; + if (dir) + return path_1.default.join(dir, `coc-nvim-${process.pid}.log`); + return path_1.default.join(os_1.default.tmpdir(), `coc-nvim-${process.pid}.log`); +} +const MAX_LOG_SIZE = 1024 * 1024; +const MAX_LOG_BACKUPS = 10; +let logfile = getLogFile(); +const level = process.env.NVIM_COC_LOG_LEVEL || 'info'; +if (!fs_1.default.existsSync(logfile)) { + try { + fs_1.default.writeFileSync(logfile, '', { encoding: 'utf8', mode: 0o666 }); + } + catch (e) { + logfile = path_1.default.join(os_1.default.tmpdir(), `coc-nvim-${process.pid}.log`); + fs_1.default.writeFileSync(logfile, '', { encoding: 'utf8', mode: 0o666 }); + // noop + } +} +log4js_1.default.configure({ + disableClustering: true, + appenders: { + out: { + type: 'file', + mode: 0o666, + filename: logfile, + maxLogSize: MAX_LOG_SIZE, + backups: MAX_LOG_BACKUPS, + layout: { + type: 'pattern', + // Format log in following pattern: + // yyyy-MM-dd HH:mm:ss.mil $Level (pid:$pid) $categroy - $message. + pattern: `%d{ISO8601} %p (pid:${process.pid}) [%c] - %m`, + }, + } + }, + categories: { + default: { appenders: ['out'], level } + } +}); +module.exports = (name = 'coc-nvim') => { + let logger = log4js_1.default.getLogger(name); + logger.getLogFile = () => { + return logfile; + }; + return logger; +}; +//# sourceMappingURL=logger.js.map + +/***/ }), +/* 187 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const debounce_1 = tslib_1.__importDefault(__webpack_require__(176)); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const os_1 = tslib_1.__importDefault(__webpack_require__(56)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const util_1 = tslib_1.__importDefault(__webpack_require__(40)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const vscode_uri_1 = __webpack_require__(180); +const which_1 = tslib_1.__importDefault(__webpack_require__(181)); +const configuration_1 = tslib_1.__importDefault(__webpack_require__(188)); +const shape_1 = tslib_1.__importDefault(__webpack_require__(205)); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const db_1 = tslib_1.__importDefault(__webpack_require__(206)); +const document_1 = tslib_1.__importDefault(__webpack_require__(207)); +const fileSystemWatcher_1 = tslib_1.__importDefault(__webpack_require__(214)); +const mru_1 = tslib_1.__importDefault(__webpack_require__(215)); +const outputChannel_1 = tslib_1.__importDefault(__webpack_require__(216)); +const resolver_1 = tslib_1.__importDefault(__webpack_require__(217)); +const status_1 = tslib_1.__importDefault(__webpack_require__(219)); +const task_1 = tslib_1.__importDefault(__webpack_require__(223)); +const terminal_1 = tslib_1.__importDefault(__webpack_require__(224)); +const willSaveHandler_1 = tslib_1.__importDefault(__webpack_require__(225)); +const types_1 = __webpack_require__(189); +const array_1 = __webpack_require__(212); +const fs_2 = __webpack_require__(200); +const index_1 = __webpack_require__(174); +const match_1 = __webpack_require__(226); +const position_1 = __webpack_require__(213); +const string_1 = __webpack_require__(210); +const watchman_1 = tslib_1.__importDefault(__webpack_require__(227)); +const uuid = __webpack_require__(220); +const requireFunc = true ? require : undefined; +const logger = __webpack_require__(186)('workspace'); +const CONFIG_FILE_NAME = 'coc-settings.json'; +let NAME_SPACE = 1080; +class Workspace { + constructor() { + this.keymaps = new Map(); + this.resolver = new resolver_1.default(); + this.rootPatterns = new Map(); + this._workspaceFolders = []; + this._insertMode = false; + this._cwd = process.cwd(); + this._blocking = false; + this._initialized = false; + this._attached = false; + this.buffers = new Map(); + this.autocmdMaxId = 0; + this.autocmds = new Map(); + this.terminals = new Map(); + this.creatingSources = new Map(); + this.outputChannels = new Map(); + this.schemeProviderMap = new Map(); + this.namespaceMap = new Map(); + this.disposables = []; + this.watchedOptions = new Set(); + this._disposed = false; + this._onDidOpenDocument = new vscode_languageserver_protocol_1.Emitter(); + this._onDidCloseDocument = new vscode_languageserver_protocol_1.Emitter(); + this._onDidChangeDocument = new vscode_languageserver_protocol_1.Emitter(); + this._onWillSaveDocument = new vscode_languageserver_protocol_1.Emitter(); + this._onDidSaveDocument = new vscode_languageserver_protocol_1.Emitter(); + this._onDidChangeWorkspaceFolders = new vscode_languageserver_protocol_1.Emitter(); + this._onDidChangeConfiguration = new vscode_languageserver_protocol_1.Emitter(); + this._onDidWorkspaceInitialized = new vscode_languageserver_protocol_1.Emitter(); + this._onDidOpenTerminal = new vscode_languageserver_protocol_1.Emitter(); + this._onDidCloseTerminal = new vscode_languageserver_protocol_1.Emitter(); + this.onDidCloseTerminal = this._onDidCloseTerminal.event; + this.onDidOpenTerminal = this._onDidOpenTerminal.event; + this.onDidChangeWorkspaceFolders = this._onDidChangeWorkspaceFolders.event; + this.onDidOpenTextDocument = this._onDidOpenDocument.event; + this.onDidCloseTextDocument = this._onDidCloseDocument.event; + this.onDidChangeTextDocument = this._onDidChangeDocument.event; + this.onWillSaveTextDocument = this._onWillSaveDocument.event; + this.onDidSaveTextDocument = this._onDidSaveDocument.event; + this.onDidChangeConfiguration = this._onDidChangeConfiguration.event; + this.onDidWorkspaceInitialized = this._onDidWorkspaceInitialized.event; + let json = requireFunc('../package.json'); + this.version = json.version; + this.configurations = this.createConfigurations(); + this.willSaveUntilHandler = new willSaveHandler_1.default(this); + this.setupDynamicAutocmd = debounce_1.default(() => { + this._setupDynamicAutocmd().catch(e => { + logger.error(e); + }); + }, global.hasOwnProperty('__TEST__') ? 0 : 100); + this.setMessageLevel(); + } + async init() { + let { nvim } = this; + this.statusLine = new status_1.default(nvim); + this._env = await nvim.call('coc#util#vim_info'); + this._insertMode = this._env.mode.startsWith('insert'); + if (this._env.workspaceFolders) { + this._workspaceFolders = this._env.workspaceFolders.map(f => { + return { + uri: vscode_uri_1.URI.file(f).toString(), + name: path_1.default.dirname(f) + }; + }); + } + this.configurations.updateUserConfig(this._env.config); + events_1.default.on('InsertEnter', () => { + this._insertMode = true; + }, null, this.disposables); + events_1.default.on('InsertLeave', () => { + this._insertMode = false; + }, null, this.disposables); + events_1.default.on('BufEnter', this.onBufEnter, this, this.disposables); + events_1.default.on('CursorMoved', this.onCursorMoved, this, this.disposables); + events_1.default.on('DirChanged', this.onDirChanged, this, this.disposables); + events_1.default.on('BufCreate', this.onBufCreate, this, this.disposables); + events_1.default.on('BufUnload', this.onBufUnload, this, this.disposables); + events_1.default.on('TermOpen', this.onBufCreate, this, this.disposables); + events_1.default.on('TermClose', this.onBufUnload, this, this.disposables); + events_1.default.on('BufWritePost', this.onBufWritePost, this, this.disposables); + events_1.default.on('BufWritePre', this.onBufWritePre, this, this.disposables); + events_1.default.on('FileType', this.onFileTypeChange, this, this.disposables); + events_1.default.on('CursorHold', this.checkBuffer, this, this.disposables); + events_1.default.on('TextChanged', this.checkBuffer, this, this.disposables); + events_1.default.on('BufReadCmd', this.onBufReadCmd, this, this.disposables); + events_1.default.on('VimResized', (columns, lines) => { + Object.assign(this._env, { columns, lines }); + }, null, this.disposables); + await this.attach(); + this.attachChangedEvents(); + this.configurations.onDidChange(e => { + this._onDidChangeConfiguration.fire(e); + }, null, this.disposables); + this.watchOption('runtimepath', (_, newValue) => { + this._env.runtimepath = newValue; + }, this.disposables); + this.watchOption('iskeyword', (_, newValue) => { + let doc = this.getDocument(this.bufnr); + if (doc) + doc.setIskeyword(newValue); + }, this.disposables); + this.watchOption('completeopt', async (_, newValue) => { + this.env.completeOpt = newValue; + if (!this._attached) + return; + if (this.insertMode) { + let suggest = this.getConfiguration('suggest'); + if (suggest.get('autoTrigger') == 'always') { + console.error(`Some plugin change completeopt on insert mode!`); // tslint:disable-line + } + } + }, this.disposables); + this.watchGlobal('coc_enabled', async (oldValue, newValue) => { + if (newValue == oldValue) + return; + if (newValue == 1) { + await this.attach(); + } + else { + await this.detach(); + } + }, this.disposables); + let provider = { + onDidChange: null, + provideTextDocumentContent: async (uri) => { + let channel = this.outputChannels.get(uri.path.slice(1)); + if (!channel) + return ''; + nvim.pauseNotification(); + nvim.command('setlocal nospell nofoldenable wrap noswapfile', true); + nvim.command('setlocal buftype=nofile bufhidden=hide', true); + nvim.command('setfiletype log', true); + await nvim.resumeNotification(); + return channel.content; + } + }; + this.disposables.push(this.registerTextDocumentContentProvider('output', provider)); + } + getConfigFile(target) { + return this.configurations.getConfigFile(target); + } + /** + * Register autocmd on vim. + */ + registerAutocmd(autocmd) { + this.autocmdMaxId += 1; + let id = this.autocmdMaxId; + this.autocmds.set(id, autocmd); + this.setupDynamicAutocmd(); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.autocmds.delete(id); + this.setupDynamicAutocmd(); + }); + } + /** + * Watch for option change. + */ + watchOption(key, callback, disposables) { + let watching = this.watchedOptions.has(key); + if (!watching) { + this.watchedOptions.add(key); + this.setupDynamicAutocmd(); + } + let disposable = events_1.default.on('OptionSet', async (changed, oldValue, newValue) => { + if (changed == key && callback) { + await Promise.resolve(callback(oldValue, newValue)); + } + }); + if (disposables) { + disposables.push(vscode_languageserver_protocol_1.Disposable.create(() => { + disposable.dispose(); + if (watching) + return; + this.watchedOptions.delete(key); + this.setupDynamicAutocmd(); + })); + } + } + /** + * Watch global variable, works on neovim only. + */ + watchGlobal(key, callback, disposables) { + let { nvim } = this; + nvim.call('coc#_watch', key, true); + let disposable = events_1.default.on('GlobalChange', async (changed, oldValue, newValue) => { + if (changed == key && callback) { + await Promise.resolve(callback(oldValue, newValue)); + } + }); + if (disposables) { + disposables.push(vscode_languageserver_protocol_1.Disposable.create(() => { + disposable.dispose(); + nvim.call('coc#_unwatch', key, true); + })); + } + } + get cwd() { + return this._cwd; + } + get env() { + return this._env; + } + get root() { + return this._root || this.cwd; + } + get rootPath() { + return this.root; + } + get workspaceFolders() { + return this._workspaceFolders; + } + /** + * uri of current file, could be null + */ + get uri() { + let { bufnr } = this; + if (bufnr) { + let document = this.getDocument(bufnr); + if (document && document.schema == 'file') { + return document.uri; + } + } + return null; + } + get workspaceFolder() { + let { rootPath } = this; + if (rootPath == os_1.default.homedir()) + return null; + return { + uri: vscode_uri_1.URI.file(rootPath).toString(), + name: path_1.default.basename(rootPath) + }; + } + get textDocuments() { + let docs = []; + for (let b of this.buffers.values()) { + docs.push(b.textDocument); + } + return docs; + } + get documents() { + return Array.from(this.buffers.values()); + } + createNameSpace(name = '') { + if (this.namespaceMap.has(name)) + return this.namespaceMap.get(name); + NAME_SPACE = NAME_SPACE + 1; + this.namespaceMap.set(name, NAME_SPACE); + return NAME_SPACE; + } + get channelNames() { + return Array.from(this.outputChannels.keys()); + } + get pluginRoot() { + return path_1.default.dirname(__dirname); + } + get isVim() { + return this._env.isVim; + } + get isNvim() { + return !this._env.isVim; + } + get completeOpt() { + return this._env.completeOpt; + } + get initialized() { + return this._initialized; + } + get ready() { + if (this._initialized) + return Promise.resolve(); + return new Promise(resolve => { + let disposable = this.onDidWorkspaceInitialized(() => { + disposable.dispose(); + resolve(); + }); + }); + } + /** + * Current filetypes. + */ + get filetypes() { + let res = new Set(); + for (let doc of this.documents) { + res.add(doc.filetype); + } + return res; + } + /** + * Check if selector match document. + */ + match(selector, document) { + return match_1.score(selector, document.uri, document.languageId); + } + /** + * Findup for filename or filenames from current filepath or root. + */ + async findUp(filename) { + let { cwd } = this; + let filepath = await this.nvim.call('expand', '%:p'); + filepath = path_1.default.normalize(filepath); + let isFile = filepath && path_1.default.isAbsolute(filepath); + if (isFile && !fs_2.isParentFolder(cwd, filepath)) { + // can't use cwd + return fs_2.findUp(filename, path_1.default.dirname(filepath)); + } + let res = fs_2.findUp(filename, cwd); + if (res && res != os_1.default.homedir()) + return res; + if (isFile) + return fs_2.findUp(filename, path_1.default.dirname(filepath)); + return null; + } + async resolveRootFolder(uri, patterns) { + let { cwd } = this; + if (uri.scheme != 'file') + return cwd; + let filepath = path_1.default.normalize(uri.fsPath); + let dir = path_1.default.dirname(filepath); + return fs_2.resolveRoot(dir, patterns) || dir; + } + /** + * Create a FileSystemWatcher instance, + * doesn't fail when watchman not found. + */ + createFileSystemWatcher(globPattern, ignoreCreate, ignoreChange, ignoreDelete) { + let watchmanPath = false ? undefined : this.getWatchmanPath(); + let channel = watchmanPath ? this.createOutputChannel('watchman') : null; + let promise = watchmanPath ? watchman_1.default.createClient(watchmanPath, this.root, channel) : Promise.resolve(null); + let watcher = new fileSystemWatcher_1.default(promise, globPattern, !!ignoreCreate, !!ignoreChange, !!ignoreDelete); + return watcher; + } + getWatchmanPath() { + const preferences = this.getConfiguration('coc.preferences'); + let watchmanPath = preferences.get('watchmanPath', 'watchman'); + try { + return which_1.default.sync(watchmanPath); + } + catch (e) { + return null; + } + } + /** + * Get configuration by section and optional resource uri. + */ + getConfiguration(section, resource) { + return this.configurations.getConfiguration(section, resource); + } + /** + * Get created document by uri or bufnr. + */ + getDocument(uri) { + if (typeof uri === 'number') { + return this.buffers.get(uri); + } + uri = vscode_uri_1.URI.parse(uri).toString(); + for (let doc of this.buffers.values()) { + if (doc && doc.uri === uri) + return doc; + } + return null; + } + /** + * Get current cursor offset in document. + */ + async getOffset() { + let document = await this.document; + let pos = await this.getCursorPosition(); + return document.textDocument.offsetAt(pos); + } + /** + * Apply WorkspaceEdit. + */ + async applyEdit(edit) { + let { nvim } = this; + let { documentChanges, changes } = edit; + if (documentChanges) { + documentChanges = this.mergeDocumentChanges(documentChanges); + if (!this.validteDocumentChanges(documentChanges)) + return false; + } + let [bufnr, cursor] = await nvim.eval('[bufnr("%"),coc#util#cursor()]'); + let document = this.getDocument(bufnr); + let uri = document ? document.uri : null; + let currEdits = null; + try { + if (documentChanges && documentChanges.length) { + let n = documentChanges.length; + for (let change of documentChanges) { + if (index_1.isDocumentEdit(change)) { + let { textDocument, edits } = change; + if (vscode_uri_1.URI.parse(textDocument.uri).toString() == uri) + currEdits = edits; + let doc = await this.loadFile(textDocument.uri); + await doc.applyEdits(nvim, edits); + } + else if (vscode_languageserver_protocol_1.CreateFile.is(change)) { + let file = vscode_uri_1.URI.parse(change.uri).fsPath; + await this.createFile(file, change.options); + } + else if (vscode_languageserver_protocol_1.RenameFile.is(change)) { + await this.renameFile(vscode_uri_1.URI.parse(change.oldUri).fsPath, vscode_uri_1.URI.parse(change.newUri).fsPath, change.options); + } + else if (vscode_languageserver_protocol_1.DeleteFile.is(change)) { + await this.deleteFile(vscode_uri_1.URI.parse(change.uri).fsPath, change.options); + } + } + this.showMessage(`${n} buffers changed.`); + } + else if (changes) { + await this.loadFiles(Object.keys(changes)); + for (let uri of Object.keys(changes)) { + let document = await this.loadFile(uri); + if (vscode_uri_1.URI.parse(uri).toString() == uri) + currEdits = changes[uri]; + await document.applyEdits(nvim, changes[uri]); + } + this.showMessage(`${Object.keys(changes).length} buffers changed.`); + } + if (currEdits) { + let changed = position_1.getChangedFromEdits({ line: cursor[0], character: cursor[1] }, currEdits); + if (changed) + await this.moveTo({ + line: cursor[0] + changed.line, + character: cursor[1] + changed.character + }); + } + } + catch (e) { + logger.error(e); + this.showMessage(`Error on applyEdits: ${e}`, 'error'); + return false; + } + await index_1.wait(50); + return true; + } + /** + * Convert location to quickfix item. + */ + async getQuickfixItem(loc, text, type = '', module) { + if (vscode_languageserver_protocol_1.LocationLink.is(loc)) { + loc = vscode_languageserver_protocol_1.Location.create(loc.targetUri, loc.targetRange); + } + let doc = this.getDocument(loc.uri); + let { uri, range } = loc; + let { line, character } = range.start; + let u = vscode_uri_1.URI.parse(uri); + let bufnr = doc ? doc.bufnr : -1; + if (!text && u.scheme == 'file') { + text = await this.getLine(uri, line); + character = string_1.byteIndex(text, character); + } + let item = { + uri, + filename: u.scheme == 'file' ? u.fsPath : uri, + lnum: line + 1, + col: character + 1, + text: text || '', + range + }; + if (module) + item.module = module; + if (type) + item.type = type; + if (bufnr != -1) + item.bufnr = bufnr; + return item; + } + /** + * Create persistence Mru instance. + */ + createMru(name) { + return new mru_1.default(name); + } + async getSelectedRange(mode, document) { + let { nvim } = this; + if (['v', 'V', 'char', 'line', '\x16'].indexOf(mode) == -1) { + this.showMessage(`Mode '${mode}' is not supported`, 'error'); + return null; + } + let isVisual = ['v', 'V', '\x16'].indexOf(mode) != -1; + let [, sl, sc] = await nvim.call('getpos', isVisual ? `'<` : `'[`); + let [, el, ec] = await nvim.call('getpos', isVisual ? `'>` : `']`); + let range = vscode_languageserver_protocol_1.Range.create(document.getPosition(sl, sc), document.getPosition(el, ec)); + if (mode == 'v' || mode == '\x16') { + range.end.character = range.end.character + 1; + } + return range; + } + /** + * Visual select range of current document + */ + async selectRange(range) { + let { nvim } = this; + let { start, end } = range; + let [bufnr, ve, selection] = await nvim.eval(`[bufnr('%'), &virtualedit, &selection, mode()]`); + let document = this.getDocument(bufnr); + if (!document) + return; + let line = document.getline(start.line); + let col = line ? string_1.byteLength(line.slice(0, start.character)) : 0; + let endLine = document.getline(end.line); + let endCol = endLine ? string_1.byteLength(endLine.slice(0, end.character)) : 0; + let move_cmd = ''; + let resetVirtualEdit = false; + move_cmd += 'v'; + endCol = await nvim.eval(`virtcol([${end.line + 1}, ${endCol}])`); + if (selection == 'inclusive') { + if (end.character == 0) { + move_cmd += `${end.line}G`; + } + else { + move_cmd += `${end.line + 1}G${endCol}|`; + } + } + else if (selection == 'old') { + move_cmd += `${end.line + 1}G${endCol}|`; + } + else { + move_cmd += `${end.line + 1}G${endCol + 1}|`; + } + col = await nvim.eval(`virtcol([${start.line + 1}, ${col}])`); + move_cmd += `o${start.line + 1}G${col + 1}|o`; + nvim.pauseNotification(); + if (ve != 'onemore') { + resetVirtualEdit = true; + nvim.setOption('virtualedit', 'onemore', true); + } + nvim.command(`noa call cursor(${start.line + 1},${col + (move_cmd == 'a' ? 0 : 1)})`, true); + // nvim.call('eval', [`feedkeys("${move_cmd}", 'in')`], true) + nvim.command(`normal! ${move_cmd}`, true); + if (resetVirtualEdit) + nvim.setOption('virtualedit', ve, true); + if (this.isVim) + nvim.command('redraw', true); + await nvim.resumeNotification(); + } + /** + * Populate locations to UI. + */ + async showLocations(locations) { + let items = await Promise.all(locations.map(loc => { + return this.getQuickfixItem(loc); + })); + let { nvim } = this; + const preferences = this.getConfiguration('coc.preferences'); + if (preferences.get('useQuickfixForLocations', false)) { + await nvim.call('setqflist', [items]); + nvim.command('copen', true); + } + else { + await nvim.setVar('coc_jump_locations', items); + if (this.env.locationlist) { + nvim.command('CocList --normal --auto-preview location', true); + } + else { + nvim.command('doautocmd User CocLocationsChange', true); + } + } + } + /** + * Get content of line by uri and line. + */ + async getLine(uri, line) { + let document = this.getDocument(uri); + if (document) + return document.getline(line) || ''; + if (!uri.startsWith('file:')) + return ''; + return await fs_2.readFileLine(vscode_uri_1.URI.parse(uri).fsPath, line); + } + /** + * Get WorkspaceFolder of uri + */ + getWorkspaceFolder(uri) { + this.workspaceFolders.sort((a, b) => b.uri.length - a.uri.length); + let filepath = vscode_uri_1.URI.parse(uri).fsPath; + return this.workspaceFolders.find(folder => fs_2.isParentFolder(vscode_uri_1.URI.parse(folder.uri).fsPath, filepath)); + } + /** + * Get content from buffer of file by uri. + */ + async readFile(uri) { + let document = this.getDocument(uri); + if (document) { + document.forceSync(); + return document.content; + } + let u = vscode_uri_1.URI.parse(uri); + if (u.scheme != 'file') + return ''; + let encoding = await this.getFileEncoding(); + return await fs_2.readFile(u.fsPath, encoding); + } + getFilepath(filepath) { + let { cwd } = this; + let rel = path_1.default.relative(cwd, filepath); + return rel.startsWith('..') ? filepath : rel; + } + onWillSaveUntil(callback, thisArg, clientId) { + return this.willSaveUntilHandler.addCallback(callback, thisArg, clientId); + } + /** + * Echo lines. + */ + async echoLines(lines, truncate = false) { + let { nvim } = this; + let cmdHeight = this.env.cmdheight; + if (lines.length > cmdHeight && truncate) { + lines = lines.slice(0, cmdHeight); + } + let maxLen = this.env.columns - 12; + lines = lines.map(line => { + line = line.replace(/\n/g, ' '); + if (truncate) + line = line.slice(0, maxLen); + return line; + }); + if (truncate && lines.length == cmdHeight) { + let last = lines[lines.length - 1]; + lines[cmdHeight - 1] = `${last.length == maxLen ? last.slice(0, -4) : last} ...`; + } + nvim.callTimer('coc#util#echo_lines', [lines], true); + } + /** + * Show message in vim. + */ + showMessage(msg, identify = 'more') { + if (this._blocking || !this.nvim) + return; + let { messageLevel } = this; + let level = types_1.MessageLevel.Error; + let method = index_1.echoErr; + switch (identify) { + case 'more': + level = types_1.MessageLevel.More; + method = index_1.echoMessage; + break; + case 'warning': + level = types_1.MessageLevel.Warning; + method = index_1.echoWarning; + break; + } + if (level >= messageLevel) { + method(this.nvim, msg); + } + } + /** + * Current document. + */ + get document() { + let { bufnr } = this; + if (bufnr == null) + return null; + if (this.buffers.has(bufnr)) { + return Promise.resolve(this.buffers.get(bufnr)); + } + if (!this.creatingSources.has(bufnr)) { + this.onBufCreate(bufnr).logError(); + } + return new Promise(resolve => { + let disposable = this.onDidOpenTextDocument(doc => { + disposable.dispose(); + resolve(this.getDocument(doc.uri)); + }); + }); + } + /** + * Get current cursor position. + */ + async getCursorPosition() { + let [line, character] = await this.nvim.call('coc#util#cursor'); + return vscode_languageserver_protocol_1.Position.create(line, character); + } + /** + * Get current document and position. + */ + async getCurrentState() { + let document = await this.document; + let position = await this.getCursorPosition(); + return { + document: document.textDocument, + position + }; + } + /** + * Get format options + */ + async getFormatOptions(uri) { + let doc; + if (uri) { + doc = this.getDocument(uri); + } + else { + doc = this.getDocument(this.bufnr); + } + let tabSize = await this.getDocumentOption('shiftwidth', doc); + if (!tabSize) + tabSize = await this.getDocumentOption('tabstop', doc); + let insertSpaces = (await this.getDocumentOption('expandtab', doc)) == 1; + return { + tabSize, + insertSpaces + }; + } + /** + * Jump to location. + */ + async jumpTo(uri, position, openCommand) { + const preferences = this.getConfiguration('coc.preferences'); + let jumpCommand = openCommand || preferences.get('jumpCommand', 'edit'); + let { nvim } = this; + let doc = this.getDocument(uri); + let bufnr = doc ? doc.bufnr : -1; + await nvim.command(`normal! m'`); + if (bufnr == this.bufnr && jumpCommand == 'edit') { + if (position) + await this.moveTo(position); + } + else if (bufnr != -1 && jumpCommand == 'edit') { + let moveCmd = ''; + if (position) { + let line = doc.getline(position.line); + let col = string_1.byteLength(line.slice(0, position.character)) + 1; + moveCmd = position ? `+call\\ cursor(${position.line + 1},${col})` : ''; + } + await this.nvim.call('coc#util#execute', [`buffer ${moveCmd} ${bufnr}`]); + } + else { + let { fsPath, scheme } = vscode_uri_1.URI.parse(uri); + let pos = position == null ? null : [position.line + 1, position.character + 1]; + if (scheme == 'file') { + let bufname = fs_2.fixDriver(path_1.default.normalize(fsPath)); + await this.nvim.call('coc#util#jump', [jumpCommand, bufname, pos]); + } + else { + await this.nvim.call('coc#util#jump', [jumpCommand, uri, pos]); + } + } + } + /** + * Move cursor to position. + */ + async moveTo(position) { + await this.nvim.call('coc#util#jumpTo', [position.line, position.character]); + } + /** + * Create a file in vim and disk + */ + async createFile(filepath, opts = {}) { + let stat = await fs_2.statAsync(filepath); + if (stat && !opts.overwrite && !opts.ignoreIfExists) { + this.showMessage(`${filepath} already exists!`, 'error'); + return; + } + if (!stat || opts.overwrite) { + // directory + if (filepath.endsWith('/')) { + try { + if (filepath.startsWith('~')) + filepath = filepath.replace(/^~/, os_1.default.homedir()); + await index_1.mkdirp(filepath); + } + catch (e) { + this.showMessage(`Can't create ${filepath}: ${e.message}`, 'error'); + } + } + else { + let uri = vscode_uri_1.URI.file(filepath).toString(); + let doc = this.getDocument(uri); + if (doc) + return; + let encoding = await this.getFileEncoding(); + fs_1.default.writeFileSync(filepath, '', encoding || ''); + await this.loadFile(uri); + } + } + } + /** + * Load uri as document. + */ + async loadFile(uri) { + let doc = this.getDocument(uri); + if (doc) + return doc; + let { nvim } = this; + let filepath = uri.startsWith('file') ? vscode_uri_1.URI.parse(uri).fsPath : uri; + nvim.call('coc#util#open_files', [[filepath]], true); + return await new Promise((resolve, reject) => { + let disposable = this.onDidOpenTextDocument(textDocument => { + let fsPath = vscode_uri_1.URI.parse(textDocument.uri).fsPath; + if (textDocument.uri == uri || fsPath == filepath) { + clearTimeout(timer); + disposable.dispose(); + resolve(this.getDocument(uri)); + } + }); + let timer = setTimeout(() => { + disposable.dispose(); + reject(new Error(`Create document ${uri} timeout after 1s.`)); + }, 1000); + }); + } + /** + * Load the files that not loaded + */ + async loadFiles(uris) { + uris = uris.filter(uri => this.getDocument(uri) == null); + if (!uris.length) + return; + let bufnrs = await this.nvim.call('coc#util#open_files', [uris.map(u => vscode_uri_1.URI.parse(u).fsPath)]); + let create = bufnrs.filter(bufnr => this.getDocument(bufnr) == null); + if (!create.length) + return; + create.map(bufnr => this.onBufCreate(bufnr).logError()); + return new Promise((resolve, reject) => { + let timer = setTimeout(() => { + disposable.dispose(); + reject(new Error(`Create document timeout after 2s.`)); + }, 2000); + let disposable = this.onDidOpenTextDocument(() => { + if (uris.every(uri => this.getDocument(uri) != null)) { + clearTimeout(timer); + disposable.dispose(); + resolve(); + } + }); + }); + } + /** + * Rename file in vim and disk + */ + async renameFile(oldPath, newPath, opts = {}) { + let { overwrite, ignoreIfExists } = opts; + let stat = await fs_2.statAsync(newPath); + if (stat && !overwrite && !ignoreIfExists) { + this.showMessage(`${newPath} already exists`, 'error'); + return; + } + if (!stat || overwrite) { + try { + await fs_2.renameAsync(oldPath, newPath); + let uri = vscode_uri_1.URI.file(oldPath).toString(); + let doc = this.getDocument(uri); + if (doc) { + await doc.buffer.setName(newPath); + // avoid cancel by unload + await this.onBufCreate(doc.bufnr); + } + } + catch (e) { + this.showMessage(`Rename error ${e.message}`, 'error'); + } + } + } + /** + * Delete file from vim and disk. + */ + async deleteFile(filepath, opts = {}) { + let { ignoreIfNotExists, recursive } = opts; + let stat = await fs_2.statAsync(filepath.replace(/\/$/, '')); + let isDir = stat && stat.isDirectory() || filepath.endsWith('/'); + if (!stat && !ignoreIfNotExists) { + this.showMessage(`${filepath} not exists`, 'error'); + return; + } + if (stat == null) + return; + if (isDir && !recursive) { + this.showMessage(`Can't remove directory, recursive not set`, 'error'); + return; + } + try { + let method = isDir ? 'rmdir' : 'unlink'; + await util_1.default.promisify(fs_1.default[method])(filepath); + if (!isDir) { + let uri = vscode_uri_1.URI.file(filepath).toString(); + let doc = this.getDocument(uri); + if (doc) + await this.nvim.command(`silent bwipeout ${doc.bufnr}`); + } + } + catch (e) { + this.showMessage(`Error on delete ${filepath}: ${e.message}`, 'error'); + } + } + /** + * Open resource by uri + */ + async openResource(uri) { + let { nvim } = this; + // not supported + if (uri.startsWith('http')) { + await nvim.call('coc#util#open_url', uri); + return; + } + let wildignore = await nvim.getOption('wildignore'); + await nvim.setOption('wildignore', ''); + await this.jumpTo(uri); + await nvim.setOption('wildignore', wildignore); + } + /** + * Create a new output channel + */ + createOutputChannel(name) { + if (this.outputChannels.has(name)) + return this.outputChannels.get(name); + let channel = new outputChannel_1.default(name, this.nvim); + this.outputChannels.set(name, channel); + return channel; + } + /** + * Reveal buffer of output channel. + */ + showOutputChannel(name, preserveFocus) { + let channel = this.outputChannels.get(name); + if (!channel) { + this.showMessage(`Channel "${name}" not found`, 'error'); + return; + } + channel.show(preserveFocus); + } + /** + * Resovle module from yarn or npm. + */ + async resolveModule(name) { + return await this.resolver.resolveModule(name); + } + /** + * Run nodejs command + */ + async runCommand(cmd, cwd, timeout) { + cwd = cwd || this.cwd; + return index_1.runCommand(cmd, { cwd }, timeout); + } + /** + * Run command in vim terminal + */ + async runTerminalCommand(cmd, cwd = this.cwd, keepfocus = false) { + return await this.nvim.callAsync('coc#util#run_terminal', { cmd, cwd, keepfocus: keepfocus ? 1 : 0 }); + } + async createTerminal(opts) { + let cmd = opts.shellPath; + let args = opts.shellArgs; + if (!cmd) + cmd = await this.nvim.getOption('shell'); + let terminal = new terminal_1.default(cmd, args || [], this.nvim, opts.name); + await terminal.start(opts.cwd || this.cwd, opts.env); + this.terminals.set(terminal.bufnr, terminal); + this._onDidOpenTerminal.fire(terminal); + return terminal; + } + /** + * Show quickpick + */ + async showQuickpick(items, placeholder = 'Choose by number') { + let msgs = [placeholder + ':']; + msgs = msgs.concat(items.map((str, index) => { + return `${index + 1}. ${str}`; + })); + let res = await this.callAsync('inputlist', [msgs]); + let n = parseInt(res, 10); + if (isNaN(n) || n <= 0 || n > msgs.length) + return -1; + return n - 1; + } + /** + * Prompt for confirm action. + */ + async showPrompt(title) { + this._blocking = true; + let res = await this.nvim.callAsync('coc#util#with_callback', ['coc#util#prompt_confirm', [title]]); + this._blocking = false; + return res == 1; + } + async callAsync(method, args) { + if (this.isNvim) + return await this.nvim.call(method, args); + return await this.nvim.callAsync('coc#util#with_callback', [method, args]); + } + /** + * Request input from user + */ + async requestInput(title, defaultValue) { + let { nvim } = this; + let res = await this.callAsync('input', [title + ': ', defaultValue || '']); + nvim.command('normal! :', true); + if (!res) { + this.showMessage('Empty word, canceled', 'warning'); + return null; + } + return res; + } + /** + * registerTextDocumentContentProvider + */ + registerTextDocumentContentProvider(scheme, provider) { + this.schemeProviderMap.set(scheme, provider); + this.setupDynamicAutocmd(); // tslint:disable-line + let disposables = []; + if (provider.onDidChange) { + provider.onDidChange(async (uri) => { + let doc = this.getDocument(uri.toString()); + if (doc) { + let { buffer } = doc; + let tokenSource = new vscode_languageserver_protocol_1.CancellationTokenSource(); + let content = await Promise.resolve(provider.provideTextDocumentContent(uri, tokenSource.token)); + await buffer.setLines(content.split('\n'), { + start: 0, + end: -1, + strictIndexing: false + }); + } + }, null, disposables); + } + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.schemeProviderMap.delete(scheme); + index_1.disposeAll(disposables); + this.setupDynamicAutocmd(); + }); + } + /** + * Register keymap + */ + registerKeymap(modes, key, fn, opts = {}) { + if (this.keymaps.has(key)) + return; + opts = Object.assign({ sync: true, cancel: true, silent: true, repeat: false }, opts); + let { nvim } = this; + this.keymaps.set(key, [fn, !!opts.repeat]); + let method = opts.sync ? 'request' : 'notify'; + let silent = opts.silent ? '' : ''; + for (let m of modes) { + if (m == 'i') { + nvim.command(`inoremap ${silent} (coc-${key}) coc#_insert_key('${method}', '${key}', ${opts.cancel ? 1 : 0})`, true); + } + else { + let modify = index_1.getKeymapModifier(m); + nvim.command(`${m}noremap ${silent} (coc-${key}) :${modify}call coc#rpc#${method}('doKeymap', ['${key}'])`, true); + } + } + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.keymaps.delete(key); + for (let m of modes) { + nvim.command(`${m}unmap (coc-${key})`, true); + } + }); + } + /** + * Register expr keymap. + */ + registerExprKeymap(mode, key, fn, buffer = false) { + let id = uuid(); + let { nvim } = this; + this.keymaps.set(id, [fn, false]); + if (mode == 'i') { + nvim.command(`inoremap ${buffer ? '' : ''} ${key} coc#_insert_key('request', '${id}')`, true); + } + else { + nvim.command(`${mode}noremap ${buffer ? '' : ''} ${key} coc#rpc#request('doKeymap', ['${id}'])`, true); + } + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.keymaps.delete(id); + nvim.command(`${mode}unmap ${buffer ? '' : ''} ${key}`, true); + }); + } + registerLocalKeymap(mode, key, fn, notify = false) { + let id = uuid(); + let { nvim } = this; + this.keymaps.set(id, [fn, false]); + nvim.command(`${mode}noremap ${key} :call coc#rpc#${notify ? 'notify' : 'request'}('doKeymap', ['${id}'])`, true); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.keymaps.delete(id); + nvim.command(`${mode}unmap ${key}`, true); + }); + } + /** + * Create StatusBarItem + */ + createStatusBarItem(priority = 0, opt = {}) { + if (!this.statusLine) { + // tslint:disable-next-line: no-empty + let fn = () => { }; + return { text: '', show: fn, dispose: fn, hide: fn, priority: 0, isProgress: true }; + } + return this.statusLine.createStatusBarItem(priority, opt.progress || false); + } + dispose() { + this._disposed = true; + for (let ch of this.outputChannels.values()) { + ch.dispose(); + } + for (let doc of this.documents) { + doc.detach(); + } + index_1.disposeAll(this.disposables); + watchman_1.default.dispose(); + this.configurations.dispose(); + this.setupDynamicAutocmd.clear(); + this.buffers.clear(); + if (this.statusLine) + this.statusLine.dispose(); + } + async detach() { + if (!this._attached) + return; + this._attached = false; + for (let bufnr of this.buffers.keys()) { + await events_1.default.fire('BufUnload', [bufnr]); + } + } + /** + * Create DB instance at extension root. + */ + createDatabase(name) { + let root; + if (global.hasOwnProperty('__TEST__')) { + root = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'coc-')); + } + else { + root = path_1.default.dirname(this.env.extensionRoot); + } + let filepath = path_1.default.join(root, name + '.json'); + return new db_1.default(filepath); + } + /** + * Create Task instance that runs in vim. + */ + createTask(id) { + return new task_1.default(this.nvim, id); + } + async _setupDynamicAutocmd() { + let schemes = this.schemeProviderMap.keys(); + let cmds = []; + for (let scheme of schemes) { + cmds.push(`autocmd BufReadCmd,FileReadCmd,SourceCmd ${scheme}://* call coc#rpc#request('CocAutocmd', ['BufReadCmd','${scheme}', expand('')])`); + } + for (let [id, autocmd] of this.autocmds.entries()) { + let args = autocmd.arglist && autocmd.arglist.length ? ', ' + autocmd.arglist.join(', ') : ''; + let event = Array.isArray(autocmd.event) ? autocmd.event.join(',') : autocmd.event; + let pattern = '*'; + if (/\buser\b/i.test(event)) { + pattern = ''; + } + cmds.push(`autocmd ${event} ${pattern} call coc#rpc#${autocmd.request ? 'request' : 'notify'}('doAutocmd', [${id}${args}])`); + } + for (let key of this.watchedOptions) { + cmds.push(`autocmd OptionSet ${key} call coc#rpc#notify('OptionSet',[expand(''), v:option_old, v:option_new])`); + } + let content = ` +augroup coc_autocmd + autocmd! + ${cmds.join('\n')} +augroup end`; + try { + let filepath = path_1.default.join(os_1.default.tmpdir(), `coc-${process.pid}.vim`); + await fs_2.writeFile(filepath, content); + let cmd = `source ${filepath}`; + const isCygwin = await this.nvim.eval('has("win32unix")'); + if (isCygwin && index_1.platform.isWindows) { + cmd = `execute "source" . substitute(system('cygpath ${filepath.replace(/\\/g, '/')}'), '\\n', '', 'g')`; + } + await this.nvim.command(cmd); + } + catch (e) { + this.showMessage(`Can't create tmp file: ${e.message}`, 'error'); + } + } + async onBufReadCmd(scheme, uri) { + let provider = this.schemeProviderMap.get(scheme); + if (!provider) { + this.showMessage(`Provider for ${scheme} not found`, 'error'); + return; + } + let tokenSource = new vscode_languageserver_protocol_1.CancellationTokenSource(); + let content = await Promise.resolve(provider.provideTextDocumentContent(vscode_uri_1.URI.parse(uri), tokenSource.token)); + let buf = await this.nvim.buffer; + await buf.setLines(content.split('\n'), { + start: 0, + end: -1, + strictIndexing: false + }); + setTimeout(async () => { + await events_1.default.fire('BufCreate', [buf.id]); + }, 30); + } + async attach() { + if (this._attached) + return; + this._attached = true; + let buffers = await this.nvim.buffers; + let bufnr = this.bufnr = await this.nvim.call('bufnr', '%'); + await Promise.all(buffers.map(buf => { + return this.onBufCreate(buf); + })); + if (!this._initialized) { + this._onDidWorkspaceInitialized.fire(void 0); + this._initialized = true; + } + await events_1.default.fire('BufEnter', [bufnr]); + let winid = await this.nvim.call('win_getid'); + await events_1.default.fire('BufWinEnter', [bufnr, winid]); + } + validteDocumentChanges(documentChanges) { + if (!documentChanges) + return true; + for (let change of documentChanges) { + if (index_1.isDocumentEdit(change)) { + let { textDocument } = change; + let { uri, version } = textDocument; + let doc = this.getDocument(uri); + if (version && !doc) { + this.showMessage(`${uri} not opened.`, 'error'); + return false; + } + if (version && doc.version != version) { + this.showMessage(`${uri} changed before apply edit`, 'error'); + return false; + } + if (!version && !doc) { + if (!uri.startsWith('file')) { + this.showMessage(`Can't apply edits to ${uri}.`, 'error'); + return false; + } + let exists = fs_1.default.existsSync(vscode_uri_1.URI.parse(uri).fsPath); + if (!exists) { + this.showMessage(`File ${uri} not exists.`, 'error'); + return false; + } + } + } + else if (vscode_languageserver_protocol_1.CreateFile.is(change) || vscode_languageserver_protocol_1.DeleteFile.is(change)) { + if (!fs_2.isFile(change.uri)) { + this.showMessage(`Chagne of scheme ${change.uri} not supported`, 'error'); + return false; + } + } + } + return true; + } + createConfigurations() { + let home = process.env.COC_VIMCONFIG || path_1.default.join(os_1.default.homedir(), '.vim'); + if (global.hasOwnProperty('__TEST__')) { + home = path_1.default.join(this.pluginRoot, 'src/__tests__'); + } + let userConfigFile = path_1.default.join(home, CONFIG_FILE_NAME); + return new configuration_1.default(userConfigFile, new shape_1.default(this)); + } + // events for sync buffer of vim + attachChangedEvents() { + if (this.isVim) { + const onChange = async (bufnr) => { + let doc = this.getDocument(bufnr); + if (doc && doc.shouldAttach) + doc.fetchContent(); + }; + events_1.default.on('TextChangedI', onChange, null, this.disposables); + events_1.default.on('TextChanged', onChange, null, this.disposables); + } + } + async onBufCreate(buf) { + let buffer = typeof buf === 'number' ? this.nvim.createBuffer(buf) : buf; + let bufnr = buffer.id; + if (this.creatingSources.has(bufnr)) + return; + let document = this.getDocument(bufnr); + let source = new vscode_languageserver_protocol_1.CancellationTokenSource(); + try { + if (document) + this.onBufUnload(bufnr, true).logError(); + document = new document_1.default(buffer, this._env); + let token = source.token; + this.creatingSources.set(bufnr, source); + let created = await document.init(this.nvim, token); + if (!created) + document = null; + } + catch (e) { + logger.error('Error on create buffer:', e); + document = null; + } + if (this.creatingSources.get(bufnr) == source) { + source.dispose(); + this.creatingSources.delete(bufnr); + } + if (!document || !document.textDocument) + return; + this.buffers.set(bufnr, document); + if (document.enabled) { + document.onDocumentDetach(uri => { + let doc = this.getDocument(uri); + if (doc) + this.onBufUnload(doc.bufnr).logError(); + }); + } + if (document.buftype == '' && document.schema == 'file') { + let config = this.getConfiguration('workspace'); + let filetypes = config.get('ignoredFiletypes', []); + if (filetypes.indexOf(document.filetype) == -1) { + let root = this.resolveRoot(document); + if (root) { + this.addWorkspaceFolder(root); + if (this.bufnr == buffer.id) { + this._root = root; + } + } + } + this.configurations.checkFolderConfiguration(document.uri); + } + if (document.enabled) { + this._onDidOpenDocument.fire(document.textDocument); + document.onDocumentChange(e => this._onDidChangeDocument.fire(e)); + } + logger.debug('buffer created', buffer.id); + } + async onBufEnter(bufnr) { + this.bufnr = bufnr; + let doc = this.getDocument(bufnr); + if (doc) { + this.configurations.setFolderConfiguration(doc.uri); + let workspaceFolder = this.getWorkspaceFolder(doc.uri); + if (workspaceFolder) + this._root = vscode_uri_1.URI.parse(workspaceFolder.uri).fsPath; + } + } + async onCursorMoved(bufnr) { + this.bufnr = bufnr; + await this.checkBuffer(bufnr); + } + async onBufWritePost(bufnr) { + let doc = this.buffers.get(bufnr); + if (!doc) + return; + this._onDidSaveDocument.fire(doc.textDocument); + } + async onBufUnload(bufnr, recreate = false) { + logger.debug('buffer unload', bufnr); + if (!recreate) { + let source = this.creatingSources.get(bufnr); + if (source) { + source.cancel(); + this.creatingSources.delete(bufnr); + } + } + if (this.terminals.has(bufnr)) { + let terminal = this.terminals.get(bufnr); + this._onDidCloseTerminal.fire(terminal); + this.terminals.delete(bufnr); + } + let doc = this.buffers.get(bufnr); + if (doc) { + this._onDidCloseDocument.fire(doc.textDocument); + this.buffers.delete(bufnr); + if (!recreate) + doc.detach(); + } + await index_1.wait(10); + } + async onBufWritePre(bufnr) { + let doc = this.buffers.get(bufnr); + if (!doc) + return; + let event = { + document: doc.textDocument, + reason: vscode_languageserver_protocol_1.TextDocumentSaveReason.Manual + }; + this._onWillSaveDocument.fire(event); + if (this.willSaveUntilHandler.hasCallback) { + await this.willSaveUntilHandler.handeWillSaveUntil(event); + } + } + onDirChanged(cwd) { + if (cwd == this._cwd) + return; + this._cwd = cwd; + } + onFileTypeChange(filetype, bufnr) { + let doc = this.getDocument(bufnr); + if (!doc) + return; + let converted = doc.convertFiletype(filetype); + if (converted == doc.filetype) + return; + this._onDidCloseDocument.fire(doc.textDocument); + doc.setFiletype(filetype); + this._onDidOpenDocument.fire(doc.textDocument); + } + async checkBuffer(bufnr) { + if (this._disposed) + return; + let doc = this.getDocument(bufnr); + if (!doc && !this.creatingSources.has(bufnr)) + await this.onBufCreate(bufnr); + } + async getFileEncoding() { + let encoding = await this.nvim.getOption('fileencoding'); + return encoding ? encoding : 'utf-8'; + } + resolveRoot(document) { + let types = [types_1.PatternType.Buffer, types_1.PatternType.LanguageServer, types_1.PatternType.Global]; + let u = vscode_uri_1.URI.parse(document.uri); + let dir = path_1.default.dirname(u.fsPath); + let { cwd } = this; + for (let patternType of types) { + let patterns = this.getRootPatterns(document, patternType); + if (patterns && patterns.length) { + let root = fs_2.resolveRoot(dir, patterns, cwd); + if (root) + return root; + } + } + if (this.cwd != os_1.default.homedir() && fs_2.isParentFolder(this.cwd, dir)) + return this.cwd; + return null; + } + getRootPatterns(document, patternType) { + let { uri } = document; + if (patternType == types_1.PatternType.Buffer) + return document.getVar('root_patterns', []) || []; + if (patternType == types_1.PatternType.LanguageServer) + return this.getServerRootPatterns(document.filetype); + const preferences = this.getConfiguration('coc.preferences', uri); + return preferences.get('rootPatterns', ['.vim', '.git', '.hg', '.projections.json']).slice(); + } + async renameCurrent() { + let { nvim } = this; + let bufnr = await nvim.call('bufnr', '%'); + let cwd = await nvim.call('getcwd'); + let doc = this.getDocument(bufnr); + if (!doc || doc.buftype != '' || doc.schema != 'file') { + nvim.errWriteLine('current buffer is not file.'); + return; + } + let oldPath = vscode_uri_1.URI.parse(doc.uri).fsPath; + let newPath = await nvim.call('input', ['New path: ', oldPath, 'file']); + newPath = newPath ? newPath.trim() : null; + if (newPath == oldPath || !newPath) + return; + let lines = await doc.buffer.lines; + let exists = fs_1.default.existsSync(oldPath); + if (exists) { + let modified = await nvim.eval('&modified'); + if (modified) + await nvim.command('noa w'); + if (oldPath.toLowerCase() != newPath.toLowerCase() && fs_1.default.existsSync(newPath)) { + let overwrite = await this.showPrompt(`${newPath} exists, overwrite?`); + if (!overwrite) + return; + fs_1.default.unlinkSync(newPath); + } + fs_1.default.renameSync(oldPath, newPath); + } + let filepath = fs_2.isParentFolder(cwd, newPath) ? path_1.default.relative(cwd, newPath) : newPath; + let cursor = await nvim.call('getcurpos'); + nvim.pauseNotification(); + if (oldPath.toLowerCase() == newPath.toLowerCase()) { + nvim.command(`keepalt ${bufnr}bwipeout!`, true); + nvim.call('coc#util#open_file', ['keepalt edit', filepath], true); + } + else { + nvim.call('coc#util#open_file', ['keepalt edit', filepath], true); + nvim.command(`${bufnr}bwipeout!`, true); + } + if (!exists && lines.join('\n') != '\n') { + nvim.call('append', [0, lines], true); + nvim.command('normal! Gdd', true); + } + nvim.call('setpos', ['.', cursor], true); + await nvim.resumeNotification(); + } + setMessageLevel() { + let config = this.getConfiguration('coc.preferences'); + let level = config.get('messageLevel', 'more'); + switch (level) { + case 'error': + this.messageLevel = types_1.MessageLevel.Error; + break; + case 'warning': + this.messageLevel = types_1.MessageLevel.Warning; + break; + default: + this.messageLevel = types_1.MessageLevel.More; + } + } + mergeDocumentChanges(changes) { + let res = []; + let documentEdits = []; + for (let change of changes) { + if (index_1.isDocumentEdit(change)) { + let { edits, textDocument } = change; + let documentEdit = documentEdits.find(o => o.textDocument.uri == textDocument.uri && o.textDocument.version === textDocument.version); + if (documentEdit) { + documentEdit.edits.push(...edits); + } + else { + documentEdits.push(change); + } + } + else { + res.push(change); + } + } + res.push(...documentEdits); + return res; + } + get folderPaths() { + return this.workspaceFolders.map(f => vscode_uri_1.URI.parse(f.uri).fsPath); + } + removeWorkspaceFolder(fsPath) { + let idx = this._workspaceFolders.findIndex(f => vscode_uri_1.URI.parse(f.uri).fsPath == fsPath); + if (idx != -1) { + let folder = this._workspaceFolders[idx]; + this._workspaceFolders.splice(idx, 1); + this._onDidChangeWorkspaceFolders.fire({ + removed: [folder], + added: [] + }); + } + } + renameWorkspaceFolder(oldPath, newPath) { + let idx = this._workspaceFolders.findIndex(f => vscode_uri_1.URI.parse(f.uri).fsPath == oldPath); + if (idx == -1) + return; + let removed = this._workspaceFolders[idx]; + let added = { + uri: vscode_uri_1.URI.file(newPath).toString(), + name: path_1.default.dirname(newPath) + }; + this._workspaceFolders.splice(idx, 1); + this._workspaceFolders.push(added); + this._onDidChangeWorkspaceFolders.fire({ + removed: [removed], + added: [added] + }); + } + addRootPatterns(filetype, rootPatterns) { + let patterns = this.rootPatterns.get(filetype) || []; + for (let p of rootPatterns) { + if (patterns.indexOf(p) == -1) { + patterns.push(p); + } + } + this.rootPatterns.set(filetype, patterns); + } + get insertMode() { + return this._insertMode; + } + getDocumentOption(name, doc) { + if (doc) { + return doc.buffer.getOption(name).catch(_e => { + return this.nvim.getOption(name); + }); + } + return this.nvim.getOption(name); + } + addWorkspaceFolder(rootPath) { + if (rootPath == os_1.default.homedir()) + return; + let { _workspaceFolders } = this; + let uri = vscode_uri_1.URI.file(rootPath).toString(); + let workspaceFolder = { uri, name: path_1.default.basename(rootPath) }; + if (_workspaceFolders.findIndex(o => o.uri == uri) == -1) { + _workspaceFolders.push(workspaceFolder); + if (this._initialized) { + this._onDidChangeWorkspaceFolders.fire({ + added: [workspaceFolder], + removed: [] + }); + } + } + return workspaceFolder; + } + getServerRootPatterns(filetype) { + let lspConfig = this.getConfiguration().get('languageserver', {}); + let patterns = []; + for (let key of Object.keys(lspConfig)) { + let config = lspConfig[key]; + let { filetypes, rootPatterns } = config; + if (filetypes && rootPatterns && filetypes.indexOf(filetype) !== -1) { + patterns.push(...rootPatterns); + } + } + patterns = patterns.concat(this.rootPatterns.get(filetype) || []); + return patterns.length ? array_1.distinct(patterns) : null; + } +} +exports.Workspace = Workspace; +exports.default = new Workspace(); +//# sourceMappingURL=workspace.js.map + +/***/ }), +/* 188 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const os_1 = tslib_1.__importDefault(__webpack_require__(56)); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const vscode_uri_1 = __webpack_require__(180); +const types_1 = __webpack_require__(189); +const object_1 = __webpack_require__(190); +const util_1 = __webpack_require__(174); +const configuration_1 = __webpack_require__(192); +const model_1 = __webpack_require__(193); +const util_2 = __webpack_require__(194); +const is_1 = __webpack_require__(191); +const fs_2 = __webpack_require__(200); +const logger = __webpack_require__(186)('configurations'); +function lookUp(tree, key) { + if (key) { + if (tree && tree.hasOwnProperty(key)) + return tree[key]; + const parts = key.split('.'); + let node = tree; + for (let i = 0; node && i < parts.length; i++) { + node = node[parts[i]]; + } + return node; + } + return tree; +} +class Configurations { + constructor(userConfigFile, _proxy) { + this.userConfigFile = userConfigFile; + this._proxy = _proxy; + this._errorItems = []; + this._folderConfigurations = new Map(); + this._onError = new vscode_languageserver_protocol_1.Emitter(); + this._onChange = new vscode_languageserver_protocol_1.Emitter(); + this.disposables = []; + this.onError = this._onError.event; + this.onDidChange = this._onChange.event; + let user = this.parseContentFromFile(userConfigFile); + let data = { + defaults: util_2.loadDefaultConfigurations(), + user, + workspace: { contents: {} } + }; + this._configuration = Configurations.parse(data); + this.watchFile(userConfigFile, types_1.ConfigurationTarget.User); + } + parseContentFromFile(filepath) { + if (!filepath) + return { contents: {} }; + let uri = vscode_uri_1.URI.file(filepath).toString(); + this._errorItems = this._errorItems.filter(o => o.location.uri != uri); + let res = util_2.parseContentFromFile(filepath, errors => { + this._errorItems.push(...errors); + }); + this._onError.fire(this._errorItems); + return res; + } + get errorItems() { + return this._errorItems; + } + get foldConfigurations() { + return this._folderConfigurations; + } + // used for extensions, no change event fired + extendsDefaults(props) { + let { defaults } = this._configuration; + let { contents } = defaults; + contents = object_1.deepClone(contents); + Object.keys(props).forEach(key => { + util_2.addToValueTree(contents, key, props[key], msg => { + logger.error(msg); // tslint:disable-line + }); + }); + let data = { + defaults: { contents }, + user: this._configuration.user, + workspace: this._configuration.workspace + }; + this._configuration = Configurations.parse(data); + } + // change user configuration, without change file + updateUserConfig(props) { + if (!props || Object.keys(props).length == 0) + return; + let { user } = this._configuration; + let model = user.clone(); + Object.keys(props).forEach(key => { + let val = props[key]; + if (val === undefined) { + model.removeValue(key); + } + else if (is_1.objectLiteral(val)) { + for (let k of Object.keys(val)) { + model.setValue(`${key}.${k}`, val[k]); + } + } + else { + model.setValue(key, val); + } + }); + this.changeConfiguration(types_1.ConfigurationTarget.User, model); + } + get defaults() { + return this._configuration.defaults; + } + get user() { + return this._configuration.user; + } + get workspace() { + return this._configuration.workspace; + } + addFolderFile(filepath) { + let { _folderConfigurations } = this; + if (_folderConfigurations.has(filepath)) + return; + if (path_1.default.resolve(filepath, '../..') == os_1.default.homedir()) + return; + let model = this.parseContentFromFile(filepath); + this.watchFile(filepath, types_1.ConfigurationTarget.Workspace); + this.changeConfiguration(types_1.ConfigurationTarget.Workspace, model, filepath); + } + watchFile(filepath, target) { + if (!fs_1.default.existsSync(filepath)) + return; + if (global.hasOwnProperty('__TEST__')) + return; + let disposable = util_1.watchFile(filepath, () => { + let model = this.parseContentFromFile(filepath); + this.changeConfiguration(target, model, filepath); + }); + this.disposables.push(disposable); + } + // create new configuration and fire change event + changeConfiguration(target, model, configFile) { + let { defaults, user, workspace } = this._configuration; + let { workspaceConfigFile } = this; + let data = { + defaults: target == types_1.ConfigurationTarget.Global ? model : defaults, + user: target == types_1.ConfigurationTarget.User ? model : user, + workspace: target == types_1.ConfigurationTarget.Workspace ? model : workspace, + }; + let configuration = Configurations.parse(data); + let changed = util_2.getChangedKeys(this._configuration.getValue(), configuration.getValue()); + if (target == types_1.ConfigurationTarget.Workspace && configFile) { + this._folderConfigurations.set(configFile, new model_1.ConfigurationModel(model.contents)); + this.workspaceConfigFile = configFile; + } + if (changed.length == 0) + return; + this._configuration = configuration; + this._onChange.fire({ + affectsConfiguration: (section, resource) => { + if (!resource || target != types_1.ConfigurationTarget.Workspace) + return changed.indexOf(section) !== -1; + let u = vscode_uri_1.URI.parse(resource); + if (u.scheme !== 'file') + return changed.indexOf(section) !== -1; + let filepath = u.fsPath; + let preRoot = workspaceConfigFile ? path_1.default.resolve(workspaceConfigFile, '../..') : ''; + if (configFile && !fs_2.isParentFolder(preRoot, filepath) && !fs_2.isParentFolder(path_1.default.resolve(configFile, '../..'), filepath)) { + return false; + } + return changed.indexOf(section) !== -1; + } + }); + } + setFolderConfiguration(uri) { + let u = vscode_uri_1.URI.parse(uri); + if (u.scheme != 'file') + return; + let filepath = u.fsPath; + for (let [configFile, model] of this.foldConfigurations) { + let root = path_1.default.resolve(configFile, '../..'); + if (fs_2.isParentFolder(root, filepath) && this.workspaceConfigFile != configFile) { + this.changeConfiguration(types_1.ConfigurationTarget.Workspace, model, configFile); + break; + } + } + } + hasFolderConfiguration(filepath) { + let { folders } = this; + return folders.findIndex(f => fs_2.isParentFolder(f, filepath)) !== -1; + } + getConfigFile(target) { + if (target == types_1.ConfigurationTarget.Global) + return null; + if (target == types_1.ConfigurationTarget.User) + return this.userConfigFile; + return this.workspaceConfigFile; + } + get folders() { + let res = []; + let { _folderConfigurations } = this; + for (let folder of _folderConfigurations.keys()) { + res.push(path_1.default.resolve(folder, '../..')); + } + return res; + } + get configuration() { + return this._configuration; + } + /** + * getConfiguration + * + * @public + * @param {string} section + * @returns {WorkspaceConfiguration} + */ + getConfiguration(section, resource) { + let configuration; + if (resource) { + let { defaults, user } = this._configuration; + configuration = new configuration_1.Configuration(defaults, user, this.getFolderConfiguration(resource)); + } + else { + configuration = this._configuration; + } + const config = Object.freeze(lookUp(configuration.getValue(null), section)); + const result = { + has(key) { + return typeof lookUp(config, key) !== 'undefined'; + }, + get: (key, defaultValue) => { + let result = lookUp(config, key); + if (result == null) + return defaultValue; + return result; + }, + update: (key, value, isUser = false) => { + let s = section ? `${section}.${key}` : key; + let target = isUser ? types_1.ConfigurationTarget.User : types_1.ConfigurationTarget.Workspace; + let model = target == types_1.ConfigurationTarget.User ? this.user.clone() : this.workspace.clone(); + if (value == undefined) { + model.removeValue(s); + } + else { + model.setValue(s, value); + } + if (!this.workspaceConfigFile && this._proxy) { + let file = this.workspaceConfigFile = this._proxy.workspaceConfigFile; + if (!fs_1.default.existsSync(file)) { + let folder = path_1.default.dirname(file); + if (!fs_1.default.existsSync(folder)) + fs_1.default.mkdirSync(folder); + fs_1.default.writeFileSync(file, '{}', { encoding: 'utf8' }); + } + } + this.changeConfiguration(target, model, target == types_1.ConfigurationTarget.Workspace ? this.workspaceConfigFile : this.userConfigFile); + if (this._proxy && !global.hasOwnProperty('__TEST__')) { + if (value == undefined) { + this._proxy.$removeConfigurationOption(target, s); + } + else { + this._proxy.$updateConfigurationOption(target, s, value); + } + } + }, + inspect: (key) => { + key = section ? `${section}.${key}` : key; + const config = this._configuration.inspect(key); + if (config) { + return { + key, + defaultValue: config.default, + globalValue: config.user, + workspaceValue: config.workspace, + }; + } + return undefined; + } + }; + Object.defineProperty(result, 'has', { + enumerable: false + }); + Object.defineProperty(result, 'get', { + enumerable: false + }); + Object.defineProperty(result, 'update', { + enumerable: false + }); + Object.defineProperty(result, 'inspect', { + enumerable: false + }); + if (typeof config === 'object') { + object_1.mixin(result, config, false); + } + return object_1.deepFreeze(result); + } + getFolderConfiguration(uri) { + let u = vscode_uri_1.URI.parse(uri); + if (u.scheme != 'file') + return new model_1.ConfigurationModel(); + let filepath = u.fsPath; + for (let [configFile, model] of this.foldConfigurations) { + let root = path_1.default.resolve(configFile, '../..'); + if (fs_2.isParentFolder(root, filepath)) + return model; + } + return new model_1.ConfigurationModel(); + } + checkFolderConfiguration(uri) { + let u = vscode_uri_1.URI.parse(uri); + if (u.scheme != 'file') + return; + let rootPath = path_1.default.dirname(u.fsPath); + if (!this.hasFolderConfiguration(rootPath)) { + let folder = fs_2.findUp('.vim', rootPath); + if (folder && folder != os_1.default.homedir()) { + let file = path_1.default.join(folder, 'coc-settings.json'); + if (fs_1.default.existsSync(file)) { + this.addFolderFile(file); + } + } + } + else { + this.setFolderConfiguration(uri); + } + } + static parse(data) { + const defaultConfiguration = new model_1.ConfigurationModel(data.defaults.contents); + const userConfiguration = new model_1.ConfigurationModel(data.user.contents); + const workspaceConfiguration = new model_1.ConfigurationModel(data.workspace.contents); + return new configuration_1.Configuration(defaultConfiguration, userConfiguration, workspaceConfiguration, new model_1.ConfigurationModel()); + } + dispose() { + util_1.disposeAll(this.disposables); + } +} +exports.default = Configurations; +//# sourceMappingURL=index.js.map + +/***/ }), +/* 189 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var PatternType; +(function (PatternType) { + PatternType[PatternType["Buffer"] = 0] = "Buffer"; + PatternType[PatternType["LanguageServer"] = 1] = "LanguageServer"; + PatternType[PatternType["Global"] = 2] = "Global"; +})(PatternType = exports.PatternType || (exports.PatternType = {})); +var SourceType; +(function (SourceType) { + SourceType[SourceType["Native"] = 0] = "Native"; + SourceType[SourceType["Remote"] = 1] = "Remote"; + SourceType[SourceType["Service"] = 2] = "Service"; +})(SourceType = exports.SourceType || (exports.SourceType = {})); +var MessageLevel; +(function (MessageLevel) { + MessageLevel[MessageLevel["More"] = 0] = "More"; + MessageLevel[MessageLevel["Warning"] = 1] = "Warning"; + MessageLevel[MessageLevel["Error"] = 2] = "Error"; +})(MessageLevel = exports.MessageLevel || (exports.MessageLevel = {})); +var ConfigurationTarget; +(function (ConfigurationTarget) { + ConfigurationTarget[ConfigurationTarget["Global"] = 0] = "Global"; + ConfigurationTarget[ConfigurationTarget["User"] = 1] = "User"; + ConfigurationTarget[ConfigurationTarget["Workspace"] = 2] = "Workspace"; +})(ConfigurationTarget = exports.ConfigurationTarget || (exports.ConfigurationTarget = {})); +var DiagnosticKind; +(function (DiagnosticKind) { + DiagnosticKind[DiagnosticKind["Syntax"] = 0] = "Syntax"; + DiagnosticKind[DiagnosticKind["Semantic"] = 1] = "Semantic"; + DiagnosticKind[DiagnosticKind["Suggestion"] = 2] = "Suggestion"; +})(DiagnosticKind = exports.DiagnosticKind || (exports.DiagnosticKind = {})); +var ServiceStat; +(function (ServiceStat) { + ServiceStat[ServiceStat["Initial"] = 0] = "Initial"; + ServiceStat[ServiceStat["Starting"] = 1] = "Starting"; + ServiceStat[ServiceStat["StartFailed"] = 2] = "StartFailed"; + ServiceStat[ServiceStat["Running"] = 3] = "Running"; + ServiceStat[ServiceStat["Stopping"] = 4] = "Stopping"; + ServiceStat[ServiceStat["Stopped"] = 5] = "Stopped"; +})(ServiceStat = exports.ServiceStat || (exports.ServiceStat = {})); +//# sourceMappingURL=types.js.map + +/***/ }), +/* 190 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const Is = tslib_1.__importStar(__webpack_require__(191)); +function deepClone(obj) { + if (!obj || typeof obj !== 'object') { + return obj; + } + if (obj instanceof RegExp) { + // See https://github.com/Microsoft/TypeScript/issues/10990 + return obj; + } + const result = Array.isArray(obj) ? [] : {}; + Object.keys(obj).forEach(key => { + if (obj[key] && typeof obj[key] === 'object') { + result[key] = deepClone(obj[key]); + } + else { + result[key] = obj[key]; + } + }); + return result; +} +exports.deepClone = deepClone; +const _hasOwnProperty = Object.prototype.hasOwnProperty; +function deepFreeze(obj) { + if (!obj || typeof obj !== 'object') { + return obj; + } + const stack = [obj]; + while (stack.length > 0) { + let obj = stack.shift(); + Object.freeze(obj); + for (const key in obj) { + if (_hasOwnProperty.call(obj, key)) { + let prop = obj[key]; + if (typeof prop === 'object' && !Object.isFrozen(prop)) { + stack.push(prop); + } + } + } + } + return obj; +} +exports.deepFreeze = deepFreeze; +/** + * Copies all properties of source into destination. The optional parameter "overwrite" allows to control + * if existing properties on the destination should be overwritten or not. Defaults to true (overwrite). + */ +function mixin(destination, source, overwrite = true) { + if (!Is.objectLiteral(destination)) { + return source; + } + if (Is.objectLiteral(source)) { + Object.keys(source).forEach(key => { + if (key in destination) { + if (overwrite) { + if (Is.objectLiteral(destination[key]) && Is.objectLiteral(source[key])) { + mixin(destination[key], source[key], overwrite); + } + else { + destination[key] = source[key]; + } + } + } + else { + destination[key] = source[key]; + } + }); + } + return destination; +} +exports.mixin = mixin; +function equals(one, other) { + if (one === other) { + return true; + } + if (one === null || + one === undefined || + other === null || + other === undefined) { + return false; + } + if (typeof one !== typeof other) { + return false; + } + if (typeof one !== 'object') { + return false; + } + if (Array.isArray(one) !== Array.isArray(other)) { + return false; + } + let i; + let key; + if (Array.isArray(one)) { + if (one.length !== other.length) { + return false; + } + for (i = 0; i < one.length; i++) { + if (!equals(one[i], other[i])) { + return false; + } + } + } + else { + const oneKeys = []; + for (key in one) { // tslint:disable-line + oneKeys.push(key); + } + oneKeys.sort(); + const otherKeys = []; + for (key in other) { // tslint:disable-line + otherKeys.push(key); + } + otherKeys.sort(); + if (!equals(oneKeys, otherKeys)) { + return false; + } + for (i = 0; i < oneKeys.length; i++) { + if (!equals(one[oneKeys[i]], other[oneKeys[i]])) { + return false; + } + } + } + return true; +} +exports.equals = equals; +//# sourceMappingURL=object.js.map + +/***/ }), +/* 191 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const hasOwnProperty = Object.prototype.hasOwnProperty; +function boolean(value) { + return typeof value === 'boolean'; +} +exports.boolean = boolean; +function string(value) { + return typeof value === 'string'; +} +exports.string = string; +function number(value) { + return typeof value === 'number'; +} +exports.number = number; +function array(array) { + return Array.isArray(array); +} +exports.array = array; +function func(value) { + return typeof value == 'function'; +} +exports.func = func; +function objectLiteral(obj) { + return (obj != null && + typeof obj === 'object' && + !Array.isArray(obj) && + !(obj instanceof RegExp) && + !(obj instanceof Date)); +} +exports.objectLiteral = objectLiteral; +function emptyObject(obj) { + if (!objectLiteral(obj)) { + return false; + } + for (let key in obj) { + if (hasOwnProperty.call(obj, key)) { + return false; + } + } + return true; +} +exports.emptyObject = emptyObject; +function typedArray(value, check) { + return Array.isArray(value) && value.every(check); +} +exports.typedArray = typedArray; +//# sourceMappingURL=is.js.map + +/***/ }), +/* 192 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const model_1 = __webpack_require__(193); +class Configuration { + constructor(_defaultConfiguration, _userConfiguration, _workspaceConfiguration, _memoryConfiguration = new model_1.ConfigurationModel()) { + this._defaultConfiguration = _defaultConfiguration; + this._userConfiguration = _userConfiguration; + this._workspaceConfiguration = _workspaceConfiguration; + this._memoryConfiguration = _memoryConfiguration; + } + getConsolidateConfiguration() { + if (!this._consolidateConfiguration) { + this._consolidateConfiguration = this._defaultConfiguration.merge(this._userConfiguration, this._workspaceConfiguration, this._memoryConfiguration); + this._consolidateConfiguration = this._consolidateConfiguration.freeze(); + } + return this._consolidateConfiguration; + } + getValue(section) { + let configuration = this.getConsolidateConfiguration(); + return configuration.getValue(section); + } + inspect(key) { + const consolidateConfigurationModel = this.getConsolidateConfiguration(); + const { _workspaceConfiguration, _memoryConfiguration } = this; + return { + default: this._defaultConfiguration.freeze().getValue(key), + user: this._userConfiguration.freeze().getValue(key), + workspace: _workspaceConfiguration.freeze().getValue(key), + memory: _memoryConfiguration.freeze().getValue(key), + value: consolidateConfigurationModel.getValue(key) + }; + } + get defaults() { + return this._defaultConfiguration; + } + get user() { + return this._userConfiguration; + } + get workspace() { + return this._workspaceConfiguration; + } + toData() { + return { + defaults: { + contents: this._defaultConfiguration.contents + }, + user: { + contents: this._userConfiguration.contents + }, + workspace: { + contents: this._workspaceConfiguration.contents + } + }; + } +} +exports.Configuration = Configuration; +//# sourceMappingURL=configuration.js.map + +/***/ }), +/* 193 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const is_1 = __webpack_require__(191); +const object_1 = __webpack_require__(190); +const util_1 = __webpack_require__(194); +class ConfigurationModel { + constructor(_contents = {}) { + this._contents = _contents; + } + get contents() { + return this._contents; + } + clone() { + return new ConfigurationModel(object_1.deepClone(this._contents)); + } + getValue(section) { + let res = section + ? util_1.getConfigurationValue(this.contents, section) + : this.contents; + return res; + } + merge(...others) { + const contents = object_1.deepClone(this.contents); + for (const other of others) { + this.mergeContents(contents, other.contents); + } + return new ConfigurationModel(contents); + } + freeze() { + if (!Object.isFrozen(this._contents)) { + Object.freeze(this._contents); + } + return this; + } + mergeContents(source, target) { + for (const key of Object.keys(target)) { + if (key in source) { + if (is_1.objectLiteral(source[key]) && is_1.objectLiteral(target[key])) { + this.mergeContents(source[key], target[key]); + continue; + } + } + source[key] = object_1.deepClone(target[key]); + } + } + // Update methods + setValue(key, value) { + util_1.addToValueTree(this.contents, key, value, message => { + // tslint:disable-next-line:no-console + console.error(message); + }); + } + removeValue(key) { + util_1.removeFromValueTree(this.contents, key); + } +} +exports.ConfigurationModel = ConfigurationModel; +//# sourceMappingURL=model.js.map + +/***/ }), +/* 194 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const jsonc_parser_1 = __webpack_require__(195); +const is_1 = __webpack_require__(191); +const object_1 = __webpack_require__(190); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const vscode_uri_1 = __webpack_require__(180); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const logger = __webpack_require__(186)('configuration-util'); +const isWebpack = typeof __webpack_require__ === "function"; +const pluginRoot = isWebpack ? path_1.default.dirname(__dirname) : path_1.default.resolve(__dirname, '../..'); +function parseContentFromFile(filepath, onError) { + if (!filepath || !fs_1.default.existsSync(filepath)) + return { contents: {} }; + let content; + let uri = vscode_uri_1.URI.file(filepath).toString(); + try { + content = fs_1.default.readFileSync(filepath, 'utf8'); + } + catch (_e) { + content = ''; + } + let [errors, contents] = parseConfiguration(content); + if (errors && errors.length) { + onError(convertErrors(uri, content, errors)); + } + return { contents }; +} +exports.parseContentFromFile = parseContentFromFile; +function parseConfiguration(content) { + if (content.length == 0) + return [[], {}]; + let errors = []; + let data = jsonc_parser_1.parse(content, errors, { allowTrailingComma: true }); + function addProperty(current, key, remains, value) { + if (remains.length == 0) { + current[key] = convert(value); + } + else { + if (!current[key]) + current[key] = {}; + let o = current[key]; + let first = remains.shift(); + addProperty(o, first, remains, value); + } + } + function convert(obj, split = false) { + if (!is_1.objectLiteral(obj)) + return obj; + if (is_1.emptyObject(obj)) + return {}; + let dest = {}; + for (let key of Object.keys(obj)) { + if (split && key.indexOf('.') !== -1) { + let parts = key.split('.'); + let first = parts.shift(); + addProperty(dest, first, parts, obj[key]); + } + else { + dest[key] = convert(obj[key]); + } + } + return dest; + } + return [errors, convert(data, true)]; +} +exports.parseConfiguration = parseConfiguration; +function convertErrors(uri, content, errors) { + let items = []; + let document = vscode_languageserver_protocol_1.TextDocument.create(uri, 'json', 0, content); + for (let err of errors) { + let msg = 'parse error'; + switch (err.error) { + case 2: + msg = 'invalid number'; + break; + case 8: + msg = 'close brace expected'; + break; + case 5: + msg = 'colon expected'; + break; + case 6: + msg = 'comma expected'; + break; + case 9: + msg = 'end of file expected'; + break; + case 16: + msg = 'invaliad character'; + break; + case 10: + msg = 'invalid commment token'; + break; + case 15: + msg = 'invalid escape character'; + break; + case 1: + msg = 'invalid symbol'; + break; + case 14: + msg = 'invalid unicode'; + break; + case 3: + msg = 'property name expected'; + break; + case 13: + msg = 'unexpected end of number'; + break; + case 12: + msg = 'unexpected end of string'; + break; + case 11: + msg = 'unexpected end of comment'; + break; + case 4: + msg = 'value expected'; + break; + default: + msg = 'Unknwn error'; + break; + } + let range = { + start: document.positionAt(err.offset), + end: document.positionAt(err.offset + err.length), + }; + let loc = vscode_languageserver_protocol_1.Location.create(uri, range); + items.push({ location: loc, message: msg }); + } + return items; +} +exports.convertErrors = convertErrors; +function addToValueTree(settingsTreeRoot, key, value, conflictReporter) { + const segments = key.split('.'); + const last = segments.pop(); + let curr = settingsTreeRoot; + for (let i = 0; i < segments.length; i++) { + let s = segments[i]; + let obj = curr[s]; + switch (typeof obj) { + case 'function': { + obj = curr[s] = {}; + break; + } + case 'undefined': { + obj = curr[s] = {}; + break; + } + case 'object': + break; + default: + conflictReporter(`Ignoring ${key} as ${segments + .slice(0, i + 1) + .join('.')} is ${JSON.stringify(obj)}`); + return; + } + curr = obj; + } + if (typeof curr === 'object') { + curr[last] = value; // workaround https://github.com/Microsoft/vscode/issues/13606 + } + else { + conflictReporter(`Ignoring ${key} as ${segments.join('.')} is ${JSON.stringify(curr)}`); + } +} +exports.addToValueTree = addToValueTree; +function removeFromValueTree(valueTree, key) { + const segments = key.split('.'); + doRemoveFromValueTree(valueTree, segments); +} +exports.removeFromValueTree = removeFromValueTree; +function doRemoveFromValueTree(valueTree, segments) { + const first = segments.shift(); + if (segments.length === 0) { + // Reached last segment + delete valueTree[first]; + return; + } + if (Object.keys(valueTree).indexOf(first) !== -1) { + const value = valueTree[first]; + if (typeof value === 'object' && !Array.isArray(value)) { + doRemoveFromValueTree(value, segments); + if (Object.keys(value).length === 0) { + delete valueTree[first]; + } + } + } +} +function getConfigurationValue(config, settingPath, defaultValue) { + function accessSetting(config, path) { + let current = config; + for (let i = 0; i < path.length; i++) { // tslint:disable-line + if (typeof current !== 'object' || current === null) { + return undefined; + } + current = current[path[i]]; + } + return current; + } + const path = settingPath.split('.'); + const result = accessSetting(config, path); + return typeof result === 'undefined' ? defaultValue : result; +} +exports.getConfigurationValue = getConfigurationValue; +function loadDefaultConfigurations() { + let file = path_1.default.join(pluginRoot, 'data/schema.json'); + if (!fs_1.default.existsSync(file)) { + console.error('schema.json not found, reinstall coc.nvim to fix this!'); // tslint:disable-line + return { contents: {} }; + } + let content = fs_1.default.readFileSync(file, 'utf8'); + let { properties } = JSON.parse(content); + let config = {}; + Object.keys(properties).forEach(key => { + let value = properties[key].default; + if (value !== undefined) { + addToValueTree(config, key, value, message => { + logger.error(message); // tslint:disable-line + }); + } + }); + return { contents: config }; +} +exports.loadDefaultConfigurations = loadDefaultConfigurations; +function getKeys(obj, curr) { + let keys = []; + for (let key of Object.keys(obj)) { + let val = obj[key]; + let newKey = curr ? `${curr}.${key}` : key; + keys.push(newKey); + if (is_1.objectLiteral(val)) { + keys.push(...getKeys(val, newKey)); + } + } + return keys; +} +exports.getKeys = getKeys; +function getChangedKeys(from, to) { + let keys = []; + let fromKeys = getKeys(from); + let toKeys = getKeys(to); + const added = toKeys.filter(key => fromKeys.indexOf(key) === -1); + const removed = fromKeys.filter(key => toKeys.indexOf(key) === -1); + keys.push(...added); + keys.push(...removed); + for (const key of fromKeys) { + if (toKeys.indexOf(key) == -1) + continue; + const value1 = getConfigurationValue(from, key); + const value2 = getConfigurationValue(to, key); + if (!object_1.equals(value1, value2)) { + keys.push(key); + } + } + return keys; +} +exports.getChangedKeys = getChangedKeys; +//# sourceMappingURL=util.js.map + +/***/ }), +/* 195 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createScanner", function() { return createScanner; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getLocation", function() { return getLocation; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parse", function() { return parse; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseTree", function() { return parseTree; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findNodeAtLocation", function() { return findNodeAtLocation; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findNodeAtOffset", function() { return findNodeAtOffset; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getNodePath", function() { return getNodePath; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getNodeValue", function() { return getNodeValue; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "visit", function() { return visit; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stripComments", function() { return stripComments; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "printParseErrorCode", function() { return printParseErrorCode; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "format", function() { return format; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "modify", function() { return modify; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "applyEdits", function() { return applyEdits; }); +/* harmony import */ var _impl_format__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(196); +/* harmony import */ var _impl_edit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(198); +/* harmony import */ var _impl_scanner__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(197); +/* harmony import */ var _impl_parser__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(199); +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + + + + +/** + * Creates a JSON scanner on the given text. + * If ignoreTrivia is set, whitespaces or comments are ignored. + */ +var createScanner = _impl_scanner__WEBPACK_IMPORTED_MODULE_2__["createScanner"]; +/** + * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index. + */ +var getLocation = _impl_parser__WEBPACK_IMPORTED_MODULE_3__["getLocation"]; +/** + * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result. + * Therefore, always check the errors list to find out if the input was valid. + */ +var parse = _impl_parser__WEBPACK_IMPORTED_MODULE_3__["parse"]; +/** + * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result. + */ +var parseTree = _impl_parser__WEBPACK_IMPORTED_MODULE_3__["parseTree"]; +/** + * Finds the node at the given path in a JSON DOM. + */ +var findNodeAtLocation = _impl_parser__WEBPACK_IMPORTED_MODULE_3__["findNodeAtLocation"]; +/** + * Finds the innermost node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset. + */ +var findNodeAtOffset = _impl_parser__WEBPACK_IMPORTED_MODULE_3__["findNodeAtOffset"]; +/** + * Gets the JSON path of the given JSON DOM node + */ +var getNodePath = _impl_parser__WEBPACK_IMPORTED_MODULE_3__["getNodePath"]; +/** + * Evaluates the JavaScript object of the given JSON DOM node + */ +var getNodeValue = _impl_parser__WEBPACK_IMPORTED_MODULE_3__["getNodeValue"]; +/** + * Parses the given text and invokes the visitor functions for each object, array and literal reached. + */ +var visit = _impl_parser__WEBPACK_IMPORTED_MODULE_3__["visit"]; +/** + * Takes JSON with JavaScript-style comments and remove + * them. Optionally replaces every none-newline character + * of comments with a replaceCharacter + */ +var stripComments = _impl_parser__WEBPACK_IMPORTED_MODULE_3__["stripComments"]; +function printParseErrorCode(code) { + switch (code) { + case 1 /* InvalidSymbol */: return 'InvalidSymbol'; + case 2 /* InvalidNumberFormat */: return 'InvalidNumberFormat'; + case 3 /* PropertyNameExpected */: return 'PropertyNameExpected'; + case 4 /* ValueExpected */: return 'ValueExpected'; + case 5 /* ColonExpected */: return 'ColonExpected'; + case 6 /* CommaExpected */: return 'CommaExpected'; + case 7 /* CloseBraceExpected */: return 'CloseBraceExpected'; + case 8 /* CloseBracketExpected */: return 'CloseBracketExpected'; + case 9 /* EndOfFileExpected */: return 'EndOfFileExpected'; + case 10 /* InvalidCommentToken */: return 'InvalidCommentToken'; + case 11 /* UnexpectedEndOfComment */: return 'UnexpectedEndOfComment'; + case 12 /* UnexpectedEndOfString */: return 'UnexpectedEndOfString'; + case 13 /* UnexpectedEndOfNumber */: return 'UnexpectedEndOfNumber'; + case 14 /* InvalidUnicode */: return 'InvalidUnicode'; + case 15 /* InvalidEscapeCharacter */: return 'InvalidEscapeCharacter'; + case 16 /* InvalidCharacter */: return 'InvalidCharacter'; + } + return ''; +} +/** + * Computes the edits needed to format a JSON document. + * + * @param documentText The input text + * @param range The range to format or `undefined` to format the full content + * @param options The formatting options + * @returns A list of edit operations describing the formatting changes to the original document. Edits can be either inserts, replacements or + * removals of text segments. All offsets refer to the original state of the document. No two edits must change or remove the same range of + * text in the original document. However, multiple edits can have + * the same offset, for example multiple inserts, or an insert followed by a remove or replace. The order in the array defines which edit is applied first. + * To apply edits to an input, you can use `applyEdits`. + */ +function format(documentText, range, options) { + return _impl_format__WEBPACK_IMPORTED_MODULE_0__["format"](documentText, range, options); +} +/** + * Computes the edits needed to modify a value in the JSON document. + * + * @param documentText The input text + * @param path The path of the value to change. The path represents either to the document root, a property or an array item. + * If the path points to an non-existing property or item, it will be created. + * @param value The new value for the specified property or item. If the value is undefined, + * the property or item will be removed. + * @param options Options + * @returns A list of edit operations describing the formatting changes to the original document. Edits can be either inserts, replacements or + * removals of text segments. All offsets refer to the original state of the document. No two edits must change or remove the same range of + * text in the original document. However, multiple edits can have + * the same offset, for example multiple inserts, or an insert followed by a remove or replace. The order in the array defines which edit is applied first. + * To apply edits to an input, you can use `applyEdits`. + */ +function modify(text, path, value, options) { + return _impl_edit__WEBPACK_IMPORTED_MODULE_1__["setProperty"](text, path, value, options.formattingOptions, options.getInsertionIndex); +} +/** + * Applies edits to a input string. + */ +function applyEdits(text, edits) { + for (var i = edits.length - 1; i >= 0; i--) { + text = _impl_edit__WEBPACK_IMPORTED_MODULE_1__["applyEdit"](text, edits[i]); + } + return text; +} +//# sourceMappingURL=main.js.map + +/***/ }), +/* 196 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "format", function() { return format; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isEOL", function() { return isEOL; }); +/* harmony import */ var _scanner__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(197); +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + +function format(documentText, range, options) { + var initialIndentLevel; + var formatText; + var formatTextStart; + var rangeStart; + var rangeEnd; + if (range) { + rangeStart = range.offset; + rangeEnd = rangeStart + range.length; + formatTextStart = rangeStart; + while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) { + formatTextStart--; + } + var endOffset = rangeEnd; + while (endOffset < documentText.length && !isEOL(documentText, endOffset)) { + endOffset++; + } + formatText = documentText.substring(formatTextStart, endOffset); + initialIndentLevel = computeIndentLevel(formatText, options); + } + else { + formatText = documentText; + initialIndentLevel = 0; + formatTextStart = 0; + rangeStart = 0; + rangeEnd = documentText.length; + } + var eol = getEOL(options, documentText); + var lineBreak = false; + var indentLevel = 0; + var indentValue; + if (options.insertSpaces) { + indentValue = repeat(' ', options.tabSize || 4); + } + else { + indentValue = '\t'; + } + var scanner = Object(_scanner__WEBPACK_IMPORTED_MODULE_0__["createScanner"])(formatText, false); + var hasError = false; + function newLineAndIndent() { + return eol + repeat(indentValue, initialIndentLevel + indentLevel); + } + function scanNext() { + var token = scanner.scan(); + lineBreak = false; + while (token === 15 /* Trivia */ || token === 14 /* LineBreakTrivia */) { + lineBreak = lineBreak || (token === 14 /* LineBreakTrivia */); + token = scanner.scan(); + } + hasError = token === 16 /* Unknown */ || scanner.getTokenError() !== 0 /* None */; + return token; + } + var editOperations = []; + function addEdit(text, startOffset, endOffset) { + if (!hasError && startOffset < rangeEnd && endOffset > rangeStart && documentText.substring(startOffset, endOffset) !== text) { + editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text }); + } + } + var firstToken = scanNext(); + if (firstToken !== 17 /* EOF */) { + var firstTokenStart = scanner.getTokenOffset() + formatTextStart; + var initialIndent = repeat(indentValue, initialIndentLevel); + addEdit(initialIndent, formatTextStart, firstTokenStart); + } + while (firstToken !== 17 /* EOF */) { + var firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart; + var secondToken = scanNext(); + var replaceContent = ''; + while (!lineBreak && (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */)) { + // comments on the same line: keep them on the same line, but ignore them otherwise + var commentTokenStart = scanner.getTokenOffset() + formatTextStart; + addEdit(' ', firstTokenEnd, commentTokenStart); + firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart; + replaceContent = secondToken === 12 /* LineCommentTrivia */ ? newLineAndIndent() : ''; + secondToken = scanNext(); + } + if (secondToken === 2 /* CloseBraceToken */) { + if (firstToken !== 1 /* OpenBraceToken */) { + indentLevel--; + replaceContent = newLineAndIndent(); + } + } + else if (secondToken === 4 /* CloseBracketToken */) { + if (firstToken !== 3 /* OpenBracketToken */) { + indentLevel--; + replaceContent = newLineAndIndent(); + } + } + else { + switch (firstToken) { + case 3 /* OpenBracketToken */: + case 1 /* OpenBraceToken */: + indentLevel++; + replaceContent = newLineAndIndent(); + break; + case 5 /* CommaToken */: + case 12 /* LineCommentTrivia */: + replaceContent = newLineAndIndent(); + break; + case 13 /* BlockCommentTrivia */: + if (lineBreak) { + replaceContent = newLineAndIndent(); + } + else { + // symbol following comment on the same line: keep on same line, separate with ' ' + replaceContent = ' '; + } + break; + case 6 /* ColonToken */: + replaceContent = ' '; + break; + case 10 /* StringLiteral */: + if (secondToken === 6 /* ColonToken */) { + replaceContent = ''; + break; + } + // fall through + case 7 /* NullKeyword */: + case 8 /* TrueKeyword */: + case 9 /* FalseKeyword */: + case 11 /* NumericLiteral */: + case 2 /* CloseBraceToken */: + case 4 /* CloseBracketToken */: + if (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */) { + replaceContent = ' '; + } + else if (secondToken !== 5 /* CommaToken */ && secondToken !== 17 /* EOF */) { + hasError = true; + } + break; + case 16 /* Unknown */: + hasError = true; + break; + } + if (lineBreak && (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */)) { + replaceContent = newLineAndIndent(); + } + } + var secondTokenStart = scanner.getTokenOffset() + formatTextStart; + addEdit(replaceContent, firstTokenEnd, secondTokenStart); + firstToken = secondToken; + } + return editOperations; +} +function repeat(s, count) { + var result = ''; + for (var i = 0; i < count; i++) { + result += s; + } + return result; +} +function computeIndentLevel(content, options) { + var i = 0; + var nChars = 0; + var tabSize = options.tabSize || 4; + while (i < content.length) { + var ch = content.charAt(i); + if (ch === ' ') { + nChars++; + } + else if (ch === '\t') { + nChars += tabSize; + } + else { + break; + } + i++; + } + return Math.floor(nChars / tabSize); +} +function getEOL(options, text) { + for (var i = 0; i < text.length; i++) { + var ch = text.charAt(i); + if (ch === '\r') { + if (i + 1 < text.length && text.charAt(i + 1) === '\n') { + return '\r\n'; + } + return '\r'; + } + else if (ch === '\n') { + return '\n'; + } + } + return (options && options.eol) || '\n'; +} +function isEOL(text, offset) { + return '\r\n'.indexOf(text.charAt(offset)) !== -1; +} +//# sourceMappingURL=format.js.map + +/***/ }), +/* 197 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createScanner", function() { return createScanner; }); +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * Creates a JSON scanner on the given text. + * If ignoreTrivia is set, whitespaces or comments are ignored. + */ +function createScanner(text, ignoreTrivia) { + if (ignoreTrivia === void 0) { ignoreTrivia = false; } + var pos = 0, len = text.length, value = '', tokenOffset = 0, token = 16 /* Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* None */; + function scanHexDigits(count, exact) { + var digits = 0; + var value = 0; + while (digits < count || !exact) { + var ch = text.charCodeAt(pos); + if (ch >= 48 /* _0 */ && ch <= 57 /* _9 */) { + value = value * 16 + ch - 48 /* _0 */; + } + else if (ch >= 65 /* A */ && ch <= 70 /* F */) { + value = value * 16 + ch - 65 /* A */ + 10; + } + else if (ch >= 97 /* a */ && ch <= 102 /* f */) { + value = value * 16 + ch - 97 /* a */ + 10; + } + else { + break; + } + pos++; + digits++; + } + if (digits < count) { + value = -1; + } + return value; + } + function setPosition(newPosition) { + pos = newPosition; + value = ''; + tokenOffset = 0; + token = 16 /* Unknown */; + scanError = 0 /* None */; + } + function scanNumber() { + var start = pos; + if (text.charCodeAt(pos) === 48 /* _0 */) { + pos++; + } + else { + pos++; + while (pos < text.length && isDigit(text.charCodeAt(pos))) { + pos++; + } + } + if (pos < text.length && text.charCodeAt(pos) === 46 /* dot */) { + pos++; + if (pos < text.length && isDigit(text.charCodeAt(pos))) { + pos++; + while (pos < text.length && isDigit(text.charCodeAt(pos))) { + pos++; + } + } + else { + scanError = 3 /* UnexpectedEndOfNumber */; + return text.substring(start, pos); + } + } + var end = pos; + if (pos < text.length && (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */)) { + pos++; + if (pos < text.length && text.charCodeAt(pos) === 43 /* plus */ || text.charCodeAt(pos) === 45 /* minus */) { + pos++; + } + if (pos < text.length && isDigit(text.charCodeAt(pos))) { + pos++; + while (pos < text.length && isDigit(text.charCodeAt(pos))) { + pos++; + } + end = pos; + } + else { + scanError = 3 /* UnexpectedEndOfNumber */; + } + } + return text.substring(start, end); + } + function scanString() { + var result = '', start = pos; + while (true) { + if (pos >= len) { + result += text.substring(start, pos); + scanError = 2 /* UnexpectedEndOfString */; + break; + } + var ch = text.charCodeAt(pos); + if (ch === 34 /* doubleQuote */) { + result += text.substring(start, pos); + pos++; + break; + } + if (ch === 92 /* backslash */) { + result += text.substring(start, pos); + pos++; + if (pos >= len) { + scanError = 2 /* UnexpectedEndOfString */; + break; + } + ch = text.charCodeAt(pos++); + switch (ch) { + case 34 /* doubleQuote */: + result += '\"'; + break; + case 92 /* backslash */: + result += '\\'; + break; + case 47 /* slash */: + result += '/'; + break; + case 98 /* b */: + result += '\b'; + break; + case 102 /* f */: + result += '\f'; + break; + case 110 /* n */: + result += '\n'; + break; + case 114 /* r */: + result += '\r'; + break; + case 116 /* t */: + result += '\t'; + break; + case 117 /* u */: + var ch_1 = scanHexDigits(4, true); + if (ch_1 >= 0) { + result += String.fromCharCode(ch_1); + } + else { + scanError = 4 /* InvalidUnicode */; + } + break; + default: + scanError = 5 /* InvalidEscapeCharacter */; + } + start = pos; + continue; + } + if (ch >= 0 && ch <= 0x1f) { + if (isLineBreak(ch)) { + result += text.substring(start, pos); + scanError = 2 /* UnexpectedEndOfString */; + break; + } + else { + scanError = 6 /* InvalidCharacter */; + // mark as error but continue with string + } + } + pos++; + } + return result; + } + function scanNext() { + value = ''; + scanError = 0 /* None */; + tokenOffset = pos; + lineStartOffset = lineNumber; + prevTokenLineStartOffset = tokenLineStartOffset; + if (pos >= len) { + // at the end + tokenOffset = len; + return token = 17 /* EOF */; + } + var code = text.charCodeAt(pos); + // trivia: whitespace + if (isWhiteSpace(code)) { + do { + pos++; + value += String.fromCharCode(code); + code = text.charCodeAt(pos); + } while (isWhiteSpace(code)); + return token = 15 /* Trivia */; + } + // trivia: newlines + if (isLineBreak(code)) { + pos++; + value += String.fromCharCode(code); + if (code === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) { + pos++; + value += '\n'; + } + lineNumber++; + tokenLineStartOffset = pos; + return token = 14 /* LineBreakTrivia */; + } + switch (code) { + // tokens: []{}:, + case 123 /* openBrace */: + pos++; + return token = 1 /* OpenBraceToken */; + case 125 /* closeBrace */: + pos++; + return token = 2 /* CloseBraceToken */; + case 91 /* openBracket */: + pos++; + return token = 3 /* OpenBracketToken */; + case 93 /* closeBracket */: + pos++; + return token = 4 /* CloseBracketToken */; + case 58 /* colon */: + pos++; + return token = 6 /* ColonToken */; + case 44 /* comma */: + pos++; + return token = 5 /* CommaToken */; + // strings + case 34 /* doubleQuote */: + pos++; + value = scanString(); + return token = 10 /* StringLiteral */; + // comments + case 47 /* slash */: + var start = pos - 1; + // Single-line comment + if (text.charCodeAt(pos + 1) === 47 /* slash */) { + pos += 2; + while (pos < len) { + if (isLineBreak(text.charCodeAt(pos))) { + break; + } + pos++; + } + value = text.substring(start, pos); + return token = 12 /* LineCommentTrivia */; + } + // Multi-line comment + if (text.charCodeAt(pos + 1) === 42 /* asterisk */) { + pos += 2; + var safeLength = len - 1; // For lookahead. + var commentClosed = false; + while (pos < safeLength) { + var ch = text.charCodeAt(pos); + if (ch === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) { + pos += 2; + commentClosed = true; + break; + } + pos++; + if (isLineBreak(ch)) { + if (ch === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) { + pos++; + } + lineNumber++; + tokenLineStartOffset = pos; + } + } + if (!commentClosed) { + pos++; + scanError = 1 /* UnexpectedEndOfComment */; + } + value = text.substring(start, pos); + return token = 13 /* BlockCommentTrivia */; + } + // just a single slash + value += String.fromCharCode(code); + pos++; + return token = 16 /* Unknown */; + // numbers + case 45 /* minus */: + value += String.fromCharCode(code); + pos++; + if (pos === len || !isDigit(text.charCodeAt(pos))) { + return token = 16 /* Unknown */; + } + // found a minus, followed by a number so + // we fall through to proceed with scanning + // numbers + case 48 /* _0 */: + case 49 /* _1 */: + case 50 /* _2 */: + case 51 /* _3 */: + case 52 /* _4 */: + case 53 /* _5 */: + case 54 /* _6 */: + case 55 /* _7 */: + case 56 /* _8 */: + case 57 /* _9 */: + value += scanNumber(); + return token = 11 /* NumericLiteral */; + // literals and unknown symbols + default: + // is a literal? Read the full word. + while (pos < len && isUnknownContentCharacter(code)) { + pos++; + code = text.charCodeAt(pos); + } + if (tokenOffset !== pos) { + value = text.substring(tokenOffset, pos); + // keywords: true, false, null + switch (value) { + case 'true': return token = 8 /* TrueKeyword */; + case 'false': return token = 9 /* FalseKeyword */; + case 'null': return token = 7 /* NullKeyword */; + } + return token = 16 /* Unknown */; + } + // some + value += String.fromCharCode(code); + pos++; + return token = 16 /* Unknown */; + } + } + function isUnknownContentCharacter(code) { + if (isWhiteSpace(code) || isLineBreak(code)) { + return false; + } + switch (code) { + case 125 /* closeBrace */: + case 93 /* closeBracket */: + case 123 /* openBrace */: + case 91 /* openBracket */: + case 34 /* doubleQuote */: + case 58 /* colon */: + case 44 /* comma */: + case 47 /* slash */: + return false; + } + return true; + } + function scanNextNonTrivia() { + var result; + do { + result = scanNext(); + } while (result >= 12 /* LineCommentTrivia */ && result <= 15 /* Trivia */); + return result; + } + return { + setPosition: setPosition, + getPosition: function () { return pos; }, + scan: ignoreTrivia ? scanNextNonTrivia : scanNext, + getToken: function () { return token; }, + getTokenValue: function () { return value; }, + getTokenOffset: function () { return tokenOffset; }, + getTokenLength: function () { return pos - tokenOffset; }, + getTokenStartLine: function () { return lineStartOffset; }, + getTokenStartCharacter: function () { return tokenOffset - prevTokenLineStartOffset; }, + getTokenError: function () { return scanError; }, + }; +} +function isWhiteSpace(ch) { + return ch === 32 /* space */ || ch === 9 /* tab */ || ch === 11 /* verticalTab */ || ch === 12 /* formFeed */ || + ch === 160 /* nonBreakingSpace */ || ch === 5760 /* ogham */ || ch >= 8192 /* enQuad */ && ch <= 8203 /* zeroWidthSpace */ || + ch === 8239 /* narrowNoBreakSpace */ || ch === 8287 /* mathematicalSpace */ || ch === 12288 /* ideographicSpace */ || ch === 65279 /* byteOrderMark */; +} +function isLineBreak(ch) { + return ch === 10 /* lineFeed */ || ch === 13 /* carriageReturn */ || ch === 8232 /* lineSeparator */ || ch === 8233 /* paragraphSeparator */; +} +function isDigit(ch) { + return ch >= 48 /* _0 */ && ch <= 57 /* _9 */; +} +//# sourceMappingURL=scanner.js.map + +/***/ }), +/* 198 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeProperty", function() { return removeProperty; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setProperty", function() { return setProperty; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "applyEdit", function() { return applyEdit; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isWS", function() { return isWS; }); +/* harmony import */ var _format__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(196); +/* harmony import */ var _parser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(199); +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + + +function removeProperty(text, path, formattingOptions) { + return setProperty(text, path, void 0, formattingOptions); +} +function setProperty(text, originalPath, value, formattingOptions, getInsertionIndex) { + var _a; + var path = originalPath.slice(); + var errors = []; + var root = Object(_parser__WEBPACK_IMPORTED_MODULE_1__["parseTree"])(text, errors); + var parent = void 0; + var lastSegment = void 0; + while (path.length > 0) { + lastSegment = path.pop(); + parent = Object(_parser__WEBPACK_IMPORTED_MODULE_1__["findNodeAtLocation"])(root, path); + if (parent === void 0 && value !== void 0) { + if (typeof lastSegment === 'string') { + value = (_a = {}, _a[lastSegment] = value, _a); + } + else { + value = [value]; + } + } + else { + break; + } + } + if (!parent) { + // empty document + if (value === void 0) { // delete + throw new Error('Can not delete in empty document'); + } + return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, formattingOptions); + } + else if (parent.type === 'object' && typeof lastSegment === 'string' && Array.isArray(parent.children)) { + var existing = Object(_parser__WEBPACK_IMPORTED_MODULE_1__["findNodeAtLocation"])(parent, [lastSegment]); + if (existing !== void 0) { + if (value === void 0) { // delete + if (!existing.parent) { + throw new Error('Malformed AST'); + } + var propertyIndex = parent.children.indexOf(existing.parent); + var removeBegin = void 0; + var removeEnd = existing.parent.offset + existing.parent.length; + if (propertyIndex > 0) { + // remove the comma of the previous node + var previous = parent.children[propertyIndex - 1]; + removeBegin = previous.offset + previous.length; + } + else { + removeBegin = parent.offset + 1; + if (parent.children.length > 1) { + // remove the comma of the next node + var next = parent.children[1]; + removeEnd = next.offset; + } + } + return withFormatting(text, { offset: removeBegin, length: removeEnd - removeBegin, content: '' }, formattingOptions); + } + else { + // set value of existing property + return withFormatting(text, { offset: existing.offset, length: existing.length, content: JSON.stringify(value) }, formattingOptions); + } + } + else { + if (value === void 0) { // delete + return []; // property does not exist, nothing to do + } + var newProperty = JSON.stringify(lastSegment) + ": " + JSON.stringify(value); + var index = getInsertionIndex ? getInsertionIndex(parent.children.map(function (p) { return p.children[0].value; })) : parent.children.length; + var edit = void 0; + if (index > 0) { + var previous = parent.children[index - 1]; + edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty }; + } + else if (parent.children.length === 0) { + edit = { offset: parent.offset + 1, length: 0, content: newProperty }; + } + else { + edit = { offset: parent.offset + 1, length: 0, content: newProperty + ',' }; + } + return withFormatting(text, edit, formattingOptions); + } + } + else if (parent.type === 'array' && typeof lastSegment === 'number' && Array.isArray(parent.children)) { + var insertIndex = lastSegment; + if (insertIndex === -1) { + // Insert + var newProperty = "" + JSON.stringify(value); + var edit = void 0; + if (parent.children.length === 0) { + edit = { offset: parent.offset + 1, length: 0, content: newProperty }; + } + else { + var previous = parent.children[parent.children.length - 1]; + edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty }; + } + return withFormatting(text, edit, formattingOptions); + } + else { + if (value === void 0 && parent.children.length >= 0) { + //Removal + var removalIndex = lastSegment; + var toRemove = parent.children[removalIndex]; + var edit = void 0; + if (parent.children.length === 1) { + // only item + edit = { offset: parent.offset + 1, length: parent.length - 2, content: '' }; + } + else if (parent.children.length - 1 === removalIndex) { + // last item + var previous = parent.children[removalIndex - 1]; + var offset = previous.offset + previous.length; + var parentEndOffset = parent.offset + parent.length; + edit = { offset: offset, length: parentEndOffset - 2 - offset, content: '' }; + } + else { + edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: '' }; + } + return withFormatting(text, edit, formattingOptions); + } + else { + throw new Error('Array modification not supported yet'); + } + } + } + else { + throw new Error("Can not add " + (typeof lastSegment !== 'number' ? 'index' : 'property') + " to parent of type " + parent.type); + } +} +function withFormatting(text, edit, formattingOptions) { + // apply the edit + var newText = applyEdit(text, edit); + // format the new text + var begin = edit.offset; + var end = edit.offset + edit.content.length; + if (edit.length === 0 || edit.content.length === 0) { // insert or remove + while (begin > 0 && !Object(_format__WEBPACK_IMPORTED_MODULE_0__["isEOL"])(newText, begin - 1)) { + begin--; + } + while (end < newText.length && !Object(_format__WEBPACK_IMPORTED_MODULE_0__["isEOL"])(newText, end)) { + end++; + } + } + var edits = Object(_format__WEBPACK_IMPORTED_MODULE_0__["format"])(newText, { offset: begin, length: end - begin }, formattingOptions); + // apply the formatting edits and track the begin and end offsets of the changes + for (var i = edits.length - 1; i >= 0; i--) { + var edit_1 = edits[i]; + newText = applyEdit(newText, edit_1); + begin = Math.min(begin, edit_1.offset); + end = Math.max(end, edit_1.offset + edit_1.length); + end += edit_1.content.length - edit_1.length; + } + // create a single edit with all changes + var editLength = text.length - (newText.length - end) - begin; + return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }]; +} +function applyEdit(text, edit) { + return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length); +} +function isWS(text, offset) { + return '\r\n \t'.indexOf(text.charAt(offset)) !== -1; +} +//# sourceMappingURL=edit.js.map + +/***/ }), +/* 199 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getLocation", function() { return getLocation; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parse", function() { return parse; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseTree", function() { return parseTree; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findNodeAtLocation", function() { return findNodeAtLocation; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getNodePath", function() { return getNodePath; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getNodeValue", function() { return getNodeValue; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "contains", function() { return contains; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findNodeAtOffset", function() { return findNodeAtOffset; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "visit", function() { return visit; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stripComments", function() { return stripComments; }); +/* harmony import */ var _scanner__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(197); +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + +var ParseOptions; +(function (ParseOptions) { + ParseOptions.DEFAULT = { + allowTrailingComma: false + }; +})(ParseOptions || (ParseOptions = {})); +/** + * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index. + */ +function getLocation(text, position) { + var segments = []; // strings or numbers + var earlyReturnException = new Object(); + var previousNode = void 0; + var previousNodeInst = { + value: {}, + offset: 0, + length: 0, + type: 'object', + parent: void 0 + }; + var isAtPropertyKey = false; + function setPreviousNode(value, offset, length, type) { + previousNodeInst.value = value; + previousNodeInst.offset = offset; + previousNodeInst.length = length; + previousNodeInst.type = type; + previousNodeInst.colonOffset = void 0; + previousNode = previousNodeInst; + } + try { + visit(text, { + onObjectBegin: function (offset, length) { + if (position <= offset) { + throw earlyReturnException; + } + previousNode = void 0; + isAtPropertyKey = position > offset; + segments.push(''); // push a placeholder (will be replaced) + }, + onObjectProperty: function (name, offset, length) { + if (position < offset) { + throw earlyReturnException; + } + setPreviousNode(name, offset, length, 'property'); + segments[segments.length - 1] = name; + if (position <= offset + length) { + throw earlyReturnException; + } + }, + onObjectEnd: function (offset, length) { + if (position <= offset) { + throw earlyReturnException; + } + previousNode = void 0; + segments.pop(); + }, + onArrayBegin: function (offset, length) { + if (position <= offset) { + throw earlyReturnException; + } + previousNode = void 0; + segments.push(0); + }, + onArrayEnd: function (offset, length) { + if (position <= offset) { + throw earlyReturnException; + } + previousNode = void 0; + segments.pop(); + }, + onLiteralValue: function (value, offset, length) { + if (position < offset) { + throw earlyReturnException; + } + setPreviousNode(value, offset, length, getLiteralNodeType(value)); + if (position <= offset + length) { + throw earlyReturnException; + } + }, + onSeparator: function (sep, offset, length) { + if (position <= offset) { + throw earlyReturnException; + } + if (sep === ':' && previousNode && previousNode.type === 'property') { + previousNode.colonOffset = offset; + isAtPropertyKey = false; + previousNode = void 0; + } + else if (sep === ',') { + var last = segments[segments.length - 1]; + if (typeof last === 'number') { + segments[segments.length - 1] = last + 1; + } + else { + isAtPropertyKey = true; + segments[segments.length - 1] = ''; + } + previousNode = void 0; + } + } + }); + } + catch (e) { + if (e !== earlyReturnException) { + throw e; + } + } + return { + path: segments, + previousNode: previousNode, + isAtPropertyKey: isAtPropertyKey, + matches: function (pattern) { + var k = 0; + for (var i = 0; k < pattern.length && i < segments.length; i++) { + if (pattern[k] === segments[i] || pattern[k] === '*') { + k++; + } + else if (pattern[k] !== '**') { + return false; + } + } + return k === pattern.length; + } + }; +} +/** + * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result. + * Therefore always check the errors list to find out if the input was valid. + */ +function parse(text, errors, options) { + if (errors === void 0) { errors = []; } + if (options === void 0) { options = ParseOptions.DEFAULT; } + var currentProperty = null; + var currentParent = []; + var previousParents = []; + function onValue(value) { + if (Array.isArray(currentParent)) { + currentParent.push(value); + } + else if (currentProperty) { + currentParent[currentProperty] = value; + } + } + var visitor = { + onObjectBegin: function () { + var object = {}; + onValue(object); + previousParents.push(currentParent); + currentParent = object; + currentProperty = null; + }, + onObjectProperty: function (name) { + currentProperty = name; + }, + onObjectEnd: function () { + currentParent = previousParents.pop(); + }, + onArrayBegin: function () { + var array = []; + onValue(array); + previousParents.push(currentParent); + currentParent = array; + currentProperty = null; + }, + onArrayEnd: function () { + currentParent = previousParents.pop(); + }, + onLiteralValue: onValue, + onError: function (error, offset, length) { + errors.push({ error: error, offset: offset, length: length }); + } + }; + visit(text, visitor, options); + return currentParent[0]; +} +/** + * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result. + */ +function parseTree(text, errors, options) { + if (errors === void 0) { errors = []; } + if (options === void 0) { options = ParseOptions.DEFAULT; } + var currentParent = { type: 'array', offset: -1, length: -1, children: [], parent: void 0 }; // artificial root + function ensurePropertyComplete(endOffset) { + if (currentParent.type === 'property') { + currentParent.length = endOffset - currentParent.offset; + currentParent = currentParent.parent; + } + } + function onValue(valueNode) { + currentParent.children.push(valueNode); + return valueNode; + } + var visitor = { + onObjectBegin: function (offset) { + currentParent = onValue({ type: 'object', offset: offset, length: -1, parent: currentParent, children: [] }); + }, + onObjectProperty: function (name, offset, length) { + currentParent = onValue({ type: 'property', offset: offset, length: -1, parent: currentParent, children: [] }); + currentParent.children.push({ type: 'string', value: name, offset: offset, length: length, parent: currentParent }); + }, + onObjectEnd: function (offset, length) { + currentParent.length = offset + length - currentParent.offset; + currentParent = currentParent.parent; + ensurePropertyComplete(offset + length); + }, + onArrayBegin: function (offset, length) { + currentParent = onValue({ type: 'array', offset: offset, length: -1, parent: currentParent, children: [] }); + }, + onArrayEnd: function (offset, length) { + currentParent.length = offset + length - currentParent.offset; + currentParent = currentParent.parent; + ensurePropertyComplete(offset + length); + }, + onLiteralValue: function (value, offset, length) { + onValue({ type: getLiteralNodeType(value), offset: offset, length: length, parent: currentParent, value: value }); + ensurePropertyComplete(offset + length); + }, + onSeparator: function (sep, offset, length) { + if (currentParent.type === 'property') { + if (sep === ':') { + currentParent.colonOffset = offset; + } + else if (sep === ',') { + ensurePropertyComplete(offset); + } + } + }, + onError: function (error, offset, length) { + errors.push({ error: error, offset: offset, length: length }); + } + }; + visit(text, visitor, options); + var result = currentParent.children[0]; + if (result) { + delete result.parent; + } + return result; +} +/** + * Finds the node at the given path in a JSON DOM. + */ +function findNodeAtLocation(root, path) { + if (!root) { + return void 0; + } + var node = root; + for (var _i = 0, path_1 = path; _i < path_1.length; _i++) { + var segment = path_1[_i]; + if (typeof segment === 'string') { + if (node.type !== 'object' || !Array.isArray(node.children)) { + return void 0; + } + var found = false; + for (var _a = 0, _b = node.children; _a < _b.length; _a++) { + var propertyNode = _b[_a]; + if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment) { + node = propertyNode.children[1]; + found = true; + break; + } + } + if (!found) { + return void 0; + } + } + else { + var index = segment; + if (node.type !== 'array' || index < 0 || !Array.isArray(node.children) || index >= node.children.length) { + return void 0; + } + node = node.children[index]; + } + } + return node; +} +/** + * Gets the JSON path of the given JSON DOM node + */ +function getNodePath(node) { + if (!node.parent || !node.parent.children) { + return []; + } + var path = getNodePath(node.parent); + if (node.parent.type === 'property') { + var key = node.parent.children[0].value; + path.push(key); + } + else if (node.parent.type === 'array') { + var index = node.parent.children.indexOf(node); + if (index !== -1) { + path.push(index); + } + } + return path; +} +/** + * Evaluates the JavaScript object of the given JSON DOM node + */ +function getNodeValue(node) { + switch (node.type) { + case 'array': + return node.children.map(getNodeValue); + case 'object': + var obj = Object.create(null); + for (var _i = 0, _a = node.children; _i < _a.length; _i++) { + var prop = _a[_i]; + var valueNode = prop.children[1]; + if (valueNode) { + obj[prop.children[0].value] = getNodeValue(valueNode); + } + } + return obj; + case 'null': + case 'string': + case 'number': + case 'boolean': + return node.value; + default: + return void 0; + } +} +function contains(node, offset, includeRightBound) { + if (includeRightBound === void 0) { includeRightBound = false; } + return (offset >= node.offset && offset < (node.offset + node.length)) || includeRightBound && (offset === (node.offset + node.length)); +} +/** + * Finds the most inner node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset. + */ +function findNodeAtOffset(node, offset, includeRightBound) { + if (includeRightBound === void 0) { includeRightBound = false; } + if (contains(node, offset, includeRightBound)) { + var children = node.children; + if (Array.isArray(children)) { + for (var i = 0; i < children.length && children[i].offset <= offset; i++) { + var item = findNodeAtOffset(children[i], offset, includeRightBound); + if (item) { + return item; + } + } + } + return node; + } + return void 0; +} +/** + * Parses the given text and invokes the visitor functions for each object, array and literal reached. + */ +function visit(text, visitor, options) { + if (options === void 0) { options = ParseOptions.DEFAULT; } + var _scanner = Object(_scanner__WEBPACK_IMPORTED_MODULE_0__["createScanner"])(text, false); + function toNoArgVisit(visitFunction) { + return visitFunction ? function () { return visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()); } : function () { return true; }; + } + function toOneArgVisit(visitFunction) { + return visitFunction ? function (arg) { return visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()); } : function () { return true; }; + } + var onObjectBegin = toNoArgVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisit(visitor.onObjectProperty), onObjectEnd = toNoArgVisit(visitor.onObjectEnd), onArrayBegin = toNoArgVisit(visitor.onArrayBegin), onArrayEnd = toNoArgVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisit(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError); + var disallowComments = options && options.disallowComments; + var allowTrailingComma = options && options.allowTrailingComma; + function scanNext() { + while (true) { + var token = _scanner.scan(); + switch (_scanner.getTokenError()) { + case 4 /* InvalidUnicode */: + handleError(14 /* InvalidUnicode */); + break; + case 5 /* InvalidEscapeCharacter */: + handleError(15 /* InvalidEscapeCharacter */); + break; + case 3 /* UnexpectedEndOfNumber */: + handleError(13 /* UnexpectedEndOfNumber */); + break; + case 1 /* UnexpectedEndOfComment */: + if (!disallowComments) { + handleError(11 /* UnexpectedEndOfComment */); + } + break; + case 2 /* UnexpectedEndOfString */: + handleError(12 /* UnexpectedEndOfString */); + break; + case 6 /* InvalidCharacter */: + handleError(16 /* InvalidCharacter */); + break; + } + switch (token) { + case 12 /* LineCommentTrivia */: + case 13 /* BlockCommentTrivia */: + if (disallowComments) { + handleError(10 /* InvalidCommentToken */); + } + else { + onComment(); + } + break; + case 16 /* Unknown */: + handleError(1 /* InvalidSymbol */); + break; + case 15 /* Trivia */: + case 14 /* LineBreakTrivia */: + break; + default: + return token; + } + } + } + function handleError(error, skipUntilAfter, skipUntil) { + if (skipUntilAfter === void 0) { skipUntilAfter = []; } + if (skipUntil === void 0) { skipUntil = []; } + onError(error); + if (skipUntilAfter.length + skipUntil.length > 0) { + var token = _scanner.getToken(); + while (token !== 17 /* EOF */) { + if (skipUntilAfter.indexOf(token) !== -1) { + scanNext(); + break; + } + else if (skipUntil.indexOf(token) !== -1) { + break; + } + token = scanNext(); + } + } + } + function parseString(isValue) { + var value = _scanner.getTokenValue(); + if (isValue) { + onLiteralValue(value); + } + else { + onObjectProperty(value); + } + scanNext(); + return true; + } + function parseLiteral() { + switch (_scanner.getToken()) { + case 11 /* NumericLiteral */: + var value = 0; + try { + value = JSON.parse(_scanner.getTokenValue()); + if (typeof value !== 'number') { + handleError(2 /* InvalidNumberFormat */); + value = 0; + } + } + catch (e) { + handleError(2 /* InvalidNumberFormat */); + } + onLiteralValue(value); + break; + case 7 /* NullKeyword */: + onLiteralValue(null); + break; + case 8 /* TrueKeyword */: + onLiteralValue(true); + break; + case 9 /* FalseKeyword */: + onLiteralValue(false); + break; + default: + return false; + } + scanNext(); + return true; + } + function parseProperty() { + if (_scanner.getToken() !== 10 /* StringLiteral */) { + handleError(3 /* PropertyNameExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]); + return false; + } + parseString(false); + if (_scanner.getToken() === 6 /* ColonToken */) { + onSeparator(':'); + scanNext(); // consume colon + if (!parseValue()) { + handleError(4 /* ValueExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]); + } + } + else { + handleError(5 /* ColonExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]); + } + return true; + } + function parseObject() { + onObjectBegin(); + scanNext(); // consume open brace + var needsComma = false; + while (_scanner.getToken() !== 2 /* CloseBraceToken */ && _scanner.getToken() !== 17 /* EOF */) { + if (_scanner.getToken() === 5 /* CommaToken */) { + if (!needsComma) { + handleError(4 /* ValueExpected */, [], []); + } + onSeparator(','); + scanNext(); // consume comma + if (_scanner.getToken() === 2 /* CloseBraceToken */ && allowTrailingComma) { + break; + } + } + else if (needsComma) { + handleError(6 /* CommaExpected */, [], []); + } + if (!parseProperty()) { + handleError(4 /* ValueExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]); + } + needsComma = true; + } + onObjectEnd(); + if (_scanner.getToken() !== 2 /* CloseBraceToken */) { + handleError(7 /* CloseBraceExpected */, [2 /* CloseBraceToken */], []); + } + else { + scanNext(); // consume close brace + } + return true; + } + function parseArray() { + onArrayBegin(); + scanNext(); // consume open bracket + var needsComma = false; + while (_scanner.getToken() !== 4 /* CloseBracketToken */ && _scanner.getToken() !== 17 /* EOF */) { + if (_scanner.getToken() === 5 /* CommaToken */) { + if (!needsComma) { + handleError(4 /* ValueExpected */, [], []); + } + onSeparator(','); + scanNext(); // consume comma + if (_scanner.getToken() === 4 /* CloseBracketToken */ && allowTrailingComma) { + break; + } + } + else if (needsComma) { + handleError(6 /* CommaExpected */, [], []); + } + if (!parseValue()) { + handleError(4 /* ValueExpected */, [], [4 /* CloseBracketToken */, 5 /* CommaToken */]); + } + needsComma = true; + } + onArrayEnd(); + if (_scanner.getToken() !== 4 /* CloseBracketToken */) { + handleError(8 /* CloseBracketExpected */, [4 /* CloseBracketToken */], []); + } + else { + scanNext(); // consume close bracket + } + return true; + } + function parseValue() { + switch (_scanner.getToken()) { + case 3 /* OpenBracketToken */: + return parseArray(); + case 1 /* OpenBraceToken */: + return parseObject(); + case 10 /* StringLiteral */: + return parseString(true); + default: + return parseLiteral(); + } + } + scanNext(); + if (_scanner.getToken() === 17 /* EOF */) { + return true; + } + if (!parseValue()) { + handleError(4 /* ValueExpected */, [], []); + return false; + } + if (_scanner.getToken() !== 17 /* EOF */) { + handleError(9 /* EndOfFileExpected */, [], []); + } + return true; +} +/** + * Takes JSON with JavaScript-style comments and remove + * them. Optionally replaces every none-newline character + * of comments with a replaceCharacter + */ +function stripComments(text, replaceCh) { + var _scanner = Object(_scanner__WEBPACK_IMPORTED_MODULE_0__["createScanner"])(text), parts = [], kind, offset = 0, pos; + do { + pos = _scanner.getPosition(); + kind = _scanner.scan(); + switch (kind) { + case 12 /* LineCommentTrivia */: + case 13 /* BlockCommentTrivia */: + case 17 /* EOF */: + if (offset !== pos) { + parts.push(text.substring(offset, pos)); + } + if (replaceCh !== void 0) { + parts.push(_scanner.getTokenValue().replace(/[^\r\n]/g, replaceCh)); + } + offset = _scanner.getPosition(); + break; + } + } while (kind !== 17 /* EOF */); + return parts.join(''); +} +function getLiteralNodeType(value) { + switch (typeof value) { + case 'boolean': return 'boolean'; + case 'number': return 'number'; + case 'string': return 'string'; + default: return 'null'; + } +} +//# sourceMappingURL=parser.js.map + +/***/ }), +/* 200 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const child_process_1 = __webpack_require__(175); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const net_1 = tslib_1.__importDefault(__webpack_require__(6)); +const os_1 = tslib_1.__importDefault(__webpack_require__(56)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const readline_1 = tslib_1.__importDefault(__webpack_require__(60)); +const util_1 = tslib_1.__importDefault(__webpack_require__(40)); +const minimatch_1 = tslib_1.__importDefault(__webpack_require__(201)); +const logger = __webpack_require__(186)('util-fs'); +async function statAsync(filepath) { + let stat = null; + try { + stat = await util_1.default.promisify(fs_1.default.stat)(filepath); + } + catch (e) { } // tslint:disable-line + return stat; +} +exports.statAsync = statAsync; +async function isDirectory(filepath) { + let stat = await statAsync(filepath); + return stat && stat.isDirectory(); +} +exports.isDirectory = isDirectory; +async function unlinkAsync(filepath) { + try { + await util_1.default.promisify(fs_1.default.unlink)(filepath); + } + catch (e) { } // tslint:disable-line +} +exports.unlinkAsync = unlinkAsync; +function renameAsync(oldPath, newPath) { + return new Promise((resolve, reject) => { + fs_1.default.rename(oldPath, newPath, err => { + if (err) + return reject(err); + resolve(); + }); + }); +} +exports.renameAsync = renameAsync; +async function isGitIgnored(fullpath) { + if (!fullpath) + return false; + let stat = await statAsync(fullpath); + if (!stat || !stat.isFile()) + return false; + let root = null; + try { + let { stdout } = await util_1.default.promisify(child_process_1.exec)('git rev-parse --show-toplevel', { cwd: path_1.default.dirname(fullpath) }); + root = stdout.trim(); + } + catch (e) { } // tslint:disable-line + if (!root) + return false; + let file = path_1.default.relative(root, fullpath); + try { + let { stdout } = await util_1.default.promisify(child_process_1.exec)(`git check-ignore ${file}`, { cwd: root }); + return stdout.trim() == file; + } + catch (e) { } // tslint:disable-line + return false; +} +exports.isGitIgnored = isGitIgnored; +function resolveRoot(dir, subs, cwd) { + let home = os_1.default.homedir(); + if (isParentFolder(dir, home, true)) + return null; + if (cwd && isParentFolder(cwd, dir, true) && inDirectory(cwd, subs)) + return cwd; + let parts = dir.split(path_1.default.sep); + let curr = [parts.shift()]; + for (let part of parts) { + curr.push(part); + let dir = curr.join(path_1.default.sep); + if (dir != home && inDirectory(dir, subs)) { + return dir; + } + } + return null; +} +exports.resolveRoot = resolveRoot; +function inDirectory(dir, subs) { + try { + let files = fs_1.default.readdirSync(dir); + for (let pattern of subs) { + // note, only '*' expanded + let is_wildcard = (pattern.indexOf('*') !== -1); + let res = is_wildcard ? + (minimatch_1.default.match(files, pattern, { nobrace: true, noext: true, nocomment: true, nonegate: true, dot: true }).length !== 0) : + (files.indexOf(pattern) !== -1); + if (res) + return true; + } + } + catch (e) { + // could be failed without permission + } + return false; +} +exports.inDirectory = inDirectory; +function findUp(name, cwd) { + let root = path_1.default.parse(cwd).root; + let subs = Array.isArray(name) ? name : [name]; + while (cwd && cwd !== root) { + let find = inDirectory(cwd, subs); + if (find) { + for (let sub of subs) { + let filepath = path_1.default.join(cwd, sub); + if (fs_1.default.existsSync(filepath)) { + return filepath; + } + } + } + cwd = path_1.default.dirname(cwd); + } + return null; +} +exports.findUp = findUp; +function readFile(fullpath, encoding) { + return new Promise((resolve, reject) => { + fs_1.default.readFile(fullpath, encoding, (err, content) => { + if (err) + reject(err); + resolve(content); + }); + }); +} +exports.readFile = readFile; +function getFileLineCount(filepath) { + let i; + let count = 0; + return new Promise((resolve, reject) => { + fs_1.default.createReadStream(filepath) + .on('error', e => reject(e)) + .on('data', chunk => { + for (i = 0; i < chunk.length; ++i) + if (chunk[i] == 10) + count++; + }) + .on('end', () => resolve(count)); + }); +} +exports.getFileLineCount = getFileLineCount; +function readFileLines(fullpath, start, end) { + let res = []; + const rl = readline_1.default.createInterface({ + input: fs_1.default.createReadStream(fullpath, { encoding: 'utf8' }), + crlfDelay: Infinity, + terminal: false + }); + let n = 0; + return new Promise((resolve, reject) => { + rl.on('line', line => { + if (n == 0 && line.startsWith('\uFEFF')) { + // handle BOM + line = line.slice(1); + } + if (n >= start && n <= end) { + res.push(line); + } + if (n == end) { + rl.close(); + } + n = n + 1; + }); + rl.on('close', () => { + resolve(res); + }); + rl.on('error', reject); + }); +} +exports.readFileLines = readFileLines; +function readFileLine(fullpath, count) { + const rl = readline_1.default.createInterface({ + input: fs_1.default.createReadStream(fullpath, { encoding: 'utf8' }), + crlfDelay: Infinity, + terminal: false + }); + let n = 0; + return new Promise((resolve, reject) => { + rl.on('line', line => { + if (n == count) { + if (n == 0 && line.startsWith('\uFEFF')) { + // handle BOM + line = line.slice(1); + } + rl.close(); + resolve(line); + return; + } + n = n + 1; + }); + rl.on('error', reject); + }); +} +exports.readFileLine = readFileLine; +async function writeFile(fullpath, content) { + await util_1.default.promisify(fs_1.default.writeFile)(fullpath, content, 'utf8'); +} +exports.writeFile = writeFile; +function validSocket(path) { + let clientSocket = new net_1.default.Socket(); + return new Promise(resolve => { + clientSocket.on('error', () => { + resolve(false); + }); + clientSocket.connect({ path }, () => { + clientSocket.unref(); + resolve(true); + }); + }); +} +exports.validSocket = validSocket; +function isFile(uri) { + return uri.startsWith('file:'); +} +exports.isFile = isFile; +exports.readdirAsync = util_1.default.promisify(fs_1.default.readdir); +exports.realpathAsync = util_1.default.promisify(fs_1.default.realpath); +function parentDirs(pth) { + let { root, dir } = path_1.default.parse(pth); + if (dir === root) + return [root]; + const dirs = [root]; + const parts = dir.slice(root.length).split(path_1.default.sep); + for (let i = 1; i <= parts.length; i++) { + dirs.push(path_1.default.join(root, parts.slice(0, i).join(path_1.default.sep))); + } + return dirs; +} +exports.parentDirs = parentDirs; +function isParentFolder(folder, filepath, checkEqual = false) { + let pdir = fixDriver(path_1.default.resolve(path_1.default.normalize(folder))); + let dir = fixDriver(path_1.default.resolve(path_1.default.normalize(filepath))); + if (pdir == '//') + pdir = '/'; + if (pdir == dir) + return checkEqual ? true : false; + if (pdir.endsWith(path_1.default.sep)) + return dir.startsWith(pdir); + return dir.startsWith(pdir) && dir[pdir.length] == path_1.default.sep; +} +exports.isParentFolder = isParentFolder; +// use uppercase for windows driver +function fixDriver(filepath) { + if (os_1.default.platform() != 'win32' || filepath[1] != ':') + return filepath; + return filepath[0].toUpperCase() + filepath.slice(1); +} +exports.fixDriver = fixDriver; +//# sourceMappingURL=fs.js.map + +/***/ }), +/* 201 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = minimatch +minimatch.Minimatch = Minimatch + +var path = { sep: '/' } +try { + path = __webpack_require__(57) +} catch (er) {} + +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = __webpack_require__(202) + +var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } +} + +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' + +// * => any number of characters +var star = qmark + '*?' + +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' + +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' + +// characters that need to be escaped in RegExp. +var reSpecials = charSet('().*{}+?[]^$\\!') + +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split('').reduce(function (set, c) { + set[c] = true + return set + }, {}) +} + +// normalizes slashes. +var slashSplit = /\/+/ + +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) + } +} + +function ext (a, b) { + a = a || {} + b = b || {} + var t = {} + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + return t +} + +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch + + var orig = minimatch + + var m = function minimatch (p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)) + } + + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } + + return m +} + +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch + return minimatch.defaults(def).Minimatch +} + +function minimatch (p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false + } + + // "" only matches "" + if (pattern.trim() === '') return p === '' + + return new Minimatch(pattern, options).match(p) +} + +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options) + } + + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + pattern = pattern.trim() + + // windows support: need to use /, not \ + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } + + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false + + // make the set of regexps etc. + this.make() +} + +Minimatch.prototype.debug = function () {} + +Minimatch.prototype.make = make +function make () { + // don't do it more than once. + if (this._made) return + + var pattern = this.pattern + var options = this.options + + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } + + // step 1: figure out negation, etc. + this.parseNegate() + + // step 2: expand braces + var set = this.globSet = this.braceExpand() + + if (options.debug) this.debug = console.error + + this.debug(this.pattern, set) + + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) + + this.debug(this.pattern, set) + + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) + + this.debug(this.pattern, set) + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1 + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var negateOffset = 0 + + if (options.nonegate) return + + for (var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === '!' + ; i++) { + negate = !negate + negateOffset++ + } + + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate +} + +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options) +} + +Minimatch.prototype.braceExpand = braceExpand + +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options + } else { + options = {} + } + } + + pattern = typeof pattern === 'undefined' + ? this.pattern : pattern + + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern') + } + + if (options.nobrace || + !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern] + } + + return expand(pattern) +} + +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long') + } + + var options = this.options + + // shortcuts + if (!options.noglobstar && pattern === '**') return GLOBSTAR + if (pattern === '') return '' + + var re = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star + hasMagic = true + break + case '?': + re += qmark + hasMagic = true + break + default: + re += '\\' + stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false + } + } + + for (var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c) + + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c + escaping = false + continue + } + + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false + + case '\\': + clearStateChar() + escaping = true + continue + + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) + + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === '!' && i === classStart + 1) c = '^' + re += c + continue + } + + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue + + case '(': + if (inClass) { + re += '(' + continue + } + + if (!stateChar) { + re += '\\(' + continue + } + + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }) + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue + + case ')': + if (inClass || !patternListStack.length) { + re += '\\)' + continue + } + + clearStateChar() + hasMagic = true + var pl = patternListStack.pop() + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close + if (pl.type === '!') { + negativeLists.push(pl) + } + pl.reEnd = re.length + continue + + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|' + escaping = false + continue + } + + clearStateChar() + re += '|' + continue + + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar() + + if (inClass) { + re += '\\' + c + continue + } + + inClass = true + classStart = i + reClassStart = re.length + re += c + continue + + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c + escaping = false + continue + } + + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } + } + + // finish up the class. + hasMagic = true + inClass = false + re += c + continue + + default: + // swallow any state char that wasn't consumed + clearStateChar() + + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === '^' && inClass)) { + re += '\\' + } + + re += c + + } // switch + } // for + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1) + sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + hasMagic = hasMagic || sp[1] + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length) + this.debug('setting tail', re, pl) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\' + } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|' + }) + + this.debug('tail=%j\n %s', tail, tail, pl, re) + var t = pl.type === '*' ? star + : pl.type === '?' ? qmark + : '\\' + pl.type + + hasMagic = true + re = re.slice(0, pl.reStart) + t + '\\(' + tail + } + + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += '\\\\' + } + + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case '.': + case '[': + case '(': addPatternStart = true + } + + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] + + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) + + nlLast += nlAfter + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter + + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } + + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re + } + + if (addPatternStart) { + re = patternStart + re + } + + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic] + } + + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } + + var flags = options.nocase ? 'i' : '' + try { + var regExp = new RegExp('^' + re + '$', flags) + } catch (er) { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.') + } + + regExp._glob = pattern + regExp._src = re + + return regExp +} + +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() +} + +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp + + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set + + if (!set.length) { + this.regexp = false + return this.regexp + } + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var flags = options.nocase ? 'i' : '' + + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === 'string') ? regExpEscape(p) + : p._src + }).join('\\\/') + }).join('|') + + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$' + + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$' + + try { + this.regexp = new RegExp(re, flags) + } catch (ex) { + this.regexp = false + } + return this.regexp +} + +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} + +Minimatch.prototype.match = match +function match (f, partial) { + this.debug('match', f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === '' + + if (f === '/' && partial) return true + + var options = this.options + + // windows: need to use /, not \ + if (path.sep !== '/') { + f = f.split(path.sep).join('/') + } + + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, 'split', f) + + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set + this.debug(this.pattern, 'set', set) + + // Find the basename of the path by looking for the last non-empty segment + var filename + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } + + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} + +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options + + this.debug('matchOne', + { 'this': this, file: file, pattern: pattern }) + + this.debug('matchOne', file.length, pattern.length) + + for (var fi = 0, + pi = 0, + fl = file.length, + pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi++, pi++) { + this.debug('matchOne loop') + var p = pattern[pi] + var f = file[fi] + + this.debug(pattern, p, f) + + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + var pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) return false + } + return true + } + + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr] + + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr) + break + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr++ + } + } + + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) + if (fr === fl) return true + } + return false + } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === 'string') { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } + this.debug('string match', p, f, hit) + } else { + hit = f.match(p) + this.debug('pattern match', p, f, hit) + } + + if (!hit) return false + } + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') + return emptyFileEnd + } + + // should be unreachable. + throw new Error('wtf?') +} + +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, '$1') +} + +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +} + + +/***/ }), +/* 202 */ +/***/ (function(module, exports, __webpack_require__) { + +var concatMap = __webpack_require__(203); +var balanced = __webpack_require__(204); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + + + +/***/ }), +/* 203 */ +/***/ (function(module, exports) { + +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + + +/***/ }), +/* 204 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} + + +/***/ }), +/* 205 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const jsonc_parser_1 = __webpack_require__(195); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const vscode_uri_1 = __webpack_require__(180); +const logger = __webpack_require__(186)('configuration-shape'); +class ConfigurationProxy { + constructor(workspace) { + this.workspace = workspace; + } + get nvim() { + return this.workspace.nvim; + } + async modifyConfiguration(target, key, value) { + let { nvim, workspace } = this; + let file = workspace.getConfigFile(target); + if (!file) + return; + let formattingOptions = { tabSize: 2, insertSpaces: true }; + let content = fs_1.default.readFileSync(file, 'utf8'); + value = value == null ? undefined : value; + let edits = jsonc_parser_1.modify(content, [key], value, { formattingOptions }); + content = jsonc_parser_1.applyEdits(content, edits); + fs_1.default.writeFileSync(file, content, 'utf8'); + let doc = workspace.getDocument(vscode_uri_1.URI.file(file).toString()); + if (doc) + nvim.command('checktime', true); + return; + } + get workspaceConfigFile() { + let folder = path_1.default.join(this.workspace.root, '.vim'); + return path_1.default.join(folder, 'coc-settings.json'); + } + $updateConfigurationOption(target, key, value) { + this.modifyConfiguration(target, key, value); // tslint:disable-line + } + $removeConfigurationOption(target, key) { + this.modifyConfiguration(target, key); // tslint:disable-line + } +} +exports.default = ConfigurationProxy; +//# sourceMappingURL=shape.js.map + +/***/ }), +/* 206 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const mkdirp_1 = tslib_1.__importDefault(__webpack_require__(179)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +class DB { + constructor(filepath) { + this.filepath = filepath; + } + /** + * Get data by key. + * + * @param {string} key unique key allows dot notation. + * @returns {any} + */ + fetch(key) { + let obj = this.load(); + if (!key) + return obj; + let parts = key.split('.'); + for (let part of parts) { + if (typeof obj[part] == 'undefined') { + return undefined; + } + obj = obj[part]; + } + return obj; + } + /** + * Check if key exists + * + * @param {string} key unique key allows dot notation. + */ + exists(key) { + let obj = this.load(); + let parts = key.split('.'); + for (let part of parts) { + if (typeof obj[part] == 'undefined') { + return false; + } + obj = obj[part]; + } + return true; + } + /** + * Delete data by key + * + * @param {string} key unique key allows dot notation. + */ + delete(key) { + let obj = this.load(); + let origin = obj; + let parts = key.split('.'); + let len = parts.length; + for (let i = 0; i < len; i++) { + if (typeof obj[parts[i]] == 'undefined') { + break; + } + if (i == len - 1) { + delete obj[parts[i]]; + fs_1.default.writeFileSync(this.filepath, JSON.stringify(origin, null, 2), 'utf8'); + break; + } + obj = obj[parts[i]]; + } + } + /** + * Save data with key + * + * @param {string} key unique string that allows dot notation. + * @param {number|null|boolean|string|{[index} data saved data. + */ + push(key, data) { + let origin = this.load() || {}; + let obj = origin; + let parts = key.split('.'); + let len = parts.length; + if (obj == null) { + let dir = path_1.default.dirname(this.filepath); + mkdirp_1.default.sync(dir); + obj = origin; + } + for (let i = 0; i < len; i++) { + let key = parts[i]; + if (i == len - 1) { + obj[key] = data; + fs_1.default.writeFileSync(this.filepath, JSON.stringify(origin, null, 2)); + break; + } + if (typeof obj[key] == 'undefined') { + obj[key] = {}; + obj = obj[key]; + } + else { + obj = obj[key]; + } + } + } + load() { + let dir = path_1.default.dirname(this.filepath); + let stat = fs_1.default.statSync(dir); + if (!stat || !stat.isDirectory()) { + mkdirp_1.default.sync(dir); + fs_1.default.writeFileSync(this.filepath, '{}', 'utf8'); + return {}; + } + try { + let content = fs_1.default.readFileSync(this.filepath, 'utf8'); + return JSON.parse(content.trim()); + } + catch (e) { + fs_1.default.writeFileSync(this.filepath, '{}', 'utf8'); + return {}; + } + } + /** + * Empty db file. + */ + clear() { + let stat = fs_1.default.statSync(this.filepath); + if (!stat || !stat.isFile()) + return; + fs_1.default.writeFileSync(this.filepath, '{}', 'utf8'); + } + /** + * Remove db file. + */ + destroy() { + if (fs_1.default.existsSync(this.filepath)) { + fs_1.default.unlinkSync(this.filepath); + } + } +} +exports.default = DB; +//# sourceMappingURL=db.js.map + +/***/ }), +/* 207 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const debounce_1 = tslib_1.__importDefault(__webpack_require__(176)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const vscode_uri_1 = __webpack_require__(180); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const diff_1 = __webpack_require__(208); +const fs_1 = __webpack_require__(200); +const index_1 = __webpack_require__(174); +const string_1 = __webpack_require__(210); +const chars_1 = __webpack_require__(211); +const array_1 = __webpack_require__(212); +const position_1 = __webpack_require__(213); +const logger = __webpack_require__(186)('model-document'); +// wrapper class of TextDocument +class Document { + constructor(buffer, env) { + this.buffer = buffer; + this.env = env; + this.paused = false; + this.isIgnored = false; + // start id for matchaddpos + this.colorId = 1080; + this.eol = true; + this.attached = false; + // real current lines + this.lines = []; + this._words = []; + this._onDocumentChange = new vscode_languageserver_protocol_1.Emitter(); + this._onDocumentDetach = new vscode_languageserver_protocol_1.Emitter(); + this.onDocumentChange = this._onDocumentChange.event; + this.onDocumentDetach = this._onDocumentDetach.event; + this.fireContentChanges = debounce_1.default(() => { + this.nvim.mode.then(m => { + if (m.blocking) { + this.fireContentChanges(); + return; + } + this._fireContentChanges(); + }).logError(); + }, 200); + this.fetchContent = debounce_1.default(() => { + this._fetchContent().logError(); + }, 50); + } + /** + * Check if current document should be attached for changes. + * + * Currently only attach for empty and `acwrite` buftype. + */ + get shouldAttach() { + let { buftype } = this; + if (!this.getVar('enabled', true)) + return false; + if (this.uri.endsWith('%5BCommand%20Line%5D')) + return true; + return buftype == '' || buftype == 'acwrite'; + } + get enabled() { + return this.getVar('enabled', true); + } + /** + * All words, extracted by `iskeyword` option. + */ + get words() { + return this._words; + } + /** + * Map filetype for languageserver. + */ + convertFiletype(filetype) { + let map = this.env.filetypeMap; + if (filetype == 'json' && this.uri && this.uri.endsWith('coc-settings.json')) { + return 'jsonc'; + } + if (filetype == 'javascript.jsx') + return 'javascriptreact'; + if (filetype == 'typescript.jsx' || filetype == 'typescript.tsx') + return 'typescriptreact'; + return map[filetype] || filetype; + } + /** + * Get current buffer changedtick. + */ + get changedtick() { + return this._changedtick; + } + /** + * Scheme of document. + */ + get schema() { + return vscode_uri_1.URI.parse(this.uri).scheme; + } + /** + * Line count of current buffer. + */ + get lineCount() { + return this.lines.length; + } + /** + * Initialize document model. + * + * @internal + */ + async init(nvim, token) { + this.nvim = nvim; + let { buffer } = this; + let opts = await nvim.call('coc#util#get_bufoptions', buffer.id); + if (opts == null) + return false; + let buftype = this.buftype = opts.buftype; + this.variables = opts.variables; + this._changedtick = opts.changedtick; + this.eol = opts.eol == 1; + let uri = this._uri = index_1.getUri(opts.fullpath, buffer.id, buftype, this.env.isCygwin); + if (token.isCancellationRequested) + return false; + try { + if (!this.env.isVim) { + let res = await this.attach(); + if (!res) + return false; + } + else { + this.lines = await buffer.lines; + } + this.attached = true; + } + catch (e) { + logger.error('attach error:', e); + return false; + } + this._filetype = this.convertFiletype(opts.filetype); + this.textDocument = vscode_languageserver_protocol_1.TextDocument.create(uri, this.filetype, 1, this.getDocumentContent()); + this.setIskeyword(opts.iskeyword); + this.gitCheck(); + if (token.isCancellationRequested) { + this.detach(); + return false; + } + return true; + } + async attach() { + if (this.shouldAttach) { + let attached = await this.buffer.attach(false); + if (!attached) + return false; + this.lines = await this.buffer.lines; + } + else { + this.lines = await this.buffer.lines; + return true; + } + if (!this.buffer.isAttached) + return; + this.buffer.listen('lines', (...args) => { + this.onChange.apply(this, args); + }); + this.buffer.listen('detach', async () => { + await index_1.wait(30); + if (!this.attached) + return; + // it could be detached by `edit!` + let attached = await this.attach(); + if (!attached) + this.detach(); + }); + this.buffer.listen('changedtick', (_buf, tick) => { + this._changedtick = tick; + }); + if (this.textDocument) { + this.fireContentChanges(); + } + return true; + } + onChange(buf, tick, firstline, lastline, linedata + // more:boolean + ) { + if (buf.id !== this.buffer.id || tick == null) + return; + this._changedtick = tick; + let lines = this.lines.slice(0, firstline); + lines = lines.concat(linedata, this.lines.slice(lastline)); + this.lines = lines; + this.fireContentChanges(); + } + /** + * Make sure current document synced correctly + */ + async checkDocument() { + this.paused = false; + let { buffer } = this; + this._changedtick = await buffer.changedtick; + this.lines = await buffer.lines; + this.fireContentChanges.clear(); + this._fireContentChanges(); + } + /** + * Check if document changed after last synchronize + */ + get dirty() { + return this.content != this.getDocumentContent(); + } + _fireContentChanges(force = false) { + let { paused, textDocument } = this; + if (paused && !force) + return; + let { cursor } = events_1.default; + try { + let content = this.getDocumentContent(); + let endOffset = null; + if (cursor && cursor.bufnr == this.bufnr) { + endOffset = this.getEndOffset(cursor.lnum, cursor.col, cursor.insert); + if (!cursor.insert && content.length < this.content.length) { + endOffset = endOffset + 1; + } + } + let change = diff_1.getChange(this.content, content, endOffset); + if (change == null) + return; + this.createDocument(); + let { version, uri } = this; + let start = textDocument.positionAt(change.start); + let end = textDocument.positionAt(change.end); + let original = textDocument.getText(vscode_languageserver_protocol_1.Range.create(start, end)); + let changes = [{ + range: { start, end }, + rangeLength: change.end - change.start, + text: change.newText + }]; + this._onDocumentChange.fire({ + bufnr: this.bufnr, + original, + textDocument: { version, uri }, + contentChanges: changes + }); + this._words = this.chars.matchKeywords(this.lines.join('\n')); + } + catch (e) { + logger.error(e.message); + } + } + /** + * Buffer number + */ + get bufnr() { + return this.buffer.id; + } + /** + * Content of textDocument. + */ + get content() { + return this.textDocument.getText(); + } + /** + * Coverted filetype. + */ + get filetype() { + return this._filetype; + } + get uri() { + return this._uri; + } + get version() { + return this.textDocument ? this.textDocument.version : null; + } + async applyEdits(nvim, _edits, sync = true) { + let edits = []; + if (Array.isArray(nvim)) { + sync = _edits == null ? true : _edits; + edits = nvim; + } + else { + edits = _edits || []; + } + if (edits.length == 0) + return; + edits.forEach(edit => { + edit.newText = edit.newText.replace(/\r/g, ''); + }); + let orig = this.lines.join('\n') + (this.eol ? '\n' : ''); + let textDocument = vscode_languageserver_protocol_1.TextDocument.create(this.uri, this.filetype, 1, orig); + let content = vscode_languageserver_protocol_1.TextDocument.applyEdits(textDocument, edits); + // could be equal sometimes + if (orig === content) { + this.createDocument(); + } + else { + let d = diff_1.diffLines(orig, content); + await this.buffer.setLines(d.replacement, { + start: d.start, + end: d.end, + strictIndexing: false + }); + // can't wait vim sync buffer + this.lines = (this.eol && content.endsWith('\n') ? content.slice(0, -1) : content).split('\n'); + if (sync) + this.forceSync(); + } + } + changeLines(lines, sync = true, check = false) { + let { nvim } = this; + let filtered = []; + for (let [lnum, text] of lines) { + if (check && this.lines[lnum] != text) { + filtered.push([lnum, text]); + } + this.lines[lnum] = text; + } + if (check && !filtered.length) + return; + nvim.call('coc#util#change_lines', [this.bufnr, check ? filtered : lines], true); + if (sync) + this.forceSync(); + } + /** + * Force emit change event when necessary. + */ + forceSync(ignorePause = true) { + this.fireContentChanges.clear(); + this._fireContentChanges(ignorePause); + } + /** + * Get offset from lnum & col + */ + getOffset(lnum, col) { + return this.textDocument.offsetAt({ + line: lnum - 1, + character: col + }); + } + /** + * Check string is word. + */ + isWord(word) { + return this.chars.isKeyword(word); + } + /** + * Generate more words by split word with `-` + */ + getMoreWords() { + let res = []; + let { words, chars } = this; + if (!chars.isKeywordChar('-')) + return res; + for (let word of words) { + word = word.replace(/^-+/, ''); + if (word.indexOf('-') !== -1) { + let parts = word.split('-'); + for (let part of parts) { + if (part.length > 2 && + res.indexOf(part) === -1 && + words.indexOf(part) === -1) { + res.push(part); + } + } + } + } + return res; + } + /** + * Current word for replacement + */ + getWordRangeAtPosition(position, extraChars, current = true) { + let chars = this.chars.clone(); + if (extraChars && extraChars.length) { + for (let ch of extraChars) { + chars.addKeyword(ch); + } + } + let line = this.getline(position.line, current); + if (line.length == 0 || position.character >= line.length) + return null; + if (!chars.isKeywordChar(line[position.character])) + return null; + let start = position.character; + let end = position.character + 1; + if (!chars.isKeywordChar(line[start])) { + return vscode_languageserver_protocol_1.Range.create(position, { line: position.line, character: position.character + 1 }); + } + while (start >= 0) { + let ch = line[start - 1]; + if (!ch || !chars.isKeyword(ch)) + break; + start = start - 1; + } + while (end <= line.length) { + let ch = line[end]; + if (!ch || !chars.isKeywordChar(ch)) + break; + end = end + 1; + } + return vscode_languageserver_protocol_1.Range.create(position.line, start, position.line, end); + } + gitCheck() { + let { uri } = this; + if (!uri.startsWith('file') || this.buftype != '') + return; + let filepath = vscode_uri_1.URI.parse(uri).fsPath; + fs_1.isGitIgnored(filepath).then(isIgnored => { + this.isIgnored = isIgnored; + }, () => { + this.isIgnored = false; + }); + } + createDocument(changeCount = 1) { + let { version, uri, filetype } = this; + version = version + changeCount; + this.textDocument = vscode_languageserver_protocol_1.TextDocument.create(uri, filetype, version, this.getDocumentContent()); + } + async _fetchContent() { + if (!this.env.isVim || !this.attached) + return; + let { nvim, buffer } = this; + let { id } = buffer; + let o = (await nvim.call('coc#util#get_content', id)); + if (!o) + return; + let { content, changedtick } = o; + this._changedtick = changedtick; + let newLines = content.split('\n'); + this.lines = newLines; + this._fireContentChanges(); + } + /** + * Get change from vim8, used by workspace + */ + async patchChange() { + if (!this.env.isVim || !this.attached) + return; + let change = await this.nvim.call('coc#util#get_changeinfo', []); + if (change.changedtick == this._changedtick) + return; + let { lines } = this; + let { lnum, line, changedtick } = change; + this._changedtick = changedtick; + lines[lnum - 1] = line; + } + /** + * Get changedtick from vim8, used by workspace + */ + async patchChangedTick() { + if (!this.env.isVim || !this.attached) + return; + this._changedtick = await this.nvim.call('getbufvar', [this.bufnr, 'changedtick']); + } + /** + * Get ranges of word in textDocument. + */ + getSymbolRanges(word) { + this.forceSync(); + let { textDocument } = this; + let res = []; + let content = textDocument.getText(); + let str = ''; + for (let i = 0, l = content.length; i < l; i++) { + let ch = content[i]; + if ('-' == ch && str.length == 0) { + continue; + } + let isKeyword = this.chars.isKeywordChar(ch); + if (isKeyword) { + str = str + ch; + } + if (str.length > 0 && !isKeyword && str == word) { + res.push(vscode_languageserver_protocol_1.Range.create(textDocument.positionAt(i - str.length), textDocument.positionAt(i))); + } + if (!isKeyword) { + str = ''; + } + } + return res; + } + /** + * Adjust col with new valid character before position. + */ + fixStartcol(position, valids) { + let line = this.getline(position.line); + if (!line) + return null; + let { character } = position; + let start = line.slice(0, character); + let col = string_1.byteLength(start); + let { chars } = this; + for (let i = start.length - 1; i >= 0; i--) { + let c = start[i]; + if (c == ' ') + break; + if (!chars.isKeywordChar(c) && valids.indexOf(c) === -1) { + break; + } + col = col - string_1.byteLength(c); + } + return col; + } + /** + * Use matchaddpos for highlight ranges, must use `redraw` command on vim + */ + matchAddRanges(ranges, hlGroup, priority = 10) { + let res = []; + let arr = []; + let splited = ranges.reduce((p, c) => { + for (let i = c.start.line; i <= c.end.line; i++) { + let curr = this.getline(i) || ''; + let sc = i == c.start.line ? c.start.character : 0; + let ec = i == c.end.line ? c.end.character : curr.length; + if (sc == ec) + continue; + p.push(vscode_languageserver_protocol_1.Range.create(i, sc, i, ec)); + } + return p; + }, []); + for (let range of splited) { + let { start, end } = range; + let line = this.getline(start.line); + if (start.character == end.character) + continue; + arr.push([start.line + 1, string_1.byteIndex(line, start.character) + 1, string_1.byteLength(line.slice(start.character, end.character))]); + } + for (let grouped of array_1.group(arr, 8)) { + let id = this.colorId; + this.colorId = this.colorId + 1; + this.nvim.call('matchaddpos', [hlGroup, grouped, priority, id], true); + res.push(id); + } + this.nvim.call('coc#util#add_matchids', [res], true); + return res; + } + /** + * Highlight ranges in document, return match id list. + * + * Note: match id could by namespace id or vim's match id. + */ + highlightRanges(ranges, hlGroup, srcId, priority = 10) { + let res = []; + if (this.env.isVim && !this.env.textprop) { + res = this.matchAddRanges(ranges, hlGroup, priority); + } + else { + let lineRanges = []; + for (let range of ranges) { + if (range.start.line == range.end.line) { + lineRanges.push(range); + } + else { + // split range by lines + for (let i = range.start.line; i < range.end.line; i++) { + let line = this.getline(i); + if (i == range.start.line) { + lineRanges.push(vscode_languageserver_protocol_1.Range.create(i, range.start.character, i, line.length)); + } + else if (i == range.end.line) { + lineRanges.push(vscode_languageserver_protocol_1.Range.create(i, Math.min(line.match(/^\s*/)[0].length, range.end.character), i, range.end.character)); + } + else { + lineRanges.push(vscode_languageserver_protocol_1.Range.create(i, Math.min(line.match(/^\s*/)[0].length, line.length), i, line.length)); + } + } + } + } + for (let range of lineRanges) { + let { start, end } = range; + if (position_1.comparePosition(start, end) == 0) + continue; + let line = this.getline(start.line); + // tslint:disable-next-line: no-floating-promises + this.buffer.addHighlight({ + hlGroup, + srcId, + line: start.line, + colStart: string_1.byteIndex(line, start.character), + colEnd: end.line - start.line == 1 && end.character == 0 ? -1 : string_1.byteIndex(line, end.character) + }); + } + res.push(srcId); + } + return res; + } + /** + * Clear match id list, for vim support namespace, list should be namespace id list. + */ + clearMatchIds(ids) { + if (this.env.isVim && !this.env.textprop) { + this.nvim.call('coc#util#clearmatches', [Array.from(ids)], true); + } + else { + ids = array_1.distinct(Array.from(ids)); + let hasNamesapce = this.nvim.hasFunction('nvim_create_namespace'); + ids.forEach(id => { + if (hasNamesapce) { + this.buffer.clearNamespace(id); + } + else { + this.buffer.clearHighlight({ srcId: id }); + } + }); + } + } + /** + * Get cwd of this document. + */ + async getcwd() { + let wid = await this.nvim.call('bufwinid', this.buffer.id); + if (wid == -1) + return await this.nvim.call('getcwd'); + return await this.nvim.call('getcwd', wid); + } + /** + * Real current line + */ + getline(line, current = true) { + if (current) + return this.lines[line] || ''; + let lines = this.textDocument.getText().split(/\r?\n/); + return lines[line] || ''; + } + /** + * Get lines, zero indexed, end exclude. + */ + getLines(start, end) { + return this.lines.slice(start, end); + } + /** + * Get current content text. + */ + getDocumentContent() { + let content = this.lines.join('\n'); + return this.eol ? content + '\n' : content; + } + /** + * Get variable value by key, defined by `b:coc_{key}` + */ + getVar(key, defaultValue) { + let val = this.variables[`coc_${key}`]; + return val === undefined ? defaultValue : val; + } + /** + * Get position from lnum & col + */ + getPosition(lnum, col) { + let line = this.getline(lnum - 1); + if (!line || col == 0) + return { line: lnum - 1, character: 0 }; + let pre = string_1.byteSlice(line, 0, col - 1); + return { line: lnum - 1, character: pre.length }; + } + getEndOffset(lnum, col, insert) { + let total = 0; + let len = this.lines.length; + for (let i = lnum - 1; i < len; i++) { + let line = this.lines[i]; + if (i == lnum - 1 && line.length) { + if (!insert && string_1.byteLength(line) >= col) + col = col + 1; + total = total + line.slice(string_1.characterIndex(line, col - 1)).length; + } + else { + total = total + line.length; + } + if (!this.eol && i == len - 1) + break; + total = total + 1; + } + return total; + } + /** + * Recreate document with new filetype. + * + * @internal + */ + setFiletype(filetype) { + let { uri, version } = this; + this._filetype = this.convertFiletype(filetype); + version = version ? version + 1 : 1; + let textDocument = vscode_languageserver_protocol_1.TextDocument.create(uri, this.filetype, version, this.content); + this.textDocument = textDocument; + } + /** + * Change iskeyword option of document + * + * @internal + */ + setIskeyword(iskeyword) { + let chars = this.chars = new chars_1.Chars(iskeyword); + let additional = this.getVar('additional_keywords', []); + if (additional && Array.isArray(additional)) { + for (let ch of additional) { + chars.addKeyword(ch); + } + } + let lines = this.lines.length > 30000 ? this.lines.slice(0, 30000) : this.lines; + this._words = this.chars.matchKeywords(lines.join('\n')); + } + /** + * Detach document. + * + * @internal + */ + detach() { + // neovim not detach on `:checktime` + if (this.attached) { + this.attached = false; + this.buffer.detach().catch(_e => { + // noop + }); + this._onDocumentDetach.fire(this.uri); + } + this.fetchContent.clear(); + this.fireContentChanges.clear(); + this._onDocumentChange.dispose(); + this._onDocumentDetach.dispose(); + } + /** + * Get localify bonus map. + * + * @internal + */ + getLocalifyBonus(sp, ep) { + let res = new Map(); + let { chars } = this; + let startLine = Math.max(0, sp.line - 100); + let endLine = Math.min(this.lineCount, sp.line + 100); + let content = this.lines.slice(startLine, endLine).join('\n'); + sp = vscode_languageserver_protocol_1.Position.create(sp.line - startLine, sp.character); + ep = vscode_languageserver_protocol_1.Position.create(ep.line - startLine, ep.character); + let doc = vscode_languageserver_protocol_1.TextDocument.create(this.uri, this.filetype, 1, content); + let headCount = doc.offsetAt(sp); + let len = content.length; + let tailCount = len - doc.offsetAt(ep); + let start = 0; + let preKeyword = false; + for (let i = 0; i < headCount; i++) { + let iskeyword = chars.isKeyword(content[i]); + if (!preKeyword && iskeyword) { + start = i; + } + else if (preKeyword && (!iskeyword || i == headCount - 1)) { + if (i - start > 1) { + let str = content.slice(start, i); + res.set(str, i / headCount); + } + } + preKeyword = iskeyword; + } + start = len - tailCount; + preKeyword = false; + for (let i = start; i < content.length; i++) { + let iskeyword = chars.isKeyword(content[i]); + if (!preKeyword && iskeyword) { + start = i; + } + else if (preKeyword && (!iskeyword || i == len - 1)) { + if (i - start > 1) { + let end = i == len - 1 ? i + 1 : i; + let str = content.slice(start, end); + let score = res.get(str) || 0; + res.set(str, Math.max(score, (len - i + (end - start)) / tailCount)); + } + } + preKeyword = iskeyword; + } + return res; + } +} +exports.default = Document; +//# sourceMappingURL=document.js.map + +/***/ }), +/* 208 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fast_diff_1 = tslib_1.__importDefault(__webpack_require__(209)); +const string_1 = __webpack_require__(210); +const logger = __webpack_require__(186)('util-diff'); +function diffLines(from, to) { + let newLines = to.split('\n'); + let oldLines = from.split('\n'); + let start = 0; + let end = oldLines.length; + let oldLen = end; + let len = newLines.length; + for (let i = 0; i <= end; i++) { + if (newLines[i] !== oldLines[i]) { + start = i; + break; + } + if (i == end) { + start = end; + } + } + if (start != newLines.length) { + let maxRemain = Math.min(end - start, len - start); + for (let j = 0; j < maxRemain; j++) { + if (oldLines[oldLen - j - 1] != newLines[len - j - 1]) { + break; + } + end = end - 1; + } + } + return { + start, + end, + replacement: newLines.slice(start, len - (oldLen - end)) + }; +} +exports.diffLines = diffLines; +function getChange(oldStr, newStr, cursorEnd) { + let start = 0; + let ol = oldStr.length; + let nl = newStr.length; + let max = Math.min(ol, nl); + let newText = ''; + let endOffset = -1; + let maxEndOffset = -1; + for (let i = 0; i <= max; i++) { + if (cursorEnd != null && i == cursorEnd) { + endOffset = i; + } + if (oldStr[ol - i - 1] != newStr[nl - i - 1]) { + if (endOffset == -1) + endOffset = i; + maxEndOffset = i; + break; + } + } + if (endOffset == -1) + return null; + let remain = max - endOffset; + if (remain == 0) { + start = 0; + } + else { + for (let i = 0; i <= remain; i++) { + if (oldStr[i] != newStr[i] || i == remain) { + start = i; + break; + } + } + } + if (maxEndOffset != -1 + && maxEndOffset != endOffset + && start + maxEndOffset < max) { + endOffset = maxEndOffset; + } + let end = ol - endOffset; + newText = newStr.slice(start, nl - endOffset); + if (ol == nl && start == end) + return null; + // optimize for add new line(s) + if (start == end) { + let pre = start == 0 ? '' : newStr[start - 1]; + if (pre && pre != '\n' + && oldStr[start] == '\n' + && newText.startsWith('\n')) { + return { start: start + 1, end: end + 1, newText: newText.slice(1) + '\n' }; + } + } + return { start, end, newText }; +} +exports.getChange = getChange; +function patchLine(from, to, fill = ' ') { + if (from == to) + return to; + let idx = to.indexOf(from); + if (idx !== -1) + return fill.repeat(idx) + from; + let result = fast_diff_1.default(from, to); + let str = ''; + for (let item of result) { + if (item[0] == fast_diff_1.default.DELETE) { + // not allowed + return to; + } + else if (item[0] == fast_diff_1.default.INSERT) { + str = str + fill.repeat(string_1.byteLength(item[1])); + } + else { + str = str + item[1]; + } + } + return str; +} +exports.patchLine = patchLine; +//# sourceMappingURL=diff.js.map + +/***/ }), +/* 209 */ +/***/ (function(module, exports) { + +/** + * This library modifies the diff-patch-match library by Neil Fraser + * by removing the patch and match functionality and certain advanced + * options in the diff function. The original license is as follows: + * + * === + * + * Diff Match and Patch + * + * Copyright 2006 Google Inc. + * http://code.google.com/p/google-diff-match-patch/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/** + * The data structure representing a diff is an array of tuples: + * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']] + * which means: delete 'Hello', add 'Goodbye' and keep ' world.' + */ +var DIFF_DELETE = -1; +var DIFF_INSERT = 1; +var DIFF_EQUAL = 0; + + +/** + * Find the differences between two texts. Simplifies the problem by stripping + * any common prefix or suffix off the texts before diffing. + * @param {string} text1 Old string to be diffed. + * @param {string} text2 New string to be diffed. + * @param {Int|Object} [cursor_pos] Edit position in text1 or object with more info + * @return {Array} Array of diff tuples. + */ +function diff_main(text1, text2, cursor_pos, _fix_unicode) { + // Check for equality + if (text1 === text2) { + if (text1) { + return [[DIFF_EQUAL, text1]]; + } + return []; + } + + if (cursor_pos != null) { + var editdiff = find_cursor_edit_diff(text1, text2, cursor_pos); + if (editdiff) { + return editdiff; + } + } + + // Trim off common prefix (speedup). + var commonlength = diff_commonPrefix(text1, text2); + var commonprefix = text1.substring(0, commonlength); + text1 = text1.substring(commonlength); + text2 = text2.substring(commonlength); + + // Trim off common suffix (speedup). + commonlength = diff_commonSuffix(text1, text2); + var commonsuffix = text1.substring(text1.length - commonlength); + text1 = text1.substring(0, text1.length - commonlength); + text2 = text2.substring(0, text2.length - commonlength); + + // Compute the diff on the middle block. + var diffs = diff_compute_(text1, text2); + + // Restore the prefix and suffix. + if (commonprefix) { + diffs.unshift([DIFF_EQUAL, commonprefix]); + } + if (commonsuffix) { + diffs.push([DIFF_EQUAL, commonsuffix]); + } + diff_cleanupMerge(diffs, _fix_unicode); + return diffs; +}; + + +/** + * Find the differences between two texts. Assumes that the texts do not + * have any common prefix or suffix. + * @param {string} text1 Old string to be diffed. + * @param {string} text2 New string to be diffed. + * @return {Array} Array of diff tuples. + */ +function diff_compute_(text1, text2) { + var diffs; + + if (!text1) { + // Just add some text (speedup). + return [[DIFF_INSERT, text2]]; + } + + if (!text2) { + // Just delete some text (speedup). + return [[DIFF_DELETE, text1]]; + } + + var longtext = text1.length > text2.length ? text1 : text2; + var shorttext = text1.length > text2.length ? text2 : text1; + var i = longtext.indexOf(shorttext); + if (i !== -1) { + // Shorter text is inside the longer text (speedup). + diffs = [ + [DIFF_INSERT, longtext.substring(0, i)], + [DIFF_EQUAL, shorttext], + [DIFF_INSERT, longtext.substring(i + shorttext.length)] + ]; + // Swap insertions for deletions if diff is reversed. + if (text1.length > text2.length) { + diffs[0][0] = diffs[2][0] = DIFF_DELETE; + } + return diffs; + } + + if (shorttext.length === 1) { + // Single character string. + // After the previous speedup, the character can't be an equality. + return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]]; + } + + // Check to see if the problem can be split in two. + var hm = diff_halfMatch_(text1, text2); + if (hm) { + // A half-match was found, sort out the return data. + var text1_a = hm[0]; + var text1_b = hm[1]; + var text2_a = hm[2]; + var text2_b = hm[3]; + var mid_common = hm[4]; + // Send both pairs off for separate processing. + var diffs_a = diff_main(text1_a, text2_a); + var diffs_b = diff_main(text1_b, text2_b); + // Merge the results. + return diffs_a.concat([[DIFF_EQUAL, mid_common]], diffs_b); + } + + return diff_bisect_(text1, text2); +}; + + +/** + * Find the 'middle snake' of a diff, split the problem in two + * and return the recursively constructed diff. + * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations. + * @param {string} text1 Old string to be diffed. + * @param {string} text2 New string to be diffed. + * @return {Array} Array of diff tuples. + * @private + */ +function diff_bisect_(text1, text2) { + // Cache the text lengths to prevent multiple calls. + var text1_length = text1.length; + var text2_length = text2.length; + var max_d = Math.ceil((text1_length + text2_length) / 2); + var v_offset = max_d; + var v_length = 2 * max_d; + var v1 = new Array(v_length); + var v2 = new Array(v_length); + // Setting all elements to -1 is faster in Chrome & Firefox than mixing + // integers and undefined. + for (var x = 0; x < v_length; x++) { + v1[x] = -1; + v2[x] = -1; + } + v1[v_offset + 1] = 0; + v2[v_offset + 1] = 0; + var delta = text1_length - text2_length; + // If the total number of characters is odd, then the front path will collide + // with the reverse path. + var front = (delta % 2 !== 0); + // Offsets for start and end of k loop. + // Prevents mapping of space beyond the grid. + var k1start = 0; + var k1end = 0; + var k2start = 0; + var k2end = 0; + for (var d = 0; d < max_d; d++) { + // Walk the front path one step. + for (var k1 = -d + k1start; k1 <= d - k1end; k1 += 2) { + var k1_offset = v_offset + k1; + var x1; + if (k1 === -d || (k1 !== d && v1[k1_offset - 1] < v1[k1_offset + 1])) { + x1 = v1[k1_offset + 1]; + } else { + x1 = v1[k1_offset - 1] + 1; + } + var y1 = x1 - k1; + while ( + x1 < text1_length && y1 < text2_length && + text1.charAt(x1) === text2.charAt(y1) + ) { + x1++; + y1++; + } + v1[k1_offset] = x1; + if (x1 > text1_length) { + // Ran off the right of the graph. + k1end += 2; + } else if (y1 > text2_length) { + // Ran off the bottom of the graph. + k1start += 2; + } else if (front) { + var k2_offset = v_offset + delta - k1; + if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] !== -1) { + // Mirror x2 onto top-left coordinate system. + var x2 = text1_length - v2[k2_offset]; + if (x1 >= x2) { + // Overlap detected. + return diff_bisectSplit_(text1, text2, x1, y1); + } + } + } + } + + // Walk the reverse path one step. + for (var k2 = -d + k2start; k2 <= d - k2end; k2 += 2) { + var k2_offset = v_offset + k2; + var x2; + if (k2 === -d || (k2 !== d && v2[k2_offset - 1] < v2[k2_offset + 1])) { + x2 = v2[k2_offset + 1]; + } else { + x2 = v2[k2_offset - 1] + 1; + } + var y2 = x2 - k2; + while ( + x2 < text1_length && y2 < text2_length && + text1.charAt(text1_length - x2 - 1) === text2.charAt(text2_length - y2 - 1) + ) { + x2++; + y2++; + } + v2[k2_offset] = x2; + if (x2 > text1_length) { + // Ran off the left of the graph. + k2end += 2; + } else if (y2 > text2_length) { + // Ran off the top of the graph. + k2start += 2; + } else if (!front) { + var k1_offset = v_offset + delta - k2; + if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] !== -1) { + var x1 = v1[k1_offset]; + var y1 = v_offset + x1 - k1_offset; + // Mirror x2 onto top-left coordinate system. + x2 = text1_length - x2; + if (x1 >= x2) { + // Overlap detected. + return diff_bisectSplit_(text1, text2, x1, y1); + } + } + } + } + } + // Diff took too long and hit the deadline or + // number of diffs equals number of characters, no commonality at all. + return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]]; +}; + + +/** + * Given the location of the 'middle snake', split the diff in two parts + * and recurse. + * @param {string} text1 Old string to be diffed. + * @param {string} text2 New string to be diffed. + * @param {number} x Index of split point in text1. + * @param {number} y Index of split point in text2. + * @return {Array} Array of diff tuples. + */ +function diff_bisectSplit_(text1, text2, x, y) { + var text1a = text1.substring(0, x); + var text2a = text2.substring(0, y); + var text1b = text1.substring(x); + var text2b = text2.substring(y); + + // Compute both diffs serially. + var diffs = diff_main(text1a, text2a); + var diffsb = diff_main(text1b, text2b); + + return diffs.concat(diffsb); +}; + + +/** + * Determine the common prefix of two strings. + * @param {string} text1 First string. + * @param {string} text2 Second string. + * @return {number} The number of characters common to the start of each + * string. + */ +function diff_commonPrefix(text1, text2) { + // Quick check for common null cases. + if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) { + return 0; + } + // Binary search. + // Performance analysis: http://neil.fraser.name/news/2007/10/09/ + var pointermin = 0; + var pointermax = Math.min(text1.length, text2.length); + var pointermid = pointermax; + var pointerstart = 0; + while (pointermin < pointermid) { + if ( + text1.substring(pointerstart, pointermid) == + text2.substring(pointerstart, pointermid) + ) { + pointermin = pointermid; + pointerstart = pointermin; + } else { + pointermax = pointermid; + } + pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); + } + + if (is_surrogate_pair_start(text1.charCodeAt(pointermid - 1))) { + pointermid--; + } + + return pointermid; +}; + + +/** + * Determine the common suffix of two strings. + * @param {string} text1 First string. + * @param {string} text2 Second string. + * @return {number} The number of characters common to the end of each string. + */ +function diff_commonSuffix(text1, text2) { + // Quick check for common null cases. + if (!text1 || !text2 || text1.slice(-1) !== text2.slice(-1)) { + return 0; + } + // Binary search. + // Performance analysis: http://neil.fraser.name/news/2007/10/09/ + var pointermin = 0; + var pointermax = Math.min(text1.length, text2.length); + var pointermid = pointermax; + var pointerend = 0; + while (pointermin < pointermid) { + if ( + text1.substring(text1.length - pointermid, text1.length - pointerend) == + text2.substring(text2.length - pointermid, text2.length - pointerend) + ) { + pointermin = pointermid; + pointerend = pointermin; + } else { + pointermax = pointermid; + } + pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); + } + + if (is_surrogate_pair_end(text1.charCodeAt(text1.length - pointermid))) { + pointermid--; + } + + return pointermid; +}; + + +/** + * Do the two texts share a substring which is at least half the length of the + * longer text? + * This speedup can produce non-minimal diffs. + * @param {string} text1 First string. + * @param {string} text2 Second string. + * @return {Array.} Five element Array, containing the prefix of + * text1, the suffix of text1, the prefix of text2, the suffix of + * text2 and the common middle. Or null if there was no match. + */ +function diff_halfMatch_(text1, text2) { + var longtext = text1.length > text2.length ? text1 : text2; + var shorttext = text1.length > text2.length ? text2 : text1; + if (longtext.length < 4 || shorttext.length * 2 < longtext.length) { + return null; // Pointless. + } + + /** + * Does a substring of shorttext exist within longtext such that the substring + * is at least half the length of longtext? + * Closure, but does not reference any external variables. + * @param {string} longtext Longer string. + * @param {string} shorttext Shorter string. + * @param {number} i Start index of quarter length substring within longtext. + * @return {Array.} Five element Array, containing the prefix of + * longtext, the suffix of longtext, the prefix of shorttext, the suffix + * of shorttext and the common middle. Or null if there was no match. + * @private + */ + function diff_halfMatchI_(longtext, shorttext, i) { + // Start with a 1/4 length substring at position i as a seed. + var seed = longtext.substring(i, i + Math.floor(longtext.length / 4)); + var j = -1; + var best_common = ''; + var best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b; + while ((j = shorttext.indexOf(seed, j + 1)) !== -1) { + var prefixLength = diff_commonPrefix( + longtext.substring(i), shorttext.substring(j)); + var suffixLength = diff_commonSuffix( + longtext.substring(0, i), shorttext.substring(0, j)); + if (best_common.length < suffixLength + prefixLength) { + best_common = shorttext.substring( + j - suffixLength, j) + shorttext.substring(j, j + prefixLength); + best_longtext_a = longtext.substring(0, i - suffixLength); + best_longtext_b = longtext.substring(i + prefixLength); + best_shorttext_a = shorttext.substring(0, j - suffixLength); + best_shorttext_b = shorttext.substring(j + prefixLength); + } + } + if (best_common.length * 2 >= longtext.length) { + return [ + best_longtext_a, best_longtext_b, + best_shorttext_a, best_shorttext_b, best_common + ]; + } else { + return null; + } + } + + // First check if the second quarter is the seed for a half-match. + var hm1 = diff_halfMatchI_(longtext, shorttext, Math.ceil(longtext.length / 4)); + // Check again based on the third quarter. + var hm2 = diff_halfMatchI_(longtext, shorttext, Math.ceil(longtext.length / 2)); + var hm; + if (!hm1 && !hm2) { + return null; + } else if (!hm2) { + hm = hm1; + } else if (!hm1) { + hm = hm2; + } else { + // Both matched. Select the longest. + hm = hm1[4].length > hm2[4].length ? hm1 : hm2; + } + + // A half-match was found, sort out the return data. + var text1_a, text1_b, text2_a, text2_b; + if (text1.length > text2.length) { + text1_a = hm[0]; + text1_b = hm[1]; + text2_a = hm[2]; + text2_b = hm[3]; + } else { + text2_a = hm[0]; + text2_b = hm[1]; + text1_a = hm[2]; + text1_b = hm[3]; + } + var mid_common = hm[4]; + return [text1_a, text1_b, text2_a, text2_b, mid_common]; +}; + + +/** + * Reorder and merge like edit sections. Merge equalities. + * Any edit section can move as long as it doesn't cross an equality. + * @param {Array} diffs Array of diff tuples. + * @param {boolean} fix_unicode Whether to normalize to a unicode-correct diff + */ +function diff_cleanupMerge(diffs, fix_unicode) { + diffs.push([DIFF_EQUAL, '']); // Add a dummy entry at the end. + var pointer = 0; + var count_delete = 0; + var count_insert = 0; + var text_delete = ''; + var text_insert = ''; + var commonlength; + while (pointer < diffs.length) { + if (pointer < diffs.length - 1 && !diffs[pointer][1]) { + diffs.splice(pointer, 1); + continue; + } + switch (diffs[pointer][0]) { + case DIFF_INSERT: + + count_insert++; + text_insert += diffs[pointer][1]; + pointer++; + break; + case DIFF_DELETE: + count_delete++; + text_delete += diffs[pointer][1]; + pointer++; + break; + case DIFF_EQUAL: + var previous_equality = pointer - count_insert - count_delete - 1; + if (fix_unicode) { + // prevent splitting of unicode surrogate pairs. when fix_unicode is true, + // we assume that the old and new text in the diff are complete and correct + // unicode-encoded JS strings, but the tuple boundaries may fall between + // surrogate pairs. we fix this by shaving off stray surrogates from the end + // of the previous equality and the beginning of this equality. this may create + // empty equalities or a common prefix or suffix. for example, if AB and AC are + // emojis, `[[0, 'A'], [-1, 'BA'], [0, 'C']]` would turn into deleting 'ABAC' and + // inserting 'AC', and then the common suffix 'AC' will be eliminated. in this + // particular case, both equalities go away, we absorb any previous inequalities, + // and we keep scanning for the next equality before rewriting the tuples. + if (previous_equality >= 0 && ends_with_pair_start(diffs[previous_equality][1])) { + var stray = diffs[previous_equality][1].slice(-1); + diffs[previous_equality][1] = diffs[previous_equality][1].slice(0, -1); + text_delete = stray + text_delete; + text_insert = stray + text_insert; + if (!diffs[previous_equality][1]) { + // emptied out previous equality, so delete it and include previous delete/insert + diffs.splice(previous_equality, 1); + pointer--; + var k = previous_equality - 1; + if (diffs[k] && diffs[k][0] === DIFF_INSERT) { + count_insert++; + text_insert = diffs[k][1] + text_insert; + k--; + } + if (diffs[k] && diffs[k][0] === DIFF_DELETE) { + count_delete++; + text_delete = diffs[k][1] + text_delete; + k--; + } + previous_equality = k; + } + } + if (starts_with_pair_end(diffs[pointer][1])) { + var stray = diffs[pointer][1].charAt(0); + diffs[pointer][1] = diffs[pointer][1].slice(1); + text_delete += stray; + text_insert += stray; + } + } + if (pointer < diffs.length - 1 && !diffs[pointer][1]) { + // for empty equality not at end, wait for next equality + diffs.splice(pointer, 1); + break; + } + if (text_delete.length > 0 || text_insert.length > 0) { + // note that diff_commonPrefix and diff_commonSuffix are unicode-aware + if (text_delete.length > 0 && text_insert.length > 0) { + // Factor out any common prefixes. + commonlength = diff_commonPrefix(text_insert, text_delete); + if (commonlength !== 0) { + if (previous_equality >= 0) { + diffs[previous_equality][1] += text_insert.substring(0, commonlength); + } else { + diffs.splice(0, 0, [DIFF_EQUAL, text_insert.substring(0, commonlength)]); + pointer++; + } + text_insert = text_insert.substring(commonlength); + text_delete = text_delete.substring(commonlength); + } + // Factor out any common suffixes. + commonlength = diff_commonSuffix(text_insert, text_delete); + if (commonlength !== 0) { + diffs[pointer][1] = + text_insert.substring(text_insert.length - commonlength) + diffs[pointer][1]; + text_insert = text_insert.substring(0, text_insert.length - commonlength); + text_delete = text_delete.substring(0, text_delete.length - commonlength); + } + } + // Delete the offending records and add the merged ones. + var n = count_insert + count_delete; + if (text_delete.length === 0 && text_insert.length === 0) { + diffs.splice(pointer - n, n); + pointer = pointer - n; + } else if (text_delete.length === 0) { + diffs.splice(pointer - n, n, [DIFF_INSERT, text_insert]); + pointer = pointer - n + 1; + } else if (text_insert.length === 0) { + diffs.splice(pointer - n, n, [DIFF_DELETE, text_delete]); + pointer = pointer - n + 1; + } else { + diffs.splice(pointer - n, n, [DIFF_DELETE, text_delete], [DIFF_INSERT, text_insert]); + pointer = pointer - n + 2; + } + } + if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) { + // Merge this equality with the previous one. + diffs[pointer - 1][1] += diffs[pointer][1]; + diffs.splice(pointer, 1); + } else { + pointer++; + } + count_insert = 0; + count_delete = 0; + text_delete = ''; + text_insert = ''; + break; + } + } + if (diffs[diffs.length - 1][1] === '') { + diffs.pop(); // Remove the dummy entry at the end. + } + + // Second pass: look for single edits surrounded on both sides by equalities + // which can be shifted sideways to eliminate an equality. + // e.g: ABAC -> ABAC + var changes = false; + pointer = 1; + // Intentionally ignore the first and last element (don't need checking). + while (pointer < diffs.length - 1) { + if (diffs[pointer - 1][0] === DIFF_EQUAL && + diffs[pointer + 1][0] === DIFF_EQUAL) { + // This is a single edit surrounded by equalities. + if (diffs[pointer][1].substring(diffs[pointer][1].length - + diffs[pointer - 1][1].length) === diffs[pointer - 1][1]) { + // Shift the edit over the previous equality. + diffs[pointer][1] = diffs[pointer - 1][1] + + diffs[pointer][1].substring(0, diffs[pointer][1].length - + diffs[pointer - 1][1].length); + diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1]; + diffs.splice(pointer - 1, 1); + changes = true; + } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) == + diffs[pointer + 1][1]) { + // Shift the edit over the next equality. + diffs[pointer - 1][1] += diffs[pointer + 1][1]; + diffs[pointer][1] = + diffs[pointer][1].substring(diffs[pointer + 1][1].length) + + diffs[pointer + 1][1]; + diffs.splice(pointer + 1, 1); + changes = true; + } + } + pointer++; + } + // If shifts were made, the diff needs reordering and another shift sweep. + if (changes) { + diff_cleanupMerge(diffs, fix_unicode); + } +}; + +function is_surrogate_pair_start(charCode) { + return charCode >= 0xD800 && charCode <= 0xDBFF; +} + +function is_surrogate_pair_end(charCode) { + return charCode >= 0xDC00 && charCode <= 0xDFFF; +} + +function starts_with_pair_end(str) { + return is_surrogate_pair_end(str.charCodeAt(0)); +} + +function ends_with_pair_start(str) { + return is_surrogate_pair_start(str.charCodeAt(str.length - 1)); +} + +function remove_empty_tuples(tuples) { + var ret = []; + for (var i = 0; i < tuples.length; i++) { + if (tuples[i][1].length > 0) { + ret.push(tuples[i]); + } + } + return ret; +} + +function make_edit_splice(before, oldMiddle, newMiddle, after) { + if (ends_with_pair_start(before) || starts_with_pair_end(after)) { + return null; + } + return remove_empty_tuples([ + [DIFF_EQUAL, before], + [DIFF_DELETE, oldMiddle], + [DIFF_INSERT, newMiddle], + [DIFF_EQUAL, after] + ]); +} + +function find_cursor_edit_diff(oldText, newText, cursor_pos) { + // note: this runs after equality check has ruled out exact equality + var oldRange = typeof cursor_pos === 'number' ? + { index: cursor_pos, length: 0 } : cursor_pos.oldRange; + var newRange = typeof cursor_pos === 'number' ? + null : cursor_pos.newRange; + // take into account the old and new selection to generate the best diff + // possible for a text edit. for example, a text change from "xxx" to "xx" + // could be a delete or forwards-delete of any one of the x's, or the + // result of selecting two of the x's and typing "x". + var oldLength = oldText.length; + var newLength = newText.length; + if (oldRange.length === 0 && (newRange === null || newRange.length === 0)) { + // see if we have an insert or delete before or after cursor + var oldCursor = oldRange.index; + var oldBefore = oldText.slice(0, oldCursor); + var oldAfter = oldText.slice(oldCursor); + var maybeNewCursor = newRange ? newRange.index : null; + editBefore: { + // is this an insert or delete right before oldCursor? + var newCursor = oldCursor + newLength - oldLength; + if (maybeNewCursor !== null && maybeNewCursor !== newCursor) { + break editBefore; + } + if (newCursor < 0 || newCursor > newLength) { + break editBefore; + } + var newBefore = newText.slice(0, newCursor); + var newAfter = newText.slice(newCursor); + if (newAfter !== oldAfter) { + break editBefore; + } + var prefixLength = Math.min(oldCursor, newCursor); + var oldPrefix = oldBefore.slice(0, prefixLength); + var newPrefix = newBefore.slice(0, prefixLength); + if (oldPrefix !== newPrefix) { + break editBefore; + } + var oldMiddle = oldBefore.slice(prefixLength); + var newMiddle = newBefore.slice(prefixLength); + return make_edit_splice(oldPrefix, oldMiddle, newMiddle, oldAfter); + } + editAfter: { + // is this an insert or delete right after oldCursor? + if (maybeNewCursor !== null && maybeNewCursor !== oldCursor) { + break editAfter; + } + var cursor = oldCursor; + var newBefore = newText.slice(0, cursor); + var newAfter = newText.slice(cursor); + if (newBefore !== oldBefore) { + break editAfter; + } + var suffixLength = Math.min(oldLength - cursor, newLength - cursor); + var oldSuffix = oldAfter.slice(oldAfter.length - suffixLength); + var newSuffix = newAfter.slice(newAfter.length - suffixLength); + if (oldSuffix !== newSuffix) { + break editAfter; + } + var oldMiddle = oldAfter.slice(0, oldAfter.length - suffixLength); + var newMiddle = newAfter.slice(0, newAfter.length - suffixLength); + return make_edit_splice(oldBefore, oldMiddle, newMiddle, oldSuffix); + } + } + if (oldRange.length > 0 && newRange && newRange.length === 0) { + replaceRange: { + // see if diff could be a splice of the old selection range + var oldPrefix = oldText.slice(0, oldRange.index); + var oldSuffix = oldText.slice(oldRange.index + oldRange.length); + var prefixLength = oldPrefix.length; + var suffixLength = oldSuffix.length; + if (newLength < prefixLength + suffixLength) { + break replaceRange; + } + var newPrefix = newText.slice(0, prefixLength); + var newSuffix = newText.slice(newLength - suffixLength); + if (oldPrefix !== newPrefix || oldSuffix !== newSuffix) { + break replaceRange; + } + var oldMiddle = oldText.slice(prefixLength, oldLength - suffixLength); + var newMiddle = newText.slice(prefixLength, newLength - suffixLength); + return make_edit_splice(oldPrefix, oldMiddle, newMiddle, oldSuffix); + } + } + + return null; +} + +function diff(text1, text2, cursor_pos) { + // only pass fix_unicode=true at the top level, not when diff_main is + // recursively invoked + return diff_main(text1, text2, cursor_pos, true); +} + +diff.INSERT = DIFF_INSERT; +diff.DELETE = DIFF_DELETE; +diff.EQUAL = DIFF_EQUAL; + +module.exports = diff; + + +/***/ }), +/* 210 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +// nvim use utf8 +function byteLength(str) { + return Buffer.byteLength(str); +} +exports.byteLength = byteLength; +function upperFirst(str) { + return str ? str[0].toUpperCase() + str.slice(1) : ''; +} +exports.upperFirst = upperFirst; +function byteIndex(content, index) { + let s = content.slice(0, index); + return Buffer.byteLength(s); +} +exports.byteIndex = byteIndex; +function indexOf(str, ch, count = 1) { + let curr = 0; + for (let i = 0; i < str.length; i++) { + if (str[i] == ch) { + curr = curr + 1; + if (curr == count) { + return i; + } + } + } + return -1; +} +exports.indexOf = indexOf; +function characterIndex(content, byteIndex) { + let buf = Buffer.from(content, 'utf8'); + return buf.slice(0, byteIndex).toString('utf8').length; +} +exports.characterIndex = characterIndex; +function byteSlice(content, start, end) { + let buf = Buffer.from(content, 'utf8'); + return buf.slice(start, end).toString('utf8'); +} +exports.byteSlice = byteSlice; +function isWord(character) { + let code = character.charCodeAt(0); + if (code > 128) + return false; + if (code == 95) + return true; + if (code >= 48 && code <= 57) + return true; + if (code >= 65 && code <= 90) + return true; + if (code >= 97 && code <= 122) + return true; + return false; +} +exports.isWord = isWord; +function isTriggerCharacter(character) { + if (!character) + return false; + let code = character.charCodeAt(0); + if (code > 128) + return false; + if (code >= 65 && code <= 90) + return false; + if (code >= 97 && code <= 122) + return false; + return true; +} +exports.isTriggerCharacter = isTriggerCharacter; +function resolveVariables(str, variables) { + const regexp = /\$\{(.*?)\}/g; + return str.replace(regexp, (match, name) => { + const newValue = variables[name]; + if (typeof newValue === 'string') { + return newValue; + } + return match; + }); +} +exports.resolveVariables = resolveVariables; +function isAsciiLetter(code) { + if (code >= 65 && code <= 90) + return true; + if (code >= 97 && code <= 122) + return true; + return false; +} +exports.isAsciiLetter = isAsciiLetter; +function doEqualsIgnoreCase(a, b, stopAt = a.length) { + if (typeof a !== 'string' || typeof b !== 'string') { + return false; + } + for (let i = 0; i < stopAt; i++) { + const codeA = a.charCodeAt(i); + const codeB = b.charCodeAt(i); + if (codeA === codeB) { + continue; + } + // a-z A-Z + if (isAsciiLetter(codeA) && isAsciiLetter(codeB)) { + const diff = Math.abs(codeA - codeB); + if (diff !== 0 && diff !== 32) { + return false; + } + } + // Any other charcode + else { + if (String.fromCharCode(codeA).toLowerCase() !== String.fromCharCode(codeB).toLowerCase()) { + return false; + } + } + } + return true; +} +function equalsIgnoreCase(a, b) { + const len1 = a ? a.length : 0; + const len2 = b ? b.length : 0; + if (len1 !== len2) { + return false; + } + return doEqualsIgnoreCase(a, b); +} +exports.equalsIgnoreCase = equalsIgnoreCase; +//# sourceMappingURL=string.js.map + +/***/ }), +/* 211 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const logger = __webpack_require__(186)('model-chars'); +class Range { + constructor(start, end) { + this.start = start; + this.end = end ? end : start; + } + static fromKeywordOption(keywordOption) { + let parts = keywordOption.split(','); + let ranges = []; + for (let part of parts) { + if (part == '@') { + // isalpha() of c + ranges.push(new Range(65, 90)); + ranges.push(new Range(97, 122)); + } + else if (part == '@-@') { + ranges.push(new Range(64)); + } + else if (/^([A-Za-z])-([A-Za-z])$/.test(part)) { + let ms = part.match(/^([A-Za-z])-([A-Za-z])$/); + ranges.push(new Range(ms[1].charCodeAt(0), ms[2].charCodeAt(0))); + } + else if (/^\d+-\d+$/.test(part)) { + let ms = part.match(/^(\d+)-(\d+)$/); + ranges.push(new Range(Number(ms[1]), Number(ms[2]))); + } + else if (/^\d+$/.test(part)) { + ranges.push(new Range(Number(part))); + } + else { + let c = part.charCodeAt(0); + if (!ranges.some(o => o.contains(c))) { + ranges.push(new Range(c)); + } + } + } + return ranges; + } + contains(c) { + return c >= this.start && c <= this.end; + } +} +exports.Range = Range; +class Chars { + constructor(keywordOption) { + this.ranges = []; + if (keywordOption) + this.ranges = Range.fromKeywordOption(keywordOption); + } + addKeyword(ch) { + let c = ch.charCodeAt(0); + let { ranges } = this; + if (!ranges.some(o => o.contains(c))) { + ranges.push(new Range(c)); + } + } + clone() { + let chars = new Chars(); + chars.ranges = this.ranges.slice(); + return chars; + } + setKeywordOption(keywordOption) { + this.ranges = Range.fromKeywordOption(keywordOption); + } + matchKeywords(content, min = 3) { + let length = content.length; + if (length == 0) + return []; + let res = new Set(); + let str = ''; + let len = 0; + for (let i = 0; i < length; i++) { + let ch = content[i]; + let code = ch.codePointAt(0); + if (len == 0 && code == 45) + continue; + let isKeyword = this.isKeywordCode(code); + if (isKeyword) { + if (len == 48) + continue; + str = str + ch; + len = len + 1; + } + else { + if (len >= min && len < 48) + res.add(str); + str = ''; + len = 0; + } + } + if (len != 0) + res.add(str); + return Array.from(res); + } + isKeywordCode(code) { + if (code > 255) + return true; + if (code < 33) + return false; + return this.ranges.some(r => r.contains(code)); + } + isKeywordChar(ch) { + let { ranges } = this; + let c = ch.charCodeAt(0); + if (c > 255) + return true; + if (c < 33) + return false; + return ranges.some(r => r.contains(c)); + } + isKeyword(word) { + let { ranges } = this; + for (let i = 0, l = word.length; i < l; i++) { + let ch = word.charCodeAt(i); + // for speed + if (ch > 255) + return false; + if (ranges.some(r => r.contains(ch))) + continue; + return false; + } + return true; + } +} +exports.Chars = Chars; +//# sourceMappingURL=chars.js.map + +/***/ }), +/* 212 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function intersect(array, other) { + for (let item of other) { + if (array.indexOf(item) !== -1) { + return true; + } + } + return false; +} +exports.intersect = intersect; +function tail(array, n = 0) { + return array[array.length - (1 + n)]; +} +exports.tail = tail; +function group(array, size) { + let len = array.length; + let res = []; + for (let i = 0; i < Math.ceil(len / size); i++) { + res.push(array.slice(i * size, (i + 1) * size)); + } + return res; +} +exports.group = group; +/** + * Removes duplicates from the given array. The optional keyFn allows to specify + * how elements are checked for equalness by returning a unique string for each. + */ +function distinct(array, keyFn) { + if (!keyFn) { + return array.filter((element, position) => { + return array.indexOf(element) === position; + }); + } + const seen = Object.create(null); + return array.filter(elem => { + const key = keyFn(elem); + if (seen[key]) { + return false; + } + seen[key] = true; + return true; + }); +} +exports.distinct = distinct; +function lastIndex(array, fn) { + let i = array.length - 1; + while (i >= 0) { + if (fn(array[i])) { + break; + } + i--; + } + return i; +} +exports.lastIndex = lastIndex; +exports.flatMap = (xs, f) => xs.reduce((x, y) => [...x, ...f(y)], []); +//# sourceMappingURL=array.js.map + +/***/ }), +/* 213 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function rangeInRange(r, range) { + return positionInRange(r.start, range) === 0 && positionInRange(r.end, range) === 0; +} +exports.rangeInRange = rangeInRange; +/** + * Check if two ranges have overlap character. + */ +function rangeOverlap(r, range) { + let { start, end } = r; + if (comparePosition(end, range.start) <= 0) { + return false; + } + if (comparePosition(start, range.end) >= 0) { + return false; + } + return true; +} +exports.rangeOverlap = rangeOverlap; +/** + * Check if two ranges have overlap or nested + */ +function rangeIntersect(r, range) { + if (positionInRange(r.start, range) == 0) { + return true; + } + if (positionInRange(r.end, range) == 0) { + return true; + } + if (rangeInRange(range, r)) { + return true; + } + return false; +} +exports.rangeIntersect = rangeIntersect; +function lineInRange(line, range) { + let { start, end } = range; + return line >= start.line && line <= end.line; +} +exports.lineInRange = lineInRange; +function emptyRange(range) { + let { start, end } = range; + return start.line == end.line && start.character == end.character; +} +exports.emptyRange = emptyRange; +function positionInRange(position, range) { + let { start, end } = range; + if (comparePosition(position, start) < 0) + return -1; + if (comparePosition(position, end) > 0) + return 1; + return 0; +} +exports.positionInRange = positionInRange; +function comparePosition(position, other) { + if (position.line > other.line) + return 1; + if (other.line == position.line && position.character > other.character) + return 1; + if (other.line == position.line && position.character == other.character) + return 0; + return -1; +} +exports.comparePosition = comparePosition; +function isSingleLine(range) { + return range.start.line == range.end.line; +} +exports.isSingleLine = isSingleLine; +function getChangedPosition(start, edit) { + let { range, newText } = edit; + if (comparePosition(range.end, start) <= 0) { + let lines = newText.split('\n'); + let lineCount = lines.length - (range.end.line - range.start.line) - 1; + let characterCount = 0; + if (range.end.line == start.line) { + let single = isSingleLine(range) && lineCount == 0; + let removed = single ? range.end.character - range.start.character : range.end.character; + let added = single ? newText.length : lines[lines.length - 1].length; + characterCount = added - removed; + } + return { line: lineCount, character: characterCount }; + } + return { line: 0, character: 0 }; +} +exports.getChangedPosition = getChangedPosition; +function adjustPosition(pos, edit) { + let { range, newText } = edit; + if (comparePosition(range.start, pos) > 1) + return pos; + let { start, end } = range; + let newLines = newText.split('\n'); + let delta = (end.line - start.line) - newLines.length + 1; + let lastLine = newLines[newLines.length - 1]; + let line = pos.line - delta; + if (pos.line != end.line) + return { line, character: pos.character }; + let pre = newLines.length == 1 && start.line != end.line ? start.character : 0; + let removed = start.line == end.line && newLines.length == 1 ? end.character - start.character : end.character; + let character = pre + pos.character + lastLine.length - removed; + return { + line, + character + }; +} +exports.adjustPosition = adjustPosition; +function positionToOffset(lines, line, character) { + let offset = 0; + for (let i = 0; i <= line; i++) { + if (i == line) { + offset += character; + } + else { + offset += lines[i].length + 1; + } + } + return offset; +} +exports.positionToOffset = positionToOffset; +// edit a range to newText +function editRange(range, text, edit) { + // outof range + if (!rangeInRange(edit.range, range)) + return text; + let { start, end } = edit.range; + let lines = text.split('\n'); + let character = start.line == range.start.line ? start.character - range.start.character : start.character; + let startOffset = positionToOffset(lines, start.line - range.start.line, character); + character = end.line == range.start.line ? end.character - range.start.character : end.character; + let endOffset = positionToOffset(lines, end.line - range.start.line, character); + return `${text.slice(0, startOffset)}${edit.newText}${text.slice(endOffset, text.length)}`; +} +exports.editRange = editRange; +function getChangedFromEdits(start, edits) { + let changed = { line: 0, character: 0 }; + for (let edit of edits) { + let d = getChangedPosition(start, edit); + changed = { line: changed.line + d.line, character: changed.character + d.character }; + } + return changed.line == 0 && changed.character == 0 ? null : changed; +} +exports.getChangedFromEdits = getChangedFromEdits; +//# sourceMappingURL=position.js.map + +/***/ }), +/* 214 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const vscode_uri_1 = __webpack_require__(180); +const path = __webpack_require__(57); +const util_1 = __webpack_require__(174); +const logger = __webpack_require__(186)('filesystem-watcher'); +class FileSystemWatcher { + constructor(clientPromise, globPattern, ignoreCreateEvents, ignoreChangeEvents, ignoreDeleteEvents) { + this.globPattern = globPattern; + this.ignoreCreateEvents = ignoreCreateEvents; + this.ignoreChangeEvents = ignoreChangeEvents; + this.ignoreDeleteEvents = ignoreDeleteEvents; + this._onDidCreate = new vscode_languageserver_protocol_1.Emitter(); + this._onDidChange = new vscode_languageserver_protocol_1.Emitter(); + this._onDidDelete = new vscode_languageserver_protocol_1.Emitter(); + this._onDidRename = new vscode_languageserver_protocol_1.Emitter(); + this.onDidCreate = this._onDidCreate.event; + this.onDidChange = this._onDidChange.event; + this.onDidDelete = this._onDidDelete.event; + this.onDidRename = this._onDidRename.event; + this.disposables = []; + if (!clientPromise) + return; + clientPromise.then(client => { + if (client) + return this.listen(client); + }).catch(error => { + logger.error('watchman initialize failed'); + logger.error(error.stack); + }); + } + async listen(client) { + let { globPattern, ignoreCreateEvents, ignoreChangeEvents, ignoreDeleteEvents } = this; + let disposable = await client.subscribe(globPattern, (change) => { + let { root, files } = change; + files = files.filter(f => f.type == 'f'); + for (let file of files) { + let uri = vscode_uri_1.URI.file(path.join(root, file.name)); + if (!file.exists) { + if (!ignoreDeleteEvents) + this._onDidDelete.fire(uri); + } + else { + if (file.size != 0) { + if (!ignoreChangeEvents) + this._onDidChange.fire(uri); + } + else { + if (!ignoreCreateEvents) + this._onDidCreate.fire(uri); + } + } + } + if (files.length == 2 && !files[0].exists && files[1].exists) { + let oldFile = files[0]; + let newFile = files[1]; + if (oldFile.size == newFile.size) { + this._onDidRename.fire({ + oldUri: vscode_uri_1.URI.file(path.join(root, oldFile.name)), + newUri: vscode_uri_1.URI.file(path.join(root, newFile.name)) + }); + } + } + }); + this.disposables.push(disposable); + return disposable; + } + dispose() { + util_1.disposeAll(this.disposables); + } +} +exports.default = FileSystemWatcher; +//# sourceMappingURL=fileSystemWatcher.js.map + +/***/ }), +/* 215 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const os_1 = tslib_1.__importDefault(__webpack_require__(56)); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const util_1 = tslib_1.__importDefault(__webpack_require__(40)); +const mkdirp_1 = tslib_1.__importDefault(__webpack_require__(179)); +const isWindows = process.platform == 'win32'; +const root = isWindows ? path_1.default.join(os_1.default.homedir(), 'AppData/Local/coc') : path_1.default.join(os_1.default.homedir(), '.config/coc'); +/** + * Mru - manage string items as lines in mru file. + */ +class Mru { + /** + * @param {string} name unique name + * @param {string} base? optional directory name, default to config root of coc.nvim + */ + constructor(name, base) { + this.name = name; + this.file = path_1.default.join(base || root, name); + } + /** + * Load iems from mru file + */ + async load() { + let dir = path_1.default.dirname(this.file); + try { + mkdirp_1.default.sync(dir); + if (!fs_1.default.existsSync(this.file)) { + fs_1.default.writeFileSync(this.file, '', 'utf8'); + } + let content = await util_1.default.promisify(fs_1.default.readFile)(this.file, 'utf8'); + content = content.trim(); + return content.length ? content.trim().split('\n') : []; + } + catch (e) { + return []; + } + } + /** + * Add item to mru file. + */ + async add(item) { + let items = await this.load(); + let idx = items.indexOf(item); + if (idx !== -1) + items.splice(idx, 1); + items.unshift(item); + fs_1.default.writeFileSync(this.file, items.join('\n'), 'utf8'); + } + /** + * Remove item from mru file. + */ + async remove(item) { + let items = await this.load(); + let idx = items.indexOf(item); + if (idx !== -1) { + items.splice(idx, 1); + fs_1.default.writeFileSync(this.file, items.join('\n'), 'utf8'); + } + } + /** + * Remove the data file. + */ + async clean() { + try { + await util_1.default.promisify(fs_1.default.unlink)(this.file); + } + catch (e) { + // noop + } + } +} +exports.default = Mru; +//# sourceMappingURL=mru.js.map + +/***/ }), +/* 216 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const util_1 = __webpack_require__(174); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)("outpubChannel"); +class BufferChannel { + constructor(name, nvim) { + this.name = name; + this.nvim = nvim; + this._content = ''; + this.disposables = []; + this._showing = false; + this.promise = Promise.resolve(void 0); + } + get content() { + return this._content; + } + async _append(value, isLine) { + let { buffer } = this; + if (!buffer) + return; + try { + if (isLine) { + await buffer.append(value.split('\n')); + } + else { + let last = await this.nvim.call('getbufline', [buffer.id, '$']); + let content = last + value; + if (this.buffer) { + await buffer.setLines(content.split('\n'), { + start: -2, + end: -1, + strictIndexing: false + }); + } + } + } + catch (e) { + logger.error(`Error on append output:`, e); + } + } + append(value) { + this._content += value; + this.promise = this.promise.then(() => { + return this._append(value, false); + }); + } + appendLine(value) { + this._content += value + '\n'; + this.promise = this.promise.then(() => { + return this._append(value, true); + }); + } + clear() { + this._content = ''; + let { buffer } = this; + if (buffer) { + Promise.resolve(buffer.setLines([], { + start: 0, + end: -1, + strictIndexing: false + })).catch(_e => { + // noop + }); + } + } + hide() { + let { nvim, buffer } = this; + if (buffer) + nvim.command(`silent! bd! ${buffer.id}`, true); + } + dispose() { + this.hide(); + this._content = ''; + util_1.disposeAll(this.disposables); + } + get buffer() { + let doc = workspace_1.default.getDocument(`output:///${this.name}`); + return doc ? doc.buffer : null; + } + async openBuffer(preserveFocus) { + let { nvim, buffer } = this; + if (buffer) { + let loaded = await nvim.call('bufloaded', buffer.id); + if (!loaded) + buffer = null; + } + if (!buffer) { + await nvim.command(`belowright vs output:///${this.name}`); + } + else { + // check shown + let wnr = await nvim.call('bufwinnr', buffer.id); + if (wnr != -1) + return; + await nvim.command(`vert belowright sb ${buffer.id}`); + } + if (preserveFocus) { + await nvim.command('wincmd p'); + } + } + show(preserveFocus) { + if (this._showing) + return; + this._showing = true; + this.openBuffer(preserveFocus).then(() => { + this._showing = false; + }, () => { + this._showing = false; + }); + } +} +exports.default = BufferChannel; +//# sourceMappingURL=outputChannel.js.map + +/***/ }), +/* 217 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const util_1 = __webpack_require__(174); +const fs_1 = __webpack_require__(200); +const decorator_1 = __webpack_require__(218); +const logger = __webpack_require__(186)('model-resolver'); +class Resolver { + get nodeFolder() { + if (!util_1.executable('npm')) + return Promise.resolve(''); + return util_1.runCommand('npm --loglevel silent root -g', {}, 3000).then(root => { + return root.trim(); + }); + } + get yarnFolder() { + if (!util_1.executable('yarnpkg')) + return Promise.resolve(''); + return util_1.runCommand('yarnpkg global dir', {}, 3000).then(root => { + return path_1.default.join(root.trim(), 'node_modules'); + }); + } + async resolveModule(mod) { + let nodeFolder = await this.nodeFolder; + let yarnFolder = await this.yarnFolder; + if (yarnFolder) { + let s = await fs_1.statAsync(path_1.default.join(yarnFolder, mod, 'package.json')); + if (s && s.isFile()) + return path_1.default.join(yarnFolder, mod); + } + if (nodeFolder) { + let s = await fs_1.statAsync(path_1.default.join(nodeFolder, mod, 'package.json')); + if (s && s.isFile()) + return path_1.default.join(nodeFolder, mod); + } + return null; + } +} +tslib_1.__decorate([ + decorator_1.memorize +], Resolver.prototype, "nodeFolder", null); +tslib_1.__decorate([ + decorator_1.memorize +], Resolver.prototype, "yarnFolder", null); +exports.default = Resolver; +//# sourceMappingURL=resolver.js.map + +/***/ }), +/* 218 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const logger = __webpack_require__(186)('util-decorator'); +function memorize(_target, key, descriptor) { + let fn = descriptor.get; + if (typeof fn !== 'function') + return; + let memoKey = '$' + key; + descriptor.get = function (...args) { + if (this.hasOwnProperty(memoKey)) + return Promise.resolve(this[memoKey]); + return new Promise((resolve, reject) => { + Promise.resolve(fn.apply(this, args)).then(res => { + this[memoKey] = res; + resolve(res); + }, e => { + reject(e); + }); + }); + }; +} +exports.memorize = memorize; +//# sourceMappingURL=decorator.js.map + +/***/ }), +/* 219 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const uuidv1 = __webpack_require__(220); +const logger = __webpack_require__(186)('model-status'); +const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; +class StatusLine { + constructor(nvim) { + this.nvim = nvim; + this.items = new Map(); + this.shownIds = new Set(); + this._text = ''; + this.interval = setInterval(() => { + this.setStatusText().logError(); + }, 100); + } + dispose() { + clearInterval(this.interval); + } + createStatusBarItem(priority = 0, isProgress = false) { + let uid = uuidv1(); + let item = { + text: '', + priority, + isProgress, + show: () => { + this.shownIds.add(uid); + }, + hide: () => { + this.shownIds.delete(uid); + }, + dispose: () => { + this.shownIds.delete(uid); + this.items.delete(uid); + } + }; + this.items.set(uid, item); + return item; + } + getText() { + if (this.shownIds.size == 0) + return ''; + let d = new Date(); + let idx = Math.floor(d.getMilliseconds() / 100); + let text = ''; + let items = []; + for (let [id, item] of this.items) { + if (this.shownIds.has(id)) { + items.push(item); + } + } + items.sort((a, b) => a.priority - b.priority); + for (let item of items) { + if (!item.isProgress) { + text = `${text} ${item.text}`; + } + else { + text = `${text} ${frames[idx]} ${item.text}`; + } + } + return text; + } + async setStatusText() { + let text = this.getText(); + let { nvim } = this; + if (text != this._text) { + this._text = text; + nvim.pauseNotification(); + this.nvim.setVar('coc_status', text, true); + this.nvim.command('redraws', true); + this.nvim.call('coc#util#do_autocmd', ['CocStatusChange'], true); + await nvim.resumeNotification(false, true); + } + } +} +exports.default = StatusLine; +//# sourceMappingURL=status.js.map + +/***/ }), +/* 220 */ +/***/ (function(module, exports, __webpack_require__) { + +var rng = __webpack_require__(221); +var bytesToUuid = __webpack_require__(222); + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html + +var _nodeId; +var _clockseq; + +// Previous uuid creation time +var _lastMSecs = 0; +var _lastNSecs = 0; + +// See https://github.com/broofa/node-uuid for API details +function v1(options, buf, offset) { + var i = buf && offset || 0; + var b = buf || []; + + options = options || {}; + var node = options.node || _nodeId; + var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; + + // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + if (node == null || clockseq == null) { + var seedBytes = rng(); + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [ + seedBytes[0] | 0x01, + seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] + ]; + } + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } + + // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); + + // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; + + // Time since last uuid creation (in msecs) + var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; + + // Per 4.2.1.2, Bump clockseq on clock regression + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } + + // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } + + // Per 4.2.1.2 Throw error if too many uuids are requested + if (nsecs >= 10000) { + throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + + // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + msecs += 12219292800000; + + // `time_low` + var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; + + // `time_mid` + var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; + + // `time_high_and_version` + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + b[i++] = tmh >>> 16 & 0xff; + + // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + b[i++] = clockseq >>> 8 | 0x80; + + // `clock_seq_low` + b[i++] = clockseq & 0xff; + + // `node` + for (var n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf ? buf : bytesToUuid(b); +} + +module.exports = v1; + + +/***/ }), +/* 221 */ +/***/ (function(module, exports, __webpack_require__) { + +// Unique ID creation requires a high quality random # generator. In node.js +// this is pretty straight-forward - we use the crypto API. + +var crypto = __webpack_require__(159); + +module.exports = function nodeRNG() { + return crypto.randomBytes(16); +}; + + +/***/ }), +/* 222 */ +/***/ (function(module, exports) { + +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +var byteToHex = []; +for (var i = 0; i < 256; ++i) { + byteToHex[i] = (i + 0x100).toString(16).substr(1); +} + +function bytesToUuid(buf, offset) { + var i = offset || 0; + var bth = byteToHex; + // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 + return ([bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]]]).join(''); +} + +module.exports = bytesToUuid; + + +/***/ }), +/* 223 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const util_1 = __webpack_require__(174); +/** + * Controls long running task started by vim. + * Useful to keep the task running after CocRestart. + * + * @public + */ +class Task { + /** + * @param {Neovim} nvim + * @param {string} id unique id + */ + constructor(nvim, id) { + this.nvim = nvim; + this.id = id; + this.disposables = []; + this._onExit = new vscode_languageserver_protocol_1.Emitter(); + this._onStderr = new vscode_languageserver_protocol_1.Emitter(); + this._onStdout = new vscode_languageserver_protocol_1.Emitter(); + this.onExit = this._onExit.event; + this.onStdout = this._onStdout.event; + this.onStderr = this._onStderr.event; + events_1.default.on('TaskExit', (id, code) => { + if (id == this.id) { + this._onExit.fire(code); + } + }, null, this.disposables); + events_1.default.on('TaskStderr', (id, lines) => { + if (id == this.id) { + this._onStderr.fire(lines); + } + }, null, this.disposables); + let stdout = []; + let timer; + events_1.default.on('TaskStdout', (id, lines) => { + if (id == this.id) { + if (timer) + clearTimeout(timer); + stdout.push(...lines); + timer = setTimeout(() => { + this._onStdout.fire(stdout); + stdout = []; + }, 100); + } + }, null, this.disposables); + } + /** + * Start task, task will be restarted when already running. + * + * @param {TaskOptions} opts + * @returns {Promise} + */ + async start(opts) { + let { nvim } = this; + return await nvim.call('coc#task#start', [this.id, opts]); + } + /** + * Stop task by SIGTERM or SIGKILL + */ + async stop() { + let { nvim } = this; + await nvim.call('coc#task#stop', [this.id]); + } + /** + * Check if the task is running. + */ + get running() { + let { nvim } = this; + return nvim.call('coc#task#running', [this.id]); + } + /** + * Stop task and dispose all events. + */ + dispose() { + let { nvim } = this; + nvim.call('coc#task#stop', [this.id], true); + this._onStdout.dispose(); + this._onStderr.dispose(); + this._onExit.dispose(); + util_1.disposeAll(this.disposables); + } +} +exports.default = Task; +//# sourceMappingURL=task.js.map + +/***/ }), +/* 224 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const logger = __webpack_require__(186)('model-terminal'); +class TerminalModel { + constructor(cmd, args, nvim, _name) { + this.cmd = cmd; + this.args = args; + this.nvim = nvim; + this._name = _name; + this.pid = 0; + } + async start(cwd, env) { + let { nvim } = this; + let cmd = [this.cmd, ...this.args]; + let [bufnr, pid] = await nvim.call('coc#terminal#start', [cmd, cwd, env || {}]); + this.bufnr = bufnr; + this.pid = pid; + } + get name() { + return this._name || this.cmd; + } + get processId() { + return Promise.resolve(this.pid); + } + sendText(text, addNewLine = true) { + if (!this.bufnr) + return; + this.nvim.call('coc#terminal#send', [this.bufnr, text, addNewLine], true); + } + async show(preserveFocus) { + let { bufnr, nvim } = this; + if (!bufnr) + return; + let [loaded, winid] = await nvim.eval(`[bufloaded(${bufnr}),bufwinid(${bufnr})]`); + if (!loaded) + return false; + nvim.pauseNotification(); + if (winid == -1) { + nvim.command(`below ${bufnr}sb`, true); + nvim.command('resize 8', true); + nvim.call('coc#util#do_autocmd', ['CocTerminalOpen'], true); + } + else { + nvim.call('win_gotoid', [winid], true); + } + nvim.command('normal! G', true); + if (preserveFocus) { + nvim.command('wincmd p', true); + } + await nvim.resumeNotification(); + return true; + } + async hide() { + let { bufnr, nvim } = this; + if (!bufnr) + return; + let winnr = await nvim.call('bufwinnr', bufnr); + if (winnr == -1) + return; + await nvim.command(`${winnr}close!`); + } + dispose() { + let { bufnr, nvim } = this; + if (!bufnr) + return; + nvim.call('coc#terminal#close', [bufnr], true); + } +} +exports.default = TerminalModel; +//# sourceMappingURL=terminal.js.map + +/***/ }), +/* 225 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const util_1 = __webpack_require__(174); +const logger = __webpack_require__(186)('willSaveHandler'); +class WillSaveUntilHandler { + constructor(workspace) { + this.workspace = workspace; + this.callbacks = []; + } + get nvim() { + return this.workspace.nvim; + } + addCallback(callback, thisArg, clientId) { + let fn = (event) => { + let { nvim, workspace } = this; + let ev = Object.assign({}, event); + return new Promise(resolve => { + let called = false; + ev.waitUntil = (thenable) => { + called = true; + let { document } = ev; + let timer = setTimeout(() => { + workspace.showMessage(`${clientId} will save operation timeout after 0.5s`, 'warning'); + resolve(null); + }, 500); + Promise.resolve(thenable).then((edits) => { + clearTimeout(timer); + let doc = workspace.getDocument(document.uri); + if (doc && edits && vscode_languageserver_protocol_1.TextEdit.is(edits[0])) { + doc.applyEdits(nvim, edits).then(() => { + // make sure server received ChangedText + setTimeout(resolve, 50); + }, e => { + logger.error(e); + workspace.showMessage(`${clientId} error on applyEdits ${e.message}`, 'error'); + resolve(); + }); + } + else { + resolve(); + } + }, e => { + clearTimeout(timer); + logger.error(`${clientId} error on willSaveUntil ${e.message}`, 'error'); + resolve(); + }); + }; + callback.call(thisArg, ev); + if (!called) { + resolve(); + } + }); + }; + this.callbacks.push(fn); + return vscode_languageserver_protocol_1.Disposable.create(() => { + let idx = this.callbacks.indexOf(fn); + if (idx != -1) { + this.callbacks.splice(idx, 1); + } + }); + } + get hasCallback() { + let { callbacks } = this; + return callbacks.length > 0; + } + async handeWillSaveUntil(event) { + let { callbacks, workspace } = this; + let { document } = event; + if (!callbacks.length) + return; + let doc = workspace.getDocument(document.uri); + if (!doc) + return; + let now = Date.now(); + if (doc.dirty) { + doc.forceSync(); + await util_1.wait(60); + } + for (let fn of callbacks) { + event.document = doc.textDocument; + try { + await fn(event); + } + catch (e) { + logger.error(e); + } + } + logger.info(`Will save cost: ${Date.now() - now}`); + } +} +exports.default = WillSaveUntilHandler; +//# sourceMappingURL=willSaveHandler.js.map + +/***/ }), +/* 226 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const minimatch_1 = tslib_1.__importDefault(__webpack_require__(201)); +const vscode_uri_1 = __webpack_require__(180); +function score(selector, uri, languageId) { + if (Array.isArray(selector)) { + // array -> take max individual value + let ret = 0; + for (const filter of selector) { + const value = score(filter, uri, languageId); + if (value === 10) { + return value; // already at the highest + } + if (value > ret) { + ret = value; + } + } + return ret; + } + else if (typeof selector === 'string') { + // short-hand notion, desugars to + // 'fooLang' -> { language: 'fooLang'} + // '*' -> { language: '*' } + if (selector === '*') { + return 5; + } + else if (selector === languageId) { + return 10; + } + else { + return 0; + } + } + else if (selector) { + let u = vscode_uri_1.URI.parse(uri); + // filter -> select accordingly, use defaults for scheme + const { language, pattern, scheme } = selector; + let ret = 0; + if (scheme) { + if (scheme === u.scheme) { + ret = 5; + } + else if (scheme === '*') { + ret = 3; + } + else { + return 0; + } + } + if (language) { + if (language === languageId) { + ret = 10; + } + else if (language === '*') { + ret = Math.max(ret, 5); + } + else { + return 0; + } + } + if (pattern) { + if (pattern === u.fsPath || minimatch_1.default(u.fsPath, pattern, { dot: true })) { + ret = 5; + } + else { + return 0; + } + } + return ret; + } + else { + return 0; + } +} +exports.score = score; +//# sourceMappingURL=match.js.map + +/***/ }), +/* 227 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fb_watchman_1 = tslib_1.__importDefault(__webpack_require__(228)); +const os_1 = tslib_1.__importDefault(__webpack_require__(56)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const uuidv1 = __webpack_require__(220); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const minimatch_1 = tslib_1.__importDefault(__webpack_require__(201)); +const logger = __webpack_require__(186)('watchman'); +const requiredCapabilities = ['relative_root', 'cmd-watch-project', 'wildmatch']; +const clientsMap = new Map(); +/** + * Watchman wrapper for fb-watchman client + * + * @public + */ +class Watchman { + constructor(binaryPath, channel) { + this.channel = channel; + this._disposed = false; + this.client = new fb_watchman_1.default.Client({ + watchmanBinaryPath: binaryPath + }); + this.client.setMaxListeners(300); + } + checkCapability() { + let { client } = this; + return new Promise((resolve, reject) => { + client.capabilityCheck({ + optional: [], + required: requiredCapabilities + }, (error, resp) => { + if (error) + return reject(error); + let { capabilities } = resp; + for (let key of Object.keys(capabilities)) { + if (!capabilities[key]) + return resolve(false); + } + resolve(true); + }); + }); + } + async watchProject(root) { + try { + let resp = await this.command(['watch-project', root]); + let { watch, warning, relative_path } = resp; + if (warning) + logger.warn(warning); + this.watch = watch; + this.relative_path = relative_path; + logger.info(`watchman watching project: ${root}`); + this.appendOutput(`watchman watching project: ${root}`); + } + catch (e) { + logger.error(e); + return false; + } + return true; + } + command(args) { + return new Promise((resolve, reject) => { + this.client.command(args, (error, resp) => { + if (error) + return reject(error); + resolve(resp); + }); + }); + } + async subscribe(globPattern, cb) { + let { watch, relative_path } = this; + if (!watch) { + this.appendOutput(`watchman not watching: ${watch}`, 'Error'); + return null; + } + let { clock } = await this.command(['clock', watch]); + let uid = uuidv1(); + let sub = { + expression: ['allof', ['match', '**/*', 'wholename']], + fields: ['name', 'size', 'exists', 'type', 'mtime_ms', 'ctime_ms'], + since: clock, + }; + let root = watch; + if (relative_path) { + sub.relative_root = relative_path; + root = path_1.default.join(watch, relative_path); + } + let { subscribe } = await this.command(['subscribe', watch, uid, sub]); + if (global.hasOwnProperty('__TEST__')) + global.subscribe = subscribe; + this.appendOutput(`subscribing "${globPattern}" in ${root}`); + this.client.on('subscription', resp => { + if (!resp || resp.subscription != uid) + return; + let { files } = resp; + files = files.filter(f => f.type == 'f'); + if (!files || !files.length || !minimatch_1.default(files[0].name, globPattern)) + return; + let ev = Object.assign({}, resp); + if (this.relative_path) + ev.root = path_1.default.resolve(resp.root, this.relative_path); + // resp.root = this.relative_path + files.map(f => f.mtime_ms = +f.mtime_ms); + this.appendOutput(`file change detected: ${JSON.stringify(ev, null, 2)}`); + cb(ev); + }); + return vscode_languageserver_protocol_1.Disposable.create(() => { + return this.unsubscribe(subscribe); + }); + } + unsubscribe(subscription) { + if (this._disposed) + return Promise.resolve(); + let { watch } = this; + if (!watch) + return; + this.appendOutput(`unsubscribe "${subscription}" in: ${watch}`); + return this.command(['unsubscribe', watch, subscription]).catch(e => { + logger.error(e); + }); + } + dispose() { + this._disposed = true; + this.client.removeAllListeners(); + this.client.end(); + } + appendOutput(message, type = "Info") { + if (this.channel) { + this.channel.appendLine(`[${type} - ${(new Date().toLocaleTimeString())}] ${message}`); + } + } + static dispose() { + for (let promise of clientsMap.values()) { + promise.then(client => { + client.dispose(); + }, _e => { + // noop + }); + } + } + static createClient(binaryPath, root, channel) { + if (root == os_1.default.homedir() || root == '/' || path_1.default.parse(root).base == root) + return null; + let client = clientsMap.get(root); + if (client) + return client; + let promise = new Promise(async (resolve, reject) => { + try { + let watchman = new Watchman(binaryPath, channel); + let valid = await watchman.checkCapability(); + if (!valid) + return resolve(null); + let watching = await watchman.watchProject(root); + if (!watching) + return resolve(null); + resolve(watchman); + } + catch (e) { + reject(e); + } + }); + clientsMap.set(root, promise); + return promise; + } +} +exports.default = Watchman; +//# sourceMappingURL=watchman.js.map + +/***/ }), +/* 228 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* Copyright 2014-present Facebook, Inc. + * Licensed under the Apache License, Version 2.0 */ + + + +var net = __webpack_require__(6); +var EE = __webpack_require__(49).EventEmitter; +var util = __webpack_require__(40); +var childProcess = __webpack_require__(175); +var bser = __webpack_require__(229); + +// We'll emit the responses to these when they get sent down to us +var unilateralTags = ['subscription', 'log']; + +/** + * @param options An object with the following optional keys: + * * 'watchmanBinaryPath' (string) Absolute path to the watchman binary. + * If not provided, the Client locates the binary using the PATH specified + * by the node child_process's default env. + */ +function Client(options) { + var self = this; + EE.call(this); + + this.watchmanBinaryPath = 'watchman'; + if (options && options.watchmanBinaryPath) { + this.watchmanBinaryPath = options.watchmanBinaryPath.trim(); + }; + this.commands = []; +} +util.inherits(Client, EE); + +module.exports.Client = Client; + +// Try to send the next queued command, if any +Client.prototype.sendNextCommand = function() { + if (this.currentCommand) { + // There's a command pending response, don't send this new one yet + return; + } + + this.currentCommand = this.commands.shift(); + if (!this.currentCommand) { + // No further commands are queued + return; + } + + this.socket.write(bser.dumpToBuffer(this.currentCommand.cmd)); +} + +Client.prototype.cancelCommands = function(why) { + var error = new Error(why); + + // Steal all pending commands before we start cancellation, in + // case something decides to schedule more commands + var cmds = this.commands; + this.commands = []; + + if (this.currentCommand) { + cmds.unshift(this.currentCommand); + this.currentCommand = null; + } + + // Synthesize an error condition for any commands that were queued + cmds.forEach(function(cmd) { + cmd.cb(error); + }); +} + +Client.prototype.connect = function() { + var self = this; + + function makeSock(sockname) { + // bunser will decode the watchman BSER protocol for us + self.bunser = new bser.BunserBuf(); + // For each decoded line: + self.bunser.on('value', function(obj) { + // Figure out if this is a unliteral response or if it is the + // response portion of a request-response sequence. At the time + // of writing, there are only two possible unilateral responses. + var unilateral = false; + for (var i = 0; i < unilateralTags.length; i++) { + var tag = unilateralTags[i]; + if (tag in obj) { + unilateral = tag; + } + } + + if (unilateral) { + self.emit(unilateral, obj); + } else if (self.currentCommand) { + var cmd = self.currentCommand; + self.currentCommand = null; + if ('error' in obj) { + var error = new Error(obj.error); + error.watchmanResponse = obj; + cmd.cb(error); + } else { + cmd.cb(null, obj); + } + } + + // See if we can dispatch the next queued command, if any + self.sendNextCommand(); + }); + self.bunser.on('error', function(err) { + self.emit('error', err); + }); + + self.socket = net.createConnection(sockname); + self.socket.on('connect', function() { + self.connecting = false; + self.emit('connect'); + self.sendNextCommand(); + }); + self.socket.on('error', function(err) { + self.connecting = false; + self.emit('error', err); + }); + self.socket.on('data', function(buf) { + if (self.bunser) { + self.bunser.append(buf); + } + }); + self.socket.on('end', function() { + self.socket = null; + self.bunser = null; + self.cancelCommands('The watchman connection was closed'); + self.emit('end'); + }); + } + + // triggers will export the sock path to the environment. + // If we're invoked in such a way, we can simply pick up the + // definition from the environment and avoid having to fork off + // a process to figure it out + if (process.env.WATCHMAN_SOCK) { + makeSock(process.env.WATCHMAN_SOCK); + return; + } + + // We need to ask the client binary where to find it. + // This will cause the service to start for us if it isn't + // already running. + var args = ['--no-pretty', 'get-sockname']; + + // We use the more elaborate spawn rather than exec because there + // are some error cases on Windows where process spawning can hang. + // It is desirable to pipe stderr directly to stderr live so that + // we can discover the problem. + var proc = null; + var spawnFailed = false; + + function spawnError(error) { + if (spawnFailed) { + // For ENOENT, proc 'close' will also trigger with a negative code, + // let's suppress that second error. + return; + } + spawnFailed = true; + if (error.errno === 'EACCES') { + error.message = 'The Watchman CLI is installed but cannot ' + + 'be spawned because of a permission problem'; + } else if (error.errno === 'ENOENT') { + error.message = 'Watchman was not found in PATH. See ' + + 'https://facebook.github.io/watchman/docs/install.html ' + + 'for installation instructions'; + } + console.error('Watchman: ', error.message); + self.emit('error', error); + } + + try { + proc = childProcess.spawn(this.watchmanBinaryPath, args, { + stdio: ['ignore', 'pipe', 'pipe'] + }); + } catch (error) { + spawnError(error); + return; + } + + var stdout = []; + var stderr = []; + proc.stdout.on('data', function(data) { + stdout.push(data); + }); + proc.stderr.on('data', function(data) { + data = data.toString('utf8'); + stderr.push(data); + console.error(data); + }); + proc.on('error', function(error) { + spawnError(error); + }); + + proc.on('close', function (code, signal) { + if (code !== 0) { + spawnError(new Error( + self.watchmanBinaryPath + ' ' + args.join(' ') + + ' returned with exit code=' + code + ', signal=' + + signal + ', stderr= ' + stderr.join(''))); + return; + } + try { + var obj = JSON.parse(stdout.join('')); + if ('error' in obj) { + var error = new Error(obj.error); + error.watchmanResponse = obj; + self.emit('error', error); + return; + } + makeSock(obj.sockname); + } catch (e) { + self.emit('error', e); + } + }); +} + +Client.prototype.command = function(args, done) { + done = done || function() {}; + + // Queue up the command + this.commands.push({cmd: args, cb: done}); + + // Establish a connection if we don't already have one + if (!this.socket) { + if (!this.connecting) { + this.connecting = true; + this.connect(); + return; + } + return; + } + + // If we're already connected and idle, try sending the command immediately + this.sendNextCommand(); +} + +var cap_versions = { + "cmd-watch-del-all": "3.1.1", + "cmd-watch-project": "3.1", + "relative_root": "3.3", + "term-dirname": "3.1", + "term-idirname": "3.1", + "wildmatch": "3.7", +} + +// Compares a vs b, returns < 0 if a < b, > 0 if b > b, 0 if a == b +function vers_compare(a, b) { + a = a.split('.'); + b = b.split('.'); + for (var i = 0; i < 3; i++) { + var d = parseInt(a[i] || '0') - parseInt(b[i] || '0'); + if (d != 0) { + return d; + } + } + return 0; // Equal +} + +function have_cap(vers, name) { + if (name in cap_versions) { + return vers_compare(vers, cap_versions[name]) >= 0; + } + return false; +} + +// This is a helper that we expose for testing purposes +Client.prototype._synthesizeCapabilityCheck = function( + resp, optional, required) { + resp.capabilities = {} + var version = resp.version; + optional.forEach(function (name) { + resp.capabilities[name] = have_cap(version, name); + }); + required.forEach(function (name) { + var have = have_cap(version, name); + resp.capabilities[name] = have; + if (!have) { + resp.error = 'client required capability `' + name + + '` is not supported by this server'; + } + }); + return resp; +} + +Client.prototype.capabilityCheck = function(caps, done) { + var optional = caps.optional || []; + var required = caps.required || []; + var self = this; + this.command(['version', { + optional: optional, + required: required + }], function (error, resp) { + if (error) { + done(error); + return; + } + if (!('capabilities' in resp)) { + // Server doesn't support capabilities, so we need to + // synthesize the results based on the version + resp = self._synthesizeCapabilityCheck(resp, optional, required); + if (resp.error) { + error = new Error(resp.error); + error.watchmanResponse = resp; + done(error); + return; + } + } + done(null, resp); + }); +} + +// Close the connection to the service +Client.prototype.end = function() { + this.cancelCommands('The client was ended'); + if (this.socket) { + this.socket.end(); + this.socket = null; + } + this.bunser = null; +} + + +/***/ }), +/* 229 */ +/***/ (function(module, exports, __webpack_require__) { + +/* Copyright 2015-present Facebook, Inc. + * Licensed under the Apache License, Version 2.0 */ + +var EE = __webpack_require__(49).EventEmitter; +var util = __webpack_require__(40); +var os = __webpack_require__(56); +var assert = __webpack_require__(101); +var Int64 = __webpack_require__(230); + +// BSER uses the local endianness to reduce byte swapping overheads +// (the protocol is expressly local IPC only). We need to tell node +// to use the native endianness when reading various native values. +var isBigEndian = os.endianness() == 'BE'; + +// Find the next power-of-2 >= size +function nextPow2(size) { + return Math.pow(2, Math.ceil(Math.log(size) / Math.LN2)); +} + +// Expandable buffer that we can provide a size hint for +function Accumulator(initsize) { + this.buf = new Buffer(nextPow2(initsize || 8192)); + this.readOffset = 0; + this.writeOffset = 0; +} +// For testing +exports.Accumulator = Accumulator + +// How much we can write into this buffer without allocating +Accumulator.prototype.writeAvail = function() { + return this.buf.length - this.writeOffset; +} + +// How much we can read +Accumulator.prototype.readAvail = function() { + return this.writeOffset - this.readOffset; +} + +// Ensure that we have enough space for size bytes +Accumulator.prototype.reserve = function(size) { + if (size < this.writeAvail()) { + return; + } + + // If we can make room by shunting down, do so + if (this.readOffset > 0) { + this.buf.copy(this.buf, 0, this.readOffset, this.writeOffset); + this.writeOffset -= this.readOffset; + this.readOffset = 0; + } + + // If we made enough room, no need to allocate more + if (size < this.writeAvail()) { + return; + } + + // Allocate a replacement and copy it in + var buf = new Buffer(nextPow2(this.buf.length + size - this.writeAvail())); + this.buf.copy(buf); + this.buf = buf; +} + +// Append buffer or string. Will resize as needed +Accumulator.prototype.append = function(buf) { + if (Buffer.isBuffer(buf)) { + this.reserve(buf.length); + buf.copy(this.buf, this.writeOffset, 0, buf.length); + this.writeOffset += buf.length; + } else { + var size = Buffer.byteLength(buf); + this.reserve(size); + this.buf.write(buf, this.writeOffset); + this.writeOffset += size; + } +} + +Accumulator.prototype.assertReadableSize = function(size) { + if (this.readAvail() < size) { + throw new Error("wanted to read " + size + + " bytes but only have " + this.readAvail()); + } +} + +Accumulator.prototype.peekString = function(size) { + this.assertReadableSize(size); + return this.buf.toString('utf-8', this.readOffset, this.readOffset + size); +} + +Accumulator.prototype.readString = function(size) { + var str = this.peekString(size); + this.readOffset += size; + return str; +} + +Accumulator.prototype.peekInt = function(size) { + this.assertReadableSize(size); + switch (size) { + case 1: + return this.buf.readInt8(this.readOffset, size); + case 2: + return isBigEndian ? + this.buf.readInt16BE(this.readOffset, size) : + this.buf.readInt16LE(this.readOffset, size); + case 4: + return isBigEndian ? + this.buf.readInt32BE(this.readOffset, size) : + this.buf.readInt32LE(this.readOffset, size); + case 8: + var big = this.buf.slice(this.readOffset, this.readOffset + 8); + if (isBigEndian) { + // On a big endian system we can simply pass the buffer directly + return new Int64(big); + } + // Otherwise we need to byteswap + return new Int64(byteswap64(big)); + default: + throw new Error("invalid integer size " + size); + } +} + +Accumulator.prototype.readInt = function(bytes) { + var ival = this.peekInt(bytes); + if (ival instanceof Int64 && isFinite(ival.valueOf())) { + ival = ival.valueOf(); + } + this.readOffset += bytes; + return ival; +} + +Accumulator.prototype.peekDouble = function() { + this.assertReadableSize(8); + return isBigEndian ? + this.buf.readDoubleBE(this.readOffset) : + this.buf.readDoubleLE(this.readOffset); +} + +Accumulator.prototype.readDouble = function() { + var dval = this.peekDouble(); + this.readOffset += 8; + return dval; +} + +Accumulator.prototype.readAdvance = function(size) { + if (size > 0) { + this.assertReadableSize(size); + } else if (size < 0 && this.readOffset + size < 0) { + throw new Error("advance with negative offset " + size + + " would seek off the start of the buffer"); + } + this.readOffset += size; +} + +Accumulator.prototype.writeByte = function(value) { + this.reserve(1); + this.buf.writeInt8(value, this.writeOffset); + ++this.writeOffset; +} + +Accumulator.prototype.writeInt = function(value, size) { + this.reserve(size); + switch (size) { + case 1: + this.buf.writeInt8(value, this.writeOffset); + break; + case 2: + if (isBigEndian) { + this.buf.writeInt16BE(value, this.writeOffset); + } else { + this.buf.writeInt16LE(value, this.writeOffset); + } + break; + case 4: + if (isBigEndian) { + this.buf.writeInt32BE(value, this.writeOffset); + } else { + this.buf.writeInt32LE(value, this.writeOffset); + } + break; + default: + throw new Error("unsupported integer size " + size); + } + this.writeOffset += size; +} + +Accumulator.prototype.writeDouble = function(value) { + this.reserve(8); + if (isBigEndian) { + this.buf.writeDoubleBE(value, this.writeOffset); + } else { + this.buf.writeDoubleLE(value, this.writeOffset); + } + this.writeOffset += 8; +} + +var BSER_ARRAY = 0x00; +var BSER_OBJECT = 0x01; +var BSER_STRING = 0x02; +var BSER_INT8 = 0x03; +var BSER_INT16 = 0x04; +var BSER_INT32 = 0x05; +var BSER_INT64 = 0x06; +var BSER_REAL = 0x07; +var BSER_TRUE = 0x08; +var BSER_FALSE = 0x09; +var BSER_NULL = 0x0a; +var BSER_TEMPLATE = 0x0b; +var BSER_SKIP = 0x0c; + +var ST_NEED_PDU = 0; // Need to read and decode PDU length +var ST_FILL_PDU = 1; // Know the length, need to read whole content + +var MAX_INT8 = 127; +var MAX_INT16 = 32767; +var MAX_INT32 = 2147483647; + +function BunserBuf() { + EE.call(this); + this.buf = new Accumulator(); + this.state = ST_NEED_PDU; +} +util.inherits(BunserBuf, EE); +exports.BunserBuf = BunserBuf; + +BunserBuf.prototype.append = function(buf, synchronous) { + if (synchronous) { + this.buf.append(buf); + return this.process(synchronous); + } + + try { + this.buf.append(buf); + } catch (err) { + this.emit('error', err); + return; + } + // Arrange to decode later. This allows the consuming + // application to make progress with other work in the + // case that we have a lot of subscription updates coming + // in from a large tree. + this.processLater(); +} + +BunserBuf.prototype.processLater = function() { + var self = this; + process.nextTick(function() { + try { + self.process(false); + } catch (err) { + self.emit('error', err); + } + }); +} + +// Do something with the buffer to advance our state. +// If we're running synchronously we'll return either +// the value we've decoded or undefined if we don't +// yet have enought data. +// If we're running asynchronously, we'll emit the value +// when it becomes ready and schedule another invocation +// of process on the next tick if we still have data we +// can process. +BunserBuf.prototype.process = function(synchronous) { + if (this.state == ST_NEED_PDU) { + if (this.buf.readAvail() < 2) { + return; + } + // Validate BSER header + this.expectCode(0); + this.expectCode(1); + this.pduLen = this.decodeInt(true /* relaxed */); + if (this.pduLen === false) { + // Need more data, walk backwards + this.buf.readAdvance(-2); + return; + } + // Ensure that we have a big enough buffer to read the rest of the PDU + this.buf.reserve(this.pduLen); + this.state = ST_FILL_PDU; + } + + if (this.state == ST_FILL_PDU) { + if (this.buf.readAvail() < this.pduLen) { + // Need more data + return; + } + + // We have enough to decode it + var val = this.decodeAny(); + if (synchronous) { + return val; + } + this.emit('value', val); + this.state = ST_NEED_PDU; + } + + if (!synchronous && this.buf.readAvail() > 0) { + this.processLater(); + } +} + +BunserBuf.prototype.raise = function(reason) { + throw new Error(reason + ", in Buffer of length " + + this.buf.buf.length + " (" + this.buf.readAvail() + + " readable) at offset " + this.buf.readOffset + " buffer: " + + JSON.stringify(this.buf.buf.slice( + this.buf.readOffset, this.buf.readOffset + 32).toJSON())); +} + +BunserBuf.prototype.expectCode = function(expected) { + var code = this.buf.readInt(1); + if (code != expected) { + this.raise("expected bser opcode " + expected + " but got " + code); + } +} + +BunserBuf.prototype.decodeAny = function() { + var code = this.buf.peekInt(1); + switch (code) { + case BSER_INT8: + case BSER_INT16: + case BSER_INT32: + case BSER_INT64: + return this.decodeInt(); + case BSER_REAL: + this.buf.readAdvance(1); + return this.buf.readDouble(); + case BSER_TRUE: + this.buf.readAdvance(1); + return true; + case BSER_FALSE: + this.buf.readAdvance(1); + return false; + case BSER_NULL: + this.buf.readAdvance(1); + return null; + case BSER_STRING: + return this.decodeString(); + case BSER_ARRAY: + return this.decodeArray(); + case BSER_OBJECT: + return this.decodeObject(); + case BSER_TEMPLATE: + return this.decodeTemplate(); + default: + this.raise("unhandled bser opcode " + code); + } +} + +BunserBuf.prototype.decodeArray = function() { + this.expectCode(BSER_ARRAY); + var nitems = this.decodeInt(); + var arr = []; + for (var i = 0; i < nitems; ++i) { + arr.push(this.decodeAny()); + } + return arr; +} + +BunserBuf.prototype.decodeObject = function() { + this.expectCode(BSER_OBJECT); + var nitems = this.decodeInt(); + var res = {}; + for (var i = 0; i < nitems; ++i) { + var key = this.decodeString(); + var val = this.decodeAny(); + res[key] = val; + } + return res; +} + +BunserBuf.prototype.decodeTemplate = function() { + this.expectCode(BSER_TEMPLATE); + var keys = this.decodeArray(); + var nitems = this.decodeInt(); + var arr = []; + for (var i = 0; i < nitems; ++i) { + var obj = {}; + for (var keyidx = 0; keyidx < keys.length; ++keyidx) { + if (this.buf.peekInt(1) == BSER_SKIP) { + this.buf.readAdvance(1); + continue; + } + var val = this.decodeAny(); + obj[keys[keyidx]] = val; + } + arr.push(obj); + } + return arr; +} + +BunserBuf.prototype.decodeString = function() { + this.expectCode(BSER_STRING); + var len = this.decodeInt(); + return this.buf.readString(len); +} + +// This is unusual compared to the other decode functions in that +// we may not have enough data available to satisfy the read, and +// we don't want to throw. This is only true when we're reading +// the PDU length from the PDU header; we'll set relaxSizeAsserts +// in that case. +BunserBuf.prototype.decodeInt = function(relaxSizeAsserts) { + if (relaxSizeAsserts && !this.buf.readAvail(1)) { + return false; + } else { + this.buf.assertReadableSize(1); + } + var code = this.buf.peekInt(1); + var size = 0; + switch (code) { + case BSER_INT8: + size = 1; + break; + case BSER_INT16: + size = 2; + break; + case BSER_INT32: + size = 4; + break; + case BSER_INT64: + size = 8; + break; + default: + this.raise("invalid bser int encoding " + code); + } + + if (relaxSizeAsserts && !this.buf.readAvail(1 + size)) { + return false; + } + this.buf.readAdvance(1); + return this.buf.readInt(size); +} + +// synchronously BSER decode a string and return the value +function loadFromBuffer(input) { + var buf = new BunserBuf(); + var result = buf.append(input, true); + if (buf.buf.readAvail()) { + throw Error( + 'excess data found after input buffer, use BunserBuf instead'); + } + if (typeof result === 'undefined') { + throw Error( + 'no bser found in string and no error raised!?'); + } + return result; +} +exports.loadFromBuffer = loadFromBuffer + +// Byteswap an arbitrary buffer, flipping from one endian +// to the other, returning a new buffer with the resultant data +function byteswap64(buf) { + var swap = new Buffer(buf.length); + for (var i = 0; i < buf.length; i++) { + swap[i] = buf[buf.length -1 - i]; + } + return swap; +} + +function dump_int64(buf, val) { + // Get the raw bytes. The Int64 buffer is big endian + var be = val.toBuffer(); + + if (isBigEndian) { + // We're a big endian system, so the buffer is exactly how we + // want it to be + buf.writeByte(BSER_INT64); + buf.append(be); + return; + } + // We need to byte swap to get the correct representation + var le = byteswap64(be); + buf.writeByte(BSER_INT64); + buf.append(le); +} + +function dump_int(buf, val) { + var abs = Math.abs(val); + if (abs <= MAX_INT8) { + buf.writeByte(BSER_INT8); + buf.writeInt(val, 1); + } else if (abs <= MAX_INT16) { + buf.writeByte(BSER_INT16); + buf.writeInt(val, 2); + } else if (abs <= MAX_INT32) { + buf.writeByte(BSER_INT32); + buf.writeInt(val, 4); + } else { + dump_int64(buf, new Int64(val)); + } +} + +function dump_any(buf, val) { + switch (typeof(val)) { + case 'number': + // check if it is an integer or a float + if (isFinite(val) && Math.floor(val) === val) { + dump_int(buf, val); + } else { + buf.writeByte(BSER_REAL); + buf.writeDouble(val); + } + return; + case 'string': + buf.writeByte(BSER_STRING); + dump_int(buf, Buffer.byteLength(val)); + buf.append(val); + return; + case 'boolean': + buf.writeByte(val ? BSER_TRUE : BSER_FALSE); + return; + case 'object': + if (val === null) { + buf.writeByte(BSER_NULL); + return; + } + if (val instanceof Int64) { + dump_int64(buf, val); + return; + } + if (Array.isArray(val)) { + buf.writeByte(BSER_ARRAY); + dump_int(buf, val.length); + for (var i = 0; i < val.length; ++i) { + dump_any(buf, val[i]); + } + return; + } + buf.writeByte(BSER_OBJECT); + var keys = Object.keys(val); + + // First pass to compute number of defined keys + var num_keys = keys.length; + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + var v = val[key]; + if (typeof(v) == 'undefined') { + num_keys--; + } + } + dump_int(buf, num_keys); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + var v = val[key]; + if (typeof(v) == 'undefined') { + // Don't include it + continue; + } + dump_any(buf, key); + try { + dump_any(buf, v); + } catch (e) { + throw new Error( + e.message + ' (while serializing object property with name `' + + key + "')"); + } + } + return; + + default: + throw new Error('cannot serialize type ' + typeof(val) + ' to BSER'); + } +} + +// BSER encode value and return a buffer of the contents +function dumpToBuffer(val) { + var buf = new Accumulator(); + // Build out the header + buf.writeByte(0); + buf.writeByte(1); + // Reserve room for an int32 to hold our PDU length + buf.writeByte(BSER_INT32); + buf.writeInt(0, 4); // We'll come back and fill this in at the end + + dump_any(buf, val); + + // Compute PDU length + var off = buf.writeOffset; + var len = off - 7 /* the header length */; + buf.writeOffset = 3; // The length value to fill in + buf.writeInt(len, 4); // write the length in the space we reserved + buf.writeOffset = off; + + return buf.buf.slice(0, off); +} +exports.dumpToBuffer = dumpToBuffer + +/***/ }), +/* 230 */ +/***/ (function(module, exports) { + +// Int64.js +// +// Copyright (c) 2012 Robert Kieffer +// MIT License - http://opensource.org/licenses/mit-license.php + +/** + * Support for handling 64-bit int numbers in Javascript (node.js) + * + * JS Numbers are IEEE-754 binary double-precision floats, which limits the + * range of values that can be represented with integer precision to: + * + * 2^^53 <= N <= 2^53 + * + * Int64 objects wrap a node Buffer that holds the 8-bytes of int64 data. These + * objects operate directly on the buffer which means that if they are created + * using an existing buffer then setting the value will modify the Buffer, and + * vice-versa. + * + * Internal Representation + * + * The internal buffer format is Big Endian. I.e. the most-significant byte is + * at buffer[0], the least-significant at buffer[7]. For the purposes of + * converting to/from JS native numbers, the value is assumed to be a signed + * integer stored in 2's complement form. + * + * For details about IEEE-754 see: + * http://en.wikipedia.org/wiki/Double_precision_floating-point_format + */ + +// Useful masks and values for bit twiddling +var MASK31 = 0x7fffffff, VAL31 = 0x80000000; +var MASK32 = 0xffffffff, VAL32 = 0x100000000; + +// Map for converting hex octets to strings +var _HEX = []; +for (var i = 0; i < 256; i++) { + _HEX[i] = (i > 0xF ? '' : '0') + i.toString(16); +} + +// +// Int64 +// + +/** + * Constructor accepts any of the following argument types: + * + * new Int64(buffer[, offset=0]) - Existing Buffer with byte offset + * new Int64(Uint8Array[, offset=0]) - Existing Uint8Array with a byte offset + * new Int64(string) - Hex string (throws if n is outside int64 range) + * new Int64(number) - Number (throws if n is outside int64 range) + * new Int64(hi, lo) - Raw bits as two 32-bit values + */ +var Int64 = module.exports = function(a1, a2) { + if (a1 instanceof Buffer) { + this.buffer = a1; + this.offset = a2 || 0; + } else if (Object.prototype.toString.call(a1) == '[object Uint8Array]') { + // Under Browserify, Buffers can extend Uint8Arrays rather than an + // instance of Buffer. We could assume the passed in Uint8Array is actually + // a buffer but that won't handle the case where a raw Uint8Array is passed + // in. We construct a new Buffer just in case. + this.buffer = new Buffer(a1); + this.offset = a2 || 0; + } else { + this.buffer = this.buffer || new Buffer(8); + this.offset = 0; + this.setValue.apply(this, arguments); + } +}; + + +// Max integer value that JS can accurately represent +Int64.MAX_INT = Math.pow(2, 53); + +// Min integer value that JS can accurately represent +Int64.MIN_INT = -Math.pow(2, 53); + +Int64.prototype = { + + constructor: Int64, + + /** + * Do in-place 2's compliment. See + * http://en.wikipedia.org/wiki/Two's_complement + */ + _2scomp: function() { + var b = this.buffer, o = this.offset, carry = 1; + for (var i = o + 7; i >= o; i--) { + var v = (b[i] ^ 0xff) + carry; + b[i] = v & 0xff; + carry = v >> 8; + } + }, + + /** + * Set the value. Takes any of the following arguments: + * + * setValue(string) - A hexidecimal string + * setValue(number) - Number (throws if n is outside int64 range) + * setValue(hi, lo) - Raw bits as two 32-bit values + */ + setValue: function(hi, lo) { + var negate = false; + if (arguments.length == 1) { + if (typeof(hi) == 'number') { + // Simplify bitfield retrieval by using abs() value. We restore sign + // later + negate = hi < 0; + hi = Math.abs(hi); + lo = hi % VAL32; + hi = hi / VAL32; + if (hi > VAL32) throw new RangeError(hi + ' is outside Int64 range'); + hi = hi | 0; + } else if (typeof(hi) == 'string') { + hi = (hi + '').replace(/^0x/, ''); + lo = hi.substr(-8); + hi = hi.length > 8 ? hi.substr(0, hi.length - 8) : ''; + hi = parseInt(hi, 16); + lo = parseInt(lo, 16); + } else { + throw new Error(hi + ' must be a Number or String'); + } + } + + // Technically we should throw if hi or lo is outside int32 range here, but + // it's not worth the effort. Anything past the 32'nd bit is ignored. + + // Copy bytes to buffer + var b = this.buffer, o = this.offset; + for (var i = 7; i >= 0; i--) { + b[o+i] = lo & 0xff; + lo = i == 4 ? hi : lo >>> 8; + } + + // Restore sign of passed argument + if (negate) this._2scomp(); + }, + + /** + * Convert to a native JS number. + * + * WARNING: Do not expect this value to be accurate to integer precision for + * large (positive or negative) numbers! + * + * @param allowImprecise If true, no check is performed to verify the + * returned value is accurate to integer precision. If false, imprecise + * numbers (very large positive or negative numbers) will be forced to +/- + * Infinity. + */ + toNumber: function(allowImprecise) { + var b = this.buffer, o = this.offset; + + // Running sum of octets, doing a 2's complement + var negate = b[o] & 0x80, x = 0, carry = 1; + for (var i = 7, m = 1; i >= 0; i--, m *= 256) { + var v = b[o+i]; + + // 2's complement for negative numbers + if (negate) { + v = (v ^ 0xff) + carry; + carry = v >> 8; + v = v & 0xff; + } + + x += v * m; + } + + // Return Infinity if we've lost integer precision + if (!allowImprecise && x >= Int64.MAX_INT) { + return negate ? -Infinity : Infinity; + } + + return negate ? -x : x; + }, + + /** + * Convert to a JS Number. Returns +/-Infinity for values that can't be + * represented to integer precision. + */ + valueOf: function() { + return this.toNumber(false); + }, + + /** + * Return string value + * + * @param radix Just like Number#toString()'s radix + */ + toString: function(radix) { + return this.valueOf().toString(radix || 10); + }, + + /** + * Return a string showing the buffer octets, with MSB on the left. + * + * @param sep separator string. default is '' (empty string) + */ + toOctetString: function(sep) { + var out = new Array(8); + var b = this.buffer, o = this.offset; + for (var i = 0; i < 8; i++) { + out[i] = _HEX[b[o+i]]; + } + return out.join(sep || ''); + }, + + /** + * Returns the int64's 8 bytes in a buffer. + * + * @param {bool} [rawBuffer=false] If no offset and this is true, return the internal buffer. Should only be used if + * you're discarding the Int64 afterwards, as it breaks encapsulation. + */ + toBuffer: function(rawBuffer) { + if (rawBuffer && this.offset === 0) return this.buffer; + + var out = new Buffer(8); + this.buffer.copy(out, 0, this.offset, this.offset + 8); + return out; + }, + + /** + * Copy 8 bytes of int64 into target buffer at target offset. + * + * @param {Buffer} targetBuffer Buffer to copy into. + * @param {number} [targetOffset=0] Offset into target buffer. + */ + copy: function(targetBuffer, targetOffset) { + this.buffer.copy(targetBuffer, targetOffset || 0, this.offset, this.offset + 8); + }, + + /** + * Returns a number indicating whether this comes before or after or is the + * same as the other in sort order. + * + * @param {Int64} other Other Int64 to compare. + */ + compare: function(other) { + + // If sign bits differ ... + if ((this.buffer[this.offset] & 0x80) != (other.buffer[other.offset] & 0x80)) { + return other.buffer[other.offset] - this.buffer[this.offset]; + } + + // otherwise, compare bytes lexicographically + for (var i = 0; i < 8; i++) { + if (this.buffer[this.offset+i] !== other.buffer[other.offset+i]) { + return this.buffer[this.offset+i] - other.buffer[other.offset+i]; + } + } + return 0; + }, + + /** + * Returns a boolean indicating if this integer is equal to other. + * + * @param {Int64} other Other Int64 to compare. + */ + equals: function(other) { + return this.compare(other) === 0; + }, + + /** + * Pretty output in console.log + */ + inspect: function() { + return '[Int64 value:' + this + ' octets:' + this.toOctetString(' ') + ']'; + } +}; + + +/***/ }), +/* 231 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const events_1 = __webpack_require__(49); +const vscode_languageserver_types_1 = __webpack_require__(161); +const commands_1 = tslib_1.__importDefault(__webpack_require__(232)); +const completion_1 = tslib_1.__importDefault(__webpack_require__(236)); +const manager_1 = tslib_1.__importDefault(__webpack_require__(316)); +const extensions_1 = tslib_1.__importDefault(__webpack_require__(238)); +const handler_1 = tslib_1.__importDefault(__webpack_require__(399)); +const manager_2 = tslib_1.__importDefault(__webpack_require__(364)); +const services_1 = tslib_1.__importDefault(__webpack_require__(351)); +const manager_3 = tslib_1.__importDefault(__webpack_require__(233)); +const sources_1 = tslib_1.__importDefault(__webpack_require__(237)); +const types_1 = __webpack_require__(189); +const cursors_1 = tslib_1.__importDefault(__webpack_require__(407)); +const clean_1 = tslib_1.__importDefault(__webpack_require__(409)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('plugin'); +class Plugin extends events_1.EventEmitter { + constructor(nvim) { + super(); + this.nvim = nvim; + this._ready = false; + Object.defineProperty(workspace_1.default, 'nvim', { + get: () => this.nvim + }); + this.cursors = new cursors_1.default(nvim); + this.addMethod('hasProvider', async (id) => { + return this.handler.hasProvider(id); + }); + this.addMethod('hasSelected', () => { + return completion_1.default.hasSelected(); + }); + this.addMethod('listNames', () => { + return manager_2.default.names; + }); + this.addMethod('search', (...args) => { + return this.handler.search(args); + }); + this.addMethod('cursorsSelect', (bufnr, kind, mode) => { + return this.cursors.select(bufnr, kind, mode); + }); + this.addMethod('codeActionRange', (start, end, only) => { + return this.handler.codeActionRange(start, end, only); + }); + this.addMethod('rootPatterns', bufnr => { + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return null; + return { + buffer: workspace_1.default.getRootPatterns(doc, types_1.PatternType.Buffer), + server: workspace_1.default.getRootPatterns(doc, types_1.PatternType.LanguageServer), + global: workspace_1.default.getRootPatterns(doc, types_1.PatternType.Global) + }; + }); + this.addMethod('installExtensions', async (...list) => { + await extensions_1.default.installExtensions(list); + }); + this.addMethod('saveRefactor', async (bufnr) => { + await this.handler.saveRefactor(bufnr); + }); + this.addMethod('updateExtensions', async () => { + await extensions_1.default.updateExtensions(); + }); + this.addMethod('commandList', () => { + return commands_1.default.commandList.map(o => o.id); + }); + this.addMethod('openList', async (...args) => { + await this.ready; + await manager_2.default.start(args); + }); + this.addMethod('runCommand', async (...args) => { + await this.ready; + return await this.handler.runCommand(...args); + }); + this.addMethod('selectFunction', async (inner, visualmode) => { + return await this.handler.selectFunction(inner, visualmode); + }); + this.addMethod('listResume', () => { + return manager_2.default.resume(); + }); + this.addMethod('listPrev', () => { + return manager_2.default.previous(); + }); + this.addMethod('listNext', () => { + return manager_2.default.next(); + }); + this.addMethod('detach', () => { + return workspace_1.default.detach(); + }); + this.addMethod('sendRequest', (id, method, params) => { + return services_1.default.sendRequest(id, method, params); + }); + this.addMethod('registNotification', async (id, method) => { + await services_1.default.registNotification(id, method); + }); + this.addMethod('doAutocmd', async (id, ...args) => { + let autocmd = workspace_1.default.autocmds.get(id); + if (autocmd) { + try { + await Promise.resolve(autocmd.callback.apply(autocmd.thisArg, args)); + } + catch (e) { + logger.error(`Error on autocmd ${autocmd.event}`, e); + workspace_1.default.showMessage(`Error on autocmd ${autocmd.event}: ${e.message}`); + } + } + }); + this.addMethod('updateConfig', (section, val) => { + workspace_1.default.configurations.updateUserConfig({ [section]: val }); + }); + this.addMethod('snippetNext', async () => { + await manager_3.default.nextPlaceholder(); + return ''; + }); + this.addMethod('snippetPrev', async () => { + await manager_3.default.previousPlaceholder(); + return ''; + }); + this.addMethod('snippetCancel', () => { + manager_3.default.cancel(); + }); + this.addMethod('openLog', () => { + let file = logger.getLogFile(); + nvim.call(`coc#util#open_file`, ['edit', file], true); + }); + this.addMethod('doKeymap', async (key, defaultReturn = '') => { + let [fn, repeat] = workspace_1.default.keymaps.get(key); + if (!fn) { + logger.error(`keymap for ${key} not found`); + return defaultReturn; + } + let res = await Promise.resolve(fn()); + if (repeat) + await nvim.command(`silent! call repeat#set("\\(coc-${key})", -1)`); + return res || defaultReturn; + }); + this.addMethod('registExtensions', async (...folders) => { + for (let folder of folders) { + await extensions_1.default.loadExtension(folder); + } + }); + workspace_1.default.onDidChangeWorkspaceFolders(() => { + nvim.setVar('WorkspaceFolders', workspace_1.default.folderPaths, true); + }); + commands_1.default.init(nvim, this); + clean_1.default(); // tslint:disable-line + } + addMethod(name, fn) { + Object.defineProperty(this, name, { value: fn }); + } + addCommand(cmd) { + let id = `vim.${cmd.id}`; + commands_1.default.registerCommand(id, async () => { + await this.nvim.command(cmd.cmd); + }); + if (cmd.title) + commands_1.default.titles.set(id, cmd.title); + } + async init() { + let { nvim } = this; + try { + await extensions_1.default.init(); + await workspace_1.default.init(); + completion_1.default.init(); + manager_1.default.init(); + manager_2.default.init(nvim); + nvim.setVar('coc_workspace_initialized', 1, true); + nvim.setVar('coc_process_pid', process.pid, true); + nvim.setVar('WorkspaceFolders', workspace_1.default.folderPaths, true); + sources_1.default.init(); + this.handler = new handler_1.default(nvim); + services_1.default.init(); + await extensions_1.default.activateExtensions(); + nvim.setVar('coc_service_initialized', 1, true); + nvim.call('coc#util#do_autocmd', ['CocNvimInit'], true); + this._ready = true; + let cmds = await nvim.getVar('coc_vim_commands'); + if (cmds && cmds.length) { + for (let cmd of cmds) { + this.addCommand(cmd); + } + } + logger.info(`coc ${this.version} initialized with node: ${process.version}`); + this.emit('ready'); + } + catch (e) { + this._ready = false; + console.error(`Error on initialize: ${e.stack}`); // tslint:disable-line + logger.error(e.stack); + } + workspace_1.default.onDidOpenTextDocument(async (doc) => { + if (!doc.uri.endsWith('coc-settings.json')) + return; + if (extensions_1.default.has('coc-json') || extensions_1.default.isDisabled('coc-json')) + return; + workspace_1.default.showMessage(`Run :CocInstall coc-json for json intellisense`, 'more'); + }); + } + get isReady() { + return this._ready; + } + get ready() { + if (this._ready) + return Promise.resolve(); + return new Promise(resolve => { + this.once('ready', () => { + resolve(); + }); + }); + } + async findLocations(id, method, params, openCommand) { + let { document, position } = await workspace_1.default.getCurrentState(); + params = params || {}; + Object.assign(params, { + textDocument: { uri: document.uri }, + position + }); + let res = await services_1.default.sendRequest(id, method, params); + if (!res) { + workspace_1.default.showMessage(`Locations of "${method}" not found!`, 'warning'); + return; + } + let locations = []; + if (Array.isArray(res)) { + locations = res; + } + else if (res.hasOwnProperty('location') && res.hasOwnProperty('children')) { + function getLocation(item) { + locations.push(item.location); + if (item.children && item.children.length) { + for (let loc of item.children) { + getLocation(loc); + } + } + } + getLocation(res); + } + await this.handler.handleLocations(locations, openCommand); + } + async snippetCheck(checkExpand, checkJump) { + if (checkExpand && !extensions_1.default.has('coc-snippets')) { + // tslint:disable-next-line: no-console + console.error('coc-snippets required for check expand status!'); + return false; + } + if (checkJump) { + let jumpable = manager_3.default.jumpable(); + if (jumpable) + return true; + } + if (checkExpand) { + let api = extensions_1.default.getExtensionApi('coc-snippets'); + if (api && api.hasOwnProperty('expandable')) { + let expandable = await Promise.resolve(api.expandable()); + if (expandable) + return true; + } + } + return false; + } + get version() { + return workspace_1.default.version + ( true ? '-' + "377c2729b9" : undefined); + } + async showInfo() { + if (!this.infoChannel) { + this.infoChannel = workspace_1.default.createOutputChannel('info'); + } + else { + this.infoChannel.clear(); + } + let channel = this.infoChannel; + channel.appendLine('## versions'); + channel.appendLine(''); + let out = await this.nvim.call('execute', ['version']); + channel.appendLine('vim version: ' + out.trim().split('\n', 2)[0]); + channel.appendLine('node version: ' + process.version); + channel.appendLine('coc.nvim version: ' + this.version); + channel.appendLine('term: ' + (process.env.TERM_PROGRAM || process.env.TERM)); + channel.appendLine('platform: ' + process.platform); + channel.appendLine(''); + channel.appendLine('## Messages'); + let msgs = await this.nvim.call('coc#rpc#get_errors'); + channel.append(msgs.join('\n')); + channel.appendLine(''); + for (let ch of workspace_1.default.outputChannels.values()) { + if (ch.name !== 'info') { + channel.appendLine(`## Output channel: ${ch.name}\n`); + channel.append(ch.content); + channel.appendLine(''); + } + } + channel.show(); + } + async cocAction(...args) { + if (!this._ready) + return; + let { handler } = this; + try { + switch (args[0]) { + case 'links': { + return await handler.links(); + } + case 'openLink': { + return await handler.openLink(); + } + case 'pickColor': { + return await handler.pickColor(); + } + case 'colorPresentation': { + return await handler.pickPresentation(); + } + case 'highlight': { + await handler.highlight(); + break; + } + case 'fold': { + return await handler.fold(args[1]); + } + case 'startCompletion': + await completion_1.default.startCompletion(args[1]); + break; + case 'sourceStat': + return sources_1.default.sourceStats(); + case 'refreshSource': + await sources_1.default.refresh(args[1]); + break; + case 'toggleSource': + sources_1.default.toggleSource(args[1]); + break; + case 'diagnosticInfo': + await manager_1.default.echoMessage(); + break; + case 'diagnosticNext': + await manager_1.default.jumpNext(args[1]); + break; + case 'diagnosticPrevious': + await manager_1.default.jumpPrevious(args[1]); + break; + case 'diagnosticList': + return manager_1.default.getDiagnosticList(); + case 'jumpDefinition': + return await handler.gotoDefinition(args[1]); + case 'jumpDeclaration': + return await handler.gotoDeclaration(args[1]); + case 'jumpImplementation': + return await handler.gotoImplementation(args[1]); + case 'jumpTypeDefinition': + return await handler.gotoTypeDefinition(args[1]); + case 'jumpReferences': + return await handler.gotoReferences(args[1]); + case 'doHover': + return await handler.onHover(); + case 'showSignatureHelp': + return await handler.showSignatureHelp(); + case 'documentSymbols': + return await handler.getDocumentSymbols(); + case 'symbolRanges': + return await handler.getSymbolsRanges(); + case 'selectionRanges': + return await handler.getSelectionRanges(); + case 'rangeSelect': + return await handler.selectRange(args[1], args[2]); + case 'rename': + await handler.rename(args[1]); + return; + case 'workspaceSymbols': + this.nvim.command('CocList -I symbols', true); + return; + case 'formatSelected': + return await handler.documentRangeFormatting(args[1]); + case 'format': + return await handler.documentFormatting(); + case 'commands': + return await handler.getCommands(); + case 'services': + return services_1.default.getServiceStats(); + case 'toggleService': + return services_1.default.toggle(args[1]); + case 'codeAction': + return handler.doCodeAction(args[1], args[2]); + case 'doCodeAction': + return await handler.applyCodeAction(args[1]); + case 'codeActions': + return await handler.getCurrentCodeActions(args[1], args[2]); + case 'quickfixes': + return await handler.getCurrentCodeActions(args[1], [vscode_languageserver_types_1.CodeActionKind.QuickFix]); + case 'codeLensAction': + return handler.doCodeLensAction(); + case 'runCommand': + return await handler.runCommand(...args.slice(1)); + case 'doQuickfix': + return await handler.doQuickfix(); + case 'refactor': + return await handler.doRefactor(); + case 'repeatCommand': + return await commands_1.default.repeatCommand(); + case 'extensionStats': + return await extensions_1.default.getExtensionStates(); + case 'activeExtension': + return extensions_1.default.activate(args[1], false); + case 'deactivateExtension': + return extensions_1.default.deactivate(args[1]); + case 'reloadExtension': + return await extensions_1.default.reloadExtension(args[1]); + case 'toggleExtension': + return await extensions_1.default.toggleExtension(args[1]); + case 'uninstallExtension': + return await extensions_1.default.uninstallExtension(args.slice(1)); + case 'getCurrentFunctionSymbol': + return await handler.getCurrentFunctionSymbol(); + case 'getWordEdit': + return await handler.getWordEdit(); + case 'addRanges': + return await this.cursors.addRanges(args[1]); + default: + workspace_1.default.showMessage(`unknown action ${args[0]}`, 'error'); + } + } + catch (e) { + let message = e.hasOwnProperty('message') ? e.message : e.toString(); + if (!/\btimeout\b/.test(message)) { + workspace_1.default.showMessage(`Error on '${args[0]}': ${message}`, 'error'); + } + if (e.stack) + logger.error(e.stack); + } + } + async dispose() { + this.removeAllListeners(); + manager_2.default.dispose(); + workspace_1.default.dispose(); + sources_1.default.dispose(); + await services_1.default.stopAll(); + services_1.default.dispose(); + if (this.handler) { + this.handler.dispose(); + } + manager_3.default.dispose(); + commands_1.default.dispose(); + completion_1.default.dispose(); + manager_1.default.dispose(); + } +} +exports.default = Plugin; +//# sourceMappingURL=plugin.js.map + +/***/ }), +/* 232 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const util_1 = __webpack_require__(174); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const manager_1 = tslib_1.__importDefault(__webpack_require__(233)); +const manager_2 = tslib_1.__importDefault(__webpack_require__(316)); +const vscode_uri_1 = __webpack_require__(180); +const logger = __webpack_require__(186)('commands'); +class CommandItem { + constructor(id, impl, thisArg, internal = false) { + this.id = id; + this.impl = impl; + this.thisArg = thisArg; + this.internal = internal; + } + execute(...args) { + let { impl, thisArg } = this; + return impl.apply(thisArg, args || []); + } + dispose() { + this.thisArg = null; + this.impl = null; + } +} +class CommandManager { + constructor() { + this.commands = new Map(); + this.titles = new Map(); + } + init(nvim, plugin) { + this.mru = workspace_1.default.createMru('commands'); + this.register({ + id: 'vscode.open', + execute: async (url) => { + nvim.call('coc#util#open_url', url.toString(), true); + } + }, true); + this.register({ + id: 'workbench.action.reloadWindow', + execute: () => { + nvim.command('CocRestart', true); + } + }, true); + this.register({ + id: 'editor.action.insertSnippet', + execute: async (edit) => { + let doc = workspace_1.default.getDocument(workspace_1.default.bufnr); + if (!doc) + return; + await nvim.call('coc#_cancel', []); + if (doc.dirty) + doc.forceSync(); + await manager_1.default.insertSnippet(edit.newText, true, edit.range); + } + }, true); + this.register({ + id: 'editor.action.doCodeAction', + execute: async (action) => { + await plugin.cocAction('doCodeAction', action); + } + }, true); + this.register({ + id: 'editor.action.triggerSuggest', + execute: async () => { + await util_1.wait(100); + nvim.call('coc#start', [], true); + } + }, true); + this.register({ + id: 'editor.action.triggerParameterHints', + execute: async () => { + await util_1.wait(60); + await plugin.cocAction('showSignatureHelp'); + } + }, true); + this.register({ + id: 'editor.action.addRanges', + execute: async (ranges) => { + await plugin.cocAction('addRanges', ranges); + } + }, true); + this.register({ + id: 'editor.action.restart', + execute: async () => { + await util_1.wait(30); + nvim.command('CocRestart', true); + } + }, true); + this.register({ + id: 'editor.action.showReferences', + execute: async (_filepath, _position, references) => { + await workspace_1.default.showLocations(references); + } + }, true); + this.register({ + id: 'editor.action.rename', + execute: async (uri, position) => { + await workspace_1.default.jumpTo(uri, position); + await plugin.cocAction('rename'); + } + }, true); + this.register({ + id: 'editor.action.format', + execute: async () => { + await plugin.cocAction('format'); + } + }, true); + this.register({ + id: 'workspace.diffDocument', + execute: async () => { + let document = await workspace_1.default.document; + if (!document) + return; + let lines = document.content.split('\n'); + await nvim.call('coc#util#diff_content', [lines]); + } + }, true); + this.register({ + id: 'workspace.clearWatchman', + execute: async () => { + await workspace_1.default.runCommand('watchman watch-del-all'); + } + }, false, 'run watch-del-all for watchman to free up memory.'); + this.register({ + id: 'workspace.workspaceFolders', + execute: async () => { + let folders = workspace_1.default.workspaceFolders; + let lines = folders.map(folder => vscode_uri_1.URI.parse(folder.uri).fsPath); + await workspace_1.default.echoLines(lines); + } + }, false, 'show opened workspaceFolders.'); + this.register({ + id: 'workspace.renameCurrentFile', + execute: async () => { + await workspace_1.default.renameCurrent(); + } + }, false, 'change current filename to a new name and reload it.'); + this.register({ + id: 'extensions.toggleAutoUpdate', + execute: async () => { + let config = workspace_1.default.getConfiguration('coc.preferences'); + let interval = config.get('extensionUpdateCheck', 'daily'); + if (interval == 'never') { + config.update('extensionUpdateCheck', 'daily', true); + workspace_1.default.showMessage('Extension auto update enabled.', 'more'); + } + else { + config.update('extensionUpdateCheck', 'never', true); + workspace_1.default.showMessage('Extension auto update disabled.', 'more'); + } + } + }, false, 'toggle auto update of extensions.'); + this.register({ + id: 'workspace.diagnosticRelated', + execute: () => { + return manager_2.default.jumpRelated(); + } + }, false, 'jump to related locations of current diagnostic.'); + this.register({ + id: 'workspace.showOutput', + execute: async (name) => { + if (name) { + workspace_1.default.showOutputChannel(name); + } + else { + let names = workspace_1.default.channelNames; + if (names.length == 0) + return; + if (names.length == 1) { + workspace_1.default.showOutputChannel(names[0]); + } + else { + let idx = await workspace_1.default.showQuickpick(names); + if (idx == -1) + return; + let name = names[idx]; + workspace_1.default.showOutputChannel(name); + } + } + } + }, false, 'open output buffer to show output from languageservers or extensions.'); + this.register({ + id: 'document.renameCurrentWord', + execute: async () => { + let bufnr = await nvim.call('bufnr', '%'); + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return; + let edit = await plugin.cocAction('getWordEdit'); + if (!edit) { + workspace_1.default.showMessage('Invalid position', 'warning'); + return; + } + let ranges = []; + let { changes, documentChanges } = edit; + if (changes) { + let edits = changes[doc.uri]; + if (edits) + ranges = edits.map(e => e.range); + } + else if (documentChanges) { + for (let c of documentChanges) { + if (vscode_languageserver_protocol_1.TextDocumentEdit.is(c) && c.textDocument.uri == doc.uri) { + ranges = c.edits.map(e => e.range); + } + } + } + if (ranges.length) { + await plugin.cocAction('addRanges', ranges); + } + } + }, false, 'rename word under cursor in current buffer by use multiple cursors.'); + this.register({ + id: 'document.jumpToNextSymbol', + execute: async () => { + let doc = await workspace_1.default.document; + if (!doc) + return; + let ranges = await plugin.cocAction('symbolRanges'); + if (!ranges) + return; + let { textDocument } = doc; + let offset = await workspace_1.default.getOffset(); + ranges.sort((a, b) => { + if (a.start.line != b.start.line) { + return a.start.line - b.start.line; + } + return a.start.character - b.start.character; + }); + for (let i = 0; i <= ranges.length - 1; i++) { + if (textDocument.offsetAt(ranges[i].start) > offset) { + await workspace_1.default.moveTo(ranges[i].start); + return; + } + } + await workspace_1.default.moveTo(ranges[0].start); + } + }, false, 'Jump to next symbol highlight position.'); + } + get commandList() { + let res = []; + for (let item of this.commands.values()) { + if (!item.internal) + res.push(item); + } + return res; + } + dispose() { + for (const registration of this.commands.values()) { + registration.dispose(); + } + this.commands.clear(); + } + execute(command) { + let args = [command.command]; + let arr = command.arguments; + if (arr) + args.push(...arr); + this.executeCommand.apply(this, args); + } + register(command, internal = false, description) { + for (const id of Array.isArray(command.id) ? command.id : [command.id]) { + this.registerCommand(id, command.execute, command, internal); + if (description) + this.titles.set(id, description); + } + return command; + } + has(id) { + return this.commands.has(id); + } + unregister(id) { + let item = this.commands.get(id); + if (!item) + return; + item.dispose(); + this.commands.delete(id); + } + /** + * Registers a command that can be invoked via a keyboard shortcut, + * a menu item, an action, or directly. + * + * Registering a command with an existing command identifier twice + * will cause an error. + * + * @param command A unique identifier for the command. + * @param impl A command handler function. + * @param thisArg The `this` context used when invoking the handler function. + * @return Disposable which unregisters this command on disposal. + */ + registerCommand(id, impl, thisArg, internal = false) { + if (/^_/.test(id)) + internal = true; + this.commands.set(id, new CommandItem(id, impl, thisArg, internal)); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.commands.delete(id); + }); + } + /** + * Executes the command denoted by the given command identifier. + * + * * *Note 1:* When executing an editor command not all types are allowed to + * be passed as arguments. Allowed are the primitive types `string`, `boolean`, + * `number`, `undefined`, and `null`, as well as [`Position`](#Position), [`Range`](#Range), [`URI`](#URI) and [`Location`](#Location). + * * *Note 2:* There are no restrictions when executing commands that have been contributed + * by extensions. + * + * @param command Identifier of the command to execute. + * @param rest Parameters passed to the command function. + * @return A promise that resolves to the returned value of the given command. `undefined` when + * the command handler function doesn't return anything. + */ + executeCommand(command, ...rest) { + let cmd = this.commands.get(command); + if (!cmd) { + workspace_1.default.showMessage(`Command: ${command} not found`, 'error'); + return; + } + return Promise.resolve(cmd.execute.apply(cmd, rest)).catch(e => { + workspace_1.default.showMessage(`Command error: ${e.message}`, 'error'); + logger.error(e.stack); + }); + } + async addRecent(cmd) { + await this.mru.add(cmd); + await workspace_1.default.nvim.command(`silent! call repeat#set("\\(coc-command-repeat)", -1)`); + } + async repeatCommand() { + let mruList = await this.mru.load(); + let first = mruList[0]; + if (first) { + await this.executeCommand(first); + await workspace_1.default.nvim.command(`silent! call repeat#set("\\(coc-command-repeat)", -1)`); + } + } +} +exports.CommandManager = CommandManager; +exports.default = new CommandManager(); +//# sourceMappingURL=commands.js.map + +/***/ }), +/* 233 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const Snippets = tslib_1.__importStar(__webpack_require__(234)); +const parser_1 = __webpack_require__(234); +const session_1 = __webpack_require__(235); +const variableResolve_1 = __webpack_require__(398); +const logger = __webpack_require__(186)('snippets-manager'); +class SnippetManager { + constructor() { + this.sessionMap = new Map(); + this.disposables = []; + // tslint:disable-next-line:no-floating-promises + workspace_1.default.ready.then(() => { + let config = workspace_1.default.getConfiguration('coc.preferences'); + this.statusItem = workspace_1.default.createStatusBarItem(0); + this.statusItem.text = config.get('snippetStatusText', 'SNIP'); + }); + workspace_1.default.onDidChangeTextDocument(async (e) => { + let { uri } = e.textDocument; + let doc = workspace_1.default.getDocument(uri); + if (!doc) + return; + let session = this.getSession(doc.bufnr); + if (session && session.isActive) { + await session.synchronizeUpdatedPlaceholders(e.contentChanges[0]); + } + }, null, this.disposables); + workspace_1.default.onDidCloseTextDocument(textDocument => { + let doc = workspace_1.default.getDocument(textDocument.uri); + if (!doc) + return; + let session = this.getSession(doc.bufnr); + if (session) + session.deactivate(); + }, null, this.disposables); + events_1.default.on('BufEnter', async (bufnr) => { + let session = this.getSession(bufnr); + if (!this.statusItem) + return; + if (session && session.isActive) { + this.statusItem.show(); + } + else { + this.statusItem.hide(); + } + }, null, this.disposables); + events_1.default.on('InsertEnter', async () => { + let { session } = this; + if (!session) + return; + await session.checkPosition(); + }, null, this.disposables); + } + /** + * Insert snippet at current cursor position + */ + async insertSnippet(snippet, select = true, range) { + let { nvim } = workspace_1.default; + let bufnr = await nvim.call('bufnr', '%'); + let session = this.getSession(bufnr); + if (!session) { + session = new session_1.SnippetSession(workspace_1.default.nvim, bufnr); + this.sessionMap.set(bufnr, session); + session.onCancel(() => { + this.sessionMap.delete(bufnr); + if (workspace_1.default.bufnr == bufnr) { + this.statusItem.hide(); + } + }); + } + let isActive = await session.start(snippet, select, range); + if (isActive) { + this.statusItem.show(); + } + else if (session) { + session.deactivate(); + } + nvim.command('silent! unlet g:coc_last_placeholder g:coc_selected_text', true); + return isActive; + } + isPlainText(text) { + let snippet = (new parser_1.SnippetParser()).parse(text, true); + if (snippet.placeholders.every(p => p.isFinalTabstop == true && p.toString() == '')) { + return true; + } + return false; + } + async selectCurrentPlaceholder(triggerAutocmd = true) { + let { session } = this; + if (session) + return await session.selectCurrentPlaceholder(triggerAutocmd); + } + async nextPlaceholder() { + let { session } = this; + if (session) + return await session.nextPlaceholder(); + workspace_1.default.nvim.call('coc#snippet#disable', [], true); + this.statusItem.hide(); + } + async previousPlaceholder() { + let { session } = this; + if (session) + return await session.previousPlaceholder(); + workspace_1.default.nvim.call('coc#snippet#disable', [], true); + this.statusItem.hide(); + } + cancel() { + let session = this.getSession(workspace_1.default.bufnr); + if (session) + return session.deactivate(); + workspace_1.default.nvim.call('coc#snippet#disable', [], true); + if (this.statusItem) + this.statusItem.hide(); + } + get session() { + let session = this.getSession(workspace_1.default.bufnr); + return session && session.isActive ? session : null; + } + isActived(bufnr) { + let session = this.getSession(bufnr); + return session && session.isActive; + } + jumpable() { + let { session } = this; + if (!session) + return false; + let placeholder = session.placeholder; + if (placeholder && !placeholder.isFinalTabstop) { + return true; + } + return false; + } + getSession(bufnr) { + return this.sessionMap.get(bufnr); + } + async resolveSnippet(body) { + let parser = new Snippets.SnippetParser(); + const snippet = parser.parse(body, true); + const resolver = new variableResolve_1.SnippetVariableResolver(); + snippet.resolveVariables(resolver); + return snippet; + } + dispose() { + this.cancel(); + for (let d of this.disposables) { + d.dispose(); + } + } +} +exports.SnippetManager = SnippetManager; +exports.default = new SnippetManager(); +//# sourceMappingURL=manager.js.map + +/***/ }), +/* 234 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const logger = __webpack_require__(186)('snippets-parser'); +class Scanner { + constructor() { + this.text(''); + } + static isDigitCharacter(ch) { + return ch >= 48 /* Digit0 */ && ch <= 57 /* Digit9 */; + } + static isVariableCharacter(ch) { + return ch === 95 /* Underline */ + || (ch >= 97 /* a */ && ch <= 122 /* z */) + || (ch >= 65 /* A */ && ch <= 90 /* Z */); + } + text(value) { + this.value = value; + this.pos = 0; + } + tokenText(token) { + return this.value.substr(token.pos, token.len); + } + next() { + if (this.pos >= this.value.length) { + return { type: 14 /* EOF */, pos: this.pos, len: 0 }; + } + let pos = this.pos; + let len = 0; + let ch = this.value.charCodeAt(pos); + let type; + // static types + type = Scanner._table[ch]; + if (typeof type === 'number') { + this.pos += 1; + return { type, pos, len: 1 }; + } + // number + if (Scanner.isDigitCharacter(ch)) { + type = 8 /* Int */; + do { + len += 1; + ch = this.value.charCodeAt(pos + len); + } while (Scanner.isDigitCharacter(ch)); + this.pos += len; + return { type, pos, len }; + } + // variable name + if (Scanner.isVariableCharacter(ch)) { + type = 9 /* VariableName */; + do { + ch = this.value.charCodeAt(pos + (++len)); + } while (Scanner.isVariableCharacter(ch) || Scanner.isDigitCharacter(ch)); + this.pos += len; + return { type, pos, len }; + } + // format + type = 10 /* Format */; + do { + len += 1; + ch = this.value.charCodeAt(pos + len); + } while (!isNaN(ch) + && typeof Scanner._table[ch] === 'undefined' // not static token + && !Scanner.isDigitCharacter(ch) // not number + && !Scanner.isVariableCharacter(ch) // not variable + ); + this.pos += len; + return { type, pos, len }; + } +} +exports.Scanner = Scanner; +Scanner._table = { + [36 /* DollarSign */]: 0 /* Dollar */, + [58 /* Colon */]: 1 /* Colon */, + [44 /* Comma */]: 2 /* Comma */, + [123 /* OpenCurlyBrace */]: 3 /* CurlyOpen */, + [125 /* CloseCurlyBrace */]: 4 /* CurlyClose */, + [92 /* Backslash */]: 5 /* Backslash */, + [47 /* Slash */]: 6 /* Forwardslash */, + [124 /* Pipe */]: 7 /* Pipe */, + [43 /* Plus */]: 11 /* Plus */, + [45 /* Dash */]: 12 /* Dash */, + [63 /* QuestionMark */]: 13 /* QuestionMark */, +}; +class Marker { + constructor() { + this._children = []; + } + appendChild(child) { + if (child instanceof Text && this._children[this._children.length - 1] instanceof Text) { + // this and previous child are text -> merge them + this._children[this._children.length - 1].value += child.value; + } + else { + // normal adoption of child + child.parent = this; + this._children.push(child); + } + return this; + } + setOnlyChild(child) { + child.parent = this; + this._children = [child]; + } + replace(child, others) { + const { parent } = child; + const idx = parent.children.indexOf(child); + const newChildren = parent.children.slice(0); + newChildren.splice(idx, 1, ...others); + parent._children = newChildren; + (function _fixParent(children, parent) { + for (const child of children) { + child.parent = parent; + _fixParent(child.children, child); + } + })(others, parent); + } + get children() { + return this._children; + } + get snippet() { + let candidate = this; + while (true) { + if (!candidate) { + return undefined; + } + if (candidate instanceof TextmateSnippet) { + return candidate; + } + candidate = candidate.parent; + } + } + toString() { + return this.children.reduce((prev, cur) => prev + cur.toString(), ''); + } + len() { + return 0; + } + get next() { + let { parent } = this; + let { children } = parent; + let idx = children.indexOf(this); + return children[idx + 1]; + } +} +exports.Marker = Marker; +class Text extends Marker { + constructor(value) { + super(); + this.value = value; + } + static escape(value) { + return value.replace(/\$|}|\\/g, '\\$&'); + } + toString() { + return this.value; + } + toTextmateString() { + return Text.escape(this.value); + } + len() { + return this.value.length; + } + clone() { + return new Text(this.value); + } +} +exports.Text = Text; +class TransformableMarker extends Marker { +} +exports.TransformableMarker = TransformableMarker; +class Placeholder extends TransformableMarker { + constructor(index) { + super(); + this.index = index; + } + static compareByIndex(a, b) { + if (a.index === b.index) { + return 0; + } + else if (a.isFinalTabstop) { + return 1; + } + else if (b.isFinalTabstop) { + return -1; + } + else if (a.index < b.index) { + return -1; + } + else if (a.index > b.index) { + return 1; + } + else { + return 0; + } + } + get isFinalTabstop() { + return this.index === 0; + } + get choice() { + return this._children.length === 1 && this._children[0] instanceof Choice + ? this._children[0] + : undefined; + } + toTextmateString() { + let transformString = ''; + if (this.transform) { + transformString = this.transform.toTextmateString(); + } + if (this.children.length === 0 && !this.transform) { + return `\$${this.index}`; + } + else if (this.children.length === 0) { + return `\${${this.index}${transformString}}`; + } + else if (this.choice) { + return `\${${this.index}|${this.choice.toTextmateString()}|${transformString}}`; + } + else { + return `\${${this.index}:${this.children.map(child => child.toTextmateString()).join('')}${transformString}}`; + } + } + clone() { + let ret = new Placeholder(this.index); + if (this.transform) { + ret.transform = this.transform.clone(); + } + ret._children = this.children.map(child => child.clone()); + return ret; + } +} +exports.Placeholder = Placeholder; +class Choice extends Marker { + constructor() { + super(...arguments); + this.options = []; + } + appendChild(marker) { + if (marker instanceof Text) { + marker.parent = this; + this.options.push(marker); + } + return this; + } + toString() { + return this.options[0].value; + } + toTextmateString() { + return this.options + .map(option => option.value.replace(/\||,/g, '\\$&')) + .join(','); + } + len() { + return this.options[0].len(); + } + clone() { + let ret = new Choice(); + for (let opt of this.options) { + ret.appendChild(opt); + } + return ret; + } +} +exports.Choice = Choice; +class Transform extends Marker { + resolve(value) { + let didMatch = false; + let ret = value.replace(this.regexp, (...args) => { + didMatch = true; + return this._replace(args.slice(0, -2)); + }); + // when the regex didn't match and when the transform has + // else branches, then run those + if (!didMatch && this._children.some(child => child instanceof FormatString && Boolean(child.elseValue))) { + ret = this._replace([]); + } + return ret; + } + _replace(groups) { + let ret = ''; + for (const marker of this._children) { + if (marker instanceof FormatString) { + let value = groups[marker.index] || ''; + value = marker.resolve(value); + ret += value; + } + else { + ret += marker.toString(); + } + } + return ret; + } + toString() { + return ''; + } + toTextmateString() { + return `/${this.regexp.source}/${this.children.map(c => c.toTextmateString())}/${(this.regexp.ignoreCase ? 'i' : '') + (this.regexp.global ? 'g' : '')}`; + } + clone() { + let ret = new Transform(); + ret.regexp = new RegExp(this.regexp.source, '' + (this.regexp.ignoreCase ? 'i' : '') + (this.regexp.global ? 'g' : '')); + ret._children = this.children.map(child => child.clone()); + return ret; + } +} +exports.Transform = Transform; +class FormatString extends Marker { + constructor(index, shorthandName, ifValue, elseValue) { + super(); + this.index = index; + this.shorthandName = shorthandName; + this.ifValue = ifValue; + this.elseValue = elseValue; + } + resolve(value) { + if (this.shorthandName === 'upcase') { + return !value ? '' : value.toLocaleUpperCase(); + } + else if (this.shorthandName === 'downcase') { + return !value ? '' : value.toLocaleLowerCase(); + } + else if (this.shorthandName === 'capitalize') { + return !value ? '' : (value[0].toLocaleUpperCase() + value.substr(1)); + } + else if (this.shorthandName === 'pascalcase') { + return !value ? '' : this._toPascalCase(value); + } + else if (Boolean(value) && typeof this.ifValue === 'string') { + return this.ifValue; + } + else if (!Boolean(value) && typeof this.elseValue === 'string') { + return this.elseValue; + } + else { + return value || ''; + } + } + _toPascalCase(value) { + const match = value.match(/[a-z]+/gi); + if (!match) { + return value; + } + return match.map(word => { + return word.charAt(0).toUpperCase() + + word.substr(1).toLowerCase(); + }) + .join(''); + } + toTextmateString() { + let value = '${'; + value += this.index; + if (this.shorthandName) { + value += `:/${this.shorthandName}`; + } + else if (this.ifValue && this.elseValue) { + value += `:?${this.ifValue}:${this.elseValue}`; + } + else if (this.ifValue) { + value += `:+${this.ifValue}`; + } + else if (this.elseValue) { + value += `:-${this.elseValue}`; + } + value += '}'; + return value; + } + clone() { + let ret = new FormatString(this.index, this.shorthandName, this.ifValue, this.elseValue); + return ret; + } +} +exports.FormatString = FormatString; +class Variable extends TransformableMarker { + constructor(name) { + super(); + this.name = name; + } + resolve(resolver) { + let value = resolver.resolve(this); + if (value && value.indexOf('\n') !== -1) { + // get indent of previous Text child + let { children } = this.parent; + let idx = children.indexOf(this); + let previous = children[idx - 1]; + if (previous && previous instanceof Text) { + let ms = previous.value.match(/\n([ \t]*)$/); + if (ms) { + let newLines = value.split('\n').map((s, i) => { + return i == 0 ? s : ms[1] + s.replace(/^\s*/, ''); + }); + value = newLines.join('\n'); + } + } + } + if (this.transform) { + value = this.transform.resolve(value || ''); + } + if (value !== undefined) { + this._children = [new Text(value)]; + return true; + } + return false; + } + toTextmateString() { + let transformString = ''; + if (this.transform) { + transformString = this.transform.toTextmateString(); + } + if (this.children.length === 0) { + return `\${${this.name}${transformString}}`; + } + else { + return `\${${this.name}:${this.children.map(child => child.toTextmateString()).join('')}${transformString}}`; + } + } + clone() { + const ret = new Variable(this.name); + if (this.transform) { + ret.transform = this.transform.clone(); + } + ret._children = this.children.map(child => child.clone()); + return ret; + } +} +exports.Variable = Variable; +function walk(marker, visitor) { + const stack = [...marker]; + while (stack.length > 0) { + const marker = stack.shift(); + const recurse = visitor(marker); + if (!recurse) { + break; + } + stack.unshift(...marker.children); + } +} +class TextmateSnippet extends Marker { + get placeholderInfo() { + if (!this._placeholders) { + // fill in placeholders + let all = []; + let last; + this.walk(candidate => { + if (candidate instanceof Placeholder) { + all.push(candidate); + last = !last || last.index < candidate.index ? candidate : last; + } + return true; + }); + this._placeholders = { all, last }; + } + return this._placeholders; + } + get placeholders() { + const { all } = this.placeholderInfo; + return all; + } + get maxIndexNumber() { + let { placeholders } = this; + return placeholders.reduce((curr, p) => { + return Math.max(curr, p.index); + }, 0); + } + get minIndexNumber() { + let { placeholders } = this; + let nums = placeholders.map(p => p.index); + nums.sort((a, b) => a - b); + if (nums.length > 1 && nums[0] == 0) + return nums[1]; + return nums[0] || 0; + } + insertSnippet(snippet, id, range) { + let placeholder = this.placeholders[id]; + if (!placeholder) + return; + let { index } = placeholder; + const document = vscode_languageserver_protocol_1.TextDocument.create('untitled:/1', 'snippet', 0, placeholder.toString()); + snippet = vscode_languageserver_protocol_1.TextDocument.applyEdits(document, [{ range, newText: snippet.replace(/\$0$/, '') }]); + let nested = new SnippetParser().parse(snippet, false); + let maxIndexAdded = nested.maxIndexNumber; + let totalAdd = maxIndexAdded + -1; + for (let p of nested.placeholders) { + if (p.isFinalTabstop) { + p.index = maxIndexAdded + index + 1; + } + else { + p.index = p.index + index; + } + } + this.walk(m => { + if (m instanceof Placeholder && m.index > index) { + m.index = m.index + totalAdd + 1; + } + return true; + }); + this.replace(placeholder, nested.children); + return index + 1; + } + updatePlaceholder(id, val) { + const placeholder = this.placeholders[id]; + for (let p of this.placeholders) { + if (p.index == placeholder.index) { + let child = p.children[0]; + let newText = p.transform ? p.transform.resolve(val) : val; + if (child) { + p.setOnlyChild(new Text(newText)); + } + else { + p.appendChild(new Text(newText)); + } + } + } + this._placeholders = undefined; + } + /** + * newText after update with value + */ + getPlaceholderText(id, value) { + const placeholder = this.placeholders[id]; + if (!placeholder) + return value; + return placeholder.transform ? placeholder.transform.resolve(value) : value; + } + offset(marker) { + let pos = 0; + let found = false; + this.walk(candidate => { + if (candidate === marker) { + found = true; + return false; + } + pos += candidate.len(); + return true; + }); + if (!found) { + return -1; + } + return pos; + } + fullLen(marker) { + let ret = 0; + walk([marker], marker => { + ret += marker.len(); + return true; + }); + return ret; + } + enclosingPlaceholders(placeholder) { + let ret = []; + let { parent } = placeholder; + while (parent) { + if (parent instanceof Placeholder) { + ret.push(parent); + } + parent = parent.parent; + } + return ret; + } + resolveVariables(resolver) { + this.walk(candidate => { + if (candidate instanceof Variable) { + if (candidate.resolve(resolver)) { + this._placeholders = undefined; + } + } + return true; + }); + return this; + } + appendChild(child) { + this._placeholders = undefined; + return super.appendChild(child); + } + replace(child, others) { + this._placeholders = undefined; + return super.replace(child, others); + } + toTextmateString() { + return this.children.reduce((prev, cur) => prev + cur.toTextmateString(), ''); + } + clone() { + let ret = new TextmateSnippet(); + this._children = this.children.map(child => child.clone()); + return ret; + } + walk(visitor) { + walk(this.children, visitor); + } +} +exports.TextmateSnippet = TextmateSnippet; +class SnippetParser { + constructor() { + this._scanner = new Scanner(); + } + static escape(value) { + return value.replace(/\$|}|\\/g, '\\$&'); + } + text(value) { + return this.parse(value).toString(); + } + parse(value, insertFinalTabstop) { + this._scanner.text(value); + this._token = this._scanner.next(); + const snippet = new TextmateSnippet(); + while (this._parse(snippet)) { + // nothing + } + // fill in values for placeholders. the first placeholder of an index + // that has a value defines the value for all placeholders with that index + const placeholderDefaultValues = new Map(); + const incompletePlaceholders = []; + snippet.walk(marker => { + if (marker instanceof Placeholder) { + if (marker.isFinalTabstop) { + placeholderDefaultValues.set(0, undefined); + } + else if (!placeholderDefaultValues.has(marker.index) && marker.children.length > 0) { + placeholderDefaultValues.set(marker.index, marker.children); + } + else { + incompletePlaceholders.push(marker); + } + } + return true; + }); + for (const placeholder of incompletePlaceholders) { + if (placeholderDefaultValues.has(placeholder.index)) { + const clone = new Placeholder(placeholder.index); + clone.transform = placeholder.transform; + for (const child of placeholderDefaultValues.get(placeholder.index)) { + let marker = child.clone(); + if (clone.transform) { + if (marker instanceof Text) { + marker = new Text(clone.transform.resolve(marker.value)); + } + else { + for (let child of marker.children) { + if (child instanceof Text) { + marker.replace(child, [new Text(clone.transform.resolve(child.value))]); + break; + } + } + } + } + clone.appendChild(marker); + } + snippet.replace(placeholder, [clone]); + } + } + if (!placeholderDefaultValues.has(0) && insertFinalTabstop) { + // the snippet uses placeholders but has no + // final tabstop defined -> insert at the end + snippet.appendChild(new Placeholder(0)); + } + return snippet; + } + _accept(type, value) { + if (type === undefined || this._token.type === type) { + let ret = !value ? true : this._scanner.tokenText(this._token); + this._token = this._scanner.next(); + return ret; + } + return false; + } + _backTo(token) { + this._scanner.pos = token.pos + token.len; + this._token = token; + return false; + } + _until(type) { + if (this._token.type === 14 /* EOF */) { + return false; + } + let start = this._token; + while (this._token.type !== type) { + this._token = this._scanner.next(); + if (this._token.type === 14 /* EOF */) { + return false; + } + } + let value = this._scanner.value.substring(start.pos, this._token.pos); + this._token = this._scanner.next(); + return value; + } + _parse(marker) { + return this._parseEscaped(marker) + || this._parseTabstopOrVariableName(marker) + || this._parseComplexPlaceholder(marker) + || this._parseComplexVariable(marker) + || this._parseAnything(marker); + } + // \$, \\, \} -> just text + _parseEscaped(marker) { + let value; + if (value = this._accept(5 /* Backslash */, true)) { // tslint:disable-line + // saw a backslash, append escaped token or that backslash + value = this._accept(0 /* Dollar */, true) + || this._accept(4 /* CurlyClose */, true) + || this._accept(5 /* Backslash */, true) + || value; + marker.appendChild(new Text(value)); + return true; + } + return false; + } + // $foo -> variable, $1 -> tabstop + _parseTabstopOrVariableName(parent) { + let value; + const token = this._token; + const match = this._accept(0 /* Dollar */) + && (value = this._accept(9 /* VariableName */, true) || this._accept(8 /* Int */, true)); + if (!match) { + return this._backTo(token); + } + parent.appendChild(/^\d+$/.test(value) + ? new Placeholder(Number(value)) + : new Variable(value)); + return true; + } + // ${1:}, ${1} -> placeholder + _parseComplexPlaceholder(parent) { + let index; + const token = this._token; + const match = this._accept(0 /* Dollar */) + && this._accept(3 /* CurlyOpen */) + && (index = this._accept(8 /* Int */, true)); + if (!match) { + return this._backTo(token); + } + const placeholder = new Placeholder(Number(index)); + if (this._accept(1 /* Colon */)) { + // ${1:} + while (true) { + // ...} -> done + if (this._accept(4 /* CurlyClose */)) { + parent.appendChild(placeholder); + return true; + } + if (this._parse(placeholder)) { + continue; + } + // fallback + parent.appendChild(new Text('${' + index + ':')); + placeholder.children.forEach(parent.appendChild, parent); + return true; + } + } + else if (placeholder.index > 0 && this._accept(7 /* Pipe */)) { + // ${1|one,two,three|} + const choice = new Choice(); + while (true) { + if (this._parseChoiceElement(choice)) { + if (this._accept(2 /* Comma */)) { + // opt, -> more + continue; + } + if (this._accept(7 /* Pipe */)) { + placeholder.appendChild(choice); + if (this._accept(4 /* CurlyClose */)) { + // ..|} -> done + parent.appendChild(placeholder); + return true; + } + } + } + this._backTo(token); + return false; + } + } + else if (this._accept(6 /* Forwardslash */)) { + // ${1///} + if (this._parseTransform(placeholder)) { + parent.appendChild(placeholder); + return true; + } + this._backTo(token); + return false; + } + else if (this._accept(4 /* CurlyClose */)) { + // ${1} + parent.appendChild(placeholder); + return true; + } + else { + // ${1 <- missing curly or colon + return this._backTo(token); + } + } + _parseChoiceElement(parent) { + const token = this._token; + const values = []; + while (true) { + if (this._token.type === 2 /* Comma */ || this._token.type === 7 /* Pipe */) { + break; + } + let value; + if (value = this._accept(5 /* Backslash */, true)) { // tslint:disable-line + // \, \|, or \\ + value = this._accept(2 /* Comma */, true) + || this._accept(7 /* Pipe */, true) + || this._accept(5 /* Backslash */, true) + || value; + } + else { + value = this._accept(undefined, true); + } + if (!value) { + // EOF + this._backTo(token); + return false; + } + values.push(value); + } + if (values.length === 0) { + this._backTo(token); + return false; + } + parent.appendChild(new Text(values.join(''))); + return true; + } + // ${foo:}, ${foo} -> variable + _parseComplexVariable(parent) { + let name; + const token = this._token; + const match = this._accept(0 /* Dollar */) + && this._accept(3 /* CurlyOpen */) + && (name = this._accept(9 /* VariableName */, true)); + if (!match) { + return this._backTo(token); + } + const variable = new Variable(name); + if (this._accept(1 /* Colon */)) { + // ${foo:} + while (true) { + // ...} -> done + if (this._accept(4 /* CurlyClose */)) { + parent.appendChild(variable); + return true; + } + if (this._parse(variable)) { + continue; + } + // fallback + parent.appendChild(new Text('${' + name + ':')); + variable.children.forEach(parent.appendChild, parent); + return true; + } + } + else if (this._accept(6 /* Forwardslash */)) { + // ${foo///} + if (this._parseTransform(variable)) { + parent.appendChild(variable); + return true; + } + this._backTo(token); + return false; + } + else if (this._accept(4 /* CurlyClose */)) { + // ${foo} + parent.appendChild(variable); + return true; + } + else { + // ${foo <- missing curly or colon + return this._backTo(token); + } + } + _parseTransform(parent) { + // ...//} + let transform = new Transform(); + let regexValue = ''; + let regexOptions = ''; + // (1) /regex + while (true) { + if (this._accept(6 /* Forwardslash */)) { + break; + } + let escaped; + if (escaped = this._accept(5 /* Backslash */, true)) { // tslint:disable-line + escaped = this._accept(6 /* Forwardslash */, true) || escaped; + regexValue += escaped; + continue; + } + if (this._token.type !== 14 /* EOF */) { + regexValue += this._accept(undefined, true); + continue; + } + return false; + } + // (2) /format + while (true) { + if (this._accept(6 /* Forwardslash */)) { + break; + } + let escaped; + if (escaped = this._accept(5 /* Backslash */, true)) { // tslint:disable-line + escaped = this._accept(6 /* Forwardslash */, true) || escaped; + transform.appendChild(new Text(escaped)); + continue; + } + if (this._parseFormatString(transform) || this._parseAnything(transform)) { + continue; + } + return false; + } + // (3) /option + while (true) { + if (this._accept(4 /* CurlyClose */)) { + break; + } + if (this._token.type !== 14 /* EOF */) { + regexOptions += this._accept(undefined, true); + continue; + } + return false; + } + try { + transform.regexp = new RegExp(regexValue, regexOptions); + } + catch (e) { + // invalid regexp + return false; + } + parent.transform = transform; + return true; + } + _parseFormatString(parent) { + const token = this._token; + if (!this._accept(0 /* Dollar */)) { + return false; + } + let complex = false; + if (this._accept(3 /* CurlyOpen */)) { + complex = true; + } + let index = this._accept(8 /* Int */, true); + if (!index) { + this._backTo(token); + return false; + } + else if (!complex) { + // $1 + parent.appendChild(new FormatString(Number(index))); + return true; + } + else if (this._accept(4 /* CurlyClose */)) { + // ${1} + parent.appendChild(new FormatString(Number(index))); + return true; + } + else if (!this._accept(1 /* Colon */)) { + this._backTo(token); + return false; + } + if (this._accept(6 /* Forwardslash */)) { + // ${1:/upcase} + let shorthand = this._accept(9 /* VariableName */, true); + if (!shorthand || !this._accept(4 /* CurlyClose */)) { + this._backTo(token); + return false; + } + else { + parent.appendChild(new FormatString(Number(index), shorthand)); + return true; + } + } + else if (this._accept(11 /* Plus */)) { + // ${1:+} + let ifValue = this._until(4 /* CurlyClose */); + if (ifValue) { + parent.appendChild(new FormatString(Number(index), undefined, ifValue, undefined)); + return true; + } + } + else if (this._accept(12 /* Dash */)) { + // ${2:-} + let elseValue = this._until(4 /* CurlyClose */); + if (elseValue) { + parent.appendChild(new FormatString(Number(index), undefined, undefined, elseValue)); + return true; + } + } + else if (this._accept(13 /* QuestionMark */)) { + // ${2:?:} + let ifValue = this._until(1 /* Colon */); + if (ifValue) { + let elseValue = this._until(4 /* CurlyClose */); + if (elseValue) { + parent.appendChild(new FormatString(Number(index), undefined, ifValue, elseValue)); + return true; + } + } + } + else { + // ${1:} + let elseValue = this._until(4 /* CurlyClose */); + if (elseValue) { + parent.appendChild(new FormatString(Number(index), undefined, undefined, elseValue)); + return true; + } + } + this._backTo(token); + return false; + } + _parseAnything(marker) { + if (this._token.type !== 14 /* EOF */) { + marker.appendChild(new Text(this._scanner.tokenText(this._token))); + this._accept(undefined); + return true; + } + return false; + } +} +exports.SnippetParser = SnippetParser; +//# sourceMappingURL=parser.js.map + +/***/ }), +/* 235 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const completion_1 = tslib_1.__importDefault(__webpack_require__(236)); +const util_1 = __webpack_require__(174); +const position_1 = __webpack_require__(213); +const string_1 = __webpack_require__(210); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const snippet_1 = __webpack_require__(397); +const variableResolve_1 = __webpack_require__(398); +const logger = __webpack_require__(186)('snippets-session'); +class SnippetSession { + constructor(nvim, bufnr) { + this.nvim = nvim; + this.bufnr = bufnr; + this._isActive = false; + this._currId = 0; + // Get state of line where we inserted + this.version = 0; + this.preferComplete = false; + this._snippet = null; + this._onCancelEvent = new vscode_languageserver_protocol_1.Emitter(); + this.onCancel = this._onCancelEvent.event; + let config = workspace_1.default.getConfiguration('coc.preferences'); + let suggest = workspace_1.default.getConfiguration('suggest'); + this.preferComplete = config.get('preferCompleteThanJumpPlaceholder', suggest.get('preferCompleteThanJumpPlaceholder', false)); + } + async start(snippetString, select = true, range) { + const { document, nvim } = this; + if (!document) + return false; + if (!range) { + let position = await workspace_1.default.getCursorPosition(); + range = vscode_languageserver_protocol_1.Range.create(position, position); + } + let position = range.start; + const formatOptions = await workspace_1.default.getFormatOptions(this.document.uri); + const currentLine = document.getline(position.line); + const currentIndent = currentLine.match(/^\s*/)[0]; + let inserted = normalizeSnippetString(snippetString, currentIndent, formatOptions); + const resolver = new variableResolve_1.SnippetVariableResolver(); + await resolver.init(document); + const snippet = new snippet_1.CocSnippet(inserted, position, resolver); + const edit = vscode_languageserver_protocol_1.TextEdit.replace(range, snippet.toString()); + if (snippetString.endsWith('\n') + && currentLine.slice(position.character).length) { + // make next line same indent + edit.newText = edit.newText + currentIndent; + inserted = inserted + currentIndent; + } + if (snippet.isPlainText) { + // insert as text + await document.applyEdits(nvim, [edit]); + let placeholder = snippet.finalPlaceholder; + await workspace_1.default.moveTo(placeholder.range.start); + return this._isActive; + } + await document.patchChange(); + document.forceSync(); + this.version = document.version; + await document.applyEdits(nvim, [edit]); + if (this._isActive) { + // insert check + let placeholder = this.findPlaceholder(range); + // insert to placeholder + if (placeholder && !placeholder.isFinalTabstop) { + // don't repeat snippet insert + let index = this.snippet.insertSnippet(placeholder, inserted, range); + let p = this.snippet.getPlaceholder(index); + this._currId = p.id; + if (select) + await this.selectPlaceholder(p); + return true; + } + } + // new snippet + this._snippet = snippet; + this._currId = snippet.firstPlaceholder.id; + if (select) + await this.selectPlaceholder(snippet.firstPlaceholder); + this.activate(); + return true; + } + activate() { + if (this._isActive) + return; + this._isActive = true; + this.nvim.call('coc#snippet#enable', [], true); + } + deactivate() { + if (this._isActive) { + this._isActive = false; + this._snippet = null; + this.nvim.call('coc#snippet#disable', [], true); + logger.debug("[SnippetManager::cancel]"); + } + this._onCancelEvent.fire(void 0); + this._onCancelEvent.dispose(); + } + get isActive() { + return this._isActive; + } + async nextPlaceholder() { + await this.documentSynchronize(); + if (!this.isActive) + return; + let curr = this.placeholder; + let next = this.snippet.getNextPlaceholder(curr.index); + await this.selectPlaceholder(next); + } + async previousPlaceholder() { + await this.documentSynchronize(); + if (!this.isActive) + return; + let curr = this.placeholder; + let prev = this.snippet.getPrevPlaceholder(curr.index); + await this.selectPlaceholder(prev); + } + async synchronizeUpdatedPlaceholders(change) { + if (!this.isActive || !this.document || this.document.version - this.version == 1) + return; + let edit = { range: change.range, newText: change.text }; + let { snippet } = this; + // change outside range + let adjusted = snippet.adjustTextEdit(edit); + if (adjusted) + return; + if (position_1.comparePosition(edit.range.start, snippet.range.end) > 0) { + if (!edit.newText) + return; + logger.info('Content change after snippet, cancelling snippet session'); + this.deactivate(); + return; + } + let placeholder = this.findPlaceholder(edit.range); + if (!placeholder) { + logger.info('Change outside placeholder, cancelling snippet session'); + this.deactivate(); + return; + } + if (placeholder.isFinalTabstop) { + logger.info('Change final placeholder, cancelling snippet session'); + this.deactivate(); + return; + } + this._currId = placeholder.id; + let { edits, delta } = snippet.updatePlaceholder(placeholder, edit); + if (!edits.length) + return; + this.version = this.document.version; + // let pos = await workspace.getCursorPosition() + await this.document.applyEdits(this.nvim, edits); + if (delta) { + await this.nvim.call('coc#util#move_cursor', delta); + } + } + async selectCurrentPlaceholder(triggerAutocmd = true) { + let placeholder = this.snippet.getPlaceholderById(this._currId); + if (placeholder) + await this.selectPlaceholder(placeholder, triggerAutocmd); + } + async selectPlaceholder(placeholder, triggerAutocmd = true) { + let { nvim, document } = this; + if (!document || !placeholder) + return; + let { start, end } = placeholder.range; + const len = end.character - start.character; + const col = string_1.byteLength(document.getline(start.line).slice(0, start.character)) + 1; + this._currId = placeholder.id; + if (placeholder.choice) { + await nvim.call('coc#snippet#show_choices', [start.line + 1, col, len, placeholder.choice]); + } + else { + await this.select(placeholder.range, placeholder.value, triggerAutocmd); + } + } + async select(range, text, triggerAutocmd = true) { + let { document, nvim } = this; + let { start, end } = range; + let { textDocument } = document; + let len = textDocument.offsetAt(end) - textDocument.offsetAt(start); + let line = document.getline(start.line); + let col = line ? string_1.byteLength(line.slice(0, start.character)) : 0; + let endLine = document.getline(end.line); + let endCol = endLine ? string_1.byteLength(endLine.slice(0, end.character)) : 0; + nvim.setVar('coc_last_placeholder', { + current_text: text, + start: { line: start.line, col }, + end: { line: end.line, col: endCol } + }, true); + let [ve, selection, pumvisible, mode] = await nvim.eval('[&virtualedit, &selection, pumvisible(), mode()]'); + let move_cmd = ''; + if (pumvisible && this.preferComplete) { + let pre = completion_1.default.hasSelected() ? '' : '\\'; + await nvim.eval(`feedkeys("${pre}\\", 'in')`); + return; + } + let resetVirtualEdit = false; + if (mode != 'n') + move_cmd += "\\"; + if (len == 0) { + if (col == 0 || (!mode.startsWith('i') && col < string_1.byteLength(line))) { + move_cmd += 'i'; + } + else { + move_cmd += 'a'; + } + } + else { + move_cmd += 'v'; + endCol = await this.getVirtualCol(end.line + 1, endCol); + if (selection == 'inclusive') { + if (end.character == 0) { + move_cmd += `${end.line}G`; + } + else { + move_cmd += `${end.line + 1}G${endCol}|`; + } + } + else if (selection == 'old') { + move_cmd += `${end.line + 1}G${endCol}|`; + } + else { + move_cmd += `${end.line + 1}G${endCol + 1}|`; + } + col = await this.getVirtualCol(start.line + 1, col); + move_cmd += `o${start.line + 1}G${col + 1}|o\\`; + } + nvim.pauseNotification(); + if (ve != 'onemore') { + resetVirtualEdit = true; + nvim.setOption('virtualedit', 'onemore', true); + } + nvim.command(`noa call cursor(${start.line + 1},${col + (move_cmd == 'a' ? 0 : 1)})`, true); + nvim.call('eval', [`feedkeys("${move_cmd}", 'in')`], true); + if (resetVirtualEdit) + nvim.setOption('virtualedit', ve, true); + if (workspace_1.default.env.isVim) + nvim.command('redraw', true); + await nvim.resumeNotification(); + if (triggerAutocmd) + nvim.command('silent doautocmd User CocJumpPlaceholder', true); + } + async getVirtualCol(line, col) { + let { nvim } = this; + return await nvim.eval(`virtcol([${line}, ${col}])`); + } + async documentSynchronize() { + if (!this.isActive) + return; + await this.document.patchChange(); + this.document.forceSync(); + await util_1.wait(50); + } + async checkPosition() { + if (!this.isActive) + return; + let position = await workspace_1.default.getCursorPosition(); + if (this.snippet && position_1.positionInRange(position, this.snippet.range) != 0) { + logger.info('Cursor insert out of range, cancelling snippet session'); + this.deactivate(); + } + } + findPlaceholder(range) { + if (!this.snippet) + return null; + let { placeholder } = this; + if (position_1.rangeInRange(range, placeholder.range)) + return placeholder; + return this.snippet.getPlaceholderByRange(range) || null; + } + get placeholder() { + if (!this.snippet) + return; + return this.snippet.getPlaceholderById(this._currId); + } + get snippet() { + return this._snippet; + } + get document() { + return workspace_1.default.getDocument(this.bufnr); + } +} +exports.SnippetSession = SnippetSession; +function normalizeSnippetString(snippet, indent, opts) { + let lines = snippet.split(/\r?\n/); + let ind = opts.insertSpaces ? ' '.repeat(opts.tabSize) : '\t'; + let tabSize = opts.tabSize || 2; + lines = lines.map((line, idx) => { + let space = line.match(/^\s*/)[0]; + let pre = space; + let isTab = space.startsWith('\t'); + if (isTab && opts.insertSpaces) { + pre = ind.repeat(space.length); + } + else if (!isTab && !opts.insertSpaces) { + pre = ind.repeat(space.length / tabSize); + } + return (idx == 0 || line.length == 0 ? '' : indent) + pre + line.slice(space.length); + }); + return lines.join('\n'); +} +exports.normalizeSnippetString = normalizeSnippetString; +//# sourceMappingURL=session.js.map + +/***/ }), +/* 236 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const debounce_1 = tslib_1.__importDefault(__webpack_require__(176)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const sources_1 = tslib_1.__importDefault(__webpack_require__(237)); +const util_1 = __webpack_require__(174); +const string_1 = __webpack_require__(210); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const complete_1 = tslib_1.__importDefault(__webpack_require__(394)); +const floating_1 = tslib_1.__importDefault(__webpack_require__(396)); +const logger = __webpack_require__(186)('completion'); +const completeItemKeys = ['abbr', 'menu', 'info', 'kind', 'icase', 'dup', 'empty', 'user_data']; +class Completion { + constructor() { + // current input string + this.activated = false; + this.disposables = []; + this.complete = null; + this.recentScores = {}; + this.changedTick = 0; + this.insertCharTs = 0; + this.insertLeaveTs = 0; + // only used when no pum change event + this.isResolving = false; + } + init() { + this.config = this.getCompleteConfig(); + this.floating = new floating_1.default(); + events_1.default.on('InsertCharPre', this.onInsertCharPre, this, this.disposables); + events_1.default.on('InsertLeave', this.onInsertLeave, this, this.disposables); + events_1.default.on('InsertEnter', this.onInsertEnter, this, this.disposables); + events_1.default.on('TextChangedP', this.onTextChangedP, this, this.disposables); + events_1.default.on('TextChangedI', this.onTextChangedI, this, this.disposables); + events_1.default.on('CompleteDone', this.onCompleteDone, this, this.disposables); + events_1.default.on('MenuPopupChanged', this.onPumChange, this, this.disposables); + events_1.default.on('CursorMovedI', debounce_1.default(async (bufnr, cursor) => { + // try trigger completion + let doc = workspace_1.default.getDocument(bufnr); + if (this.isActivated || !doc || cursor[1] == 1 || !this.latestInsertChar) + return; + let line = doc.getline(cursor[0] - 1); + if (!line) + return; + let pre = string_1.byteSlice(line, 0, cursor[1] - 1); + if (sources_1.default.shouldTrigger(pre, doc.filetype)) { + await this.triggerCompletion(doc, pre, false); + } + }, 50)); + workspace_1.default.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('suggest')) { + Object.assign(this.config, this.getCompleteConfig()); + } + }, null, this.disposables); + } + get nvim() { + return workspace_1.default.nvim; + } + get option() { + if (!this.complete) + return null; + return this.complete.option; + } + addRecent(word, bufnr) { + if (!word) + return; + this.recentScores[`${bufnr}|${word}`] = Date.now(); + } + async getPreviousContent(document) { + let [, lnum, col] = await this.nvim.call('getcurpos'); + if (this.option && lnum != this.option.linenr) + return null; + let line = document.getline(lnum - 1); + return col == 1 ? '' : string_1.byteSlice(line, 0, col - 1); + } + getResumeInput(pre) { + let { option, activated } = this; + if (!activated) + return null; + if (!pre) + return ''; + let input = string_1.byteSlice(pre, option.col); + if (option.blacklist && option.blacklist.indexOf(input) !== -1) + return null; + return input; + } + get bufnr() { + let { option } = this; + return option ? option.bufnr : null; + } + get isActivated() { + return this.activated; + } + getCompleteConfig() { + let config = workspace_1.default.getConfiguration('coc.preferences'); + let suggest = workspace_1.default.getConfiguration('suggest'); + function getConfig(key, defaultValue) { + return config.get(key, suggest.get(key, defaultValue)); + } + let keepCompleteopt = getConfig('keepCompleteopt', false); + let autoTrigger = getConfig('autoTrigger', 'always'); + if (keepCompleteopt) { + let { completeOpt } = workspace_1.default; + if (!completeOpt.includes('noinsert') && !completeOpt.includes('noselect')) { + autoTrigger = 'none'; + } + } + let acceptSuggestionOnCommitCharacter = workspace_1.default.env.pumevent && getConfig('acceptSuggestionOnCommitCharacter', false); + return { + autoTrigger, + keepCompleteopt, + defaultSortMethod: getConfig('defaultSortMethod', 'length'), + removeDuplicateItems: getConfig('removeDuplicateItems', false), + disableMenuShortcut: getConfig('disableMenuShortcut', false), + acceptSuggestionOnCommitCharacter, + disableKind: getConfig('disableKind', false), + disableMenu: getConfig('disableMenu', false), + previewIsKeyword: getConfig('previewIsKeyword', '@,48-57,_192-255'), + enablePreview: getConfig('enablePreview', false), + enablePreselect: getConfig('enablePreselect', false), + maxPreviewWidth: getConfig('maxPreviewWidth', 50), + labelMaxLength: getConfig('labelMaxLength', 100), + triggerAfterInsertEnter: getConfig('triggerAfterInsertEnter', false), + noselect: getConfig('noselect', true), + numberSelect: getConfig('numberSelect', false), + maxItemCount: getConfig('maxCompleteItemCount', 50), + timeout: getConfig('timeout', 500), + minTriggerInputLength: getConfig('minTriggerInputLength', 1), + snippetIndicator: getConfig('snippetIndicator', '~'), + fixInsertedWord: getConfig('fixInsertedWord', true), + localityBonus: getConfig('localityBonus', true), + highPrioritySourceLimit: getConfig('highPrioritySourceLimit', null), + lowPrioritySourceLimit: getConfig('lowPrioritySourceLimit', null), + }; + } + async startCompletion(option) { + workspace_1.default.bufnr = option.bufnr; + let document = workspace_1.default.getDocument(option.bufnr); + if (!document) + return; + // use fixed filetype + option.filetype = document.filetype; + this.document = document; + try { + await this._doComplete(option); + } + catch (e) { + this.stop(); + workspace_1.default.showMessage(`Error happens on complete: ${e.message}`, 'error'); + logger.error(e.stack); + } + } + async resumeCompletion(pre, search, force = false) { + let { document, complete, activated } = this; + if (!activated || !complete.results) + return; + if (search == this.input && !force) + return; + let last = search == null ? '' : search.slice(-1); + if (last.length == 0 || + /\s/.test(last) || + sources_1.default.shouldTrigger(pre, document.filetype) || + search.length < complete.input.length) { + this.stop(); + return; + } + this.input = search; + let items; + if (complete.isIncomplete && document.chars.isKeywordChar(last)) { + await document.patchChange(); + document.forceSync(); + await util_1.wait(30); + items = await complete.completeInComplete(search); + // check search change + let content = await this.getPreviousContent(document); + let curr = this.getResumeInput(content); + if (curr != search) + return; + } + else { + items = complete.filterResults(search); + } + if (!this.isActivated) + return; + if (!complete.isCompleting && (!items || items.length === 0)) { + this.stop(); + return; + } + await this.showCompletion(this.option.col, items); + } + hasSelected() { + if (workspace_1.default.env.pumevent) + return this.currItem != null; + if (this.config.noselect === false) + return true; + return this.isResolving; + } + async showCompletion(col, items) { + let { nvim, document, option } = this; + let { numberSelect, disableKind, labelMaxLength, disableMenuShortcut, disableMenu } = this.config; + let preselect = this.config.enablePreselect ? items.findIndex(o => o.preselect == true) : -1; + if (numberSelect && option.input.length && !/^\d/.test(option.input)) { + items = items.map((item, i) => { + let idx = i + 1; + if (i < 9) { + return Object.assign({}, item, { + abbr: item.abbr ? `${idx} ${item.abbr}` : `${idx} ${item.word}` + }); + } + return item; + }); + nvim.call('coc#_map', [], true); + } + this.changedTick = document.changedtick; + let validKeys = completeItemKeys.slice(); + if (disableKind) + validKeys = validKeys.filter(s => s != 'kind'); + if (disableMenu) + validKeys = validKeys.filter(s => s != 'menu'); + let vimItems = items.map(item => { + let obj = { word: item.word, equal: 1 }; + for (let key of validKeys) { + if (item.hasOwnProperty(key)) { + if (disableMenuShortcut && key == 'menu') { + obj[key] = item[key].replace(/\[\w+\]$/, ''); + } + else if (key == 'abbr' && item[key].length > labelMaxLength) { + obj[key] = item[key].slice(0, labelMaxLength); + } + else { + obj[key] = item[key]; + } + } + } + return obj; + }); + nvim.call('coc#_do_complete', [col, vimItems, preselect], true); + } + async _doComplete(option) { + let { source } = option; + let { nvim, config, document } = this; + // current input + this.input = option.input; + let arr = []; + if (source == null) { + arr = sources_1.default.getCompleteSources(option); + } + else { + let s = sources_1.default.getSource(source); + if (s) + arr.push(s); + } + if (!arr.length) + return; + let complete = new complete_1.default(option, document, this.recentScores, config, arr, nvim); + this.start(complete); + let items = await this.complete.doComplete(); + if (complete.isCanceled) + return; + if (items.length == 0 && !complete.isCompleting) { + this.stop(); + return; + } + complete.onDidComplete(async () => { + let content = await this.getPreviousContent(document); + let search = this.getResumeInput(content); + if (complete.isCanceled) + return; + let hasSelected = this.hasSelected(); + if (hasSelected && this.completeOpt.indexOf('noselect') !== -1) + return; + if (search == this.option.input) { + let items = complete.filterResults(search, Math.floor(Date.now() / 1000)); + await this.showCompletion(option.col, items); + return; + } + await this.resumeCompletion(content, search, true); + }); + if (items.length) { + let content = await this.getPreviousContent(document); + let search = this.getResumeInput(content); + if (complete.isCanceled) + return; + if (search == this.option.input) { + await this.showCompletion(option.col, items); + return; + } + await this.resumeCompletion(content, search, true); + } + } + async onTextChangedP() { + let { option, document } = this; + if (!option) + return; + await document.patchChange(); + let hasInsert = this.latestInsert != null; + this.lastInsert = null; + // avoid trigger filter on pumvisible + if (document.changedtick == this.changedTick) + return; + let line = document.getline(option.linenr - 1); + let curr = line.match(/^\s*/)[0]; + let ind = option.line.match(/^\s*/)[0]; + // indent change + if (ind.length != curr.length) { + this.stop(); + return; + } + if (!hasInsert) { + // this could be wrong, but can't avoid. + this.isResolving = true; + return; + } + let pre = await this.getPreviousContent(document); + if (!pre) + return; + let search = this.getResumeInput(pre); + if (sources_1.default.shouldTrigger(pre, document.filetype)) { + await this.triggerCompletion(document, pre, false); + } + else { + await this.resumeCompletion(pre, search); + } + } + async onTextChangedI(bufnr) { + let { nvim, latestInsertChar } = this; + this.lastInsert = null; + let document = workspace_1.default.getDocument(workspace_1.default.bufnr); + if (!document) + return; + await document.patchChange(); + if (!this.isActivated) { + if (!latestInsertChar) + return; + let pre = await this.getPreviousContent(document); + await this.triggerCompletion(document, pre); + return; + } + if (bufnr !== this.bufnr) + return; + // check commit character + if (this.config.acceptSuggestionOnCommitCharacter + && this.currItem + && latestInsertChar + && !this.document.isWord(latestInsertChar)) { + let resolvedItem = this.getCompleteItem(this.currItem); + if (sources_1.default.shouldCommit(resolvedItem, latestInsertChar)) { + let { linenr, col, line, colnr } = this.option; + this.stop(); + let { word } = resolvedItem; + let newLine = `${line.slice(0, col)}${word}${latestInsertChar}${line.slice(colnr - 1)}`; + await nvim.call('coc#util#setline', [linenr, newLine]); + let curcol = col + word.length + 2; + await nvim.call('cursor', [linenr, curcol]); + return; + } + } + let content = await this.getPreviousContent(document); + if (content == null) { + // cursor line changed + this.stop(); + return; + } + // check trigger character + if (sources_1.default.shouldTrigger(content, document.filetype)) { + await this.triggerCompletion(document, content, false); + return; + } + if (!this.isActivated || this.complete.isEmpty) + return; + let search = content.slice(string_1.characterIndex(content, this.option.col)); + return await this.resumeCompletion(content, search); + } + async triggerCompletion(document, pre, checkTrigger = true) { + // check trigger + if (checkTrigger) { + let shouldTrigger = await this.shouldTrigger(document, pre); + if (!shouldTrigger) + return; + } + let option = await this.nvim.call('coc#util#get_complete_option'); + if (!option) + return; + this.fixCompleteOption(option); + option.triggerCharacter = pre.slice(-1); + logger.debug('trigger completion with', option); + await this.startCompletion(option); + } + fixCompleteOption(opt) { + if (workspace_1.default.isVim) { + for (let key of ['word', 'input', 'line', 'filetype']) { + if (opt[key] == null) { + opt[key] = ''; + } + } + } + } + async onCompleteDone(item) { + let { document } = this; + if (!this.isActivated || !document || !item.hasOwnProperty('word')) + return; + let visible = await this.nvim.call('pumvisible'); + if (visible) + return; + let opt = Object.assign({}, this.option); + let resolvedItem = this.getCompleteItem(item); + this.stop(); + if (!resolvedItem) + return; + let timestamp = this.insertCharTs; + let insertLeaveTs = this.insertLeaveTs; + try { + await sources_1.default.doCompleteResolve(resolvedItem, (new vscode_languageserver_protocol_1.CancellationTokenSource()).token); + this.addRecent(resolvedItem.word, document.bufnr); + await util_1.wait(50); + if (this.insertCharTs != timestamp + || this.insertLeaveTs != insertLeaveTs) + return; + await document.patchChange(); + let content = await this.getPreviousContent(document); + if (!content.endsWith(resolvedItem.word)) + return; + await sources_1.default.doCompleteDone(resolvedItem, opt); + document.forceSync(); + } + catch (e) { + // tslint:disable-next-line:no-console + console.error(e.stack); + logger.error(`error on complete done`, e.stack); + } + } + async onInsertLeave(bufnr) { + this.insertLeaveTs = Date.now(); + if (this.isActivated) { + let doc = workspace_1.default.getDocument(bufnr); + if (doc) + doc.forceSync(); + this.stop(); + } + } + async onInsertEnter(bufnr) { + if (!this.config.triggerAfterInsertEnter) + return; + let document = workspace_1.default.getDocument(bufnr); + await document.patchChange(); + if (!document) + return; + let cursor = await this.nvim.call('coc#util#cursor'); + let line = document.getline(cursor[0]); + let pre = string_1.byteSlice(line, 0, cursor[1]); + if (!pre) + return; + await this.triggerCompletion(document, pre, false); + } + async onInsertCharPre(character) { + this.lastInsert = { + character, + timestamp: Date.now(), + }; + this.insertCharTs = this.lastInsert.timestamp; + } + get latestInsert() { + let { lastInsert } = this; + if (!lastInsert || Date.now() - lastInsert.timestamp > 500) { + return null; + } + return lastInsert; + } + get latestInsertChar() { + let { latestInsert } = this; + if (!latestInsert) + return ''; + return latestInsert.character; + } + async shouldTrigger(document, pre) { + if (pre.length == 0 || /\s/.test(pre[pre.length - 1])) + return false; + let autoTrigger = this.config.autoTrigger; + if (autoTrigger == 'none') + return false; + if (sources_1.default.shouldTrigger(pre, document.filetype)) + return true; + if (autoTrigger !== 'always') + return false; + let last = pre.slice(-1); + if (last && (document.isWord(pre.slice(-1)) || last.codePointAt(0) > 255)) { + let minLength = this.config.minTriggerInputLength; + if (minLength == 1) + return true; + let input = this.getInput(document, pre); + return input.length >= minLength; + } + return false; + } + async onPumChange(ev) { + if (!this.activated) + return; + if (this.document && this.document.uri.endsWith('%5BCommand%20Line%5D')) + return; + this.cancel(); + let { completed_item, col, row, height, width, scrollbar } = ev; + let bounding = { col, row, height, width, scrollbar }; + this.currItem = completed_item.hasOwnProperty('word') ? completed_item : null; + // it's pum change by vim, ignore it + if (this.lastInsert) + return; + let resolvedItem = this.getCompleteItem(completed_item); + if (!resolvedItem) { + this.floating.close(); + return; + } + let source = this.resolveTokenSource = new vscode_languageserver_protocol_1.CancellationTokenSource(); + let { token } = source; + await sources_1.default.doCompleteResolve(resolvedItem, token); + if (token.isCancellationRequested) + return; + let docs = resolvedItem.documentation; + if (!docs && resolvedItem.info) { + let { info } = resolvedItem; + let isText = /^[\w-\s.,\t]+$/.test(info); + docs = [{ filetype: isText ? 'txt' : this.document.filetype, content: info }]; + } + if (!docs || docs.length == 0) { + this.floating.close(); + } + else { + if (token.isCancellationRequested) + return; + await this.floating.show(docs, bounding, token); + } + this.resolveTokenSource = null; + } + start(complete) { + let { activated } = this; + this.activated = true; + this.isResolving = false; + if (activated) { + this.complete.dispose(); + } + this.complete = complete; + if (!this.config.keepCompleteopt) { + this.nvim.command(`noa set completeopt=${this.completeOpt}`, true); + } + this.document.forceSync(true); + this.document.paused = true; + } + cancel() { + if (this.resolveTokenSource) { + this.resolveTokenSource.cancel(); + this.resolveTokenSource = null; + } + } + stop() { + let { nvim } = this; + if (!this.activated) + return; + this.cancel(); + this.currItem = null; + this.activated = false; + this.document.paused = false; + this.document.fireContentChanges(); + if (this.complete) { + this.complete.dispose(); + this.complete = null; + } + nvim.pauseNotification(); + if (this.config.numberSelect) { + nvim.call('coc#_unmap', [], true); + } + if (!this.config.keepCompleteopt) { + this.nvim.command(`noa set completeopt=${workspace_1.default.completeOpt}`, true); + } + nvim.command(`let g:coc#_context['candidates'] = []`, true); + nvim.call('coc#_hide', [], true); + nvim.resumeNotification(false, true).catch(_e => { + // noop + }); + } + getInput(document, pre) { + let input = ''; + for (let i = pre.length - 1; i >= 0; i--) { + let ch = i == 0 ? null : pre[i - 1]; + if (!ch || !document.isWord(ch)) { + input = pre.slice(i, pre.length); + break; + } + } + return input; + } + get completeOpt() { + let { noselect, enablePreview } = this.config; + let preview = enablePreview && !workspace_1.default.env.pumevent ? ',preview' : ''; + if (noselect) + return `noselect,menuone${preview}`; + return `noinsert,menuone${preview}`; + } + getCompleteItem(item) { + if (!this.isActivated) + return null; + return this.complete.resolveCompletionItem(item); + } + dispose() { + util_1.disposeAll(this.disposables); + } +} +exports.Completion = Completion; +exports.default = new Completion(); +//# sourceMappingURL=index.js.map + +/***/ }), +/* 237 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fast_diff_1 = tslib_1.__importDefault(__webpack_require__(209)); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const util_1 = tslib_1.__importDefault(__webpack_require__(40)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const extensions_1 = tslib_1.__importDefault(__webpack_require__(238)); +const source_1 = tslib_1.__importDefault(__webpack_require__(389)); +const source_vim_1 = tslib_1.__importDefault(__webpack_require__(390)); +const types_1 = __webpack_require__(189); +const util_2 = __webpack_require__(174); +const fs_2 = __webpack_require__(200); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const string_1 = __webpack_require__(210); +const logger = __webpack_require__(186)('sources'); +class Sources { + constructor() { + this.sourceMap = new Map(); + this.disposables = []; + this.remoteSourcePaths = []; + } + get nvim() { + return workspace_1.default.nvim; + } + async createNativeSources() { + try { + this.disposables.push((__webpack_require__(391)).regist(this.sourceMap)); + this.disposables.push((__webpack_require__(392)).regist(this.sourceMap)); + this.disposables.push((__webpack_require__(393)).regist(this.sourceMap)); + } + catch (e) { + console.error('Create source error:' + e.message); // tslint:disable-line + } + } + async createVimSourceExtension(nvim, filepath) { + let name = path_1.default.basename(filepath, '.vim'); + try { + await nvim.command(`source ${filepath}`); + let fns = await nvim.call('coc#util#remote_fns', name); + for (let fn of ['init', 'complete']) { + if (fns.indexOf(fn) == -1) { + workspace_1.default.showMessage(`${fn} not found for source ${name}`, 'error'); + return null; + } + } + let props = await nvim.call(`coc#source#${name}#init`, []); + let packageJSON = { + name: `coc-source-${name}`, + engines: { + coc: ">= 0.0.1" + }, + activationEvents: props.filetypes ? props.filetypes.map(f => `onLanguage:${f}`) : ['*'], + contributes: { + configuration: { + properties: { + [`coc.source.${name}.enable`]: { + type: 'boolean', + default: true + }, + [`coc.source.${name}.firstMatch`]: { + type: 'boolean', + default: !!props.firstMatch + }, + [`coc.source.${name}.triggerCharacters`]: { + type: 'number', + default: props.triggerCharacters || [] + }, + [`coc.source.${name}.priority`]: { + type: 'number', + default: props.priority || 9 + }, + [`coc.source.${name}.shortcut`]: { + type: 'string', + default: props.shortcut || name.slice(0, 3).toUpperCase(), + description: 'Shortcut text shown in complete menu.' + }, + [`coc.source.${name}.disableSyntaxes`]: { + type: 'array', + default: [], + items: { + type: 'string' + } + }, + [`coc.source.${name}.filetypes`]: { + type: 'array', + default: props.filetypes || null, + description: 'Enabled filetypes.', + items: { + type: 'string' + } + } + } + } + } + }; + let source = new source_vim_1.default({ + name, + filepath, + sourceType: types_1.SourceType.Remote, + optionalFns: fns.filter(n => ['init', 'complete'].indexOf(n) == -1) + }); + let isActive = false; + let extension = { + id: packageJSON.name, + packageJSON, + exports: void 0, + extensionPath: filepath, + activate: async () => { + isActive = true; + this.addSource(source); + } + }; + Object.defineProperty(extension, 'isActive', { + get: () => { + return isActive; + } + }); + extensions_1.default.registerExtension(extension, () => { + isActive = false; + this.removeSource(source); + }); + } + catch (e) { + workspace_1.default.showMessage(`Error on create vim source ${name}: ${e.message}`, 'error'); + } + } + async createRemoteSources() { + let { runtimepath } = workspace_1.default.env; + let paths = runtimepath.split(','); + for (let path of paths) { + await this.createVimSources(path); + } + } + async createVimSources(pluginPath) { + if (this.remoteSourcePaths.indexOf(pluginPath) != -1) + return; + this.remoteSourcePaths.push(pluginPath); + let folder = path_1.default.join(pluginPath, 'autoload/coc/source'); + let stat = await fs_2.statAsync(folder); + if (stat && stat.isDirectory()) { + let arr = await util_1.default.promisify(fs_1.default.readdir)(folder); + arr = arr.filter(s => s.slice(-4) == '.vim'); + let files = arr.map(s => path_1.default.join(folder, s)); + if (files.length == 0) + return; + await Promise.all(files.map(p => { + return this.createVimSourceExtension(this.nvim, p); + })); + } + } + init() { + this.createNativeSources(); // tslint:disable-line + this.createRemoteSources(); // tslint:disable-line + events_1.default.on('BufEnter', this.onDocumentEnter, this, this.disposables); + workspace_1.default.watchOption('runtimepath', async (oldValue, newValue) => { + let result = fast_diff_1.default(oldValue, newValue); + for (let [changeType, value] of result) { + if (changeType == 1) { + let paths = value.replace(/,$/, '').split(','); + for (let p of paths) { + if (p) + await this.createVimSources(p); + } + } + } + }, this.disposables); + } + get names() { + return Array.from(this.sourceMap.keys()); + } + get sources() { + return Array.from(this.sourceMap.values()); + } + has(name) { + return this.names.findIndex(o => o == name) != -1; + } + getSource(name) { + if (!name) + return null; + return this.sourceMap.get(name) || null; + } + async doCompleteResolve(item, token) { + let source = this.getSource(item.source); + if (source && typeof source.onCompleteResolve == 'function') { + try { + await Promise.resolve(source.onCompleteResolve(item, token)); + } + catch (e) { + logger.error('Error on complete resolve:', e.stack); + } + } + } + async doCompleteDone(item, opt) { + let data = JSON.parse(item.user_data); + let source = this.getSource(data.source); + if (source && typeof source.onCompleteDone === 'function') { + await Promise.resolve(source.onCompleteDone(item, opt)); + } + } + shouldCommit(item, commitCharacter) { + if (!item || !item.source) + return false; + let source = this.getSource(item.source); + if (source && source.sourceType == types_1.SourceType.Service && typeof source.shouldCommit === 'function') { + return source.shouldCommit(item, commitCharacter); + } + return false; + } + getCompleteSources(opt) { + let { filetype } = opt; + let pre = string_1.byteSlice(opt.line, 0, opt.colnr - 1); + let isTriggered = opt.input == '' && opt.triggerCharacter; + if (isTriggered) + return this.getTriggerSources(pre, filetype); + let character = pre.length ? pre[pre.length - 1] : ''; + return this.sources.filter(source => { + let { filetypes, triggerOnly, enable } = source; + if (!enable || (filetypes && filetypes.indexOf(filetype) == -1)) { + return false; + } + if (triggerOnly && !this.checkTrigger(source, pre, character)) { + return false; + } + return true; + }); + } + checkTrigger(source, pre, character) { + let { triggerCharacters, triggerPatterns } = source; + if (!triggerCharacters && !triggerPatterns) + return false; + if (character && triggerCharacters && triggerCharacters.indexOf(character) !== -1) { + return true; + } + if (triggerPatterns && triggerPatterns.findIndex(p => p.test(pre)) !== -1) { + return true; + } + return false; + } + shouldTrigger(pre, languageId) { + let last = pre.length ? pre[pre.length - 1] : ''; + let idx = this.sources.findIndex(s => { + let { enable, triggerCharacters, triggerPatterns, filetypes } = s; + if (!enable || (filetypes && filetypes.indexOf(languageId) == -1)) + return false; + if (last && triggerCharacters) + return triggerCharacters.indexOf(last) !== -1; + if (triggerPatterns) + return triggerPatterns.findIndex(p => p.test(pre)) !== -1; + return false; + }); + return idx !== -1; + } + getTriggerSources(pre, languageId) { + let character = pre.length ? pre[pre.length - 1] : ''; + return this.sources.filter(source => { + let { filetypes, enable } = source; + if (!enable || (filetypes && filetypes.indexOf(languageId) == -1)) { + return false; + } + return this.checkTrigger(source, pre, character); + }); + } + getSourcesForFiletype(filetype, isTriggered) { + return this.sources.filter(source => { + let { filetypes } = source; + if (source.triggerOnly && isTriggered === false) { + return false; + } + if (source.enable && (!filetypes || filetypes.indexOf(filetype) !== -1)) { + return true; + } + return false; + }); + } + addSource(source) { + let { name } = source; + if (this.names.indexOf(name) !== -1) { + workspace_1.default.showMessage(`Source "${name}" recreated`, 'warning'); + } + this.sourceMap.set(name, source); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.sourceMap.delete(name); + }); + } + removeSource(source) { + let name = typeof source == 'string' ? source : source.name; + if (source == this.sourceMap.get(name)) { + this.sourceMap.delete(name); + } + } + async refresh(name) { + for (let source of this.sources) { + if (!name || source.name == name) { + if (typeof source.refresh === 'function') { + await Promise.resolve(source.refresh()); + } + } + } + } + toggleSource(name) { + if (!name) + return; + let source = this.getSource(name); + if (!source) + return; + if (typeof source.toggle === 'function') { + source.toggle(); + } + } + sourceStats() { + let res = []; + let items = this.sources; + for (let item of items) { + res.push({ + name: item.name, + priority: item.priority, + shortcut: item.shortcut || '', + filetypes: item.filetypes || [], + filepath: item.filepath || '', + type: item.sourceType == types_1.SourceType.Native + ? 'native' : item.sourceType == types_1.SourceType.Remote + ? 'remote' : 'service', + disabled: !item.enable + }); + } + return res; + } + onDocumentEnter(bufnr) { + let { sources } = this; + for (let s of sources) { + if (!s.enable) + continue; + if (typeof s.onEnter == 'function') { + s.onEnter(bufnr); + } + } + } + createSource(config) { + if (!config.name || !config.doComplete) { + // tslint:disable-next-line: no-console + console.error(`name and doComplete required for createSource`); + return; + } + let source = new source_1.default(Object.assign({ sourceType: types_1.SourceType.Service }, config)); + return this.addSource(source); + } + dispose() { + util_2.disposeAll(this.disposables); + } +} +exports.Sources = Sources; +exports.default = new Sources(); +//# sourceMappingURL=sources.js.map + +/***/ }), +/* 238 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const debounce_1 = __webpack_require__(176); +const fast_diff_1 = tslib_1.__importDefault(__webpack_require__(209)); +const os_1 = tslib_1.__importDefault(__webpack_require__(56)); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const isuri_1 = tslib_1.__importDefault(__webpack_require__(177)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const rimraf_1 = tslib_1.__importDefault(__webpack_require__(239)); +const semver_1 = tslib_1.__importDefault(__webpack_require__(1)); +const util_1 = __webpack_require__(40); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const vscode_uri_1 = __webpack_require__(180); +const which_1 = tslib_1.__importDefault(__webpack_require__(181)); +const commands_1 = tslib_1.__importDefault(__webpack_require__(232)); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const db_1 = tslib_1.__importDefault(__webpack_require__(206)); +const extension_1 = tslib_1.__importDefault(__webpack_require__(251)); +const memos_1 = tslib_1.__importDefault(__webpack_require__(308)); +const util_2 = __webpack_require__(174); +const mkdirp_1 = tslib_1.__importDefault(__webpack_require__(179)); +const array_1 = __webpack_require__(212); +__webpack_require__(309); +const factory_1 = __webpack_require__(310); +const fs_2 = __webpack_require__(200); +const watchman_1 = tslib_1.__importDefault(__webpack_require__(227)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const createLogger = __webpack_require__(186); +const logger = createLogger('extensions'); +function loadJson(file) { + try { + let content = fs_1.default.readFileSync(file, 'utf8'); + return JSON.parse(content); + } + catch (e) { + return null; + } +} +class Extensions { + constructor() { + this.list = []; + this.disabled = new Set(); + this._onDidLoadExtension = new vscode_languageserver_protocol_1.Emitter(); + this._onDidActiveExtension = new vscode_languageserver_protocol_1.Emitter(); + this._onDidUnloadExtension = new vscode_languageserver_protocol_1.Emitter(); + this._additionalSchemes = {}; + this.activated = false; + this.ready = true; + this.onDidLoadExtension = this._onDidLoadExtension.event; + this.onDidActiveExtension = this._onDidActiveExtension.event; + this.onDidUnloadExtension = this._onDidUnloadExtension.event; + } + async init() { + if (global.hasOwnProperty('__TEST__')) { + this.root = path_1.default.join(__dirname, './__tests__/extensions'); + this.manager = new extension_1.default(this.root); + let filepath = path_1.default.join(this.root, 'db.json'); + this.db = new db_1.default(filepath); + } + else { + await this.initializeRoot(); + } + let data = loadJson(this.db.filepath) || {}; + let keys = Object.keys(data.extension || {}); + for (let key of keys) { + if (data.extension[key].disabled == true) { + this.disabled.add(key); + } + } + if (process.env.COC_NO_PLUGINS) + return; + let stats = await this.globalExtensionStats(); + let localStats = await this.localExtensionStats(stats); + stats = stats.concat(localStats); + this.memos = new memos_1.default(path_1.default.resolve(this.root, '../memos.json')); + await this.loadFileExtensions(); + await Promise.all(stats.map(stat => { + return this.loadExtension(stat.root, stat.isLocal).catch(e => { + workspace_1.default.showMessage(`Can't load extension from ${stat.root}: ${e.message}'`, 'error'); + }); + })); + // watch for new local extension + workspace_1.default.watchOption('runtimepath', async (oldValue, newValue) => { + let result = fast_diff_1.default(oldValue, newValue); + for (let [changeType, value] of result) { + if (changeType == 1) { + let paths = value.replace(/,$/, '').split(','); + for (let p of paths) { + if (p) + await this.loadExtension(p, true); + } + } + } + }); + commands_1.default.register({ + id: 'extensions.forceUpdateAll', + execute: async () => { + await this.cleanExtensions(); + await this.installExtensions([]); + } + }); + } + async activateExtensions() { + this.activated = true; + if (global.hasOwnProperty('__TEST__')) + return; + for (let item of this.list) { + let { id, packageJSON } = item.extension; + this.setupActiveEvents(id, packageJSON); + } + // check extensions need watch & install + this.checkExtensions().logError(); + let config = workspace_1.default.getConfiguration('coc.preferences'); + let interval = config.get('extensionUpdateCheck', 'daily'); + if (interval != 'never') { + let now = new Date(); + let day = new Date(now.getFullYear(), now.getMonth(), now.getDate() - (interval == 'daily' ? 0 : 7)); + let ts = this.db.fetch('lastUpdate'); + if (ts && Number(ts) > day.getTime()) + return; + this.updateExtensions().logError(); + } + } + async updateExtensions() { + if (!this.root) + await this.initializeRoot(); + if (!this.npm) + return; + let lockedList = await this.getLockedList(); + let stats = await this.globalExtensionStats(); + stats = stats.filter(o => !this.disabled.has(o.id) && !lockedList.includes(o.id)); + let names = stats.map(o => o.id); + let statusItem = workspace_1.default.createStatusBarItem(0, { progress: true }); + statusItem.text = `Updating extensions.`; + statusItem.show(); + this.db.push('lastUpdate', Date.now()); + await util_2.concurrent(names.map(name => { + let o = stats.find(o => o.id == name); + return () => { + return this.manager.update(this.npm, name, o.exotic ? o.uri : undefined).then(updated => { + if (updated) + this.reloadExtension(name).logError(); + }, err => { + workspace_1.default.showMessage(`Error on update ${name}: ${err}`); + }); + }; + }), 5); + workspace_1.default.showMessage('Update completed', 'more'); + statusItem.dispose(); + } + async checkExtensions() { + let { globalExtensions, watchExtensions } = workspace_1.default.env; + if (globalExtensions && globalExtensions.length) { + let names = globalExtensions.filter(name => !this.isDisabled(name)); + let folder = path_1.default.join(this.root, 'node_modules'); + if (fs_1.default.existsSync(folder)) { + let files = await util_1.promisify(fs_1.default.readdir)(folder); + names = names.filter(s => files.indexOf(s) == -1); + } + let json = this.loadJson(); + if (json && json.dependencies) { + let vals = Object.values(json.dependencies); + names = names.filter(s => vals.findIndex(val => val.indexOf(s) !== -1) == -1); + } + this.installExtensions(names).logError(); + } + // watch for changes + if (watchExtensions && watchExtensions.length) { + let watchmanPath = workspace_1.default.getWatchmanPath(); + if (!watchmanPath) + return; + let stats = await this.getExtensionStates(); + for (let name of watchExtensions) { + let stat = stats.find(s => s.id == name); + if (stat && stat.state !== 'disabled') { + let directory = await util_1.promisify(fs_1.default.realpath)(stat.root); + let client = await watchman_1.default.createClient(watchmanPath, directory); + client.subscribe('**/*.js', debounce_1.debounce(async () => { + await this.reloadExtension(name); + workspace_1.default.showMessage(`reloaded ${name}`); + }, 100)).catch(_e => { + // noop + }); + } + } + } + } + /** + * Install extensions, can be called without initialize. + */ + async installExtensions(list = []) { + let { npm } = this; + if (!npm) + return; + if (!this.root) + await this.initializeRoot(); + let missing = this.getMissingExtensions(); + if (missing.length) + list.push(...missing); + if (!list.length) + return; + list = array_1.distinct(list); + let statusItem = workspace_1.default.createStatusBarItem(0, { progress: true }); + statusItem.show(); + statusItem.text = `Installing ${list.join(' ')}`; + await Promise.all(list.map(def => { + return this.manager.install(npm, def).then(name => { + if (name) + this.onExtensionInstall(name).logError(); + }, err => { + workspace_1.default.showMessage(`Error on install ${def}: ${err}`); + }); + })); + statusItem.dispose(); + } + /** + * Get list of extensions in package.json that not installed + */ + getMissingExtensions() { + let json = this.loadJson() || { dependencies: {} }; + let ids = []; + for (let key of Object.keys(json.dependencies)) { + let folder = path_1.default.join(this.root, 'node_modules', key); + if (!fs_1.default.existsSync(folder)) { + let val = json.dependencies[key]; + if (val.startsWith('http')) { + ids.push(val); + } + else { + ids.push(key); + } + } + } + return ids; + } + get npm() { + let npm = workspace_1.default.getConfiguration('npm').get('binPath', 'npm'); + if (npm.startsWith('~')) { + npm = os_1.default.homedir() + npm.slice(1); + } + for (let exe of [npm, 'yarnpkg', 'yarn', 'npm']) { + try { + let res = which_1.default.sync(exe); + return res; + } + catch (e) { + continue; + } + } + workspace_1.default.showMessage(`Can't find npm or yarn in your $PATH`, 'error'); + return null; + } + /** + * Get all loaded extensions. + */ + get all() { + return this.list.map(o => o.extension); + } + getExtension(id) { + return this.list.find(o => o.id == id); + } + getExtensionState(id) { + let disabled = this.isDisabled(id); + if (disabled) + return 'disabled'; + let item = this.list.find(o => o.id == id); + if (!item) + return 'unknown'; + let { extension } = item; + return extension.isActive ? 'activated' : 'loaded'; + } + async getExtensionStates() { + let globalStats = await this.globalExtensionStats(); + let localStats = await this.localExtensionStats(globalStats); + return globalStats.concat(localStats); + } + async getLockedList() { + let obj = await this.db.fetch('extension'); + obj = obj || {}; + return Object.keys(obj).filter(id => { + return obj[id].locked === true; + }); + } + async toggleLock(id) { + let key = `extension.${id}.locked`; + let locked = await this.db.fetch(key); + if (locked) { + this.db.delete(key); + } + else { + this.db.push(key, true); + } + } + async toggleExtension(id) { + let state = this.getExtensionState(id); + if (state == null) + return; + if (state == 'activated') { + this.deactivate(id); + } + let key = `extension.${id}.disabled`; + this.db.push(key, state == 'disabled' ? false : true); + if (state != 'disabled') { + this.disabled.add(id); + // unload + let idx = this.list.findIndex(o => o.id == id); + this.list.splice(idx, 1); + } + else { + this.disabled.delete(id); + let p = global.hasOwnProperty('__TEST__') ? '' : 'node_modules'; + let folder = path_1.default.join(this.root, p, id); + try { + await this.loadExtension(folder); + } + catch (e) { + workspace_1.default.showMessage(`Can't load extension ${id}: ${e.message}'`, 'error'); + } + } + await util_2.wait(200); + } + async reloadExtension(id) { + let idx = this.list.findIndex(o => o.id == id); + let directory = idx == -1 ? null : this.list[idx].directory; + this.deactivate(id); + if (idx != -1) + this.list.splice(idx, 1); + await util_2.wait(200); + if (directory) { + await this.loadExtension(directory); + } + else { + this.activate(id); + } + } + /** + * Remove all installed extensions + */ + async cleanExtensions() { + let dir = path_1.default.join(this.root, 'node_modules'); + if (!fs_1.default.existsSync(dir)) + return; + let names = fs_1.default.readdirSync(dir); + for (let name of names) { + let file = path_1.default.join(dir, name); + let stat = await util_1.promisify(fs_1.default.lstat)(file); + if (stat.isSymbolicLink()) + continue; + await util_1.promisify(rimraf_1.default)(file, { glob: false }); + } + } + async uninstallExtension(ids) { + if (!ids.length) + return; + let status = workspace_1.default.createStatusBarItem(99, { progress: true }); + try { + status.text = `Uninstalling ${ids.join(' ')}`; + status.show(); + let removed = []; + for (let id of ids) { + if (!this.isGlobalExtension(id)) { + workspace_1.default.showMessage(`Global extension '${id}' not found.`, 'error'); + continue; + } + this.deactivate(id); + removed.push(id); + } + for (let id of removed) { + let idx = this.list.findIndex(o => o.id == id); + if (idx != -1) { + this.list.splice(idx, 1); + this._onDidUnloadExtension.fire(id); + } + } + let json = this.loadJson() || { dependencies: {} }; + for (let id of removed) { + delete json.dependencies[id]; + let folder = path_1.default.join(this.root, 'node_modules', id); + if (fs_1.default.existsSync(folder)) { + await util_1.promisify(rimraf_1.default)(`${folder}`, { glob: false }); + } + } + let jsonFile = path_1.default.join(this.root, 'package.json'); + status.dispose(); + fs_1.default.writeFileSync(jsonFile, JSON.stringify(json, null, 2), { encoding: 'utf8' }); + workspace_1.default.showMessage(`Removed: ${ids.join(' ')}`); + } + catch (e) { + status.dispose(); + workspace_1.default.showMessage(`Uninstall failed: ${e.message}`, 'error'); + } + } + isDisabled(id) { + return this.disabled.has(id); + } + async onExtensionInstall(id) { + if (!id) + return; + let item = this.list.find(o => o.id == id); + if (item) + item.deactivate(); + let folder = path_1.default.join(this.root, 'node_modules', id); + let stat = await fs_2.statAsync(folder); + if (stat && stat.isDirectory()) { + let jsonFile = path_1.default.join(folder, 'package.json'); + let content = await fs_2.readFile(jsonFile, 'utf8'); + let packageJSON = JSON.parse(content); + let { engines } = packageJSON; + if (!engines || (!engines.hasOwnProperty('coc') && !engines.hasOwnProperty('vscode'))) + return; + await this.loadExtension(folder); + } + } + has(id) { + return this.list.find(o => o.id == id) != null; + } + isActivated(id) { + let item = this.list.find(o => o.id == id); + if (item && item.extension.isActive) { + return true; + } + return false; + } + async loadExtension(folder, isLocal = false) { + let jsonFile = path_1.default.join(folder, 'package.json'); + let stat = await fs_2.statAsync(jsonFile); + if (!stat || !stat.isFile()) + return; + let content = await fs_2.readFile(jsonFile, 'utf8'); + let packageJSON = JSON.parse(content); + if (this.isDisabled(packageJSON.name)) + return; + if (this.isActivated(packageJSON.name)) { + workspace_1.default.showMessage(`deactivate ${packageJSON.name}`); + this.deactivate(packageJSON.name); + await util_2.wait(200); + } + let { engines } = packageJSON; + if (engines && engines.hasOwnProperty('coc')) { + let required = engines.coc.replace(/^\^/, '>='); + if (!semver_1.default.satisfies(workspace_1.default.version, required)) { + workspace_1.default.showMessage(`Please update coc.nvim, ${packageJSON.name} requires coc.nvim ${engines.coc}`, 'warning'); + } + this.createExtension(folder, Object.freeze(packageJSON), isLocal); + } + else if (engines && engines.hasOwnProperty('vscode')) { + this.createExtension(folder, Object.freeze(packageJSON), isLocal); + } + else { + logger.info(`engine coc & vscode not found in ${jsonFile}`); + } + } + async loadFileExtensions() { + if (!process.env.COC_VIMCONFIG) + return; + let folder = path_1.default.join(process.env.COC_VIMCONFIG, 'coc-extensions'); + if (!fs_1.default.existsSync(folder)) + return; + let files = await fs_2.readdirAsync(folder); + files = files.filter(f => f.endsWith('.js')); + for (let file of files) { + this.loadExtensionFile(path_1.default.join(folder, file)); + } + } + /** + * Load single javascript file as extension. + */ + loadExtensionFile(filepath) { + let filename = path_1.default.basename(filepath); + let name = path_1.default.basename(filepath, 'js'); + if (this.isDisabled(name)) + return; + let root = path_1.default.dirname(filepath); + let packageJSON = { + name, + main: filename, + }; + this.createExtension(root, packageJSON); + } + activate(id, silent = true) { + if (this.isDisabled(id)) { + if (!silent) + workspace_1.default.showMessage(`Extension ${id} is disabled!`, 'error'); + return; + } + let item = this.list.find(o => o.id == id); + if (!item) { + workspace_1.default.showMessage(`Extension ${id} not found!`, 'error'); + return; + } + let { extension } = item; + if (extension.isActive) + return; + extension.activate().then(() => { + if (extension.isActive) { + this._onDidActiveExtension.fire(extension); + } + }, e => { + workspace_1.default.showMessage(`Error on activate ${extension.id}: ${e.stack}`, 'error'); + logger.error(`Error on activate extension ${extension.id}:`, e); + }); + } + deactivate(id) { + let item = this.list.find(o => o.id == id); + if (!item) + return false; + if (item.extension.isActive && typeof item.deactivate == 'function') { + item.deactivate(); + return true; + } + return false; + } + async call(id, method, args) { + let item = this.list.find(o => o.id == id); + if (!item) + return workspace_1.default.showMessage(`extension ${id} not found`, 'error'); + let { extension } = item; + if (!extension.isActive) { + workspace_1.default.showMessage(`extension ${id} not activated`, 'error'); + return; + } + let { exports } = extension; + if (!exports || !exports.hasOwnProperty(method)) { + workspace_1.default.showMessage(`method ${method} not found on extension ${id}`, 'error'); + return; + } + return await Promise.resolve(exports[method].apply(null, args)); + } + getExtensionApi(id) { + let item = this.list.find(o => o.id == id); + if (!item) + return null; + let { extension } = item; + return extension.isActive ? extension.exports : null; + } + registerExtension(extension, deactivate) { + let { id, packageJSON } = extension; + this.list.push({ id, extension, deactivate, isLocal: true }); + let { contributes } = packageJSON; + if (contributes) { + let { configuration } = contributes; + if (configuration && configuration.properties) { + let { properties } = configuration; + let props = {}; + for (let key of Object.keys(properties)) { + let val = properties[key].default; + if (val != null) + props[key] = val; + } + workspace_1.default.configurations.extendsDefaults(props); + } + } + this._onDidLoadExtension.fire(extension); + this.setupActiveEvents(id, packageJSON); + } + get globalExtensions() { + let json = this.loadJson(); + if (!json || !json.dependencies) + return []; + return Object.keys(json.dependencies); + } + async globalExtensionStats() { + let json = this.loadJson(); + if (!json || !json.dependencies) + return []; + let res = await Promise.all(Object.keys(json.dependencies).map(key => { + return new Promise(async (resolve) => { + try { + let val = json.dependencies[key]; + let root = path_1.default.join(this.root, 'node_modules', key); + let jsonFile = path_1.default.join(root, 'package.json'); + let stat = await fs_2.statAsync(jsonFile); + if (!stat || !stat.isFile()) + return resolve(null); + let content = await fs_2.readFile(jsonFile, 'utf8'); + root = await fs_2.realpathAsync(root); + let obj = JSON.parse(content); + let { engines } = obj; + if (!engines || (!engines.hasOwnProperty('coc') && !engines.hasOwnProperty('vscode'))) { + return resolve(null); + } + let version = obj ? obj.version || '' : ''; + let description = obj ? obj.description || '' : ''; + let uri = isuri_1.default.isValid(val) ? val : null; + resolve({ + id: key, + isLocal: false, + version, + description, + exotic: /^https?:/.test(val), + uri, + root, + state: this.getExtensionState(key) + }); + } + catch (e) { + logger.error(e); + resolve(null); + } + }); + })); + return res.filter(info => info != null); + } + async localExtensionStats(exclude) { + let runtimepath = await workspace_1.default.nvim.eval('&runtimepath'); + let included = exclude.map(o => o.root); + let names = exclude.map(o => o.id); + let paths = runtimepath.split(','); + let res = await Promise.all(paths.map(root => { + return new Promise(async (resolve) => { + try { + if (included.includes(root)) { + return resolve(null); + } + let jsonFile = path_1.default.join(root, 'package.json'); + let stat = await fs_2.statAsync(jsonFile); + if (!stat || !stat.isFile()) + return resolve(null); + let content = await fs_2.readFile(jsonFile, 'utf8'); + let obj = JSON.parse(content); + let { engines } = obj; + if (!engines || (!engines.hasOwnProperty('coc') && !engines.hasOwnProperty('vscode'))) { + return resolve(null); + } + if (names.indexOf(obj.name) !== -1) { + workspace_1.default.showMessage(`Skipped extension "${root}", please remove "${obj.name}" from your vim's plugin manager.`, 'warning'); + return resolve(null); + } + let version = obj ? obj.version || '' : ''; + let description = obj ? obj.description || '' : ''; + resolve({ + id: obj.name, + isLocal: true, + version, + description, + exotic: false, + root, + state: this.getExtensionState(obj.name) + }); + } + catch (e) { + logger.error(e); + resolve(null); + } + }); + })); + return res.filter(info => info != null); + } + isGlobalExtension(id) { + return this.globalExtensions.indexOf(id) !== -1; + } + loadJson() { + let { root } = this; + let jsonFile = path_1.default.join(root, 'package.json'); + if (!fs_1.default.existsSync(jsonFile)) + return null; + return loadJson(jsonFile); + } + get schemes() { + return this._additionalSchemes; + } + addSchemeProperty(key, def) { + this._additionalSchemes[key] = def; + workspace_1.default.configurations.extendsDefaults({ [key]: def.default }); + } + setupActiveEvents(id, packageJSON) { + let { activationEvents } = packageJSON; + if (!activationEvents || activationEvents.indexOf('*') !== -1 || !Array.isArray(activationEvents)) { + this.activate(id); + return; + } + let active = () => { + util_2.disposeAll(disposables); + this.activate(id); + active = () => { }; // tslint:disable-line + }; + let disposables = []; + for (let eventName of activationEvents) { + let parts = eventName.split(':'); + let ev = parts[0]; + if (ev == 'onLanguage') { + if (workspace_1.default.filetypes.has(parts[1])) { + active(); + return; + } + workspace_1.default.onDidOpenTextDocument(document => { + if (document.languageId == parts[1]) { + active(); + } + }, null, disposables); + } + else if (ev == 'onCommand') { + events_1.default.on('Command', command => { + if (command == parts[1]) { + active(); + // wait for service ready + return new Promise(resolve => { + setTimeout(resolve, 500); + }); + } + }, null, disposables); + } + else if (ev == 'workspaceContains') { + let check = () => { + let folders = workspace_1.default.workspaceFolders.map(o => vscode_uri_1.URI.parse(o.uri).fsPath); + for (let folder of folders) { + if (fs_2.inDirectory(folder, parts[1].split(/\s+/))) { + active(); + break; + } + } + }; + check(); + workspace_1.default.onDidChangeWorkspaceFolders(check, null, disposables); + } + else if (ev == 'onFileSystem') { + for (let doc of workspace_1.default.documents) { + let u = vscode_uri_1.URI.parse(doc.uri); + if (u.scheme == parts[1]) { + return active(); + } + } + workspace_1.default.onDidOpenTextDocument(document => { + let u = vscode_uri_1.URI.parse(document.uri); + if (u.scheme == parts[1]) { + active(); + } + }, null, disposables); + } + else { + workspace_1.default.showMessage(`Unsupported event ${eventName} of ${id}`, 'error'); + } + } + } + createExtension(root, packageJSON, isLocal = false) { + let id = `${packageJSON.name}`; + let isActive = false; + let exports = null; + let filename = path_1.default.join(root, packageJSON.main || 'index.js'); + let ext; + let subscriptions = []; + let extension = { + activate: async () => { + if (isActive) + return; + let context = { + subscriptions, + extensionPath: root, + globalState: this.memos.createMemento(`${id}|global`), + workspaceState: this.memos.createMemento(`${id}|${workspace_1.default.rootPath}`), + asAbsolutePath: relativePath => { + return path_1.default.join(root, relativePath); + }, + storagePath: path_1.default.join(this.root, `${id}-data`), + logger: createLogger(id) + }; + isActive = true; + if (!ext) { + try { + ext = factory_1.createExtension(id, filename); + } + catch (e) { + workspace_1.default.showMessage(`Error on load extension ${id} from ${filename}: ${e}`, 'error'); + logger.error(e); + return; + } + } + try { + exports = await Promise.resolve(ext.activate(context)); + } + catch (e) { + isActive = false; + workspace_1.default.showMessage(`Error on active extension ${id}: ${e.stack}`, 'error'); + logger.error(e); + } + return exports; + } + }; + Object.defineProperties(extension, { + id: { + get: () => id + }, + packageJSON: { + get: () => packageJSON + }, + extensionPath: { + get: () => root + }, + isActive: { + get: () => isActive + }, + exports: { + get: () => exports + } + }); + this.list.push({ + id, + isLocal, + extension, + directory: root, + deactivate: () => { + isActive = false; + if (ext && ext.deactivate) { + Promise.resolve(ext.deactivate()).catch(e => { + logger.error(`Error on ${id} deactivate: `, e.message); + }); + } + util_2.disposeAll(subscriptions); + subscriptions = []; + } + }); + let { contributes } = packageJSON; + if (contributes) { + let { configuration, rootPatterns, commands } = contributes; + if (configuration && configuration.properties) { + let { properties } = configuration; + let props = {}; + for (let key of Object.keys(properties)) { + let val = properties[key].default; + if (val != null) + props[key] = val; + } + workspace_1.default.configurations.extendsDefaults(props); + } + if (rootPatterns && rootPatterns.length) { + for (let item of rootPatterns) { + workspace_1.default.addRootPatterns(item.filetype, item.patterns); + } + } + if (commands && commands.length) { + for (let cmd of commands) { + commands_1.default.titles.set(cmd.command, cmd.title); + } + } + } + this._onDidLoadExtension.fire(extension); + if (this.activated) { + this.setupActiveEvents(id, packageJSON); + } + return id; + } + async initializeRoot() { + let root = this.root = await workspace_1.default.nvim.call('coc#util#extension_root'); + if (!fs_1.default.existsSync(root)) { + mkdirp_1.default.sync(root); + } + let jsonFile = path_1.default.join(root, 'package.json'); + if (!fs_1.default.existsSync(jsonFile)) { + fs_1.default.writeFileSync(jsonFile, '{"dependencies":{}}', 'utf8'); + } + if (!this.db) { + let filepath = path_1.default.join(root, 'db.json'); + this.db = new db_1.default(filepath); + } + this.manager = new extension_1.default(root); + } +} +exports.Extensions = Extensions; +exports.default = new Extensions(); +//# sourceMappingURL=extensions.js.map + +/***/ }), +/* 239 */ +/***/ (function(module, exports, __webpack_require__) { + +const assert = __webpack_require__(101) +const path = __webpack_require__(57) +const fs = __webpack_require__(55) +let glob = undefined +try { + glob = __webpack_require__(240) +} catch (_err) { + // treat glob as optional. +} + +const defaultGlobOpts = { + nosort: true, + silent: true +} + +// for EMFILE handling +let timeout = 0 + +const isWindows = (process.platform === "win32") + +const defaults = options => { + const methods = [ + 'unlink', + 'chmod', + 'stat', + 'lstat', + 'rmdir', + 'readdir' + ] + methods.forEach(m => { + options[m] = options[m] || fs[m] + m = m + 'Sync' + options[m] = options[m] || fs[m] + }) + + options.maxBusyTries = options.maxBusyTries || 3 + options.emfileWait = options.emfileWait || 1000 + if (options.glob === false) { + options.disableGlob = true + } + if (options.disableGlob !== true && glob === undefined) { + throw Error('glob dependency not found, set `options.disableGlob = true` if intentional') + } + options.disableGlob = options.disableGlob || false + options.glob = options.glob || defaultGlobOpts +} + +const rimraf = (p, options, cb) => { + if (typeof options === 'function') { + cb = options + options = {} + } + + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert.equal(typeof cb, 'function', 'rimraf: callback function required') + assert(options, 'rimraf: invalid options argument provided') + assert.equal(typeof options, 'object', 'rimraf: options should be object') + + defaults(options) + + let busyTries = 0 + let errState = null + let n = 0 + + const next = (er) => { + errState = errState || er + if (--n === 0) + cb(errState) + } + + const afterGlob = (er, results) => { + if (er) + return cb(er) + + n = results.length + if (n === 0) + return cb() + + results.forEach(p => { + const CB = (er) => { + if (er) { + if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && + busyTries < options.maxBusyTries) { + busyTries ++ + // try again, with the same exact callback as this one. + return setTimeout(() => rimraf_(p, options, CB), busyTries * 100) + } + + // this one won't happen if graceful-fs is used. + if (er.code === "EMFILE" && timeout < options.emfileWait) { + return setTimeout(() => rimraf_(p, options, CB), timeout ++) + } + + // already gone + if (er.code === "ENOENT") er = null + } + + timeout = 0 + next(er) + } + rimraf_(p, options, CB) + }) + } + + if (options.disableGlob || !glob.hasMagic(p)) + return afterGlob(null, [p]) + + options.lstat(p, (er, stat) => { + if (!er) + return afterGlob(null, [p]) + + glob(p, options.glob, afterGlob) + }) + +} + +// Two possible strategies. +// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR +// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR +// +// Both result in an extra syscall when you guess wrong. However, there +// are likely far more normal files in the world than directories. This +// is based on the assumption that a the average number of files per +// directory is >= 1. +// +// If anyone ever complains about this, then I guess the strategy could +// be made configurable somehow. But until then, YAGNI. +const rimraf_ = (p, options, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') + + // sunos lets the root user unlink directories, which is... weird. + // so we have to lstat here and make sure it's not a dir. + options.lstat(p, (er, st) => { + if (er && er.code === "ENOENT") + return cb(null) + + // Windows can EPERM on stat. Life is suffering. + if (er && er.code === "EPERM" && isWindows) + fixWinEPERM(p, options, er, cb) + + if (st && st.isDirectory()) + return rmdir(p, options, er, cb) + + options.unlink(p, er => { + if (er) { + if (er.code === "ENOENT") + return cb(null) + if (er.code === "EPERM") + return (isWindows) + ? fixWinEPERM(p, options, er, cb) + : rmdir(p, options, er, cb) + if (er.code === "EISDIR") + return rmdir(p, options, er, cb) + } + return cb(er) + }) + }) +} + +const fixWinEPERM = (p, options, er, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') + if (er) + assert(er instanceof Error) + + options.chmod(p, 0o666, er2 => { + if (er2) + cb(er2.code === "ENOENT" ? null : er) + else + options.stat(p, (er3, stats) => { + if (er3) + cb(er3.code === "ENOENT" ? null : er) + else if (stats.isDirectory()) + rmdir(p, options, er, cb) + else + options.unlink(p, cb) + }) + }) +} + +const fixWinEPERMSync = (p, options, er) => { + assert(p) + assert(options) + if (er) + assert(er instanceof Error) + + try { + options.chmodSync(p, 0o666) + } catch (er2) { + if (er2.code === "ENOENT") + return + else + throw er + } + + let stats + try { + stats = options.statSync(p) + } catch (er3) { + if (er3.code === "ENOENT") + return + else + throw er + } + + if (stats.isDirectory()) + rmdirSync(p, options, er) + else + options.unlinkSync(p) +} + +const rmdir = (p, options, originalEr, cb) => { + assert(p) + assert(options) + if (originalEr) + assert(originalEr instanceof Error) + assert(typeof cb === 'function') + + // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) + // if we guessed wrong, and it's not a directory, then + // raise the original error. + options.rmdir(p, er => { + if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) + rmkids(p, options, cb) + else if (er && er.code === "ENOTDIR") + cb(originalEr) + else + cb(er) + }) +} + +const rmkids = (p, options, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') + + options.readdir(p, (er, files) => { + if (er) + return cb(er) + let n = files.length + if (n === 0) + return options.rmdir(p, cb) + let errState + files.forEach(f => { + rimraf(path.join(p, f), options, er => { + if (errState) + return + if (er) + return cb(errState = er) + if (--n === 0) + options.rmdir(p, cb) + }) + }) + }) +} + +// this looks simpler, and is strictly *faster*, but will +// tie up the JavaScript thread and fail on excessively +// deep directory trees. +const rimrafSync = (p, options) => { + options = options || {} + defaults(options) + + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert(options, 'rimraf: missing options') + assert.equal(typeof options, 'object', 'rimraf: options should be object') + + let results + + if (options.disableGlob || !glob.hasMagic(p)) { + results = [p] + } else { + try { + options.lstatSync(p) + results = [p] + } catch (er) { + results = glob.sync(p, options.glob) + } + } + + if (!results.length) + return + + for (let i = 0; i < results.length; i++) { + const p = results[i] + + let st + try { + st = options.lstatSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + + // Windows can EPERM on stat. Life is suffering. + if (er.code === "EPERM" && isWindows) + fixWinEPERMSync(p, options, er) + } + + try { + // sunos lets the root user unlink directories, which is... weird. + if (st && st.isDirectory()) + rmdirSync(p, options, null) + else + options.unlinkSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "EPERM") + return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) + if (er.code !== "EISDIR") + throw er + + rmdirSync(p, options, er) + } + } +} + +const rmdirSync = (p, options, originalEr) => { + assert(p) + assert(options) + if (originalEr) + assert(originalEr instanceof Error) + + try { + options.rmdirSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "ENOTDIR") + throw originalEr + if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") + rmkidsSync(p, options) + } +} + +const rmkidsSync = (p, options) => { + assert(p) + assert(options) + options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options)) + + // We only end up here once we got ENOTEMPTY at least once, and + // at this point, we are guaranteed to have removed all the kids. + // So, we know that it won't be ENOENT or ENOTDIR or anything else. + // try really hard to delete stuff on windows, because it has a + // PROFOUNDLY annoying habit of not closing handles promptly when + // files are deleted, resulting in spurious ENOTEMPTY errors. + const retries = isWindows ? 100 : 1 + let i = 0 + do { + let threw = true + try { + const ret = options.rmdirSync(p, options) + threw = false + return ret + } finally { + if (++i < retries && threw) + continue + } + } while (true) +} + +module.exports = rimraf +rimraf.sync = rimrafSync + + +/***/ }), +/* 240 */ +/***/ (function(module, exports, __webpack_require__) { + +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var fs = __webpack_require__(55) +var rp = __webpack_require__(241) +var minimatch = __webpack_require__(201) +var Minimatch = minimatch.Minimatch +var inherits = __webpack_require__(243) +var EE = __webpack_require__(49).EventEmitter +var path = __webpack_require__(57) +var assert = __webpack_require__(101) +var isAbsolute = __webpack_require__(245) +var globSync = __webpack_require__(246) +var common = __webpack_require__(247) +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = __webpack_require__(248) +var util = __webpack_require__(40) +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = __webpack_require__(250) + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +function extend (origin, add) { + if (add === null || typeof add !== 'object') { + return origin + } + + var keys = Object.keys(add) + var i = keys.length + while (i--) { + origin[keys[i]] = add[keys[i]] + } + return origin +} + +glob.hasMagic = function (pattern, options_) { + var options = extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + + if (!pattern) + return false + + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + this._processing = 0 + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + var sync = true + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + sync = false + + function done () { + --self._processing + if (self._processing <= 0) { + if (sync) { + process.nextTick(function () { + self._finish() + }) + } else { + self._finish() + } + } + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + rp.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = isAbsolute(e) ? e : this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) + e = abs + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er && er.code === 'ENOENT') + return cb() + + var isSym = lstat && lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + this.emit('error', error) + this.abort() + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) + return cb(null, false, stat) + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return cb() + + return cb(null, c, stat) +} + + +/***/ }), +/* 241 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = realpath +realpath.realpath = realpath +realpath.sync = realpathSync +realpath.realpathSync = realpathSync +realpath.monkeypatch = monkeypatch +realpath.unmonkeypatch = unmonkeypatch + +var fs = __webpack_require__(55) +var origRealpath = fs.realpath +var origRealpathSync = fs.realpathSync + +var version = process.version +var ok = /^v[0-5]\./.test(version) +var old = __webpack_require__(242) + +function newError (er) { + return er && er.syscall === 'realpath' && ( + er.code === 'ELOOP' || + er.code === 'ENOMEM' || + er.code === 'ENAMETOOLONG' + ) +} + +function realpath (p, cache, cb) { + if (ok) { + return origRealpath(p, cache, cb) + } + + if (typeof cache === 'function') { + cb = cache + cache = null + } + origRealpath(p, cache, function (er, result) { + if (newError(er)) { + old.realpath(p, cache, cb) + } else { + cb(er, result) + } + }) +} + +function realpathSync (p, cache) { + if (ok) { + return origRealpathSync(p, cache) + } + + try { + return origRealpathSync(p, cache) + } catch (er) { + if (newError(er)) { + return old.realpathSync(p, cache) + } else { + throw er + } + } +} + +function monkeypatch () { + fs.realpath = realpath + fs.realpathSync = realpathSync +} + +function unmonkeypatch () { + fs.realpath = origRealpath + fs.realpathSync = origRealpathSync +} + + +/***/ }), +/* 242 */ +/***/ (function(module, exports, __webpack_require__) { + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var pathModule = __webpack_require__(57); +var isWindows = process.platform === 'win32'; +var fs = __webpack_require__(55); + +// JavaScript implementation of realpath, ported from node pre-v6 + +var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); + +function rethrow() { + // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and + // is fairly slow to generate. + var callback; + if (DEBUG) { + var backtrace = new Error; + callback = debugCallback; + } else + callback = missingCallback; + + return callback; + + function debugCallback(err) { + if (err) { + backtrace.message = err.message; + err = backtrace; + missingCallback(err); + } + } + + function missingCallback(err) { + if (err) { + if (process.throwDeprecation) + throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs + else if (!process.noDeprecation) { + var msg = 'fs: missing callback ' + (err.stack || err.message); + if (process.traceDeprecation) + console.trace(msg); + else + console.error(msg); + } + } + } +} + +function maybeCallback(cb) { + return typeof cb === 'function' ? cb : rethrow(); +} + +var normalize = pathModule.normalize; + +// Regexp that finds the next partion of a (partial) path +// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] +if (isWindows) { + var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; +} else { + var nextPartRe = /(.*?)(?:[\/]+|$)/g; +} + +// Regex to find the device root, including trailing slash. E.g. 'c:\\'. +if (isWindows) { + var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; +} else { + var splitRootRe = /^[\/]*/; +} + +exports.realpathSync = function realpathSync(p, cache) { + // make p is absolute + p = pathModule.resolve(p); + + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return cache[p]; + } + + var original = p, + seenLinks = {}, + knownHard = {}; + + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; + + start(); + + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; + + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstatSync(base); + knownHard[base] = true; + } + } + + // walk down the path, swapping out linked pathparts for their real + // values + // NB: p.length changes. + while (pos < p.length) { + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; + + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + continue; + } + + var resolvedLink; + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // some known symbolic link. no need to stat again. + resolvedLink = cache[base]; + } else { + var stat = fs.lstatSync(base); + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + continue; + } + + // read the link if it wasn't read before + // dev/ino always return 0 on windows, so skip the check. + var linkTarget = null; + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + linkTarget = seenLinks[id]; + } + } + if (linkTarget === null) { + fs.statSync(base); + linkTarget = fs.readlinkSync(base); + } + resolvedLink = pathModule.resolve(previous, linkTarget); + // track this, if given a cache. + if (cache) cache[base] = resolvedLink; + if (!isWindows) seenLinks[id] = linkTarget; + } + + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } + + if (cache) cache[original] = p; + + return p; +}; + + +exports.realpath = function realpath(p, cache, cb) { + if (typeof cb !== 'function') { + cb = maybeCallback(cache); + cache = null; + } + + // make p is absolute + p = pathModule.resolve(p); + + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return process.nextTick(cb.bind(null, null, cache[p])); + } + + var original = p, + seenLinks = {}, + knownHard = {}; + + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; + + start(); + + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; + + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstat(base, function(err) { + if (err) return cb(err); + knownHard[base] = true; + LOOP(); + }); + } else { + process.nextTick(LOOP); + } + } + + // walk down the path, swapping out linked pathparts for their real + // values + function LOOP() { + // stop if scanned past end of path + if (pos >= p.length) { + if (cache) cache[original] = p; + return cb(null, p); + } + + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; + + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + return process.nextTick(LOOP); + } + + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // known symbolic link. no need to stat again. + return gotResolvedLink(cache[base]); + } + + return fs.lstat(base, gotStat); + } + + function gotStat(err, stat) { + if (err) return cb(err); + + // if not a symlink, skip to the next path part + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + return process.nextTick(LOOP); + } + + // stat & read the link if not read before + // call gotTarget as soon as the link target is known + // dev/ino always return 0 on windows, so skip the check. + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + return gotTarget(null, seenLinks[id], base); + } + } + fs.stat(base, function(err) { + if (err) return cb(err); + + fs.readlink(base, function(err, target) { + if (!isWindows) seenLinks[id] = target; + gotTarget(err, target); + }); + }); + } + + function gotTarget(err, target, base) { + if (err) return cb(err); + + var resolvedLink = pathModule.resolve(previous, target); + if (cache) cache[base] = resolvedLink; + gotResolvedLink(resolvedLink); + } + + function gotResolvedLink(resolvedLink) { + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } +}; + + +/***/ }), +/* 243 */ +/***/ (function(module, exports, __webpack_require__) { + +try { + var util = __webpack_require__(40); + if (typeof util.inherits !== 'function') throw ''; + module.exports = util.inherits; +} catch (e) { + module.exports = __webpack_require__(244); +} + + +/***/ }), +/* 244 */ +/***/ (function(module, exports) { + +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + + +/***/ }), +/* 245 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function posix(path) { + return path.charAt(0) === '/'; +} + +function win32(path) { + // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 + var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; + var result = splitDeviceRe.exec(path); + var device = result[1] || ''; + var isUnc = Boolean(device && device.charAt(1) !== ':'); + + // UNC paths are always absolute + return Boolean(result[2] || isUnc); +} + +module.exports = process.platform === 'win32' ? win32 : posix; +module.exports.posix = posix; +module.exports.win32 = win32; + + +/***/ }), +/* 246 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = __webpack_require__(55) +var rp = __webpack_require__(241) +var minimatch = __webpack_require__(201) +var Minimatch = minimatch.Minimatch +var Glob = __webpack_require__(240).Glob +var util = __webpack_require__(40) +var path = __webpack_require__(57) +var assert = __webpack_require__(101) +var isAbsolute = __webpack_require__(245) +var common = __webpack_require__(247) +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = rp.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + if (isIgnored(this, e)) + return + + var abs = this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) { + e = abs + } + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + if (er.code === 'ENOENT') { + // lstat failed, doesn't exist + return null + } + } + + var isSym = lstat && lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + throw error + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return false + } + } + + if (lstat && lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + + +/***/ }), +/* 247 */ +/***/ (function(module, exports, __webpack_require__) { + +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = __webpack_require__(57) +var minimatch = __webpack_require__(201) +var isAbsolute = __webpack_require__(245) +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +// ignore patterns are always in dot:true mode. +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { dot: true }) + } + + return { + matcher: new Minimatch(pattern, { dot: true }), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + self.absolute = !!options.absolute + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = path.resolve(options.cwd) + self.changedCwd = self.cwd !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + // TODO: is an absolute `cwd` supposed to be resolved against `root`? + // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') + self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) + if (process.platform === "win32") + self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") + self.nomount = !!options.nomount + + // disable comments and negation in Minimatch. + // Note that they are not supported in Glob itself anyway. + options.nonegate = true + options.nocomment = true + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + var notDir = !(/\/$/.test(e)) + var c = self.cache[e] || self.cache[makeAbs(self, e)] + if (notDir && c) + notDir = c !== 'DIR' && !Array.isArray(c) + return notDir + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + + if (process.platform === 'win32') + abs = abs.replace(/\\/g, '/') + + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + + +/***/ }), +/* 248 */ +/***/ (function(module, exports, __webpack_require__) { + +var wrappy = __webpack_require__(249) +var reqs = Object.create(null) +var once = __webpack_require__(250) + +module.exports = wrappy(inflight) + +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } +} + +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + + // XXX It's somewhat ambiguous whether a new callback added in this + // pass should be queued for later execution if something in the + // list of callbacks throws, or if it should just be discarded. + // However, it's such an edge case that it hardly matters, and either + // choice is likely as surprising as the other. + // As it happens, we do go ahead and schedule it for later execution. + try { + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + } finally { + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] + } + } + }) +} + +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} + + +/***/ }), +/* 249 */ +/***/ (function(module, exports) { + +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} + + +/***/ }), +/* 250 */ +/***/ (function(module, exports, __webpack_require__) { + +var wrappy = __webpack_require__(249) +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} + +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} + + +/***/ }), +/* 251 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const child_process_1 = __webpack_require__(175); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const mkdirp_1 = tslib_1.__importDefault(__webpack_require__(179)); +const mv_1 = tslib_1.__importDefault(__webpack_require__(252)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const rc_1 = tslib_1.__importDefault(__webpack_require__(258)); +const rimraf_1 = tslib_1.__importDefault(__webpack_require__(239)); +const semver_1 = tslib_1.__importDefault(__webpack_require__(1)); +const url_1 = tslib_1.__importDefault(__webpack_require__(264)); +const util_1 = __webpack_require__(40); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const download_1 = tslib_1.__importDefault(__webpack_require__(265)); +const fetch_1 = tslib_1.__importDefault(__webpack_require__(304)); +const logger = __webpack_require__(186)('model-extension'); +function registryUrl(scope = '') { + const result = rc_1.default('npm', { registry: 'https://registry.npmjs.org/' }); + return result[`${scope}:registry`] || result.config_registry || result.registry; +} +class ExtensionManager { + constructor(root) { + this.root = root; + this.checked = false; + } + checkFolder() { + if (this.checked) + return; + this.checked = true; + let { root } = this; + mkdirp_1.default.sync(root); + mkdirp_1.default.sync(path_1.default.join(root, 'node_modules/.cache')); + } + async getInfo(ref) { + if (ref.startsWith('https:')) + return await this.getInfoFromUri(ref); + let name; + let version; + if (ref.indexOf('@') > 0) { + [name, version] = ref.split('@', 2); + } + else { + name = ref; + } + let res = await fetch_1.default(url_1.default.resolve(registryUrl(), name)); + if (!version) + version = res['dist-tags']['latest']; + let obj = res['versions'][version]; + if (!obj) + throw new Error(`${ref} not exists.`); + let requiredVersion = obj['engines'] && obj['engines']['coc']; + if (!requiredVersion) { + throw new Error(`${ref} is not valid coc extension, "engines" field with coc property required.`); + } + return { + 'dist.tarball': obj['dist']['tarball'], + 'engines.coc': requiredVersion, + version: obj['version'], + name: res.name + }; + } + async removeFolder(folder) { + if (fs_1.default.existsSync(folder)) { + let stat = await util_1.promisify(fs_1.default.lstat)(folder); + if (stat.isSymbolicLink()) { + await util_1.promisify(fs_1.default.unlink)(folder); + } + else { + await util_1.promisify(rimraf_1.default)(folder, { glob: false }); + } + } + } + async _install(npm, def, info, onMessage) { + let filepath = path_1.default.join(this.root, 'node_modules/.cache', `${info.name}-`); + if (!fs_1.default.existsSync(path_1.default.dirname(filepath))) { + fs_1.default.mkdirSync(path_1.default.dirname(filepath)); + } + let tmpFolder = await util_1.promisify(fs_1.default.mkdtemp)(filepath); + let url = info['dist.tarball']; + onMessage(`Downloading from ${url}`); + await download_1.default(url, { dest: tmpFolder }); + let content = await util_1.promisify(fs_1.default.readFile)(path_1.default.join(tmpFolder, 'package.json'), 'utf8'); + let { dependencies } = JSON.parse(content); + if (dependencies && Object.keys(dependencies).length) { + onMessage(`Installing dependencies.`); + let p = new Promise((resolve, reject) => { + let args = ['install', '--ignore-scripts', '--no-lockfile', '--no-bin-links', '--production']; + const child = child_process_1.spawn(npm, args, { cwd: tmpFolder }); + child.stderr.setEncoding('utf8'); + child.on('error', reject); + let err = ''; + child.stderr.on('data', data => { + err += data; + }); + child.on('exit', code => { + if (code) { + // tslint:disable-next-line: no-console + console.error(`${npm} install exited with ${code}, messages:\n${err}`); + } + resolve(); + }); + }); + await p; + } + let jsonFile = path_1.default.join(this.root, 'package.json'); + let obj = JSON.parse(fs_1.default.readFileSync(jsonFile, 'utf8')); + obj.dependencies = obj.dependencies || {}; + if (/^https?:/.test(def)) { + obj.dependencies[info.name] = def; + } + else { + obj.dependencies[info.name] = '>=' + info.version; + } + fs_1.default.writeFileSync(jsonFile, JSON.stringify(obj, null, 2), { encoding: 'utf8' }); + onMessage(`Moving to new folder.`); + let folder = path_1.default.join(this.root, 'node_modules', info.name); + await this.removeFolder(folder); + await util_1.promisify(mv_1.default)(tmpFolder, folder, { mkdirp: true }); + } + async install(npm, def) { + this.checkFolder(); + logger.info(`Using npm from: ${npm}`); + logger.info(`Loading info of ${def}.`); + let info = await this.getInfo(def); + let { name } = info; + let required = info['engines.coc'] ? info['engines.coc'].replace(/^\^/, '>=') : ''; + if (required && !semver_1.default.satisfies(workspace_1.default.version, required)) { + throw new Error(`${name} ${info.version} requires coc.nvim >= ${required}, please update coc.nvim.`); + } + await this._install(npm, def, info, msg => { + logger.info(msg); + }); + workspace_1.default.showMessage(`Installed extension: ${name}`, 'more'); + logger.info(`Installed extension: ${name}`); + return name; + } + async update(npm, name, uri) { + this.checkFolder(); + let folder = path_1.default.join(this.root, 'node_modules', name); + let stat = await util_1.promisify(fs_1.default.lstat)(folder); + if (stat.isSymbolicLink()) { + logger.info(`skipped update of ${name}`); + return false; + } + let version; + if (fs_1.default.existsSync(path_1.default.join(folder, 'package.json'))) { + let content = await util_1.promisify(fs_1.default.readFile)(path_1.default.join(folder, 'package.json'), 'utf8'); + version = JSON.parse(content).version; + } + logger.info(`Loading info of ${name}.`); + let info = await this.getInfo(uri ? uri : name); + if (version && info.version && semver_1.default.gte(version, info.version)) { + logger.info(`Extension ${name} is up to date.`); + return false; + } + let required = info['engines.coc'] ? info['engines.coc'].replace(/^\^/, '>=') : ''; + if (required && !semver_1.default.satisfies(workspace_1.default.version, required)) { + throw new Error(`${name} ${info.version} requires coc.nvim >= ${required}, please update coc.nvim.`); + } + await this._install(npm, uri ? uri : name, info, msg => { logger.info(msg); }); + workspace_1.default.showMessage(`Updated extension: ${name} to ${info.version}`, 'more'); + logger.info(`Update extension: ${name}`); + return true; + } + async getInfoFromUri(uri) { + if (uri.indexOf('github.com') == -1) + return; + uri = uri.replace(/\/$/, ''); + let fileUrl = uri.replace('github.com', 'raw.githubusercontent.com') + '/master/package.json'; + let content = await fetch_1.default(fileUrl); + let obj = typeof content == 'string' ? JSON.parse(content) : content; + return { + 'dist.tarball': `${uri}/archive/master.tar.gz`, + 'engines.coc': obj['engines'] ? obj['engines']['coc'] : undefined, + name: obj.name, + version: obj.version + }; + } +} +exports.default = ExtensionManager; +//# sourceMappingURL=extension.js.map + +/***/ }), +/* 252 */ +/***/ (function(module, exports, __webpack_require__) { + +var fs = __webpack_require__(55); +var ncp = __webpack_require__(253).ncp; +var path = __webpack_require__(57); +var rimraf = __webpack_require__(254); +var mkdirp = __webpack_require__(179); + +module.exports = mv; + +function mv(source, dest, options, cb){ + if (typeof options === 'function') { + cb = options; + options = {}; + } + var shouldMkdirp = !!options.mkdirp; + var clobber = options.clobber !== false; + var limit = options.limit || 16; + + if (shouldMkdirp) { + mkdirs(); + } else { + doRename(); + } + + function mkdirs() { + mkdirp(path.dirname(dest), function(err) { + if (err) return cb(err); + doRename(); + }); + } + + function doRename() { + if (clobber) { + fs.rename(source, dest, function(err) { + if (!err) return cb(); + if (err.code !== 'EXDEV') return cb(err); + moveFileAcrossDevice(source, dest, clobber, limit, cb); + }); + } else { + fs.link(source, dest, function(err) { + if (err) { + if (err.code === 'EXDEV') { + moveFileAcrossDevice(source, dest, clobber, limit, cb); + return; + } + if (err.code === 'EISDIR' || err.code === 'EPERM') { + moveDirAcrossDevice(source, dest, clobber, limit, cb); + return; + } + cb(err); + return; + } + fs.unlink(source, cb); + }); + } + } +} + +function moveFileAcrossDevice(source, dest, clobber, limit, cb) { + var outFlags = clobber ? 'w' : 'wx'; + var ins = fs.createReadStream(source); + var outs = fs.createWriteStream(dest, {flags: outFlags}); + ins.on('error', function(err){ + ins.destroy(); + outs.destroy(); + outs.removeListener('close', onClose); + if (err.code === 'EISDIR' || err.code === 'EPERM') { + moveDirAcrossDevice(source, dest, clobber, limit, cb); + } else { + cb(err); + } + }); + outs.on('error', function(err){ + ins.destroy(); + outs.destroy(); + outs.removeListener('close', onClose); + cb(err); + }); + outs.once('close', onClose); + ins.pipe(outs); + function onClose(){ + fs.unlink(source, cb); + } +} + +function moveDirAcrossDevice(source, dest, clobber, limit, cb) { + var options = { + stopOnErr: true, + clobber: false, + limit: limit, + }; + if (clobber) { + rimraf(dest, { disableGlob: true }, function(err) { + if (err) return cb(err); + startNcp(); + }); + } else { + startNcp(); + } + function startNcp() { + ncp(source, dest, options, function(errList) { + if (errList) return cb(errList[0]); + rimraf(source, { disableGlob: true }, cb); + }); + } +} + + +/***/ }), +/* 253 */ +/***/ (function(module, exports, __webpack_require__) { + +var fs = __webpack_require__(55), + path = __webpack_require__(57); + +module.exports = ncp; +ncp.ncp = ncp; + +function ncp (source, dest, options, callback) { + var cback = callback; + + if (!callback) { + cback = options; + options = {}; + } + + var basePath = process.cwd(), + currentPath = path.resolve(basePath, source), + targetPath = path.resolve(basePath, dest), + filter = options.filter, + rename = options.rename, + transform = options.transform, + clobber = options.clobber !== false, + modified = options.modified, + dereference = options.dereference, + errs = null, + started = 0, + finished = 0, + running = 0, + limit = options.limit || ncp.limit || 16; + + limit = (limit < 1) ? 1 : (limit > 512) ? 512 : limit; + + startCopy(currentPath); + + function startCopy(source) { + started++; + if (filter) { + if (filter instanceof RegExp) { + if (!filter.test(source)) { + return cb(true); + } + } + else if (typeof filter === 'function') { + if (!filter(source)) { + return cb(true); + } + } + } + return getStats(source); + } + + function getStats(source) { + var stat = dereference ? fs.stat : fs.lstat; + if (running >= limit) { + return setImmediate(function () { + getStats(source); + }); + } + running++; + stat(source, function (err, stats) { + var item = {}; + if (err) { + return onError(err); + } + + // We need to get the mode from the stats object and preserve it. + item.name = source; + item.mode = stats.mode; + item.mtime = stats.mtime; //modified time + item.atime = stats.atime; //access time + + if (stats.isDirectory()) { + return onDir(item); + } + else if (stats.isFile()) { + return onFile(item); + } + else if (stats.isSymbolicLink()) { + // Symlinks don't really need to know about the mode. + return onLink(source); + } + }); + } + + function onFile(file) { + var target = file.name.replace(currentPath, targetPath); + if(rename) { + target = rename(target); + } + isWritable(target, function (writable) { + if (writable) { + return copyFile(file, target); + } + if(clobber) { + rmFile(target, function () { + copyFile(file, target); + }); + } + if (modified) { + var stat = dereference ? fs.stat : fs.lstat; + stat(target, function(err, stats) { + //if souce modified time greater to target modified time copy file + if (file.mtime.getTime()>stats.mtime.getTime()) + copyFile(file, target); + else return cb(); + }); + } + else { + return cb(); + } + }); + } + + function copyFile(file, target) { + var readStream = fs.createReadStream(file.name), + writeStream = fs.createWriteStream(target, { mode: file.mode }); + + readStream.on('error', onError); + writeStream.on('error', onError); + + if(transform) { + transform(readStream, writeStream, file); + } else { + writeStream.on('open', function() { + readStream.pipe(writeStream); + }); + } + writeStream.once('finish', function() { + if (modified) { + //target file modified date sync. + fs.utimesSync(target, file.atime, file.mtime); + cb(); + } + else cb(); + }); + } + + function rmFile(file, done) { + fs.unlink(file, function (err) { + if (err) { + return onError(err); + } + return done(); + }); + } + + function onDir(dir) { + var target = dir.name.replace(currentPath, targetPath); + isWritable(target, function (writable) { + if (writable) { + return mkDir(dir, target); + } + copyDir(dir.name); + }); + } + + function mkDir(dir, target) { + fs.mkdir(target, dir.mode, function (err) { + if (err) { + return onError(err); + } + copyDir(dir.name); + }); + } + + function copyDir(dir) { + fs.readdir(dir, function (err, items) { + if (err) { + return onError(err); + } + items.forEach(function (item) { + startCopy(path.join(dir, item)); + }); + return cb(); + }); + } + + function onLink(link) { + var target = link.replace(currentPath, targetPath); + fs.readlink(link, function (err, resolvedPath) { + if (err) { + return onError(err); + } + checkLink(resolvedPath, target); + }); + } + + function checkLink(resolvedPath, target) { + if (dereference) { + resolvedPath = path.resolve(basePath, resolvedPath); + } + isWritable(target, function (writable) { + if (writable) { + return makeLink(resolvedPath, target); + } + fs.readlink(target, function (err, targetDest) { + if (err) { + return onError(err); + } + if (dereference) { + targetDest = path.resolve(basePath, targetDest); + } + if (targetDest === resolvedPath) { + return cb(); + } + return rmFile(target, function () { + makeLink(resolvedPath, target); + }); + }); + }); + } + + function makeLink(linkPath, target) { + fs.symlink(linkPath, target, function (err) { + if (err) { + return onError(err); + } + return cb(); + }); + } + + function isWritable(path, done) { + fs.lstat(path, function (err) { + if (err) { + if (err.code === 'ENOENT') return done(true); + return done(false); + } + return done(false); + }); + } + + function onError(err) { + if (options.stopOnError) { + return cback(err); + } + else if (!errs && options.errs) { + errs = fs.createWriteStream(options.errs); + } + else if (!errs) { + errs = []; + } + if (typeof errs.write === 'undefined') { + errs.push(err); + } + else { + errs.write(err.stack + '\n\n'); + } + return cb(); + } + + function cb(skipped) { + if (!skipped) running--; + finished++; + if ((started === finished) && (running === 0)) { + if (cback !== undefined ) { + return errs ? cback(errs) : cback(null); + } + } + } +} + + + + +/***/ }), +/* 254 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = rimraf +rimraf.sync = rimrafSync + +var assert = __webpack_require__(101) +var path = __webpack_require__(57) +var fs = __webpack_require__(55) +var glob = __webpack_require__(255) + +var globOpts = { + nosort: true, + nocomment: true, + nonegate: true, + silent: true +} + +// for EMFILE handling +var timeout = 0 + +var isWindows = (process.platform === "win32") + +function defaults (options) { + var methods = [ + 'unlink', + 'chmod', + 'stat', + 'lstat', + 'rmdir', + 'readdir' + ] + methods.forEach(function(m) { + options[m] = options[m] || fs[m] + m = m + 'Sync' + options[m] = options[m] || fs[m] + }) + + options.maxBusyTries = options.maxBusyTries || 3 + options.emfileWait = options.emfileWait || 1000 + options.disableGlob = options.disableGlob || false +} + +function rimraf (p, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} + } + + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert(options, 'rimraf: missing options') + assert.equal(typeof options, 'object', 'rimraf: options should be object') + assert.equal(typeof cb, 'function', 'rimraf: callback function required') + + defaults(options) + + var busyTries = 0 + var errState = null + var n = 0 + + if (options.disableGlob || !glob.hasMagic(p)) + return afterGlob(null, [p]) + + fs.lstat(p, function (er, stat) { + if (!er) + return afterGlob(null, [p]) + + glob(p, globOpts, afterGlob) + }) + + function next (er) { + errState = errState || er + if (--n === 0) + cb(errState) + } + + function afterGlob (er, results) { + if (er) + return cb(er) + + n = results.length + if (n === 0) + return cb() + + results.forEach(function (p) { + rimraf_(p, options, function CB (er) { + if (er) { + if (isWindows && (er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && + busyTries < options.maxBusyTries) { + busyTries ++ + var time = busyTries * 100 + // try again, with the same exact callback as this one. + return setTimeout(function () { + rimraf_(p, options, CB) + }, time) + } + + // this one won't happen if graceful-fs is used. + if (er.code === "EMFILE" && timeout < options.emfileWait) { + return setTimeout(function () { + rimraf_(p, options, CB) + }, timeout ++) + } + + // already gone + if (er.code === "ENOENT") er = null + } + + timeout = 0 + next(er) + }) + }) + } +} + +// Two possible strategies. +// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR +// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR +// +// Both result in an extra syscall when you guess wrong. However, there +// are likely far more normal files in the world than directories. This +// is based on the assumption that a the average number of files per +// directory is >= 1. +// +// If anyone ever complains about this, then I guess the strategy could +// be made configurable somehow. But until then, YAGNI. +function rimraf_ (p, options, cb) { + assert(p) + assert(options) + assert(typeof cb === 'function') + + // sunos lets the root user unlink directories, which is... weird. + // so we have to lstat here and make sure it's not a dir. + options.lstat(p, function (er, st) { + if (er && er.code === "ENOENT") + return cb(null) + + if (st && st.isDirectory()) + return rmdir(p, options, er, cb) + + options.unlink(p, function (er) { + if (er) { + if (er.code === "ENOENT") + return cb(null) + if (er.code === "EPERM") + return (isWindows) + ? fixWinEPERM(p, options, er, cb) + : rmdir(p, options, er, cb) + if (er.code === "EISDIR") + return rmdir(p, options, er, cb) + } + return cb(er) + }) + }) +} + +function fixWinEPERM (p, options, er, cb) { + assert(p) + assert(options) + assert(typeof cb === 'function') + if (er) + assert(er instanceof Error) + + options.chmod(p, 666, function (er2) { + if (er2) + cb(er2.code === "ENOENT" ? null : er) + else + options.stat(p, function(er3, stats) { + if (er3) + cb(er3.code === "ENOENT" ? null : er) + else if (stats.isDirectory()) + rmdir(p, options, er, cb) + else + options.unlink(p, cb) + }) + }) +} + +function fixWinEPERMSync (p, options, er) { + assert(p) + assert(options) + if (er) + assert(er instanceof Error) + + try { + options.chmodSync(p, 666) + } catch (er2) { + if (er2.code === "ENOENT") + return + else + throw er + } + + try { + var stats = options.statSync(p) + } catch (er3) { + if (er3.code === "ENOENT") + return + else + throw er + } + + if (stats.isDirectory()) + rmdirSync(p, options, er) + else + options.unlinkSync(p) +} + +function rmdir (p, options, originalEr, cb) { + assert(p) + assert(options) + if (originalEr) + assert(originalEr instanceof Error) + assert(typeof cb === 'function') + + // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) + // if we guessed wrong, and it's not a directory, then + // raise the original error. + options.rmdir(p, function (er) { + if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) + rmkids(p, options, cb) + else if (er && er.code === "ENOTDIR") + cb(originalEr) + else + cb(er) + }) +} + +function rmkids(p, options, cb) { + assert(p) + assert(options) + assert(typeof cb === 'function') + + options.readdir(p, function (er, files) { + if (er) + return cb(er) + var n = files.length + if (n === 0) + return options.rmdir(p, cb) + var errState + files.forEach(function (f) { + rimraf(path.join(p, f), options, function (er) { + if (errState) + return + if (er) + return cb(errState = er) + if (--n === 0) + options.rmdir(p, cb) + }) + }) + }) +} + +// this looks simpler, and is strictly *faster*, but will +// tie up the JavaScript thread and fail on excessively +// deep directory trees. +function rimrafSync (p, options) { + options = options || {} + defaults(options) + + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert(options, 'rimraf: missing options') + assert.equal(typeof options, 'object', 'rimraf: options should be object') + + var results + + if (options.disableGlob || !glob.hasMagic(p)) { + results = [p] + } else { + try { + fs.lstatSync(p) + results = [p] + } catch (er) { + results = glob.sync(p, globOpts) + } + } + + if (!results.length) + return + + for (var i = 0; i < results.length; i++) { + var p = results[i] + + try { + var st = options.lstatSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + } + + try { + // sunos lets the root user unlink directories, which is... weird. + if (st && st.isDirectory()) + rmdirSync(p, options, null) + else + options.unlinkSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "EPERM") + return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) + if (er.code !== "EISDIR") + throw er + rmdirSync(p, options, er) + } + } +} + +function rmdirSync (p, options, originalEr) { + assert(p) + assert(options) + if (originalEr) + assert(originalEr instanceof Error) + + try { + options.rmdirSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "ENOTDIR") + throw originalEr + if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") + rmkidsSync(p, options) + } +} + +function rmkidsSync (p, options) { + assert(p) + assert(options) + options.readdirSync(p).forEach(function (f) { + rimrafSync(path.join(p, f), options) + }) + options.rmdirSync(p, options) +} + + +/***/ }), +/* 255 */ +/***/ (function(module, exports, __webpack_require__) { + +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var fs = __webpack_require__(55) +var minimatch = __webpack_require__(201) +var Minimatch = minimatch.Minimatch +var inherits = __webpack_require__(243) +var EE = __webpack_require__(49).EventEmitter +var path = __webpack_require__(57) +var assert = __webpack_require__(101) +var isAbsolute = __webpack_require__(245) +var globSync = __webpack_require__(256) +var common = __webpack_require__(257) +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = __webpack_require__(248) +var util = __webpack_require__(40) +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = __webpack_require__(250) + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +function extend (origin, add) { + if (add === null || typeof add !== 'object') { + return origin + } + + var keys = Object.keys(add) + var i = keys.length + while (i--) { + origin[keys[i]] = add[keys[i]] + } + return origin +} + +glob.hasMagic = function (pattern, options_) { + var options = extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + var n = this.minimatch.set.length + this._processing = 0 + this.matches = new Array(n) + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + + function done () { + --self._processing + if (self._processing <= 0) + self._finish() + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + fs.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (this.matches[index][e]) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = this._makeAbs(e) + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + if (this.mark) + e = this._mark(e) + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er) + return cb() + + var isSym = lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && !stat.isDirectory()) + return cb(null, false, stat) + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return cb() + + return cb(null, c, stat) +} + + +/***/ }), +/* 256 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = __webpack_require__(55) +var minimatch = __webpack_require__(201) +var Minimatch = minimatch.Minimatch +var Glob = __webpack_require__(255).Glob +var util = __webpack_require__(40) +var path = __webpack_require__(57) +var assert = __webpack_require__(101) +var isAbsolute = __webpack_require__(245) +var common = __webpack_require__(257) +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = fs.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this.matches[index][e] = true + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + var abs = this._makeAbs(e) + if (this.mark) + e = this._mark(e) + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[this._makeAbs(e)] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + // lstat failed, doesn't exist + return null + } + + var isSym = lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this.matches[index][prefix] = true +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + return false + } + + if (lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + + +/***/ }), +/* 257 */ +/***/ (function(module, exports, __webpack_require__) { + +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = __webpack_require__(57) +var minimatch = __webpack_require__(201) +var isAbsolute = __webpack_require__(245) +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +// ignore patterns are always in dot:true mode. +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { dot: true }) + } + + return { + matcher: new Minimatch(pattern, { dot: true }), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = options.cwd + self.changedCwd = path.resolve(options.cwd) !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + self.nomount = !!options.nomount + + // disable comments and negation in Minimatch. + // Note that they are not supported in Glob itself anyway. + options.nonegate = true + options.nocomment = true + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + return !(/\/$/.test(e)) + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + + +/***/ }), +/* 258 */ +/***/ (function(module, exports, __webpack_require__) { + +var cc = __webpack_require__(259) +var join = __webpack_require__(57).join +var deepExtend = __webpack_require__(262) +var etc = '/etc' +var win = process.platform === "win32" +var home = win + ? process.env.USERPROFILE + : process.env.HOME + +module.exports = function (name, defaults, argv, parse) { + if('string' !== typeof name) + throw new Error('rc(name): name *must* be string') + if(!argv) + argv = __webpack_require__(263)(process.argv.slice(2)) + defaults = ( + 'string' === typeof defaults + ? cc.json(defaults) : defaults + ) || {} + + parse = parse || cc.parse + + var env = cc.env(name + '_') + + var configs = [defaults] + var configFiles = [] + function addConfigFile (file) { + if (configFiles.indexOf(file) >= 0) return + var fileConfig = cc.file(file) + if (fileConfig) { + configs.push(parse(fileConfig)) + configFiles.push(file) + } + } + + // which files do we look at? + if (!win) + [join(etc, name, 'config'), + join(etc, name + 'rc')].forEach(addConfigFile) + if (home) + [join(home, '.config', name, 'config'), + join(home, '.config', name), + join(home, '.' + name, 'config'), + join(home, '.' + name + 'rc')].forEach(addConfigFile) + addConfigFile(cc.find('.'+name+'rc')) + if (env.config) addConfigFile(env.config) + if (argv.config) addConfigFile(argv.config) + + return deepExtend.apply(null, configs.concat([ + env, + argv, + configFiles.length ? {configs: configFiles, config: configFiles[configFiles.length - 1]} : undefined, + ])) +} + + +/***/ }), +/* 259 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var fs = __webpack_require__(55) +var ini = __webpack_require__(260) +var path = __webpack_require__(57) +var stripJsonComments = __webpack_require__(261) + +var parse = exports.parse = function (content) { + + //if it ends in .json or starts with { then it must be json. + //must be done this way, because ini accepts everything. + //can't just try and parse it and let it throw if it's not ini. + //everything is ini. even json with a syntax error. + + if(/^\s*{/.test(content)) + return JSON.parse(stripJsonComments(content)) + return ini.parse(content) + +} + +var file = exports.file = function () { + var args = [].slice.call(arguments).filter(function (arg) { return arg != null }) + + //path.join breaks if it's a not a string, so just skip this. + for(var i in args) + if('string' !== typeof args[i]) + return + + var file = path.join.apply(null, args) + var content + try { + return fs.readFileSync(file,'utf-8') + } catch (err) { + return + } +} + +var json = exports.json = function () { + var content = file.apply(null, arguments) + return content ? parse(content) : null +} + +var env = exports.env = function (prefix, env) { + env = env || process.env + var obj = {} + var l = prefix.length + for(var k in env) { + if(k.toLowerCase().indexOf(prefix.toLowerCase()) === 0) { + + var keypath = k.substring(l).split('__') + + // Trim empty strings from keypath array + var _emptyStringIndex + while ((_emptyStringIndex=keypath.indexOf('')) > -1) { + keypath.splice(_emptyStringIndex, 1) + } + + var cursor = obj + keypath.forEach(function _buildSubObj(_subkey,i){ + + // (check for _subkey first so we ignore empty strings) + // (check for cursor to avoid assignment to primitive objects) + if (!_subkey || typeof cursor !== 'object') + return + + // If this is the last key, just stuff the value in there + // Assigns actual value from env variable to final key + // (unless it's just an empty string- in that case use the last valid key) + if (i === keypath.length-1) + cursor[_subkey] = env[k] + + + // Build sub-object if nothing already exists at the keypath + if (cursor[_subkey] === undefined) + cursor[_subkey] = {} + + // Increment cursor used to track the object at the current depth + cursor = cursor[_subkey] + + }) + + } + + } + + return obj +} + +var find = exports.find = function () { + var rel = path.join.apply(null, [].slice.call(arguments)) + + function find(start, rel) { + var file = path.join(start, rel) + try { + fs.statSync(file) + return file + } catch (err) { + if(path.dirname(start) !== start) // root + return find(path.dirname(start), rel) + } + } + return find(process.cwd(), rel) +} + + + + +/***/ }), +/* 260 */ +/***/ (function(module, exports) { + +exports.parse = exports.decode = decode + +exports.stringify = exports.encode = encode + +exports.safe = safe +exports.unsafe = unsafe + +var eol = typeof process !== 'undefined' && + process.platform === 'win32' ? '\r\n' : '\n' + +function encode (obj, opt) { + var children = [] + var out = '' + + if (typeof opt === 'string') { + opt = { + section: opt, + whitespace: false + } + } else { + opt = opt || {} + opt.whitespace = opt.whitespace === true + } + + var separator = opt.whitespace ? ' = ' : '=' + + Object.keys(obj).forEach(function (k, _, __) { + var val = obj[k] + if (val && Array.isArray(val)) { + val.forEach(function (item) { + out += safe(k + '[]') + separator + safe(item) + '\n' + }) + } else if (val && typeof val === 'object') { + children.push(k) + } else { + out += safe(k) + separator + safe(val) + eol + } + }) + + if (opt.section && out.length) { + out = '[' + safe(opt.section) + ']' + eol + out + } + + children.forEach(function (k, _, __) { + var nk = dotSplit(k).join('\\.') + var section = (opt.section ? opt.section + '.' : '') + nk + var child = encode(obj[k], { + section: section, + whitespace: opt.whitespace + }) + if (out.length && child.length) { + out += eol + } + out += child + }) + + return out +} + +function dotSplit (str) { + return str.replace(/\1/g, '\u0002LITERAL\\1LITERAL\u0002') + .replace(/\\\./g, '\u0001') + .split(/\./).map(function (part) { + return part.replace(/\1/g, '\\.') + .replace(/\2LITERAL\\1LITERAL\2/g, '\u0001') + }) +} + +function decode (str) { + var out = {} + var p = out + var section = null + // section |key = value + var re = /^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i + var lines = str.split(/[\r\n]+/g) + + lines.forEach(function (line, _, __) { + if (!line || line.match(/^\s*[;#]/)) return + var match = line.match(re) + if (!match) return + if (match[1] !== undefined) { + section = unsafe(match[1]) + p = out[section] = out[section] || {} + return + } + var key = unsafe(match[2]) + var value = match[3] ? unsafe(match[4]) : true + switch (value) { + case 'true': + case 'false': + case 'null': value = JSON.parse(value) + } + + // Convert keys with '[]' suffix to an array + if (key.length > 2 && key.slice(-2) === '[]') { + key = key.substring(0, key.length - 2) + if (!p[key]) { + p[key] = [] + } else if (!Array.isArray(p[key])) { + p[key] = [p[key]] + } + } + + // safeguard against resetting a previously defined + // array by accidentally forgetting the brackets + if (Array.isArray(p[key])) { + p[key].push(value) + } else { + p[key] = value + } + }) + + // {a:{y:1},"a.b":{x:2}} --> {a:{y:1,b:{x:2}}} + // use a filter to return the keys that have to be deleted. + Object.keys(out).filter(function (k, _, __) { + if (!out[k] || + typeof out[k] !== 'object' || + Array.isArray(out[k])) { + return false + } + // see if the parent section is also an object. + // if so, add it to that, and mark this one for deletion + var parts = dotSplit(k) + var p = out + var l = parts.pop() + var nl = l.replace(/\\\./g, '.') + parts.forEach(function (part, _, __) { + if (!p[part] || typeof p[part] !== 'object') p[part] = {} + p = p[part] + }) + if (p === out && nl === l) { + return false + } + p[nl] = out[k] + return true + }).forEach(function (del, _, __) { + delete out[del] + }) + + return out +} + +function isQuoted (val) { + return (val.charAt(0) === '"' && val.slice(-1) === '"') || + (val.charAt(0) === "'" && val.slice(-1) === "'") +} + +function safe (val) { + return (typeof val !== 'string' || + val.match(/[=\r\n]/) || + val.match(/^\[/) || + (val.length > 1 && + isQuoted(val)) || + val !== val.trim()) + ? JSON.stringify(val) + : val.replace(/;/g, '\\;').replace(/#/g, '\\#') +} + +function unsafe (val, doUnesc) { + val = (val || '').trim() + if (isQuoted(val)) { + // remove the single quotes before calling JSON.parse + if (val.charAt(0) === "'") { + val = val.substr(1, val.length - 2) + } + try { val = JSON.parse(val) } catch (_) {} + } else { + // walk the val to find the first not-escaped ; character + var esc = false + var unesc = '' + for (var i = 0, l = val.length; i < l; i++) { + var c = val.charAt(i) + if (esc) { + if ('\\;#'.indexOf(c) !== -1) { + unesc += c + } else { + unesc += '\\' + c + } + esc = false + } else if (';#'.indexOf(c) !== -1) { + break + } else if (c === '\\') { + esc = true + } else { + unesc += c + } + } + if (esc) { + unesc += '\\' + } + return unesc.trim() + } + return val +} + + +/***/ }), +/* 261 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var singleComment = 1; +var multiComment = 2; + +function stripWithoutWhitespace() { + return ''; +} + +function stripWithWhitespace(str, start, end) { + return str.slice(start, end).replace(/\S/g, ' '); +} + +module.exports = function (str, opts) { + opts = opts || {}; + + var currentChar; + var nextChar; + var insideString = false; + var insideComment = false; + var offset = 0; + var ret = ''; + var strip = opts.whitespace === false ? stripWithoutWhitespace : stripWithWhitespace; + + for (var i = 0; i < str.length; i++) { + currentChar = str[i]; + nextChar = str[i + 1]; + + if (!insideComment && currentChar === '"') { + var escaped = str[i - 1] === '\\' && str[i - 2] !== '\\'; + if (!escaped) { + insideString = !insideString; + } + } + + if (insideString) { + continue; + } + + if (!insideComment && currentChar + nextChar === '//') { + ret += str.slice(offset, i); + offset = i; + insideComment = singleComment; + i++; + } else if (insideComment === singleComment && currentChar + nextChar === '\r\n') { + i++; + insideComment = false; + ret += strip(str, offset, i); + offset = i; + continue; + } else if (insideComment === singleComment && currentChar === '\n') { + insideComment = false; + ret += strip(str, offset, i); + offset = i; + } else if (!insideComment && currentChar + nextChar === '/*') { + ret += str.slice(offset, i); + offset = i; + insideComment = multiComment; + i++; + continue; + } else if (insideComment === multiComment && currentChar + nextChar === '*/') { + i++; + insideComment = false; + ret += strip(str, offset, i + 1); + offset = i + 1; + continue; + } + } + + return ret + (insideComment ? strip(str.substr(offset)) : str.substr(offset)); +}; + + +/***/ }), +/* 262 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * @description Recursive object extending + * @author Viacheslav Lotsmanov + * @license MIT + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2018 Viacheslav Lotsmanov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + + +function isSpecificValue(val) { + return ( + val instanceof Buffer + || val instanceof Date + || val instanceof RegExp + ) ? true : false; +} + +function cloneSpecificValue(val) { + if (val instanceof Buffer) { + var x = Buffer.alloc + ? Buffer.alloc(val.length) + : new Buffer(val.length); + val.copy(x); + return x; + } else if (val instanceof Date) { + return new Date(val.getTime()); + } else if (val instanceof RegExp) { + return new RegExp(val); + } else { + throw new Error('Unexpected situation'); + } +} + +/** + * Recursive cloning array. + */ +function deepCloneArray(arr) { + var clone = []; + arr.forEach(function (item, index) { + if (typeof item === 'object' && item !== null) { + if (Array.isArray(item)) { + clone[index] = deepCloneArray(item); + } else if (isSpecificValue(item)) { + clone[index] = cloneSpecificValue(item); + } else { + clone[index] = deepExtend({}, item); + } + } else { + clone[index] = item; + } + }); + return clone; +} + +function safeGetProperty(object, property) { + return property === '__proto__' ? undefined : object[property]; +} + +/** + * Extening object that entered in first argument. + * + * Returns extended object or false if have no target object or incorrect type. + * + * If you wish to clone source object (without modify it), just use empty new + * object as first argument, like this: + * deepExtend({}, yourObj_1, [yourObj_N]); + */ +var deepExtend = module.exports = function (/*obj_1, [obj_2], [obj_N]*/) { + if (arguments.length < 1 || typeof arguments[0] !== 'object') { + return false; + } + + if (arguments.length < 2) { + return arguments[0]; + } + + var target = arguments[0]; + + // convert arguments to array and cut off target object + var args = Array.prototype.slice.call(arguments, 1); + + var val, src, clone; + + args.forEach(function (obj) { + // skip argument if isn't an object, is null, or is an array + if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) { + return; + } + + Object.keys(obj).forEach(function (key) { + src = safeGetProperty(target, key); // source value + val = safeGetProperty(obj, key); // new value + + // recursion prevention + if (val === target) { + return; + + /** + * if new value isn't object then just overwrite by new value + * instead of extending. + */ + } else if (typeof val !== 'object' || val === null) { + target[key] = val; + return; + + // just clone arrays (and recursive clone objects inside) + } else if (Array.isArray(val)) { + target[key] = deepCloneArray(val); + return; + + // custom cloning and overwrite for specific objects + } else if (isSpecificValue(val)) { + target[key] = cloneSpecificValue(val); + return; + + // overwrite by new value if source isn't object or array + } else if (typeof src !== 'object' || src === null || Array.isArray(src)) { + target[key] = deepExtend({}, val); + return; + + // source value and new value is objects both, extending... + } else { + target[key] = deepExtend(src, val); + return; + } + }); + }); + + return target; +}; + + +/***/ }), +/* 263 */ +/***/ (function(module, exports) { + +module.exports = function (args, opts) { + if (!opts) opts = {}; + + var flags = { bools : {}, strings : {}, unknownFn: null }; + + if (typeof opts['unknown'] === 'function') { + flags.unknownFn = opts['unknown']; + } + + if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { + flags.allBools = true; + } else { + [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { + flags.bools[key] = true; + }); + } + + var aliases = {}; + Object.keys(opts.alias || {}).forEach(function (key) { + aliases[key] = [].concat(opts.alias[key]); + aliases[key].forEach(function (x) { + aliases[x] = [key].concat(aliases[key].filter(function (y) { + return x !== y; + })); + }); + }); + + [].concat(opts.string).filter(Boolean).forEach(function (key) { + flags.strings[key] = true; + if (aliases[key]) { + flags.strings[aliases[key]] = true; + } + }); + + var defaults = opts['default'] || {}; + + var argv = { _ : [] }; + Object.keys(flags.bools).forEach(function (key) { + setArg(key, defaults[key] === undefined ? false : defaults[key]); + }); + + var notFlags = []; + + if (args.indexOf('--') !== -1) { + notFlags = args.slice(args.indexOf('--')+1); + args = args.slice(0, args.indexOf('--')); + } + + function argDefined(key, arg) { + return (flags.allBools && /^--[^=]+$/.test(arg)) || + flags.strings[key] || flags.bools[key] || aliases[key]; + } + + function setArg (key, val, arg) { + if (arg && flags.unknownFn && !argDefined(key, arg)) { + if (flags.unknownFn(arg) === false) return; + } + + var value = !flags.strings[key] && isNumber(val) + ? Number(val) : val + ; + setKey(argv, key.split('.'), value); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), value); + }); + } + + function setKey (obj, keys, value) { + var o = obj; + keys.slice(0,-1).forEach(function (key) { + if (o[key] === undefined) o[key] = {}; + o = o[key]; + }); + + var key = keys[keys.length - 1]; + if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') { + o[key] = value; + } + else if (Array.isArray(o[key])) { + o[key].push(value); + } + else { + o[key] = [ o[key], value ]; + } + } + + function aliasIsBoolean(key) { + return aliases[key].some(function (x) { + return flags.bools[x]; + }); + } + + for (var i = 0; i < args.length; i++) { + var arg = args[i]; + + if (/^--.+=/.test(arg)) { + // Using [\s\S] instead of . because js doesn't support the + // 'dotall' regex modifier. See: + // http://stackoverflow.com/a/1068308/13216 + var m = arg.match(/^--([^=]+)=([\s\S]*)$/); + var key = m[1]; + var value = m[2]; + if (flags.bools[key]) { + value = value !== 'false'; + } + setArg(key, value, arg); + } + else if (/^--no-.+/.test(arg)) { + var key = arg.match(/^--no-(.+)/)[1]; + setArg(key, false, arg); + } + else if (/^--.+/.test(arg)) { + var key = arg.match(/^--(.+)/)[1]; + var next = args[i + 1]; + if (next !== undefined && !/^-/.test(next) + && !flags.bools[key] + && !flags.allBools + && (aliases[key] ? !aliasIsBoolean(key) : true)) { + setArg(key, next, arg); + i++; + } + else if (/^(true|false)$/.test(next)) { + setArg(key, next === 'true', arg); + i++; + } + else { + setArg(key, flags.strings[key] ? '' : true, arg); + } + } + else if (/^-[^-]+/.test(arg)) { + var letters = arg.slice(1,-1).split(''); + + var broken = false; + for (var j = 0; j < letters.length; j++) { + var next = arg.slice(j+2); + + if (next === '-') { + setArg(letters[j], next, arg) + continue; + } + + if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { + setArg(letters[j], next.split('=')[1], arg); + broken = true; + break; + } + + if (/[A-Za-z]/.test(letters[j]) + && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { + setArg(letters[j], next, arg); + broken = true; + break; + } + + if (letters[j+1] && letters[j+1].match(/\W/)) { + setArg(letters[j], arg.slice(j+2), arg); + broken = true; + break; + } + else { + setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); + } + } + + var key = arg.slice(-1)[0]; + if (!broken && key !== '-') { + if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) + && !flags.bools[key] + && (aliases[key] ? !aliasIsBoolean(key) : true)) { + setArg(key, args[i+1], arg); + i++; + } + else if (args[i+1] && /true|false/.test(args[i+1])) { + setArg(key, args[i+1] === 'true', arg); + i++; + } + else { + setArg(key, flags.strings[key] ? '' : true, arg); + } + } + } + else { + if (!flags.unknownFn || flags.unknownFn(arg) !== false) { + argv._.push( + flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) + ); + } + if (opts.stopEarly) { + argv._.push.apply(argv._, args.slice(i + 1)); + break; + } + } + } + + Object.keys(defaults).forEach(function (key) { + if (!hasKey(argv, key.split('.'))) { + setKey(argv, key.split('.'), defaults[key]); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), defaults[key]); + }); + } + }); + + if (opts['--']) { + argv['--'] = new Array(); + notFlags.forEach(function(key) { + argv['--'].push(key); + }); + } + else { + notFlags.forEach(function(key) { + argv._.push(key); + }); + } + + return argv; +}; + +function hasKey (obj, keys) { + var o = obj; + keys.slice(0,-1).forEach(function (key) { + o = (o[key] || {}); + }); + + var key = keys[keys.length - 1]; + return key in o; +} + +function isNumber (x) { + if (typeof x === 'number') return true; + if (/^0x[0-9a-f]+$/i.test(x)) return true; + return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); +} + + + +/***/ }), +/* 264 */ +/***/ (function(module, exports) { + +module.exports = require("url"); + +/***/ }), +/* 265 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const follow_redirects_1 = __webpack_require__(266); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const mkdirp_1 = tslib_1.__importDefault(__webpack_require__(179)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const tar_1 = tslib_1.__importDefault(__webpack_require__(273)); +const url_1 = __webpack_require__(264); +const fetch_1 = __webpack_require__(304); +/** + * Download and extract tgz from url + * + * @param {string} url + * @param {DownloadOptions} options contains dest folder and optional onProgress callback + */ +function download(url, options) { + let { dest, onProgress } = options; + if (!dest || !path_1.default.isAbsolute(dest)) { + throw new Error(`Expect absolute file path for dest option.`); + } + if (!fs_1.default.existsSync(dest)) + mkdirp_1.default.sync(dest); + let endpoint = url_1.parse(url); + let mod = url.startsWith('https') ? follow_redirects_1.https : follow_redirects_1.http; + let agent = fetch_1.getAgent(endpoint); + let opts = Object.assign({ + method: 'GET', + hostname: endpoint.hostname, + port: endpoint.port ? parseInt(endpoint.port, 10) : (endpoint.protocol === 'https:' ? 443 : 80), + path: endpoint.path, + protocol: url.startsWith('https') ? 'https:' : 'http:', + agent, + headers: { + 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64)' + } + }, options); + return new Promise((resolve, reject) => { + const req = mod.request(opts, (res) => { + if (res.statusCode != 200) { + reject(new Error(`Invalid response from ${url}: ${res.statusCode}`)); + return; + } + if (onProgress) { + const len = parseInt(res.headers['content-length'], 10); + let cur = 0; + if (!isNaN(len)) { + res.on('data', chunk => { + cur += chunk.length; + onProgress(cur / len); + }); + } + } + let stream = res.pipe(tar_1.default.x({ strip: 1, C: dest })); + stream.on('finish', () => { + setTimeout(resolve, 100); + }); + stream.on('error', reject); + }); + req.on('error', reject); + req.end(); + }); +} +exports.default = download; +//# sourceMappingURL=download.js.map + +/***/ }), +/* 266 */ +/***/ (function(module, exports, __webpack_require__) { + +var url = __webpack_require__(264); +var URL = url.URL; +var http = __webpack_require__(267); +var https = __webpack_require__(268); +var assert = __webpack_require__(101); +var Writable = __webpack_require__(41).Writable; +var debug = __webpack_require__(269)("follow-redirects"); + +// RFC7231§4.2.1: Of the request methods defined by this specification, +// the GET, HEAD, OPTIONS, and TRACE methods are defined to be safe. +var SAFE_METHODS = { GET: true, HEAD: true, OPTIONS: true, TRACE: true }; + +// Create handlers that pass events from native requests +var eventHandlers = Object.create(null); +["abort", "aborted", "connect", "error", "socket", "timeout"].forEach(function (event) { + eventHandlers[event] = function (arg1, arg2, arg3) { + this._redirectable.emit(event, arg1, arg2, arg3); + }; +}); + +// An HTTP(S) request that can be redirected +function RedirectableRequest(options, responseCallback) { + // Initialize the request + Writable.call(this); + this._sanitizeOptions(options); + this._options = options; + this._ended = false; + this._ending = false; + this._redirectCount = 0; + this._redirects = []; + this._requestBodyLength = 0; + this._requestBodyBuffers = []; + + // Attach a callback if passed + if (responseCallback) { + this.on("response", responseCallback); + } + + // React to responses of native requests + var self = this; + this._onNativeResponse = function (response) { + self._processResponse(response); + }; + + // Perform the first request + this._performRequest(); +} +RedirectableRequest.prototype = Object.create(Writable.prototype); + +// Writes buffered data to the current native request +RedirectableRequest.prototype.write = function (data, encoding, callback) { + // Writing is not allowed if end has been called + if (this._ending) { + throw new Error("write after end"); + } + + // Validate input and shift parameters if necessary + if (!(typeof data === "string" || typeof data === "object" && ("length" in data))) { + throw new Error("data should be a string, Buffer or Uint8Array"); + } + if (typeof encoding === "function") { + callback = encoding; + encoding = null; + } + + // Ignore empty buffers, since writing them doesn't invoke the callback + // https://github.com/nodejs/node/issues/22066 + if (data.length === 0) { + if (callback) { + callback(); + } + return; + } + // Only write when we don't exceed the maximum body length + if (this._requestBodyLength + data.length <= this._options.maxBodyLength) { + this._requestBodyLength += data.length; + this._requestBodyBuffers.push({ data: data, encoding: encoding }); + this._currentRequest.write(data, encoding, callback); + } + // Error when we exceed the maximum body length + else { + this.emit("error", new Error("Request body larger than maxBodyLength limit")); + this.abort(); + } +}; + +// Ends the current native request +RedirectableRequest.prototype.end = function (data, encoding, callback) { + // Shift parameters if necessary + if (typeof data === "function") { + callback = data; + data = encoding = null; + } + else if (typeof encoding === "function") { + callback = encoding; + encoding = null; + } + + // Write data if needed and end + if (!data) { + this._ended = this._ending = true; + this._currentRequest.end(null, null, callback); + } + else { + var self = this; + var currentRequest = this._currentRequest; + this.write(data, encoding, function () { + self._ended = true; + currentRequest.end(null, null, callback); + }); + this._ending = true; + } +}; + +// Sets a header value on the current native request +RedirectableRequest.prototype.setHeader = function (name, value) { + this._options.headers[name] = value; + this._currentRequest.setHeader(name, value); +}; + +// Clears a header value on the current native request +RedirectableRequest.prototype.removeHeader = function (name) { + delete this._options.headers[name]; + this._currentRequest.removeHeader(name); +}; + +// Global timeout for all underlying requests +RedirectableRequest.prototype.setTimeout = function (msecs, callback) { + if (callback) { + this.once("timeout", callback); + } + + if (this.socket) { + startTimer(this, msecs); + } + else { + var self = this; + this._currentRequest.once("socket", function () { + startTimer(self, msecs); + }); + } + + this.once("response", clearTimer); + this.once("error", clearTimer); + + return this; +}; + +function startTimer(request, msecs) { + clearTimeout(request._timeout); + request._timeout = setTimeout(function () { + request.emit("timeout"); + }, msecs); +} + +function clearTimer() { + clearTimeout(this._timeout); +} + +// Proxy all other public ClientRequest methods +[ + "abort", "flushHeaders", "getHeader", + "setNoDelay", "setSocketKeepAlive", +].forEach(function (method) { + RedirectableRequest.prototype[method] = function (a, b) { + return this._currentRequest[method](a, b); + }; +}); + +// Proxy all public ClientRequest properties +["aborted", "connection", "socket"].forEach(function (property) { + Object.defineProperty(RedirectableRequest.prototype, property, { + get: function () { return this._currentRequest[property]; }, + }); +}); + +RedirectableRequest.prototype._sanitizeOptions = function (options) { + // Ensure headers are always present + if (!options.headers) { + options.headers = {}; + } + + // Since http.request treats host as an alias of hostname, + // but the url module interprets host as hostname plus port, + // eliminate the host property to avoid confusion. + if (options.host) { + // Use hostname if set, because it has precedence + if (!options.hostname) { + options.hostname = options.host; + } + delete options.host; + } + + // Complete the URL object when necessary + if (!options.pathname && options.path) { + var searchPos = options.path.indexOf("?"); + if (searchPos < 0) { + options.pathname = options.path; + } + else { + options.pathname = options.path.substring(0, searchPos); + options.search = options.path.substring(searchPos); + } + } +}; + + +// Executes the next native request (initial or redirect) +RedirectableRequest.prototype._performRequest = function () { + // Load the native protocol + var protocol = this._options.protocol; + var nativeProtocol = this._options.nativeProtocols[protocol]; + if (!nativeProtocol) { + this.emit("error", new Error("Unsupported protocol " + protocol)); + return; + } + + // If specified, use the agent corresponding to the protocol + // (HTTP and HTTPS use different types of agents) + if (this._options.agents) { + var scheme = protocol.substr(0, protocol.length - 1); + this._options.agent = this._options.agents[scheme]; + } + + // Create the native request + var request = this._currentRequest = + nativeProtocol.request(this._options, this._onNativeResponse); + this._currentUrl = url.format(this._options); + + // Set up event handlers + request._redirectable = this; + for (var event in eventHandlers) { + /* istanbul ignore else */ + if (event) { + request.on(event, eventHandlers[event]); + } + } + + // End a redirected request + // (The first request must be ended explicitly with RedirectableRequest#end) + if (this._isRedirect) { + // Write the request entity and end. + var i = 0; + var self = this; + var buffers = this._requestBodyBuffers; + (function writeNext(error) { + // Only write if this request has not been redirected yet + /* istanbul ignore else */ + if (request === self._currentRequest) { + // Report any write errors + /* istanbul ignore if */ + if (error) { + self.emit("error", error); + } + // Write the next buffer if there are still left + else if (i < buffers.length) { + var buffer = buffers[i++]; + /* istanbul ignore else */ + if (!request.finished) { + request.write(buffer.data, buffer.encoding, writeNext); + } + } + // End the request if `end` has been called on us + else if (self._ended) { + request.end(); + } + } + }()); + } +}; + +// Processes a response from the current native request +RedirectableRequest.prototype._processResponse = function (response) { + // Store the redirected response + var statusCode = response.statusCode; + if (this._options.trackRedirects) { + this._redirects.push({ + url: this._currentUrl, + headers: response.headers, + statusCode: statusCode, + }); + } + + // RFC7231§6.4: The 3xx (Redirection) class of status code indicates + // that further action needs to be taken by the user agent in order to + // fulfill the request. If a Location header field is provided, + // the user agent MAY automatically redirect its request to the URI + // referenced by the Location field value, + // even if the specific status code is not understood. + var location = response.headers.location; + if (location && this._options.followRedirects !== false && + statusCode >= 300 && statusCode < 400) { + // Abort the current request + this._currentRequest.removeAllListeners(); + this._currentRequest.on("error", noop); + this._currentRequest.abort(); + // Discard the remainder of the response to avoid waiting for data + response.destroy(); + + // RFC7231§6.4: A client SHOULD detect and intervene + // in cyclical redirections (i.e., "infinite" redirection loops). + if (++this._redirectCount > this._options.maxRedirects) { + this.emit("error", new Error("Max redirects exceeded.")); + return; + } + + // RFC7231§6.4: Automatic redirection needs to done with + // care for methods not known to be safe […], + // since the user might not wish to redirect an unsafe request. + // RFC7231§6.4.7: The 307 (Temporary Redirect) status code indicates + // that the target resource resides temporarily under a different URI + // and the user agent MUST NOT change the request method + // if it performs an automatic redirection to that URI. + var header; + var headers = this._options.headers; + if (statusCode !== 307 && !(this._options.method in SAFE_METHODS)) { + this._options.method = "GET"; + // Drop a possible entity and headers related to it + this._requestBodyBuffers = []; + for (header in headers) { + if (/^content-/i.test(header)) { + delete headers[header]; + } + } + } + + // Drop the Host header, as the redirect might lead to a different host + if (!this._isRedirect) { + for (header in headers) { + if (/^host$/i.test(header)) { + delete headers[header]; + } + } + } + + // Perform the redirected request + var redirectUrl = url.resolve(this._currentUrl, location); + debug("redirecting to", redirectUrl); + Object.assign(this._options, url.parse(redirectUrl)); + if (typeof this._options.beforeRedirect === "function") { + try { + this._options.beforeRedirect.call(null, this._options); + } + catch (err) { + this.emit("error", err); + return; + } + this._sanitizeOptions(this._options); + } + this._isRedirect = true; + this._performRequest(); + } + else { + // The response is not a redirect; return it as-is + response.responseUrl = this._currentUrl; + response.redirects = this._redirects; + this.emit("response", response); + + // Clean up + this._requestBodyBuffers = []; + } +}; + +// Wraps the key/value object of protocols with redirect functionality +function wrap(protocols) { + // Default settings + var exports = { + maxRedirects: 21, + maxBodyLength: 10 * 1024 * 1024, + }; + + // Wrap each protocol + var nativeProtocols = {}; + Object.keys(protocols).forEach(function (scheme) { + var protocol = scheme + ":"; + var nativeProtocol = nativeProtocols[protocol] = protocols[scheme]; + var wrappedProtocol = exports[scheme] = Object.create(nativeProtocol); + + // Executes a request, following redirects + wrappedProtocol.request = function (input, options, callback) { + // Parse parameters + if (typeof input === "string") { + var urlStr = input; + try { + input = urlToOptions(new URL(urlStr)); + } + catch (err) { + /* istanbul ignore next */ + input = url.parse(urlStr); + } + } + else if (URL && (input instanceof URL)) { + input = urlToOptions(input); + } + else { + callback = options; + options = input; + input = { protocol: protocol }; + } + if (typeof options === "function") { + callback = options; + options = null; + } + + // Set defaults + options = Object.assign({ + maxRedirects: exports.maxRedirects, + maxBodyLength: exports.maxBodyLength, + }, input, options); + options.nativeProtocols = nativeProtocols; + + assert.equal(options.protocol, protocol, "protocol mismatch"); + debug("options", options); + return new RedirectableRequest(options, callback); + }; + + // Executes a GET request, following redirects + wrappedProtocol.get = function (input, options, callback) { + var request = wrappedProtocol.request(input, options, callback); + request.end(); + return request; + }; + }); + return exports; +} + +/* istanbul ignore next */ +function noop() { /* empty */ } + +// from https://github.com/nodejs/node/blob/master/lib/internal/url.js +function urlToOptions(urlObject) { + var options = { + protocol: urlObject.protocol, + hostname: urlObject.hostname.startsWith("[") ? + /* istanbul ignore next */ + urlObject.hostname.slice(1, -1) : + urlObject.hostname, + hash: urlObject.hash, + search: urlObject.search, + pathname: urlObject.pathname, + path: urlObject.pathname + urlObject.search, + href: urlObject.href, + }; + if (urlObject.port !== "") { + options.port = Number(urlObject.port); + } + return options; +} + +// Exports +module.exports = wrap({ http: http, https: https }); +module.exports.wrap = wrap; + + +/***/ }), +/* 267 */ +/***/ (function(module, exports) { + +module.exports = require("http"); + +/***/ }), +/* 268 */ +/***/ (function(module, exports) { + +module.exports = require("https"); + +/***/ }), +/* 269 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * Detect Electron renderer / nwjs process, which is node, but we should + * treat as a browser. + */ +if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) { + module.exports = __webpack_require__(270); +} else { + module.exports = __webpack_require__(272); +} + + + +/***/ }), +/* 270 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +/* eslint-env browser */ + +/** + * This is the web browser implementation of `debug()`. + */ +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = localstorage(); +/** + * Colors. + */ + +exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33']; +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ +// eslint-disable-next-line complexity + +function useColors() { + // NB: In an Electron preload script, document will be defined but not fully + // initialized. Since we know we're in Chrome, we'll just detect this case + // explicitly + if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { + return true; + } // Internet Explorer and Edge do not support colors. + + + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } // Is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + + + return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773 + typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker + typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); +} +/** + * Colorize log arguments if enabled. + * + * @api public + */ + + +function formatArgs(args) { + args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); + + if (!this.useColors) { + return; + } + + var c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function (match) { + if (match === '%%') { + return; + } + + index++; + + if (match === '%c') { + // We only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + args.splice(lastC, 0, c); +} +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". + * + * @api public + */ + + +function log() { + var _console; + + // This hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return (typeof console === "undefined" ? "undefined" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments); +} +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + + +function save(namespaces) { + try { + if (namespaces) { + exports.storage.setItem('debug', namespaces); + } else { + exports.storage.removeItem('debug'); + } + } catch (error) {// Swallow + // XXX (@Qix-) should we be logging these? + } +} +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + + +function load() { + var r; + + try { + r = exports.storage.getItem('debug'); + } catch (error) {} // Swallow + // XXX (@Qix-) should we be logging these? + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + + + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; + } + + return r; +} +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + + +function localstorage() { + try { + // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context + // The Browser also has localStorage in the global context. + return localStorage; + } catch (error) {// Swallow + // XXX (@Qix-) should we be logging these? + } +} + +module.exports = __webpack_require__(271)(exports); +var formatters = module.exports.formatters; +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +formatters.j = function (v) { + try { + return JSON.stringify(v); + } catch (error) { + return '[UnexpectedJSONParseError]: ' + error.message; + } +}; + + + +/***/ }), +/* 271 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + */ +function setup(env) { + createDebug.debug = createDebug; + createDebug.default = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = __webpack_require__(68); + Object.keys(env).forEach(function (key) { + createDebug[key] = env[key]; + }); + /** + * Active `debug` instances. + */ + + createDebug.instances = []; + /** + * The currently active debug mode names, and names to skip. + */ + + createDebug.names = []; + createDebug.skips = []; + /** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". + */ + + createDebug.formatters = {}; + /** + * Selects a color for a debug namespace + * @param {String} namespace The namespace string for the for the debug instance to be colored + * @return {Number|String} An ANSI color code for the given namespace + * @api private + */ + + function selectColor(namespace) { + var hash = 0; + + for (var i = 0; i < namespace.length; i++) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer + } + + return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; + } + + createDebug.selectColor = selectColor; + /** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + + function createDebug(namespace) { + var prevTime; + + function debug() { + // Disabled? + if (!debug.enabled) { + return; + } + + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + var self = debug; // Set `diff` timestamp + + var curr = Number(new Date()); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + args[0] = createDebug.coerce(args[0]); + + if (typeof args[0] !== 'string') { + // Anything else let's inspect with %O + args.unshift('%O'); + } // Apply any `formatters` transformations + + + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) { + // If we encounter an escaped % then don't increase the array index + if (match === '%%') { + return match; + } + + index++; + var formatter = createDebug.formatters[format]; + + if (typeof formatter === 'function') { + var val = args[index]; + match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format` + + args.splice(index, 1); + index--; + } + + return match; + }); // Apply env-specific formatting (colors, etc.) + + createDebug.formatArgs.call(self, args); + var logFn = self.log || createDebug.log; + logFn.apply(self, args); + } + + debug.namespace = namespace; + debug.enabled = createDebug.enabled(namespace); + debug.useColors = createDebug.useColors(); + debug.color = selectColor(namespace); + debug.destroy = destroy; + debug.extend = extend; // Debug.formatArgs = formatArgs; + // debug.rawLog = rawLog; + // env-specific initialization logic for debug instances + + if (typeof createDebug.init === 'function') { + createDebug.init(debug); + } + + createDebug.instances.push(debug); + return debug; + } + + function destroy() { + var index = createDebug.instances.indexOf(this); + + if (index !== -1) { + createDebug.instances.splice(index, 1); + return true; + } + + return false; + } + + function extend(namespace, delimiter) { + return createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); + } + /** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + + + function enable(namespaces) { + createDebug.save(namespaces); + createDebug.names = []; + createDebug.skips = []; + var i; + var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); + var len = split.length; + + for (i = 0; i < len; i++) { + if (!split[i]) { + // ignore empty strings + continue; + } + + namespaces = split[i].replace(/\*/g, '.*?'); + + if (namespaces[0] === '-') { + createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + createDebug.names.push(new RegExp('^' + namespaces + '$')); + } + } + + for (i = 0; i < createDebug.instances.length; i++) { + var instance = createDebug.instances[i]; + instance.enabled = createDebug.enabled(instance.namespace); + } + } + /** + * Disable debug output. + * + * @api public + */ + + + function disable() { + createDebug.enable(''); + } + /** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + + + function enabled(name) { + if (name[name.length - 1] === '*') { + return true; + } + + var i; + var len; + + for (i = 0, len = createDebug.skips.length; i < len; i++) { + if (createDebug.skips[i].test(name)) { + return false; + } + } + + for (i = 0, len = createDebug.names.length; i < len; i++) { + if (createDebug.names[i].test(name)) { + return true; + } + } + + return false; + } + /** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + + + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + + return val; + } + + createDebug.enable(createDebug.load()); + return createDebug; +} + +module.exports = setup; + + + +/***/ }), +/* 272 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * Module dependencies. + */ +var tty = __webpack_require__(70); + +var util = __webpack_require__(40); +/** + * This is the Node.js implementation of `debug()`. + */ + + +exports.init = init; +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +/** + * Colors. + */ + +exports.colors = [6, 2, 3, 4, 5, 1]; + +try { + // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json) + // eslint-disable-next-line import/no-extraneous-dependencies + var supportsColor = __webpack_require__(71); + + if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { + exports.colors = [20, 21, 26, 27, 32, 33, 38, 39, 40, 41, 42, 43, 44, 45, 56, 57, 62, 63, 68, 69, 74, 75, 76, 77, 78, 79, 80, 81, 92, 93, 98, 99, 112, 113, 128, 129, 134, 135, 148, 149, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 178, 179, 184, 185, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 214, 215, 220, 221]; + } +} catch (error) {} // Swallow - we only care if `supports-color` is available; it doesn't have to be. + +/** + * Build up the default `inspectOpts` object from the environment variables. + * + * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js + */ + + +exports.inspectOpts = Object.keys(process.env).filter(function (key) { + return /^debug_/i.test(key); +}).reduce(function (obj, key) { + // Camel-case + var prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, function (_, k) { + return k.toUpperCase(); + }); // Coerce string value into JS value + + var val = process.env[key]; + + if (/^(yes|on|true|enabled)$/i.test(val)) { + val = true; + } else if (/^(no|off|false|disabled)$/i.test(val)) { + val = false; + } else if (val === 'null') { + val = null; + } else { + val = Number(val); + } + + obj[prop] = val; + return obj; +}, {}); +/** + * Is stdout a TTY? Colored output is enabled when `true`. + */ + +function useColors() { + return 'colors' in exports.inspectOpts ? Boolean(exports.inspectOpts.colors) : tty.isatty(process.stderr.fd); +} +/** + * Adds ANSI color escape codes if enabled. + * + * @api public + */ + + +function formatArgs(args) { + var name = this.namespace, + useColors = this.useColors; + + if (useColors) { + var c = this.color; + var colorCode = "\x1B[3" + (c < 8 ? c : '8;5;' + c); + var prefix = " ".concat(colorCode, ";1m").concat(name, " \x1B[0m"); + args[0] = prefix + args[0].split('\n').join('\n' + prefix); + args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + "\x1B[0m"); + } else { + args[0] = getDate() + name + ' ' + args[0]; + } +} + +function getDate() { + if (exports.inspectOpts.hideDate) { + return ''; + } + + return new Date().toISOString() + ' '; +} +/** + * Invokes `util.format()` with the specified arguments and writes to stderr. + */ + + +function log() { + return process.stderr.write(util.format.apply(util, arguments) + '\n'); +} +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + + +function save(namespaces) { + if (namespaces) { + process.env.DEBUG = namespaces; + } else { + // If you set a process.env field to null or undefined, it gets cast to the + // string 'null' or 'undefined'. Just delete instead. + delete process.env.DEBUG; + } +} +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + + +function load() { + return process.env.DEBUG; +} +/** + * Init logic for `debug` instances. + * + * Create a new `inspectOpts` object in case `useColors` is set + * differently for a particular `debug` instance. + */ + + +function init(debug) { + debug.inspectOpts = {}; + var keys = Object.keys(exports.inspectOpts); + + for (var i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; + } +} + +module.exports = __webpack_require__(271)(exports); +var formatters = module.exports.formatters; +/** + * Map %o to `util.inspect()`, all on a single line. + */ + +formatters.o = function (v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts).replace(/\s*\n\s*/g, ' '); +}; +/** + * Map %O to `util.inspect()`, allowing multiple lines if needed. + */ + + +formatters.O = function (v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); +}; + + + +/***/ }), +/* 273 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// high-level commands +exports.c = exports.create = __webpack_require__(274) +exports.r = exports.replace = __webpack_require__(298) +exports.t = exports.list = __webpack_require__(296) +exports.u = exports.update = __webpack_require__(299) +exports.x = exports.extract = __webpack_require__(300) + +// classes +exports.Pack = __webpack_require__(276) +exports.Unpack = __webpack_require__(301) +exports.Parse = __webpack_require__(297) +exports.ReadEntry = __webpack_require__(286) +exports.WriteEntry = __webpack_require__(288) +exports.Header = __webpack_require__(290) +exports.Pax = __webpack_require__(289) +exports.types = __webpack_require__(287) + + +/***/ }), +/* 274 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// tar -c +const hlo = __webpack_require__(275) + +const Pack = __webpack_require__(276) +const fs = __webpack_require__(55) +const fsm = __webpack_require__(295) +const t = __webpack_require__(296) +const path = __webpack_require__(57) + +const c = module.exports = (opt_, files, cb) => { + if (typeof files === 'function') + cb = files + + if (Array.isArray(opt_)) + files = opt_, opt_ = {} + + if (!files || !Array.isArray(files) || !files.length) + throw new TypeError('no files or directories specified') + + files = Array.from(files) + + const opt = hlo(opt_) + + if (opt.sync && typeof cb === 'function') + throw new TypeError('callback not supported for sync tar functions') + + if (!opt.file && typeof cb === 'function') + throw new TypeError('callback only supported with file option') + + return opt.file && opt.sync ? createFileSync(opt, files) + : opt.file ? createFile(opt, files, cb) + : opt.sync ? createSync(opt, files) + : create(opt, files) +} + +const createFileSync = (opt, files) => { + const p = new Pack.Sync(opt) + const stream = new fsm.WriteStreamSync(opt.file, { + mode: opt.mode || 0o666 + }) + p.pipe(stream) + addFilesSync(p, files) +} + +const createFile = (opt, files, cb) => { + const p = new Pack(opt) + const stream = new fsm.WriteStream(opt.file, { + mode: opt.mode || 0o666 + }) + p.pipe(stream) + + const promise = new Promise((res, rej) => { + stream.on('error', rej) + stream.on('close', res) + p.on('error', rej) + }) + + addFilesAsync(p, files) + + return cb ? promise.then(cb, cb) : promise +} + +const addFilesSync = (p, files) => { + files.forEach(file => { + if (file.charAt(0) === '@') + t({ + file: path.resolve(p.cwd, file.substr(1)), + sync: true, + noResume: true, + onentry: entry => p.add(entry) + }) + else + p.add(file) + }) + p.end() +} + +const addFilesAsync = (p, files) => { + while (files.length) { + const file = files.shift() + if (file.charAt(0) === '@') + return t({ + file: path.resolve(p.cwd, file.substr(1)), + noResume: true, + onentry: entry => p.add(entry) + }).then(_ => addFilesAsync(p, files)) + else + p.add(file) + } + p.end() +} + +const createSync = (opt, files) => { + const p = new Pack.Sync(opt) + addFilesSync(p, files) + return p +} + +const create = (opt, files) => { + const p = new Pack(opt) + addFilesAsync(p, files) + return p +} + + +/***/ }), +/* 275 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// turn tar(1) style args like `C` into the more verbose things like `cwd` + +const argmap = new Map([ + ['C', 'cwd'], + ['f', 'file'], + ['z', 'gzip'], + ['P', 'preservePaths'], + ['U', 'unlink'], + ['strip-components', 'strip'], + ['stripComponents', 'strip'], + ['keep-newer', 'newer'], + ['keepNewer', 'newer'], + ['keep-newer-files', 'newer'], + ['keepNewerFiles', 'newer'], + ['k', 'keep'], + ['keep-existing', 'keep'], + ['keepExisting', 'keep'], + ['m', 'noMtime'], + ['no-mtime', 'noMtime'], + ['p', 'preserveOwner'], + ['L', 'follow'], + ['h', 'follow'] +]) + +const parse = module.exports = opt => opt ? Object.keys(opt).map(k => [ + argmap.has(k) ? argmap.get(k) : k, opt[k] +]).reduce((set, kv) => (set[kv[0]] = kv[1], set), Object.create(null)) : {} + + +/***/ }), +/* 276 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const Buffer = __webpack_require__(277) + +// A readable tar stream creator +// Technically, this is a transform stream that you write paths into, +// and tar format comes out of. +// The `add()` method is like `write()` but returns this, +// and end() return `this` as well, so you can +// do `new Pack(opt).add('files').add('dir').end().pipe(output) +// You could also do something like: +// streamOfPaths().pipe(new Pack()).pipe(new fs.WriteStream('out.tar')) + +class PackJob { + constructor (path, absolute) { + this.path = path || './' + this.absolute = absolute + this.entry = null + this.stat = null + this.readdir = null + this.pending = false + this.ignore = false + this.piped = false + } +} + +const MiniPass = __webpack_require__(280) +const zlib = __webpack_require__(284) +const ReadEntry = __webpack_require__(286) +const WriteEntry = __webpack_require__(288) +const WriteEntrySync = WriteEntry.Sync +const WriteEntryTar = WriteEntry.Tar +const Yallist = __webpack_require__(281) +const EOF = Buffer.alloc(1024) +const ONSTAT = Symbol('onStat') +const ENDED = Symbol('ended') +const QUEUE = Symbol('queue') +const CURRENT = Symbol('current') +const PROCESS = Symbol('process') +const PROCESSING = Symbol('processing') +const PROCESSJOB = Symbol('processJob') +const JOBS = Symbol('jobs') +const JOBDONE = Symbol('jobDone') +const ADDFSENTRY = Symbol('addFSEntry') +const ADDTARENTRY = Symbol('addTarEntry') +const STAT = Symbol('stat') +const READDIR = Symbol('readdir') +const ONREADDIR = Symbol('onreaddir') +const PIPE = Symbol('pipe') +const ENTRY = Symbol('entry') +const ENTRYOPT = Symbol('entryOpt') +const WRITEENTRYCLASS = Symbol('writeEntryClass') +const WRITE = Symbol('write') +const ONDRAIN = Symbol('ondrain') + +const fs = __webpack_require__(55) +const path = __webpack_require__(57) +const warner = __webpack_require__(292) + +const Pack = warner(class Pack extends MiniPass { + constructor (opt) { + super(opt) + opt = opt || Object.create(null) + this.opt = opt + this.cwd = opt.cwd || process.cwd() + this.maxReadSize = opt.maxReadSize + this.preservePaths = !!opt.preservePaths + this.strict = !!opt.strict + this.noPax = !!opt.noPax + this.prefix = (opt.prefix || '').replace(/(\\|\/)+$/, '') + this.linkCache = opt.linkCache || new Map() + this.statCache = opt.statCache || new Map() + this.readdirCache = opt.readdirCache || new Map() + + this[WRITEENTRYCLASS] = WriteEntry + if (typeof opt.onwarn === 'function') + this.on('warn', opt.onwarn) + + this.zip = null + if (opt.gzip) { + if (typeof opt.gzip !== 'object') + opt.gzip = {} + this.zip = new zlib.Gzip(opt.gzip) + this.zip.on('data', chunk => super.write(chunk)) + this.zip.on('end', _ => super.end()) + this.zip.on('drain', _ => this[ONDRAIN]()) + this.on('resume', _ => this.zip.resume()) + } else + this.on('drain', this[ONDRAIN]) + + this.portable = !!opt.portable + this.noDirRecurse = !!opt.noDirRecurse + this.follow = !!opt.follow + this.noMtime = !!opt.noMtime + this.mtime = opt.mtime || null + + this.filter = typeof opt.filter === 'function' ? opt.filter : _ => true + + this[QUEUE] = new Yallist + this[JOBS] = 0 + this.jobs = +opt.jobs || 4 + this[PROCESSING] = false + this[ENDED] = false + } + + [WRITE] (chunk) { + return super.write(chunk) + } + + add (path) { + this.write(path) + return this + } + + end (path) { + if (path) + this.write(path) + this[ENDED] = true + this[PROCESS]() + return this + } + + write (path) { + if (this[ENDED]) + throw new Error('write after end') + + if (path instanceof ReadEntry) + this[ADDTARENTRY](path) + else + this[ADDFSENTRY](path) + return this.flowing + } + + [ADDTARENTRY] (p) { + const absolute = path.resolve(this.cwd, p.path) + if (this.prefix) + p.path = this.prefix + '/' + p.path.replace(/^\.(\/+|$)/, '') + + // in this case, we don't have to wait for the stat + if (!this.filter(p.path, p)) + p.resume() + else { + const job = new PackJob(p.path, absolute, false) + job.entry = new WriteEntryTar(p, this[ENTRYOPT](job)) + job.entry.on('end', _ => this[JOBDONE](job)) + this[JOBS] += 1 + this[QUEUE].push(job) + } + + this[PROCESS]() + } + + [ADDFSENTRY] (p) { + const absolute = path.resolve(this.cwd, p) + if (this.prefix) + p = this.prefix + '/' + p.replace(/^\.(\/+|$)/, '') + + this[QUEUE].push(new PackJob(p, absolute)) + this[PROCESS]() + } + + [STAT] (job) { + job.pending = true + this[JOBS] += 1 + const stat = this.follow ? 'stat' : 'lstat' + fs[stat](job.absolute, (er, stat) => { + job.pending = false + this[JOBS] -= 1 + if (er) + this.emit('error', er) + else + this[ONSTAT](job, stat) + }) + } + + [ONSTAT] (job, stat) { + this.statCache.set(job.absolute, stat) + job.stat = stat + + // now we have the stat, we can filter it. + if (!this.filter(job.path, stat)) + job.ignore = true + + this[PROCESS]() + } + + [READDIR] (job) { + job.pending = true + this[JOBS] += 1 + fs.readdir(job.absolute, (er, entries) => { + job.pending = false + this[JOBS] -= 1 + if (er) + return this.emit('error', er) + this[ONREADDIR](job, entries) + }) + } + + [ONREADDIR] (job, entries) { + this.readdirCache.set(job.absolute, entries) + job.readdir = entries + this[PROCESS]() + } + + [PROCESS] () { + if (this[PROCESSING]) + return + + this[PROCESSING] = true + for (let w = this[QUEUE].head; + w !== null && this[JOBS] < this.jobs; + w = w.next) { + this[PROCESSJOB](w.value) + if (w.value.ignore) { + const p = w.next + this[QUEUE].removeNode(w) + w.next = p + } + } + + this[PROCESSING] = false + + if (this[ENDED] && !this[QUEUE].length && this[JOBS] === 0) { + if (this.zip) + this.zip.end(EOF) + else { + super.write(EOF) + super.end() + } + } + } + + get [CURRENT] () { + return this[QUEUE] && this[QUEUE].head && this[QUEUE].head.value + } + + [JOBDONE] (job) { + this[QUEUE].shift() + this[JOBS] -= 1 + this[PROCESS]() + } + + [PROCESSJOB] (job) { + if (job.pending) + return + + if (job.entry) { + if (job === this[CURRENT] && !job.piped) + this[PIPE](job) + return + } + + if (!job.stat) { + if (this.statCache.has(job.absolute)) + this[ONSTAT](job, this.statCache.get(job.absolute)) + else + this[STAT](job) + } + if (!job.stat) + return + + // filtered out! + if (job.ignore) + return + + if (!this.noDirRecurse && job.stat.isDirectory() && !job.readdir) { + if (this.readdirCache.has(job.absolute)) + this[ONREADDIR](job, this.readdirCache.get(job.absolute)) + else + this[READDIR](job) + if (!job.readdir) + return + } + + // we know it doesn't have an entry, because that got checked above + job.entry = this[ENTRY](job) + if (!job.entry) { + job.ignore = true + return + } + + if (job === this[CURRENT] && !job.piped) + this[PIPE](job) + } + + [ENTRYOPT] (job) { + return { + onwarn: (msg, data) => { + this.warn(msg, data) + }, + noPax: this.noPax, + cwd: this.cwd, + absolute: job.absolute, + preservePaths: this.preservePaths, + maxReadSize: this.maxReadSize, + strict: this.strict, + portable: this.portable, + linkCache: this.linkCache, + statCache: this.statCache, + noMtime: this.noMtime, + mtime: this.mtime + } + } + + [ENTRY] (job) { + this[JOBS] += 1 + try { + return new this[WRITEENTRYCLASS](job.path, this[ENTRYOPT](job)) + .on('end', () => this[JOBDONE](job)) + .on('error', er => this.emit('error', er)) + } catch (er) { + this.emit('error', er) + } + } + + [ONDRAIN] () { + if (this[CURRENT] && this[CURRENT].entry) + this[CURRENT].entry.resume() + } + + // like .pipe() but using super, because our write() is special + [PIPE] (job) { + job.piped = true + + if (job.readdir) + job.readdir.forEach(entry => { + const p = this.prefix ? + job.path.slice(this.prefix.length + 1) || './' + : job.path + + const base = p === './' ? '' : p.replace(/\/*$/, '/') + this[ADDFSENTRY](base + entry) + }) + + const source = job.entry + const zip = this.zip + + if (zip) + source.on('data', chunk => { + if (!zip.write(chunk)) + source.pause() + }) + else + source.on('data', chunk => { + if (!super.write(chunk)) + source.pause() + }) + } + + pause () { + if (this.zip) + this.zip.pause() + return super.pause() + } +}) + +class PackSync extends Pack { + constructor (opt) { + super(opt) + this[WRITEENTRYCLASS] = WriteEntrySync + } + + // pause/resume are no-ops in sync streams. + pause () {} + resume () {} + + [STAT] (job) { + const stat = this.follow ? 'statSync' : 'lstatSync' + this[ONSTAT](job, fs[stat](job.absolute)) + } + + [READDIR] (job, stat) { + this[ONREADDIR](job, fs.readdirSync(job.absolute)) + } + + // gotta get it all in this tick + [PIPE] (job) { + const source = job.entry + const zip = this.zip + + if (job.readdir) + job.readdir.forEach(entry => { + const p = this.prefix ? + job.path.slice(this.prefix.length + 1) || './' + : job.path + + const base = p === './' ? '' : p.replace(/\/*$/, '/') + this[ADDFSENTRY](base + entry) + }) + + if (zip) + source.on('data', chunk => { + zip.write(chunk) + }) + else + source.on('data', chunk => { + super[WRITE](chunk) + }) + } +} + +Pack.Sync = PackSync + +module.exports = Pack + + +/***/ }), +/* 277 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// Buffer in node 4.x < 4.5.0 doesn't have working Buffer.from +// or Buffer.alloc, and Buffer in node 10 deprecated the ctor. +// .M, this is fine .\^/M.. +let B = Buffer +/* istanbul ignore next */ +if (!B.alloc) { + B = __webpack_require__(278).Buffer +} +module.exports = B + + +/***/ }), +/* 278 */ +/***/ (function(module, exports, __webpack_require__) { + +/* eslint-disable node/no-deprecated-api */ +var buffer = __webpack_require__(279) +var Buffer = buffer.Buffer + +// alternative to using Object.keys for old browsers +function copyProps (src, dst) { + for (var key in src) { + dst[key] = src[key] + } +} +if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { + module.exports = buffer +} else { + // Copy properties from require('buffer') + copyProps(buffer, exports) + exports.Buffer = SafeBuffer +} + +function SafeBuffer (arg, encodingOrOffset, length) { + return Buffer(arg, encodingOrOffset, length) +} + +// Copy static methods from Buffer +copyProps(Buffer, SafeBuffer) + +SafeBuffer.from = function (arg, encodingOrOffset, length) { + if (typeof arg === 'number') { + throw new TypeError('Argument must not be a number') + } + return Buffer(arg, encodingOrOffset, length) +} + +SafeBuffer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + var buf = Buffer(size) + if (fill !== undefined) { + if (typeof encoding === 'string') { + buf.fill(fill, encoding) + } else { + buf.fill(fill) + } + } else { + buf.fill(0) + } + return buf +} + +SafeBuffer.allocUnsafe = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return Buffer(size) +} + +SafeBuffer.allocUnsafeSlow = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return buffer.SlowBuffer(size) +} + + +/***/ }), +/* 279 */ +/***/ (function(module, exports) { + +module.exports = require("buffer"); + +/***/ }), +/* 280 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const EE = __webpack_require__(49) +const Yallist = __webpack_require__(281) +const EOF = Symbol('EOF') +const MAYBE_EMIT_END = Symbol('maybeEmitEnd') +const EMITTED_END = Symbol('emittedEnd') +const CLOSED = Symbol('closed') +const READ = Symbol('read') +const FLUSH = Symbol('flush') +const doIter = process.env._MP_NO_ITERATOR_SYMBOLS_ !== '1' +const ASYNCITERATOR = doIter && Symbol.asyncIterator || Symbol('asyncIterator not implemented') +const ITERATOR = doIter && Symbol.iterator || Symbol('iterator not implemented') +const FLUSHCHUNK = Symbol('flushChunk') +const SD = __webpack_require__(283).StringDecoder +const ENCODING = Symbol('encoding') +const DECODER = Symbol('decoder') +const FLOWING = Symbol('flowing') +const RESUME = Symbol('resume') +const BUFFERLENGTH = Symbol('bufferLength') +const BUFFERPUSH = Symbol('bufferPush') +const BUFFERSHIFT = Symbol('bufferShift') +const OBJECTMODE = Symbol('objectMode') + +// Buffer in node 4.x < 4.5.0 doesn't have working Buffer.from +// or Buffer.alloc, and Buffer in node 10 deprecated the ctor. +// .M, this is fine .\^/M.. +let B = Buffer +/* istanbul ignore next */ +if (!B.alloc) { + B = __webpack_require__(278).Buffer +} + +module.exports = class MiniPass extends EE { + constructor (options) { + super() + this[FLOWING] = false + this.pipes = new Yallist() + this.buffer = new Yallist() + this[OBJECTMODE] = options && options.objectMode || false + if (this[OBJECTMODE]) + this[ENCODING] = null + else + this[ENCODING] = options && options.encoding || null + if (this[ENCODING] === 'buffer') + this[ENCODING] = null + this[DECODER] = this[ENCODING] ? new SD(this[ENCODING]) : null + this[EOF] = false + this[EMITTED_END] = false + this[CLOSED] = false + this.writable = true + this.readable = true + this[BUFFERLENGTH] = 0 + } + + get bufferLength () { return this[BUFFERLENGTH] } + + get encoding () { return this[ENCODING] } + set encoding (enc) { + if (this[OBJECTMODE]) + throw new Error('cannot set encoding in objectMode') + + if (this[ENCODING] && enc !== this[ENCODING] && + (this[DECODER] && this[DECODER].lastNeed || this[BUFFERLENGTH])) + throw new Error('cannot change encoding') + + if (this[ENCODING] !== enc) { + this[DECODER] = enc ? new SD(enc) : null + if (this.buffer.length) + this.buffer = this.buffer.map(chunk => this[DECODER].write(chunk)) + } + + this[ENCODING] = enc + } + + setEncoding (enc) { + this.encoding = enc + } + + write (chunk, encoding, cb) { + if (this[EOF]) + throw new Error('write after end') + + if (typeof encoding === 'function') + cb = encoding, encoding = 'utf8' + + if (!encoding) + encoding = 'utf8' + + // fast-path writing strings of same encoding to a stream with + // an empty buffer, skipping the buffer/decoder dance + if (typeof chunk === 'string' && !this[OBJECTMODE] && + // unless it is a string already ready for us to use + !(encoding === this[ENCODING] && !this[DECODER].lastNeed)) { + chunk = B.from(chunk, encoding) + } + + if (B.isBuffer(chunk) && this[ENCODING]) + chunk = this[DECODER].write(chunk) + + try { + return this.flowing + ? (this.emit('data', chunk), this.flowing) + : (this[BUFFERPUSH](chunk), false) + } finally { + this.emit('readable') + if (cb) + cb() + } + } + + read (n) { + try { + if (this[BUFFERLENGTH] === 0 || n === 0 || n > this[BUFFERLENGTH]) + return null + + if (this[OBJECTMODE]) + n = null + + if (this.buffer.length > 1 && !this[OBJECTMODE]) { + if (this.encoding) + this.buffer = new Yallist([ + Array.from(this.buffer).join('') + ]) + else + this.buffer = new Yallist([ + B.concat(Array.from(this.buffer), this[BUFFERLENGTH]) + ]) + } + + return this[READ](n || null, this.buffer.head.value) + } finally { + this[MAYBE_EMIT_END]() + } + } + + [READ] (n, chunk) { + if (n === chunk.length || n === null) + this[BUFFERSHIFT]() + else { + this.buffer.head.value = chunk.slice(n) + chunk = chunk.slice(0, n) + this[BUFFERLENGTH] -= n + } + + this.emit('data', chunk) + + if (!this.buffer.length && !this[EOF]) + this.emit('drain') + + return chunk + } + + end (chunk, encoding, cb) { + if (typeof chunk === 'function') + cb = chunk, chunk = null + if (typeof encoding === 'function') + cb = encoding, encoding = 'utf8' + if (chunk) + this.write(chunk, encoding) + if (cb) + this.once('end', cb) + this[EOF] = true + this.writable = false + if (this.flowing) + this[MAYBE_EMIT_END]() + } + + // don't let the internal resume be overwritten + [RESUME] () { + this[FLOWING] = true + this.emit('resume') + if (this.buffer.length) + this[FLUSH]() + else if (this[EOF]) + this[MAYBE_EMIT_END]() + else + this.emit('drain') + } + + resume () { + return this[RESUME]() + } + + pause () { + this[FLOWING] = false + } + + get flowing () { + return this[FLOWING] + } + + [BUFFERPUSH] (chunk) { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] += 1 + else + this[BUFFERLENGTH] += chunk.length + return this.buffer.push(chunk) + } + + [BUFFERSHIFT] () { + if (this.buffer.length) { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] -= 1 + else + this[BUFFERLENGTH] -= this.buffer.head.value.length + } + return this.buffer.shift() + } + + [FLUSH] () { + do {} while (this[FLUSHCHUNK](this[BUFFERSHIFT]())) + + if (!this.buffer.length && !this[EOF]) + this.emit('drain') + } + + [FLUSHCHUNK] (chunk) { + return chunk ? (this.emit('data', chunk), this.flowing) : false + } + + pipe (dest, opts) { + if (dest === process.stdout || dest === process.stderr) + (opts = opts || {}).end = false + const p = { dest: dest, opts: opts, ondrain: _ => this[RESUME]() } + this.pipes.push(p) + + dest.on('drain', p.ondrain) + this[RESUME]() + return dest + } + + addListener (ev, fn) { + return this.on(ev, fn) + } + + on (ev, fn) { + try { + return super.on(ev, fn) + } finally { + if (ev === 'data' && !this.pipes.length && !this.flowing) + this[RESUME]() + else if (ev === 'end' && this[EMITTED_END]) { + super.emit('end') + this.removeAllListeners('end') + } + } + } + + get emittedEnd () { + return this[EMITTED_END] + } + + [MAYBE_EMIT_END] () { + if (!this[EMITTED_END] && this.buffer.length === 0 && this[EOF]) { + this.emit('end') + this.emit('prefinish') + this.emit('finish') + if (this[CLOSED]) + this.emit('close') + } + } + + emit (ev, data) { + if (ev === 'data') { + if (!data) + return + + if (this.pipes.length) + this.pipes.forEach(p => p.dest.write(data) || this.pause()) + } else if (ev === 'end') { + if (this[EMITTED_END] === true) + return + + this[EMITTED_END] = true + this.readable = false + + if (this[DECODER]) { + data = this[DECODER].end() + if (data) { + this.pipes.forEach(p => p.dest.write(data)) + super.emit('data', data) + } + } + + this.pipes.forEach(p => { + p.dest.removeListener('drain', p.ondrain) + if (!p.opts || p.opts.end !== false) + p.dest.end() + }) + } else if (ev === 'close') { + this[CLOSED] = true + // don't emit close before 'end' and 'finish' + if (!this[EMITTED_END]) + return + } + + const args = new Array(arguments.length) + args[0] = ev + args[1] = data + if (arguments.length > 2) { + for (let i = 2; i < arguments.length; i++) { + args[i] = arguments[i] + } + } + + try { + return super.emit.apply(this, args) + } finally { + if (ev !== 'end') + this[MAYBE_EMIT_END]() + else + this.removeAllListeners('end') + } + } + + // const all = await stream.collect() + collect () { + return new Promise((resolve, reject) => { + const buf = [] + this.on('data', c => buf.push(c)) + this.on('end', () => resolve(buf)) + this.on('error', reject) + }) + } + + // for await (let chunk of stream) + [ASYNCITERATOR] () { + const next = () => { + const res = this.read() + if (res !== null) + return Promise.resolve({ done: false, value: res }) + + if (this[EOF]) + return Promise.resolve({ done: true }) + + let resolve = null + let reject = null + const onerr = er => { + this.removeListener('data', ondata) + this.removeListener('end', onend) + reject(er) + } + const ondata = value => { + this.removeListener('error', onerr) + this.removeListener('end', onend) + this.pause() + resolve({ value: value, done: !!this[EOF] }) + } + const onend = () => { + this.removeListener('error', onerr) + this.removeListener('data', ondata) + resolve({ done: true }) + } + return new Promise((res, rej) => { + reject = rej + resolve = res + this.once('error', onerr) + this.once('end', onend) + this.once('data', ondata) + }) + } + + return { next } + } + + // for (let chunk of stream) + [ITERATOR] () { + const next = () => { + const value = this.read() + const done = value === null + return { value, done } + } + return { next } + } +} + + +/***/ }), +/* 281 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = Yallist + +Yallist.Node = Node +Yallist.create = Yallist + +function Yallist (list) { + var self = this + if (!(self instanceof Yallist)) { + self = new Yallist() + } + + self.tail = null + self.head = null + self.length = 0 + + if (list && typeof list.forEach === 'function') { + list.forEach(function (item) { + self.push(item) + }) + } else if (arguments.length > 0) { + for (var i = 0, l = arguments.length; i < l; i++) { + self.push(arguments[i]) + } + } + + return self +} + +Yallist.prototype.removeNode = function (node) { + if (node.list !== this) { + throw new Error('removing node which does not belong to this list') + } + + var next = node.next + var prev = node.prev + + if (next) { + next.prev = prev + } + + if (prev) { + prev.next = next + } + + if (node === this.head) { + this.head = next + } + if (node === this.tail) { + this.tail = prev + } + + node.list.length-- + node.next = null + node.prev = null + node.list = null +} + +Yallist.prototype.unshiftNode = function (node) { + if (node === this.head) { + return + } + + if (node.list) { + node.list.removeNode(node) + } + + var head = this.head + node.list = this + node.next = head + if (head) { + head.prev = node + } + + this.head = node + if (!this.tail) { + this.tail = node + } + this.length++ +} + +Yallist.prototype.pushNode = function (node) { + if (node === this.tail) { + return + } + + if (node.list) { + node.list.removeNode(node) + } + + var tail = this.tail + node.list = this + node.prev = tail + if (tail) { + tail.next = node + } + + this.tail = node + if (!this.head) { + this.head = node + } + this.length++ +} + +Yallist.prototype.push = function () { + for (var i = 0, l = arguments.length; i < l; i++) { + push(this, arguments[i]) + } + return this.length +} + +Yallist.prototype.unshift = function () { + for (var i = 0, l = arguments.length; i < l; i++) { + unshift(this, arguments[i]) + } + return this.length +} + +Yallist.prototype.pop = function () { + if (!this.tail) { + return undefined + } + + var res = this.tail.value + this.tail = this.tail.prev + if (this.tail) { + this.tail.next = null + } else { + this.head = null + } + this.length-- + return res +} + +Yallist.prototype.shift = function () { + if (!this.head) { + return undefined + } + + var res = this.head.value + this.head = this.head.next + if (this.head) { + this.head.prev = null + } else { + this.tail = null + } + this.length-- + return res +} + +Yallist.prototype.forEach = function (fn, thisp) { + thisp = thisp || this + for (var walker = this.head, i = 0; walker !== null; i++) { + fn.call(thisp, walker.value, i, this) + walker = walker.next + } +} + +Yallist.prototype.forEachReverse = function (fn, thisp) { + thisp = thisp || this + for (var walker = this.tail, i = this.length - 1; walker !== null; i--) { + fn.call(thisp, walker.value, i, this) + walker = walker.prev + } +} + +Yallist.prototype.get = function (n) { + for (var i = 0, walker = this.head; walker !== null && i < n; i++) { + // abort out of the list early if we hit a cycle + walker = walker.next + } + if (i === n && walker !== null) { + return walker.value + } +} + +Yallist.prototype.getReverse = function (n) { + for (var i = 0, walker = this.tail; walker !== null && i < n; i++) { + // abort out of the list early if we hit a cycle + walker = walker.prev + } + if (i === n && walker !== null) { + return walker.value + } +} + +Yallist.prototype.map = function (fn, thisp) { + thisp = thisp || this + var res = new Yallist() + for (var walker = this.head; walker !== null;) { + res.push(fn.call(thisp, walker.value, this)) + walker = walker.next + } + return res +} + +Yallist.prototype.mapReverse = function (fn, thisp) { + thisp = thisp || this + var res = new Yallist() + for (var walker = this.tail; walker !== null;) { + res.push(fn.call(thisp, walker.value, this)) + walker = walker.prev + } + return res +} + +Yallist.prototype.reduce = function (fn, initial) { + var acc + var walker = this.head + if (arguments.length > 1) { + acc = initial + } else if (this.head) { + walker = this.head.next + acc = this.head.value + } else { + throw new TypeError('Reduce of empty list with no initial value') + } + + for (var i = 0; walker !== null; i++) { + acc = fn(acc, walker.value, i) + walker = walker.next + } + + return acc +} + +Yallist.prototype.reduceReverse = function (fn, initial) { + var acc + var walker = this.tail + if (arguments.length > 1) { + acc = initial + } else if (this.tail) { + walker = this.tail.prev + acc = this.tail.value + } else { + throw new TypeError('Reduce of empty list with no initial value') + } + + for (var i = this.length - 1; walker !== null; i--) { + acc = fn(acc, walker.value, i) + walker = walker.prev + } + + return acc +} + +Yallist.prototype.toArray = function () { + var arr = new Array(this.length) + for (var i = 0, walker = this.head; walker !== null; i++) { + arr[i] = walker.value + walker = walker.next + } + return arr +} + +Yallist.prototype.toArrayReverse = function () { + var arr = new Array(this.length) + for (var i = 0, walker = this.tail; walker !== null; i++) { + arr[i] = walker.value + walker = walker.prev + } + return arr +} + +Yallist.prototype.slice = function (from, to) { + to = to || this.length + if (to < 0) { + to += this.length + } + from = from || 0 + if (from < 0) { + from += this.length + } + var ret = new Yallist() + if (to < from || to < 0) { + return ret + } + if (from < 0) { + from = 0 + } + if (to > this.length) { + to = this.length + } + for (var i = 0, walker = this.head; walker !== null && i < from; i++) { + walker = walker.next + } + for (; walker !== null && i < to; i++, walker = walker.next) { + ret.push(walker.value) + } + return ret +} + +Yallist.prototype.sliceReverse = function (from, to) { + to = to || this.length + if (to < 0) { + to += this.length + } + from = from || 0 + if (from < 0) { + from += this.length + } + var ret = new Yallist() + if (to < from || to < 0) { + return ret + } + if (from < 0) { + from = 0 + } + if (to > this.length) { + to = this.length + } + for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) { + walker = walker.prev + } + for (; walker !== null && i > from; i--, walker = walker.prev) { + ret.push(walker.value) + } + return ret +} + +Yallist.prototype.reverse = function () { + var head = this.head + var tail = this.tail + for (var walker = head; walker !== null; walker = walker.prev) { + var p = walker.prev + walker.prev = walker.next + walker.next = p + } + this.head = tail + this.tail = head + return this +} + +function push (self, item) { + self.tail = new Node(item, self.tail, null, self) + if (!self.head) { + self.head = self.tail + } + self.length++ +} + +function unshift (self, item) { + self.head = new Node(item, null, self.head, self) + if (!self.tail) { + self.tail = self.head + } + self.length++ +} + +function Node (value, prev, next, list) { + if (!(this instanceof Node)) { + return new Node(value, prev, next, list) + } + + this.list = list + this.value = value + + if (prev) { + prev.next = this + this.prev = prev + } else { + this.prev = null + } + + if (next) { + next.prev = this + this.next = next + } else { + this.next = null + } +} + +try { + // add if support for Symbol.iterator is present + __webpack_require__(282)(Yallist) +} catch (er) {} + + +/***/ }), +/* 282 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = function (Yallist) { + Yallist.prototype[Symbol.iterator] = function* () { + for (let walker = this.head; walker; walker = walker.next) { + yield walker.value + } + } +} + + +/***/ }), +/* 283 */ +/***/ (function(module, exports) { + +module.exports = require("string_decoder"); + +/***/ }), +/* 284 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const assert = __webpack_require__(101) +const Buffer = __webpack_require__(279).Buffer +const realZlib = __webpack_require__(137) + +const constants = exports.constants = __webpack_require__(285) +const MiniPass = __webpack_require__(280) + +const OriginalBufferConcat = Buffer.concat + +class ZlibError extends Error { + constructor (msg, errno) { + super('zlib: ' + msg) + this.errno = errno + this.code = codes.get(errno) + } + + get name () { + return 'ZlibError' + } +} + +// translation table for return codes. +const codes = new Map([ + [constants.Z_OK, 'Z_OK'], + [constants.Z_STREAM_END, 'Z_STREAM_END'], + [constants.Z_NEED_DICT, 'Z_NEED_DICT'], + [constants.Z_ERRNO, 'Z_ERRNO'], + [constants.Z_STREAM_ERROR, 'Z_STREAM_ERROR'], + [constants.Z_DATA_ERROR, 'Z_DATA_ERROR'], + [constants.Z_MEM_ERROR, 'Z_MEM_ERROR'], + [constants.Z_BUF_ERROR, 'Z_BUF_ERROR'], + [constants.Z_VERSION_ERROR, 'Z_VERSION_ERROR'] +]) + +const validFlushFlags = new Set([ + constants.Z_NO_FLUSH, + constants.Z_PARTIAL_FLUSH, + constants.Z_SYNC_FLUSH, + constants.Z_FULL_FLUSH, + constants.Z_FINISH, + constants.Z_BLOCK +]) + +const strategies = new Set([ + constants.Z_FILTERED, + constants.Z_HUFFMAN_ONLY, + constants.Z_RLE, + constants.Z_FIXED, + constants.Z_DEFAULT_STRATEGY +]) + +// the Zlib class they all inherit from +// This thing manages the queue of requests, and returns +// true or false if there is anything in the queue when +// you call the .write() method. +const _opts = Symbol('opts') +const _flushFlag = Symbol('flushFlag') +const _finishFlush = Symbol('finishFlush') +const _handle = Symbol('handle') +const _onError = Symbol('onError') +const _level = Symbol('level') +const _strategy = Symbol('strategy') +const _ended = Symbol('ended') + +class Zlib extends MiniPass { + constructor (opts, mode) { + super(opts) + this[_ended] = false + this[_opts] = opts = opts || {} + if (opts.flush && !validFlushFlags.has(opts.flush)) { + throw new TypeError('Invalid flush flag: ' + opts.flush) + } + if (opts.finishFlush && !validFlushFlags.has(opts.finishFlush)) { + throw new TypeError('Invalid flush flag: ' + opts.finishFlush) + } + + this[_flushFlag] = opts.flush || constants.Z_NO_FLUSH + this[_finishFlush] = typeof opts.finishFlush !== 'undefined' ? + opts.finishFlush : constants.Z_FINISH + + if (opts.chunkSize) { + if (opts.chunkSize < constants.Z_MIN_CHUNK) { + throw new RangeError('Invalid chunk size: ' + opts.chunkSize) + } + } + + if (opts.windowBits) { + if (opts.windowBits < constants.Z_MIN_WINDOWBITS || + opts.windowBits > constants.Z_MAX_WINDOWBITS) { + throw new RangeError('Invalid windowBits: ' + opts.windowBits) + } + } + + if (opts.level) { + if (opts.level < constants.Z_MIN_LEVEL || + opts.level > constants.Z_MAX_LEVEL) { + throw new RangeError('Invalid compression level: ' + opts.level) + } + } + + if (opts.memLevel) { + if (opts.memLevel < constants.Z_MIN_MEMLEVEL || + opts.memLevel > constants.Z_MAX_MEMLEVEL) { + throw new RangeError('Invalid memLevel: ' + opts.memLevel) + } + } + + if (opts.strategy && !(strategies.has(opts.strategy))) + throw new TypeError('Invalid strategy: ' + opts.strategy) + + if (opts.dictionary) { + if (!(opts.dictionary instanceof Buffer)) { + throw new TypeError('Invalid dictionary: it should be a Buffer instance') + } + } + + this[_handle] = new realZlib[mode](opts) + + this[_onError] = (err) => { + // there is no way to cleanly recover. + // continuing only obscures problems. + this.close() + + const error = new ZlibError(err.message, err.errno) + this.emit('error', error) + } + this[_handle].on('error', this[_onError]) + + const level = typeof opts.level === 'number' ? opts.level + : constants.Z_DEFAULT_COMPRESSION + + var strategy = typeof opts.strategy === 'number' ? opts.strategy + : constants.Z_DEFAULT_STRATEGY + + // API changed in node v9 + /* istanbul ignore next */ + + this[_level] = level + this[_strategy] = strategy + + this.once('end', this.close) + } + + close () { + if (this[_handle]) { + this[_handle].close() + this[_handle] = null + this.emit('close') + } + } + + params (level, strategy) { + if (!this[_handle]) + throw new Error('cannot switch params when binding is closed') + + // no way to test this without also not supporting params at all + /* istanbul ignore if */ + if (!this[_handle].params) + throw new Error('not supported in this implementation') + + if (level < constants.Z_MIN_LEVEL || + level > constants.Z_MAX_LEVEL) { + throw new RangeError('Invalid compression level: ' + level) + } + + if (!(strategies.has(strategy))) + throw new TypeError('Invalid strategy: ' + strategy) + + if (this[_level] !== level || this[_strategy] !== strategy) { + this.flush(constants.Z_SYNC_FLUSH) + assert(this[_handle], 'zlib binding closed') + // .params() calls .flush(), but the latter is always async in the + // core zlib. We override .flush() temporarily to intercept that and + // flush synchronously. + const origFlush = this[_handle].flush + this[_handle].flush = (flushFlag, cb) => { + this[_handle].flush = origFlush + this.flush(flushFlag) + cb() + } + this[_handle].params(level, strategy) + /* istanbul ignore else */ + if (this[_handle]) { + this[_level] = level + this[_strategy] = strategy + } + } + } + + reset () { + assert(this[_handle], 'zlib binding closed') + return this[_handle].reset() + } + + flush (kind) { + if (kind === undefined) + kind = constants.Z_FULL_FLUSH + + if (this.ended) + return + + const flushFlag = this[_flushFlag] + this[_flushFlag] = kind + this.write(Buffer.alloc(0)) + this[_flushFlag] = flushFlag + } + + end (chunk, encoding, cb) { + if (chunk) + this.write(chunk, encoding) + this.flush(this[_finishFlush]) + this[_ended] = true + return super.end(null, null, cb) + } + + get ended () { + return this[_ended] + } + + write (chunk, encoding, cb) { + // process the chunk using the sync process + // then super.write() all the outputted chunks + if (typeof encoding === 'function') + cb = encoding, encoding = 'utf8' + + if (typeof chunk === 'string') + chunk = Buffer.from(chunk, encoding) + + assert(this[_handle], 'zlib binding closed') + + // _processChunk tries to .close() the native handle after it's done, so we + // intercept that by temporarily making it a no-op. + const nativeHandle = this[_handle]._handle + const originalNativeClose = nativeHandle.close + nativeHandle.close = () => {} + const originalClose = this[_handle].close + this[_handle].close = () => {} + // It also calls `Buffer.concat()` at the end, which may be convenient + // for some, but which we are not interested in as it slows us down. + Buffer.concat = (args) => args + let result + try { + result = this[_handle]._processChunk(chunk, this[_flushFlag]) + } catch (err) { + this[_onError](err) + } finally { + Buffer.concat = OriginalBufferConcat + if (this[_handle]) { + // Core zlib resets `_handle` to null after attempting to close the + // native handle. Our no-op handler prevented actual closure, but we + // need to restore the `._handle` property. + this[_handle]._handle = nativeHandle + nativeHandle.close = originalNativeClose + this[_handle].close = originalClose + // `_processChunk()` adds an 'error' listener. If we don't remove it + // after each call, these handlers start piling up. + this[_handle].removeAllListeners('error') + } + } + + let writeReturn + if (result) { + if (Array.isArray(result) && result.length > 0) { + // The first buffer is always `handle._outBuffer`, which would be + // re-used for later invocations; so, we always have to copy that one. + writeReturn = super.write(Buffer.from(result[0])) + for (let i = 1; i < result.length; i++) { + writeReturn = super.write(result[i]) + } + } else { + writeReturn = super.write(Buffer.from(result)) + } + } + + if (cb) + cb() + return writeReturn + } +} + +// minimal 2-byte header +class Deflate extends Zlib { + constructor (opts) { + super(opts, 'Deflate') + } +} + +class Inflate extends Zlib { + constructor (opts) { + super(opts, 'Inflate') + } +} + +// gzip - bigger header, same deflate compression +class Gzip extends Zlib { + constructor (opts) { + super(opts, 'Gzip') + } +} + +class Gunzip extends Zlib { + constructor (opts) { + super(opts, 'Gunzip') + } +} + +// raw - no header +class DeflateRaw extends Zlib { + constructor (opts) { + super(opts, 'DeflateRaw') + } +} + +class InflateRaw extends Zlib { + constructor (opts) { + super(opts, 'InflateRaw') + } +} + +// auto-detect header. +class Unzip extends Zlib { + constructor (opts) { + super(opts, 'Unzip') + } +} + +exports.Deflate = Deflate +exports.Inflate = Inflate +exports.Gzip = Gzip +exports.Gunzip = Gunzip +exports.DeflateRaw = DeflateRaw +exports.InflateRaw = InflateRaw +exports.Unzip = Unzip + + +/***/ }), +/* 285 */ +/***/ (function(module, exports) { + +module.exports = Object.freeze({ + Z_NO_FLUSH: 0, + Z_PARTIAL_FLUSH: 1, + Z_SYNC_FLUSH: 2, + Z_FULL_FLUSH: 3, + Z_FINISH: 4, + Z_BLOCK: 5, + Z_OK: 0, + Z_STREAM_END: 1, + Z_NEED_DICT: 2, + Z_ERRNO: -1, + Z_STREAM_ERROR: -2, + Z_DATA_ERROR: -3, + Z_MEM_ERROR: -4, + Z_BUF_ERROR: -5, + Z_VERSION_ERROR: -6, + Z_NO_COMPRESSION: 0, + Z_BEST_SPEED: 1, + Z_BEST_COMPRESSION: 9, + Z_DEFAULT_COMPRESSION: -1, + Z_FILTERED: 1, + Z_HUFFMAN_ONLY: 2, + Z_RLE: 3, + Z_FIXED: 4, + Z_DEFAULT_STRATEGY: 0, + ZLIB_VERNUM: 4736, + DEFLATE: 1, + INFLATE: 2, + GZIP: 3, + GUNZIP: 4, + DEFLATERAW: 5, + INFLATERAW: 6, + UNZIP: 7, + Z_MIN_WINDOWBITS: 8, + Z_MAX_WINDOWBITS: 15, + Z_DEFAULT_WINDOWBITS: 15, + Z_MIN_CHUNK: 64, + Z_MAX_CHUNK: Infinity, + Z_DEFAULT_CHUNK: 16384, + Z_MIN_MEMLEVEL: 1, + Z_MAX_MEMLEVEL: 9, + Z_DEFAULT_MEMLEVEL: 8, + Z_MIN_LEVEL: -1, + Z_MAX_LEVEL: 9, + Z_DEFAULT_LEVEL: -1 +}) + + +/***/ }), +/* 286 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const types = __webpack_require__(287) +const MiniPass = __webpack_require__(280) + +const SLURP = Symbol('slurp') +module.exports = class ReadEntry extends MiniPass { + constructor (header, ex, gex) { + super() + this.extended = ex + this.globalExtended = gex + this.header = header + this.startBlockSize = 512 * Math.ceil(header.size / 512) + this.blockRemain = this.startBlockSize + this.remain = header.size + this.type = header.type + this.meta = false + this.ignore = false + switch (this.type) { + case 'File': + case 'OldFile': + case 'Link': + case 'SymbolicLink': + case 'CharacterDevice': + case 'BlockDevice': + case 'Directory': + case 'FIFO': + case 'ContiguousFile': + case 'GNUDumpDir': + break + + case 'NextFileHasLongLinkpath': + case 'NextFileHasLongPath': + case 'OldGnuLongPath': + case 'GlobalExtendedHeader': + case 'ExtendedHeader': + case 'OldExtendedHeader': + this.meta = true + break + + // NOTE: gnutar and bsdtar treat unrecognized types as 'File' + // it may be worth doing the same, but with a warning. + default: + this.ignore = true + } + + this.path = header.path + this.mode = header.mode + if (this.mode) + this.mode = this.mode & 0o7777 + this.uid = header.uid + this.gid = header.gid + this.uname = header.uname + this.gname = header.gname + this.size = header.size + this.mtime = header.mtime + this.atime = header.atime + this.ctime = header.ctime + this.linkpath = header.linkpath + this.uname = header.uname + this.gname = header.gname + + if (ex) this[SLURP](ex) + if (gex) this[SLURP](gex, true) + } + + write (data) { + const writeLen = data.length + if (writeLen > this.blockRemain) + throw new Error('writing more to entry than is appropriate') + + const r = this.remain + const br = this.blockRemain + this.remain = Math.max(0, r - writeLen) + this.blockRemain = Math.max(0, br - writeLen) + if (this.ignore) + return true + + if (r >= writeLen) + return super.write(data) + + // r < writeLen + return super.write(data.slice(0, r)) + } + + [SLURP] (ex, global) { + for (let k in ex) { + // we slurp in everything except for the path attribute in + // a global extended header, because that's weird. + if (ex[k] !== null && ex[k] !== undefined && + !(global && k === 'path')) + this[k] = ex[k] + } + } +} + + +/***/ }), +/* 287 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// map types from key to human-friendly name +exports.name = new Map([ + ['0', 'File'], + // same as File + ['', 'OldFile'], + ['1', 'Link'], + ['2', 'SymbolicLink'], + // Devices and FIFOs aren't fully supported + // they are parsed, but skipped when unpacking + ['3', 'CharacterDevice'], + ['4', 'BlockDevice'], + ['5', 'Directory'], + ['6', 'FIFO'], + // same as File + ['7', 'ContiguousFile'], + // pax headers + ['g', 'GlobalExtendedHeader'], + ['x', 'ExtendedHeader'], + // vendor-specific stuff + // skip + ['A', 'SolarisACL'], + // like 5, but with data, which should be skipped + ['D', 'GNUDumpDir'], + // metadata only, skip + ['I', 'Inode'], + // data = link path of next file + ['K', 'NextFileHasLongLinkpath'], + // data = path of next file + ['L', 'NextFileHasLongPath'], + // skip + ['M', 'ContinuationFile'], + // like L + ['N', 'OldGnuLongPath'], + // skip + ['S', 'SparseFile'], + // skip + ['V', 'TapeVolumeHeader'], + // like x + ['X', 'OldExtendedHeader'] +]) + +// map the other direction +exports.code = new Map(Array.from(exports.name).map(kv => [kv[1], kv[0]])) + + +/***/ }), +/* 288 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const Buffer = __webpack_require__(277) +const MiniPass = __webpack_require__(280) +const Pax = __webpack_require__(289) +const Header = __webpack_require__(290) +const ReadEntry = __webpack_require__(286) +const fs = __webpack_require__(55) +const path = __webpack_require__(57) + +const types = __webpack_require__(287) +const maxReadSize = 16 * 1024 * 1024 +const PROCESS = Symbol('process') +const FILE = Symbol('file') +const DIRECTORY = Symbol('directory') +const SYMLINK = Symbol('symlink') +const HARDLINK = Symbol('hardlink') +const HEADER = Symbol('header') +const READ = Symbol('read') +const LSTAT = Symbol('lstat') +const ONLSTAT = Symbol('onlstat') +const ONREAD = Symbol('onread') +const ONREADLINK = Symbol('onreadlink') +const OPENFILE = Symbol('openfile') +const ONOPENFILE = Symbol('onopenfile') +const CLOSE = Symbol('close') +const MODE = Symbol('mode') +const warner = __webpack_require__(292) +const winchars = __webpack_require__(293) + +const modeFix = __webpack_require__(294) + +const WriteEntry = warner(class WriteEntry extends MiniPass { + constructor (p, opt) { + opt = opt || {} + super(opt) + if (typeof p !== 'string') + throw new TypeError('path is required') + this.path = p + // suppress atime, ctime, uid, gid, uname, gname + this.portable = !!opt.portable + // until node has builtin pwnam functions, this'll have to do + this.myuid = process.getuid && process.getuid() + this.myuser = process.env.USER || '' + this.maxReadSize = opt.maxReadSize || maxReadSize + this.linkCache = opt.linkCache || new Map() + this.statCache = opt.statCache || new Map() + this.preservePaths = !!opt.preservePaths + this.cwd = opt.cwd || process.cwd() + this.strict = !!opt.strict + this.noPax = !!opt.noPax + this.noMtime = !!opt.noMtime + this.mtime = opt.mtime || null + + if (typeof opt.onwarn === 'function') + this.on('warn', opt.onwarn) + + if (!this.preservePaths && path.win32.isAbsolute(p)) { + // absolutes on posix are also absolutes on win32 + // so we only need to test this one to get both + const parsed = path.win32.parse(p) + this.warn('stripping ' + parsed.root + ' from absolute path', p) + this.path = p.substr(parsed.root.length) + } + + this.win32 = !!opt.win32 || process.platform === 'win32' + if (this.win32) { + this.path = winchars.decode(this.path.replace(/\\/g, '/')) + p = p.replace(/\\/g, '/') + } + + this.absolute = opt.absolute || path.resolve(this.cwd, p) + + if (this.path === '') + this.path = './' + + if (this.statCache.has(this.absolute)) + this[ONLSTAT](this.statCache.get(this.absolute)) + else + this[LSTAT]() + } + + [LSTAT] () { + fs.lstat(this.absolute, (er, stat) => { + if (er) + return this.emit('error', er) + this[ONLSTAT](stat) + }) + } + + [ONLSTAT] (stat) { + this.statCache.set(this.absolute, stat) + this.stat = stat + if (!stat.isFile()) + stat.size = 0 + this.type = getType(stat) + this.emit('stat', stat) + this[PROCESS]() + } + + [PROCESS] () { + switch (this.type) { + case 'File': return this[FILE]() + case 'Directory': return this[DIRECTORY]() + case 'SymbolicLink': return this[SYMLINK]() + // unsupported types are ignored. + default: return this.end() + } + } + + [MODE] (mode) { + return modeFix(mode, this.type === 'Directory') + } + + [HEADER] () { + if (this.type === 'Directory' && this.portable) + this.noMtime = true + + this.header = new Header({ + path: this.path, + linkpath: this.linkpath, + // only the permissions and setuid/setgid/sticky bitflags + // not the higher-order bits that specify file type + mode: this[MODE](this.stat.mode), + uid: this.portable ? null : this.stat.uid, + gid: this.portable ? null : this.stat.gid, + size: this.stat.size, + mtime: this.noMtime ? null : this.mtime || this.stat.mtime, + type: this.type, + uname: this.portable ? null : + this.stat.uid === this.myuid ? this.myuser : '', + atime: this.portable ? null : this.stat.atime, + ctime: this.portable ? null : this.stat.ctime + }) + + if (this.header.encode() && !this.noPax) + this.write(new Pax({ + atime: this.portable ? null : this.header.atime, + ctime: this.portable ? null : this.header.ctime, + gid: this.portable ? null : this.header.gid, + mtime: this.noMtime ? null : this.mtime || this.header.mtime, + path: this.path, + linkpath: this.linkpath, + size: this.header.size, + uid: this.portable ? null : this.header.uid, + uname: this.portable ? null : this.header.uname, + dev: this.portable ? null : this.stat.dev, + ino: this.portable ? null : this.stat.ino, + nlink: this.portable ? null : this.stat.nlink + }).encode()) + this.write(this.header.block) + } + + [DIRECTORY] () { + if (this.path.substr(-1) !== '/') + this.path += '/' + this.stat.size = 0 + this[HEADER]() + this.end() + } + + [SYMLINK] () { + fs.readlink(this.absolute, (er, linkpath) => { + if (er) + return this.emit('error', er) + this[ONREADLINK](linkpath) + }) + } + + [ONREADLINK] (linkpath) { + this.linkpath = linkpath + this[HEADER]() + this.end() + } + + [HARDLINK] (linkpath) { + this.type = 'Link' + this.linkpath = path.relative(this.cwd, linkpath) + this.stat.size = 0 + this[HEADER]() + this.end() + } + + [FILE] () { + if (this.stat.nlink > 1) { + const linkKey = this.stat.dev + ':' + this.stat.ino + if (this.linkCache.has(linkKey)) { + const linkpath = this.linkCache.get(linkKey) + if (linkpath.indexOf(this.cwd) === 0) + return this[HARDLINK](linkpath) + } + this.linkCache.set(linkKey, this.absolute) + } + + this[HEADER]() + if (this.stat.size === 0) + return this.end() + + this[OPENFILE]() + } + + [OPENFILE] () { + fs.open(this.absolute, 'r', (er, fd) => { + if (er) + return this.emit('error', er) + this[ONOPENFILE](fd) + }) + } + + [ONOPENFILE] (fd) { + const blockLen = 512 * Math.ceil(this.stat.size / 512) + const bufLen = Math.min(blockLen, this.maxReadSize) + const buf = Buffer.allocUnsafe(bufLen) + this[READ](fd, buf, 0, buf.length, 0, this.stat.size, blockLen) + } + + [READ] (fd, buf, offset, length, pos, remain, blockRemain) { + fs.read(fd, buf, offset, length, pos, (er, bytesRead) => { + if (er) + return this[CLOSE](fd, _ => this.emit('error', er)) + this[ONREAD](fd, buf, offset, length, pos, remain, blockRemain, bytesRead) + }) + } + + [CLOSE] (fd, cb) { + fs.close(fd, cb) + } + + [ONREAD] (fd, buf, offset, length, pos, remain, blockRemain, bytesRead) { + if (bytesRead <= 0 && remain > 0) { + const er = new Error('encountered unexpected EOF') + er.path = this.absolute + er.syscall = 'read' + er.code = 'EOF' + this[CLOSE](fd) + return this.emit('error', er) + } + + if (bytesRead > remain) { + const er = new Error('did not encounter expected EOF') + er.path = this.absolute + er.syscall = 'read' + er.code = 'EOF' + this[CLOSE](fd) + return this.emit('error', er) + } + + // null out the rest of the buffer, if we could fit the block padding + if (bytesRead === remain) { + for (let i = bytesRead; i < length && bytesRead < blockRemain; i++) { + buf[i + offset] = 0 + bytesRead ++ + remain ++ + } + } + + const writeBuf = offset === 0 && bytesRead === buf.length ? + buf : buf.slice(offset, offset + bytesRead) + remain -= bytesRead + blockRemain -= bytesRead + pos += bytesRead + offset += bytesRead + + this.write(writeBuf) + + if (!remain) { + if (blockRemain) + this.write(Buffer.alloc(blockRemain)) + this.end() + this[CLOSE](fd, _ => _) + return + } + + if (offset >= length) { + buf = Buffer.allocUnsafe(length) + offset = 0 + } + length = buf.length - offset + this[READ](fd, buf, offset, length, pos, remain, blockRemain) + } +}) + +class WriteEntrySync extends WriteEntry { + constructor (path, opt) { + super(path, opt) + } + + [LSTAT] () { + this[ONLSTAT](fs.lstatSync(this.absolute)) + } + + [SYMLINK] () { + this[ONREADLINK](fs.readlinkSync(this.absolute)) + } + + [OPENFILE] () { + this[ONOPENFILE](fs.openSync(this.absolute, 'r')) + } + + [READ] (fd, buf, offset, length, pos, remain, blockRemain) { + let threw = true + try { + const bytesRead = fs.readSync(fd, buf, offset, length, pos) + this[ONREAD](fd, buf, offset, length, pos, remain, blockRemain, bytesRead) + threw = false + } finally { + if (threw) + try { this[CLOSE](fd) } catch (er) {} + } + } + + [CLOSE] (fd) { + fs.closeSync(fd) + } +} + +const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { + constructor (readEntry, opt) { + opt = opt || {} + super(opt) + this.preservePaths = !!opt.preservePaths + this.portable = !!opt.portable + this.strict = !!opt.strict + this.noPax = !!opt.noPax + this.noMtime = !!opt.noMtime + + this.readEntry = readEntry + this.type = readEntry.type + if (this.type === 'Directory' && this.portable) + this.noMtime = true + + this.path = readEntry.path + this.mode = this[MODE](readEntry.mode) + this.uid = this.portable ? null : readEntry.uid + this.gid = this.portable ? null : readEntry.gid + this.uname = this.portable ? null : readEntry.uname + this.gname = this.portable ? null : readEntry.gname + this.size = readEntry.size + this.mtime = this.noMtime ? null : opt.mtime || readEntry.mtime + this.atime = this.portable ? null : readEntry.atime + this.ctime = this.portable ? null : readEntry.ctime + this.linkpath = readEntry.linkpath + + if (typeof opt.onwarn === 'function') + this.on('warn', opt.onwarn) + + if (path.isAbsolute(this.path) && !this.preservePaths) { + const parsed = path.parse(this.path) + this.warn( + 'stripping ' + parsed.root + ' from absolute path', + this.path + ) + this.path = this.path.substr(parsed.root.length) + } + + this.remain = readEntry.size + this.blockRemain = readEntry.startBlockSize + + this.header = new Header({ + path: this.path, + linkpath: this.linkpath, + // only the permissions and setuid/setgid/sticky bitflags + // not the higher-order bits that specify file type + mode: this.mode, + uid: this.portable ? null : this.uid, + gid: this.portable ? null : this.gid, + size: this.size, + mtime: this.noMtime ? null : this.mtime, + type: this.type, + uname: this.portable ? null : this.uname, + atime: this.portable ? null : this.atime, + ctime: this.portable ? null : this.ctime + }) + + if (this.header.encode() && !this.noPax) + super.write(new Pax({ + atime: this.portable ? null : this.atime, + ctime: this.portable ? null : this.ctime, + gid: this.portable ? null : this.gid, + mtime: this.noMtime ? null : this.mtime, + path: this.path, + linkpath: this.linkpath, + size: this.size, + uid: this.portable ? null : this.uid, + uname: this.portable ? null : this.uname, + dev: this.portable ? null : this.readEntry.dev, + ino: this.portable ? null : this.readEntry.ino, + nlink: this.portable ? null : this.readEntry.nlink + }).encode()) + + super.write(this.header.block) + readEntry.pipe(this) + } + + [MODE] (mode) { + return modeFix(mode, this.type === 'Directory') + } + + write (data) { + const writeLen = data.length + if (writeLen > this.blockRemain) + throw new Error('writing more to entry than is appropriate') + this.blockRemain -= writeLen + return super.write(data) + } + + end () { + if (this.blockRemain) + this.write(Buffer.alloc(this.blockRemain)) + return super.end() + } +}) + +WriteEntry.Sync = WriteEntrySync +WriteEntry.Tar = WriteEntryTar + +const getType = stat => + stat.isFile() ? 'File' + : stat.isDirectory() ? 'Directory' + : stat.isSymbolicLink() ? 'SymbolicLink' + : 'Unsupported' + +module.exports = WriteEntry + + +/***/ }), +/* 289 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const Buffer = __webpack_require__(277) +const Header = __webpack_require__(290) +const path = __webpack_require__(57) + +class Pax { + constructor (obj, global) { + this.atime = obj.atime || null + this.charset = obj.charset || null + this.comment = obj.comment || null + this.ctime = obj.ctime || null + this.gid = obj.gid || null + this.gname = obj.gname || null + this.linkpath = obj.linkpath || null + this.mtime = obj.mtime || null + this.path = obj.path || null + this.size = obj.size || null + this.uid = obj.uid || null + this.uname = obj.uname || null + this.dev = obj.dev || null + this.ino = obj.ino || null + this.nlink = obj.nlink || null + this.global = global || false + } + + encode () { + const body = this.encodeBody() + if (body === '') + return null + + const bodyLen = Buffer.byteLength(body) + // round up to 512 bytes + // add 512 for header + const bufLen = 512 * Math.ceil(1 + bodyLen / 512) + const buf = Buffer.allocUnsafe(bufLen) + + // 0-fill the header section, it might not hit every field + for (let i = 0; i < 512; i++) { + buf[i] = 0 + } + + new Header({ + // XXX split the path + // then the path should be PaxHeader + basename, but less than 99, + // prepend with the dirname + path: ('PaxHeader/' + path.basename(this.path)).slice(0, 99), + mode: this.mode || 0o644, + uid: this.uid || null, + gid: this.gid || null, + size: bodyLen, + mtime: this.mtime || null, + type: this.global ? 'GlobalExtendedHeader' : 'ExtendedHeader', + linkpath: '', + uname: this.uname || '', + gname: this.gname || '', + devmaj: 0, + devmin: 0, + atime: this.atime || null, + ctime: this.ctime || null + }).encode(buf) + + buf.write(body, 512, bodyLen, 'utf8') + + // null pad after the body + for (let i = bodyLen + 512; i < buf.length; i++) { + buf[i] = 0 + } + + return buf + } + + encodeBody () { + return ( + this.encodeField('path') + + this.encodeField('ctime') + + this.encodeField('atime') + + this.encodeField('dev') + + this.encodeField('ino') + + this.encodeField('nlink') + + this.encodeField('charset') + + this.encodeField('comment') + + this.encodeField('gid') + + this.encodeField('gname') + + this.encodeField('linkpath') + + this.encodeField('mtime') + + this.encodeField('size') + + this.encodeField('uid') + + this.encodeField('uname') + ) + } + + encodeField (field) { + if (this[field] === null || this[field] === undefined) + return '' + const v = this[field] instanceof Date ? this[field].getTime() / 1000 + : this[field] + const s = ' ' + + (field === 'dev' || field === 'ino' || field === 'nlink' + ? 'SCHILY.' : '') + + field + '=' + v + '\n' + const byteLen = Buffer.byteLength(s) + // the digits includes the length of the digits in ascii base-10 + // so if it's 9 characters, then adding 1 for the 9 makes it 10 + // which makes it 11 chars. + let digits = Math.floor(Math.log(byteLen) / Math.log(10)) + 1 + if (byteLen + digits >= Math.pow(10, digits)) + digits += 1 + const len = digits + byteLen + return len + s + } +} + +Pax.parse = (string, ex, g) => new Pax(merge(parseKV(string), ex), g) + +const merge = (a, b) => + b ? Object.keys(a).reduce((s, k) => (s[k] = a[k], s), b) : a + +const parseKV = string => + string + .replace(/\n$/, '') + .split('\n') + .reduce(parseKVLine, Object.create(null)) + +const parseKVLine = (set, line) => { + const n = parseInt(line, 10) + + // XXX Values with \n in them will fail this. + // Refactor to not be a naive line-by-line parse. + if (n !== Buffer.byteLength(line) + 1) + return set + + line = line.substr((n + ' ').length) + const kv = line.split('=') + const k = kv.shift().replace(/^SCHILY\.(dev|ino|nlink)/, '$1') + if (!k) + return set + + const v = kv.join('=') + set[k] = /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k) + ? new Date(v * 1000) + : /^[0-9]+$/.test(v) ? +v + : v + return set +} + +module.exports = Pax + + +/***/ }), +/* 290 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// parse a 512-byte header block to a data object, or vice-versa +// encode returns `true` if a pax extended header is needed, because +// the data could not be faithfully encoded in a simple header. +// (Also, check header.needPax to see if it needs a pax header.) + +const Buffer = __webpack_require__(277) +const types = __webpack_require__(287) +const pathModule = __webpack_require__(57).posix +const large = __webpack_require__(291) + +const SLURP = Symbol('slurp') +const TYPE = Symbol('type') + +class Header { + constructor (data, off, ex, gex) { + this.cksumValid = false + this.needPax = false + this.nullBlock = false + + this.block = null + this.path = null + this.mode = null + this.uid = null + this.gid = null + this.size = null + this.mtime = null + this.cksum = null + this[TYPE] = '0' + this.linkpath = null + this.uname = null + this.gname = null + this.devmaj = 0 + this.devmin = 0 + this.atime = null + this.ctime = null + + if (Buffer.isBuffer(data)) + this.decode(data, off || 0, ex, gex) + else if (data) + this.set(data) + } + + decode (buf, off, ex, gex) { + if (!off) + off = 0 + + if (!buf || !(buf.length >= off + 512)) + throw new Error('need 512 bytes for header') + + this.path = decString(buf, off, 100) + this.mode = decNumber(buf, off + 100, 8) + this.uid = decNumber(buf, off + 108, 8) + this.gid = decNumber(buf, off + 116, 8) + this.size = decNumber(buf, off + 124, 12) + this.mtime = decDate(buf, off + 136, 12) + this.cksum = decNumber(buf, off + 148, 12) + + // if we have extended or global extended headers, apply them now + // See https://github.com/npm/node-tar/pull/187 + this[SLURP](ex) + this[SLURP](gex, true) + + // old tar versions marked dirs as a file with a trailing / + this[TYPE] = decString(buf, off + 156, 1) + if (this[TYPE] === '') + this[TYPE] = '0' + if (this[TYPE] === '0' && this.path.substr(-1) === '/') + this[TYPE] = '5' + + // tar implementations sometimes incorrectly put the stat(dir).size + // as the size in the tarball, even though Directory entries are + // not able to have any body at all. In the very rare chance that + // it actually DOES have a body, we weren't going to do anything with + // it anyway, and it'll just be a warning about an invalid header. + if (this[TYPE] === '5') + this.size = 0 + + this.linkpath = decString(buf, off + 157, 100) + if (buf.slice(off + 257, off + 265).toString() === 'ustar\u000000') { + this.uname = decString(buf, off + 265, 32) + this.gname = decString(buf, off + 297, 32) + this.devmaj = decNumber(buf, off + 329, 8) + this.devmin = decNumber(buf, off + 337, 8) + if (buf[off + 475] !== 0) { + // definitely a prefix, definitely >130 chars. + const prefix = decString(buf, off + 345, 155) + this.path = prefix + '/' + this.path + } else { + const prefix = decString(buf, off + 345, 130) + if (prefix) + this.path = prefix + '/' + this.path + this.atime = decDate(buf, off + 476, 12) + this.ctime = decDate(buf, off + 488, 12) + } + } + + let sum = 8 * 0x20 + for (let i = off; i < off + 148; i++) { + sum += buf[i] + } + for (let i = off + 156; i < off + 512; i++) { + sum += buf[i] + } + this.cksumValid = sum === this.cksum + if (this.cksum === null && sum === 8 * 0x20) + this.nullBlock = true + } + + [SLURP] (ex, global) { + for (let k in ex) { + // we slurp in everything except for the path attribute in + // a global extended header, because that's weird. + if (ex[k] !== null && ex[k] !== undefined && + !(global && k === 'path')) + this[k] = ex[k] + } + } + + encode (buf, off) { + if (!buf) { + buf = this.block = Buffer.alloc(512) + off = 0 + } + + if (!off) + off = 0 + + if (!(buf.length >= off + 512)) + throw new Error('need 512 bytes for header') + + const prefixSize = this.ctime || this.atime ? 130 : 155 + const split = splitPrefix(this.path || '', prefixSize) + const path = split[0] + const prefix = split[1] + this.needPax = split[2] + + this.needPax = encString(buf, off, 100, path) || this.needPax + this.needPax = encNumber(buf, off + 100, 8, this.mode) || this.needPax + this.needPax = encNumber(buf, off + 108, 8, this.uid) || this.needPax + this.needPax = encNumber(buf, off + 116, 8, this.gid) || this.needPax + this.needPax = encNumber(buf, off + 124, 12, this.size) || this.needPax + this.needPax = encDate(buf, off + 136, 12, this.mtime) || this.needPax + buf[off + 156] = this[TYPE].charCodeAt(0) + this.needPax = encString(buf, off + 157, 100, this.linkpath) || this.needPax + buf.write('ustar\u000000', off + 257, 8) + this.needPax = encString(buf, off + 265, 32, this.uname) || this.needPax + this.needPax = encString(buf, off + 297, 32, this.gname) || this.needPax + this.needPax = encNumber(buf, off + 329, 8, this.devmaj) || this.needPax + this.needPax = encNumber(buf, off + 337, 8, this.devmin) || this.needPax + this.needPax = encString(buf, off + 345, prefixSize, prefix) || this.needPax + if (buf[off + 475] !== 0) + this.needPax = encString(buf, off + 345, 155, prefix) || this.needPax + else { + this.needPax = encString(buf, off + 345, 130, prefix) || this.needPax + this.needPax = encDate(buf, off + 476, 12, this.atime) || this.needPax + this.needPax = encDate(buf, off + 488, 12, this.ctime) || this.needPax + } + + let sum = 8 * 0x20 + for (let i = off; i < off + 148; i++) { + sum += buf[i] + } + for (let i = off + 156; i < off + 512; i++) { + sum += buf[i] + } + this.cksum = sum + encNumber(buf, off + 148, 8, this.cksum) + this.cksumValid = true + + return this.needPax + } + + set (data) { + for (let i in data) { + if (data[i] !== null && data[i] !== undefined) + this[i] = data[i] + } + } + + get type () { + return types.name.get(this[TYPE]) || this[TYPE] + } + + get typeKey () { + return this[TYPE] + } + + set type (type) { + if (types.code.has(type)) + this[TYPE] = types.code.get(type) + else + this[TYPE] = type + } +} + +const splitPrefix = (p, prefixSize) => { + const pathSize = 100 + let pp = p + let prefix = '' + let ret + const root = pathModule.parse(p).root || '.' + + if (Buffer.byteLength(pp) < pathSize) + ret = [pp, prefix, false] + else { + // first set prefix to the dir, and path to the base + prefix = pathModule.dirname(pp) + pp = pathModule.basename(pp) + + do { + // both fit! + if (Buffer.byteLength(pp) <= pathSize && + Buffer.byteLength(prefix) <= prefixSize) + ret = [pp, prefix, false] + + // prefix fits in prefix, but path doesn't fit in path + else if (Buffer.byteLength(pp) > pathSize && + Buffer.byteLength(prefix) <= prefixSize) + ret = [pp.substr(0, pathSize - 1), prefix, true] + + else { + // make path take a bit from prefix + pp = pathModule.join(pathModule.basename(prefix), pp) + prefix = pathModule.dirname(prefix) + } + } while (prefix !== root && !ret) + + // at this point, found no resolution, just truncate + if (!ret) + ret = [p.substr(0, pathSize - 1), '', true] + } + return ret +} + +const decString = (buf, off, size) => + buf.slice(off, off + size).toString('utf8').replace(/\0.*/, '') + +const decDate = (buf, off, size) => + numToDate(decNumber(buf, off, size)) + +const numToDate = num => num === null ? null : new Date(num * 1000) + +const decNumber = (buf, off, size) => + buf[off] & 0x80 ? large.parse(buf.slice(off, off + size)) + : decSmallNumber(buf, off, size) + +const nanNull = value => isNaN(value) ? null : value + +const decSmallNumber = (buf, off, size) => + nanNull(parseInt( + buf.slice(off, off + size) + .toString('utf8').replace(/\0.*$/, '').trim(), 8)) + +// the maximum encodable as a null-terminated octal, by field size +const MAXNUM = { + 12: 0o77777777777, + 8 : 0o7777777 +} + +const encNumber = (buf, off, size, number) => + number === null ? false : + number > MAXNUM[size] || number < 0 + ? (large.encode(number, buf.slice(off, off + size)), true) + : (encSmallNumber(buf, off, size, number), false) + +const encSmallNumber = (buf, off, size, number) => + buf.write(octalString(number, size), off, size, 'ascii') + +const octalString = (number, size) => + padOctal(Math.floor(number).toString(8), size) + +const padOctal = (string, size) => + (string.length === size - 1 ? string + : new Array(size - string.length - 1).join('0') + string + ' ') + '\0' + +const encDate = (buf, off, size, date) => + date === null ? false : + encNumber(buf, off, size, date.getTime() / 1000) + +// enough to fill the longest string we've got +const NULLS = new Array(156).join('\0') +// pad with nulls, return true if it's longer or non-ascii +const encString = (buf, off, size, string) => + string === null ? false : + (buf.write(string + NULLS, off, size, 'utf8'), + string.length !== Buffer.byteLength(string) || string.length > size) + +module.exports = Header + + +/***/ }), +/* 291 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// Tar can encode large and negative numbers using a leading byte of +// 0xff for negative, and 0x80 for positive. + +const encode = exports.encode = (num, buf) => { + if (!Number.isSafeInteger(num)) + // The number is so large that javascript cannot represent it with integer + // precision. + throw TypeError('cannot encode number outside of javascript safe integer range') + else if (num < 0) + encodeNegative(num, buf) + else + encodePositive(num, buf) + return buf +} + +const encodePositive = (num, buf) => { + buf[0] = 0x80 + + for (var i = buf.length; i > 1; i--) { + buf[i-1] = num & 0xff + num = Math.floor(num / 0x100) + } +} + +const encodeNegative = (num, buf) => { + buf[0] = 0xff + var flipped = false + num = num * -1 + for (var i = buf.length; i > 1; i--) { + var byte = num & 0xff + num = Math.floor(num / 0x100) + if (flipped) + buf[i-1] = onesComp(byte) + else if (byte === 0) + buf[i-1] = 0 + else { + flipped = true + buf[i-1] = twosComp(byte) + } + } +} + +const parse = exports.parse = (buf) => { + var post = buf[buf.length - 1] + var pre = buf[0] + var value; + if (pre === 0x80) + value = pos(buf.slice(1, buf.length)) + else if (pre === 0xff) + value = twos(buf) + else + throw TypeError('invalid base256 encoding') + + if (!Number.isSafeInteger(value)) + // The number is so large that javascript cannot represent it with integer + // precision. + throw TypeError('parsed number outside of javascript safe integer range') + + return value +} + +const twos = (buf) => { + var len = buf.length + var sum = 0 + var flipped = false + for (var i = len - 1; i > -1; i--) { + var byte = buf[i] + var f + if (flipped) + f = onesComp(byte) + else if (byte === 0) + f = byte + else { + flipped = true + f = twosComp(byte) + } + if (f !== 0) + sum -= f * Math.pow(256, len - i - 1) + } + return sum +} + +const pos = (buf) => { + var len = buf.length + var sum = 0 + for (var i = len - 1; i > -1; i--) { + var byte = buf[i] + if (byte !== 0) + sum += byte * Math.pow(256, len - i - 1) + } + return sum +} + +const onesComp = byte => (0xff ^ byte) & 0xff + +const twosComp = byte => ((0xff ^ byte) + 1) & 0xff + + +/***/ }), +/* 292 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = Base => class extends Base { + warn (msg, data) { + if (!this.strict) + this.emit('warn', msg, data) + else if (data instanceof Error) + this.emit('error', data) + else { + const er = new Error(msg) + er.data = data + this.emit('error', er) + } + } +} + + +/***/ }), +/* 293 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// When writing files on Windows, translate the characters to their +// 0xf000 higher-encoded versions. + +const raw = [ + '|', + '<', + '>', + '?', + ':' +] + +const win = raw.map(char => + String.fromCharCode(0xf000 + char.charCodeAt(0))) + +const toWin = new Map(raw.map((char, i) => [char, win[i]])) +const toRaw = new Map(win.map((char, i) => [char, raw[i]])) + +module.exports = { + encode: s => raw.reduce((s, c) => s.split(c).join(toWin.get(c)), s), + decode: s => win.reduce((s, c) => s.split(c).join(toRaw.get(c)), s) +} + + +/***/ }), +/* 294 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = (mode, isDir) => { + mode &= 0o7777 + // if dirs are readable, then they should be listable + if (isDir) { + if (mode & 0o400) + mode |= 0o100 + if (mode & 0o40) + mode |= 0o10 + if (mode & 0o4) + mode |= 0o1 + } + return mode +} + + +/***/ }), +/* 295 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const MiniPass = __webpack_require__(280) +const EE = __webpack_require__(49).EventEmitter +const fs = __webpack_require__(55) + +// for writev +const binding = process.binding('fs') +const writeBuffers = binding.writeBuffers +const FSReqWrap = binding.FSReqWrap || binding.FSReqCallback + +const _autoClose = Symbol('_autoClose') +const _close = Symbol('_close') +const _ended = Symbol('_ended') +const _fd = Symbol('_fd') +const _finished = Symbol('_finished') +const _flags = Symbol('_flags') +const _flush = Symbol('_flush') +const _handleChunk = Symbol('_handleChunk') +const _makeBuf = Symbol('_makeBuf') +const _mode = Symbol('_mode') +const _needDrain = Symbol('_needDrain') +const _onerror = Symbol('_onerror') +const _onopen = Symbol('_onopen') +const _onread = Symbol('_onread') +const _onwrite = Symbol('_onwrite') +const _open = Symbol('_open') +const _path = Symbol('_path') +const _pos = Symbol('_pos') +const _queue = Symbol('_queue') +const _read = Symbol('_read') +const _readSize = Symbol('_readSize') +const _reading = Symbol('_reading') +const _remain = Symbol('_remain') +const _size = Symbol('_size') +const _write = Symbol('_write') +const _writing = Symbol('_writing') +const _defaultFlag = Symbol('_defaultFlag') + +class ReadStream extends MiniPass { + constructor (path, opt) { + opt = opt || {} + super(opt) + + this.writable = false + + if (typeof path !== 'string') + throw new TypeError('path must be a string') + + this[_fd] = typeof opt.fd === 'number' ? opt.fd : null + this[_path] = path + this[_readSize] = opt.readSize || 16*1024*1024 + this[_reading] = false + this[_size] = typeof opt.size === 'number' ? opt.size : Infinity + this[_remain] = this[_size] + this[_autoClose] = typeof opt.autoClose === 'boolean' ? + opt.autoClose : true + + if (typeof this[_fd] === 'number') + this[_read]() + else + this[_open]() + } + + get fd () { return this[_fd] } + get path () { return this[_path] } + + write () { + throw new TypeError('this is a readable stream') + } + + end () { + throw new TypeError('this is a readable stream') + } + + [_open] () { + fs.open(this[_path], 'r', (er, fd) => this[_onopen](er, fd)) + } + + [_onopen] (er, fd) { + if (er) + this[_onerror](er) + else { + this[_fd] = fd + this.emit('open', fd) + this[_read]() + } + } + + [_makeBuf] () { + return Buffer.allocUnsafe(Math.min(this[_readSize], this[_remain])) + } + + [_read] () { + if (!this[_reading]) { + this[_reading] = true + const buf = this[_makeBuf]() + /* istanbul ignore if */ + if (buf.length === 0) return process.nextTick(() => this[_onread](null, 0, buf)) + fs.read(this[_fd], buf, 0, buf.length, null, (er, br, buf) => + this[_onread](er, br, buf)) + } + } + + [_onread] (er, br, buf) { + this[_reading] = false + if (er) + this[_onerror](er) + else if (this[_handleChunk](br, buf)) + this[_read]() + } + + [_close] () { + if (this[_autoClose] && typeof this[_fd] === 'number') { + fs.close(this[_fd], _ => this.emit('close')) + this[_fd] = null + } + } + + [_onerror] (er) { + this[_reading] = true + this[_close]() + this.emit('error', er) + } + + [_handleChunk] (br, buf) { + let ret = false + // no effect if infinite + this[_remain] -= br + if (br > 0) + ret = super.write(br < buf.length ? buf.slice(0, br) : buf) + + if (br === 0 || this[_remain] <= 0) { + ret = false + this[_close]() + super.end() + } + + return ret + } + + emit (ev, data) { + switch (ev) { + case 'prefinish': + case 'finish': + break + + case 'drain': + if (typeof this[_fd] === 'number') + this[_read]() + break + + default: + return super.emit(ev, data) + } + } +} + +class ReadStreamSync extends ReadStream { + [_open] () { + let threw = true + try { + this[_onopen](null, fs.openSync(this[_path], 'r')) + threw = false + } finally { + if (threw) + this[_close]() + } + } + + [_read] () { + let threw = true + try { + if (!this[_reading]) { + this[_reading] = true + do { + const buf = this[_makeBuf]() + /* istanbul ignore next */ + const br = buf.length === 0 ? 0 : fs.readSync(this[_fd], buf, 0, buf.length, null) + if (!this[_handleChunk](br, buf)) + break + } while (true) + this[_reading] = false + } + threw = false + } finally { + if (threw) + this[_close]() + } + } + + [_close] () { + if (this[_autoClose] && typeof this[_fd] === 'number') { + try { + fs.closeSync(this[_fd]) + } catch (er) {} + this[_fd] = null + this.emit('close') + } + } +} + +class WriteStream extends EE { + constructor (path, opt) { + opt = opt || {} + super(opt) + this.readable = false + this[_writing] = false + this[_ended] = false + this[_needDrain] = false + this[_queue] = [] + this[_path] = path + this[_fd] = typeof opt.fd === 'number' ? opt.fd : null + this[_mode] = opt.mode === undefined ? 0o666 : opt.mode + this[_pos] = typeof opt.start === 'number' ? opt.start : null + this[_autoClose] = typeof opt.autoClose === 'boolean' ? + opt.autoClose : true + + // truncating makes no sense when writing into the middle + const defaultFlag = this[_pos] !== null ? 'r+' : 'w' + this[_defaultFlag] = opt.flags === undefined + this[_flags] = this[_defaultFlag] ? defaultFlag : opt.flags + + if (this[_fd] === null) + this[_open]() + } + + get fd () { return this[_fd] } + get path () { return this[_path] } + + [_onerror] (er) { + this[_close]() + this[_writing] = true + this.emit('error', er) + } + + [_open] () { + fs.open(this[_path], this[_flags], this[_mode], + (er, fd) => this[_onopen](er, fd)) + } + + [_onopen] (er, fd) { + if (this[_defaultFlag] && + this[_flags] === 'r+' && + er && er.code === 'ENOENT') { + this[_flags] = 'w' + this[_open]() + } else if (er) + this[_onerror](er) + else { + this[_fd] = fd + this.emit('open', fd) + this[_flush]() + } + } + + end (buf, enc) { + if (buf) + this.write(buf, enc) + + this[_ended] = true + + // synthetic after-write logic, where drain/finish live + if (!this[_writing] && !this[_queue].length && + typeof this[_fd] === 'number') + this[_onwrite](null, 0) + } + + write (buf, enc) { + if (typeof buf === 'string') + buf = new Buffer(buf, enc) + + if (this[_ended]) { + this.emit('error', new Error('write() after end()')) + return false + } + + if (this[_fd] === null || this[_writing] || this[_queue].length) { + this[_queue].push(buf) + this[_needDrain] = true + return false + } + + this[_writing] = true + this[_write](buf) + return true + } + + [_write] (buf) { + fs.write(this[_fd], buf, 0, buf.length, this[_pos], (er, bw) => + this[_onwrite](er, bw)) + } + + [_onwrite] (er, bw) { + if (er) + this[_onerror](er) + else { + if (this[_pos] !== null) + this[_pos] += bw + if (this[_queue].length) + this[_flush]() + else { + this[_writing] = false + + if (this[_ended] && !this[_finished]) { + this[_finished] = true + this[_close]() + this.emit('finish') + } else if (this[_needDrain]) { + this[_needDrain] = false + this.emit('drain') + } + } + } + } + + [_flush] () { + if (this[_queue].length === 0) { + if (this[_ended]) + this[_onwrite](null, 0) + } else if (this[_queue].length === 1) + this[_write](this[_queue].pop()) + else { + const iovec = this[_queue] + this[_queue] = [] + writev(this[_fd], iovec, this[_pos], + (er, bw) => this[_onwrite](er, bw)) + } + } + + [_close] () { + if (this[_autoClose] && typeof this[_fd] === 'number') { + fs.close(this[_fd], _ => this.emit('close')) + this[_fd] = null + } + } +} + +class WriteStreamSync extends WriteStream { + [_open] () { + let fd + try { + fd = fs.openSync(this[_path], this[_flags], this[_mode]) + } catch (er) { + if (this[_defaultFlag] && + this[_flags] === 'r+' && + er && er.code === 'ENOENT') { + this[_flags] = 'w' + return this[_open]() + } else + throw er + } + this[_onopen](null, fd) + } + + [_close] () { + if (this[_autoClose] && typeof this[_fd] === 'number') { + try { + fs.closeSync(this[_fd]) + } catch (er) {} + this[_fd] = null + this.emit('close') + } + } + + [_write] (buf) { + try { + this[_onwrite](null, + fs.writeSync(this[_fd], buf, 0, buf.length, this[_pos])) + } catch (er) { + this[_onwrite](er, 0) + } + } +} + +const writev = (fd, iovec, pos, cb) => { + const done = (er, bw) => cb(er, bw, iovec) + const req = new FSReqWrap() + req.oncomplete = done + binding.writeBuffers(fd, iovec, pos, req) +} + +exports.ReadStream = ReadStream +exports.ReadStreamSync = ReadStreamSync + +exports.WriteStream = WriteStream +exports.WriteStreamSync = WriteStreamSync + + +/***/ }), +/* 296 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const Buffer = __webpack_require__(277) + +// XXX: This shares a lot in common with extract.js +// maybe some DRY opportunity here? + +// tar -t +const hlo = __webpack_require__(275) +const Parser = __webpack_require__(297) +const fs = __webpack_require__(55) +const fsm = __webpack_require__(295) +const path = __webpack_require__(57) + +const t = module.exports = (opt_, files, cb) => { + if (typeof opt_ === 'function') + cb = opt_, files = null, opt_ = {} + else if (Array.isArray(opt_)) + files = opt_, opt_ = {} + + if (typeof files === 'function') + cb = files, files = null + + if (!files) + files = [] + else + files = Array.from(files) + + const opt = hlo(opt_) + + if (opt.sync && typeof cb === 'function') + throw new TypeError('callback not supported for sync tar functions') + + if (!opt.file && typeof cb === 'function') + throw new TypeError('callback only supported with file option') + + if (files.length) + filesFilter(opt, files) + + if (!opt.noResume) + onentryFunction(opt) + + return opt.file && opt.sync ? listFileSync(opt) + : opt.file ? listFile(opt, cb) + : list(opt) +} + +const onentryFunction = opt => { + const onentry = opt.onentry + opt.onentry = onentry ? e => { + onentry(e) + e.resume() + } : e => e.resume() +} + +// construct a filter that limits the file entries listed +// include child entries if a dir is included +const filesFilter = (opt, files) => { + const map = new Map(files.map(f => [f.replace(/\/+$/, ''), true])) + const filter = opt.filter + + const mapHas = (file, r) => { + const root = r || path.parse(file).root || '.' + const ret = file === root ? false + : map.has(file) ? map.get(file) + : mapHas(path.dirname(file), root) + + map.set(file, ret) + return ret + } + + opt.filter = filter + ? (file, entry) => filter(file, entry) && mapHas(file.replace(/\/+$/, '')) + : file => mapHas(file.replace(/\/+$/, '')) +} + +const listFileSync = opt => { + const p = list(opt) + const file = opt.file + let threw = true + let fd + try { + const stat = fs.statSync(file) + const readSize = opt.maxReadSize || 16*1024*1024 + if (stat.size < readSize) { + p.end(fs.readFileSync(file)) + } else { + let pos = 0 + const buf = Buffer.allocUnsafe(readSize) + fd = fs.openSync(file, 'r') + while (pos < stat.size) { + let bytesRead = fs.readSync(fd, buf, 0, readSize, pos) + pos += bytesRead + p.write(buf.slice(0, bytesRead)) + } + p.end() + } + threw = false + } finally { + if (threw && fd) + try { fs.closeSync(fd) } catch (er) {} + } +} + +const listFile = (opt, cb) => { + const parse = new Parser(opt) + const readSize = opt.maxReadSize || 16*1024*1024 + + const file = opt.file + const p = new Promise((resolve, reject) => { + parse.on('error', reject) + parse.on('end', resolve) + + fs.stat(file, (er, stat) => { + if (er) + reject(er) + else { + const stream = new fsm.ReadStream(file, { + readSize: readSize, + size: stat.size + }) + stream.on('error', reject) + stream.pipe(parse) + } + }) + }) + return cb ? p.then(cb, cb) : p +} + +const list = opt => new Parser(opt) + + +/***/ }), +/* 297 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// this[BUFFER] is the remainder of a chunk if we're waiting for +// the full 512 bytes of a header to come in. We will Buffer.concat() +// it to the next write(), which is a mem copy, but a small one. +// +// this[QUEUE] is a Yallist of entries that haven't been emitted +// yet this can only get filled up if the user keeps write()ing after +// a write() returns false, or does a write() with more than one entry +// +// We don't buffer chunks, we always parse them and either create an +// entry, or push it into the active entry. The ReadEntry class knows +// to throw data away if .ignore=true +// +// Shift entry off the buffer when it emits 'end', and emit 'entry' for +// the next one in the list. +// +// At any time, we're pushing body chunks into the entry at WRITEENTRY, +// and waiting for 'end' on the entry at READENTRY +// +// ignored entries get .resume() called on them straight away + +const warner = __webpack_require__(292) +const path = __webpack_require__(57) +const Header = __webpack_require__(290) +const EE = __webpack_require__(49) +const Yallist = __webpack_require__(281) +const maxMetaEntrySize = 1024 * 1024 +const Entry = __webpack_require__(286) +const Pax = __webpack_require__(289) +const zlib = __webpack_require__(284) +const Buffer = __webpack_require__(277) + +const gzipHeader = Buffer.from([0x1f, 0x8b]) +const STATE = Symbol('state') +const WRITEENTRY = Symbol('writeEntry') +const READENTRY = Symbol('readEntry') +const NEXTENTRY = Symbol('nextEntry') +const PROCESSENTRY = Symbol('processEntry') +const EX = Symbol('extendedHeader') +const GEX = Symbol('globalExtendedHeader') +const META = Symbol('meta') +const EMITMETA = Symbol('emitMeta') +const BUFFER = Symbol('buffer') +const QUEUE = Symbol('queue') +const ENDED = Symbol('ended') +const EMITTEDEND = Symbol('emittedEnd') +const EMIT = Symbol('emit') +const UNZIP = Symbol('unzip') +const CONSUMECHUNK = Symbol('consumeChunk') +const CONSUMECHUNKSUB = Symbol('consumeChunkSub') +const CONSUMEBODY = Symbol('consumeBody') +const CONSUMEMETA = Symbol('consumeMeta') +const CONSUMEHEADER = Symbol('consumeHeader') +const CONSUMING = Symbol('consuming') +const BUFFERCONCAT = Symbol('bufferConcat') +const MAYBEEND = Symbol('maybeEnd') +const WRITING = Symbol('writing') +const ABORTED = Symbol('aborted') +const DONE = Symbol('onDone') + +const noop = _ => true + +module.exports = warner(class Parser extends EE { + constructor (opt) { + opt = opt || {} + super(opt) + + if (opt.ondone) + this.on(DONE, opt.ondone) + else + this.on(DONE, _ => { + this.emit('prefinish') + this.emit('finish') + this.emit('end') + this.emit('close') + }) + + this.strict = !!opt.strict + this.maxMetaEntrySize = opt.maxMetaEntrySize || maxMetaEntrySize + this.filter = typeof opt.filter === 'function' ? opt.filter : noop + + // have to set this so that streams are ok piping into it + this.writable = true + this.readable = false + + this[QUEUE] = new Yallist() + this[BUFFER] = null + this[READENTRY] = null + this[WRITEENTRY] = null + this[STATE] = 'begin' + this[META] = '' + this[EX] = null + this[GEX] = null + this[ENDED] = false + this[UNZIP] = null + this[ABORTED] = false + if (typeof opt.onwarn === 'function') + this.on('warn', opt.onwarn) + if (typeof opt.onentry === 'function') + this.on('entry', opt.onentry) + } + + [CONSUMEHEADER] (chunk, position) { + const header = new Header(chunk, position, this[EX], this[GEX]) + + if (header.nullBlock) + this[EMIT]('nullBlock') + else if (!header.cksumValid) + this.warn('invalid entry', header) + else if (!header.path) + this.warn('invalid: path is required', header) + else { + const type = header.type + if (/^(Symbolic)?Link$/.test(type) && !header.linkpath) + this.warn('invalid: linkpath required', header) + else if (!/^(Symbolic)?Link$/.test(type) && header.linkpath) + this.warn('invalid: linkpath forbidden', header) + else { + const entry = this[WRITEENTRY] = new Entry(header, this[EX], this[GEX]) + + if (entry.meta) { + if (entry.size > this.maxMetaEntrySize) { + entry.ignore = true + this[EMIT]('ignoredEntry', entry) + this[STATE] = 'ignore' + } else if (entry.size > 0) { + this[META] = '' + entry.on('data', c => this[META] += c) + this[STATE] = 'meta' + } + } else { + + this[EX] = null + entry.ignore = entry.ignore || !this.filter(entry.path, entry) + if (entry.ignore) { + this[EMIT]('ignoredEntry', entry) + this[STATE] = entry.remain ? 'ignore' : 'begin' + } else { + if (entry.remain) + this[STATE] = 'body' + else { + this[STATE] = 'begin' + entry.end() + } + + if (!this[READENTRY]) { + this[QUEUE].push(entry) + this[NEXTENTRY]() + } else + this[QUEUE].push(entry) + } + } + } + } + } + + [PROCESSENTRY] (entry) { + let go = true + + if (!entry) { + this[READENTRY] = null + go = false + } else if (Array.isArray(entry)) + this.emit.apply(this, entry) + else { + this[READENTRY] = entry + this.emit('entry', entry) + if (!entry.emittedEnd) { + entry.on('end', _ => this[NEXTENTRY]()) + go = false + } + } + + return go + } + + [NEXTENTRY] () { + do {} while (this[PROCESSENTRY](this[QUEUE].shift())) + + if (!this[QUEUE].length) { + // At this point, there's nothing in the queue, but we may have an + // entry which is being consumed (readEntry). + // If we don't, then we definitely can handle more data. + // If we do, and either it's flowing, or it has never had any data + // written to it, then it needs more. + // The only other possibility is that it has returned false from a + // write() call, so we wait for the next drain to continue. + const re = this[READENTRY] + const drainNow = !re || re.flowing || re.size === re.remain + if (drainNow) { + if (!this[WRITING]) + this.emit('drain') + } else + re.once('drain', _ => this.emit('drain')) + } + } + + [CONSUMEBODY] (chunk, position) { + // write up to but no more than writeEntry.blockRemain + const entry = this[WRITEENTRY] + const br = entry.blockRemain + const c = (br >= chunk.length && position === 0) ? chunk + : chunk.slice(position, position + br) + + entry.write(c) + + if (!entry.blockRemain) { + this[STATE] = 'begin' + this[WRITEENTRY] = null + entry.end() + } + + return c.length + } + + [CONSUMEMETA] (chunk, position) { + const entry = this[WRITEENTRY] + const ret = this[CONSUMEBODY](chunk, position) + + // if we finished, then the entry is reset + if (!this[WRITEENTRY]) + this[EMITMETA](entry) + + return ret + } + + [EMIT] (ev, data, extra) { + if (!this[QUEUE].length && !this[READENTRY]) + this.emit(ev, data, extra) + else + this[QUEUE].push([ev, data, extra]) + } + + [EMITMETA] (entry) { + this[EMIT]('meta', this[META]) + switch (entry.type) { + case 'ExtendedHeader': + case 'OldExtendedHeader': + this[EX] = Pax.parse(this[META], this[EX], false) + break + + case 'GlobalExtendedHeader': + this[GEX] = Pax.parse(this[META], this[GEX], true) + break + + case 'NextFileHasLongPath': + case 'OldGnuLongPath': + this[EX] = this[EX] || Object.create(null) + this[EX].path = this[META].replace(/\0.*/, '') + break + + case 'NextFileHasLongLinkpath': + this[EX] = this[EX] || Object.create(null) + this[EX].linkpath = this[META].replace(/\0.*/, '') + break + + /* istanbul ignore next */ + default: throw new Error('unknown meta: ' + entry.type) + } + } + + abort (msg, error) { + this[ABORTED] = true + this.warn(msg, error) + this.emit('abort', error) + this.emit('error', error) + } + + write (chunk) { + if (this[ABORTED]) + return + + // first write, might be gzipped + if (this[UNZIP] === null && chunk) { + if (this[BUFFER]) { + chunk = Buffer.concat([this[BUFFER], chunk]) + this[BUFFER] = null + } + if (chunk.length < gzipHeader.length) { + this[BUFFER] = chunk + return true + } + for (let i = 0; this[UNZIP] === null && i < gzipHeader.length; i++) { + if (chunk[i] !== gzipHeader[i]) + this[UNZIP] = false + } + if (this[UNZIP] === null) { + const ended = this[ENDED] + this[ENDED] = false + this[UNZIP] = new zlib.Unzip() + this[UNZIP].on('data', chunk => this[CONSUMECHUNK](chunk)) + this[UNZIP].on('error', er => + this.abort(er.message, er)) + this[UNZIP].on('end', _ => { + this[ENDED] = true + this[CONSUMECHUNK]() + }) + this[WRITING] = true + const ret = this[UNZIP][ended ? 'end' : 'write' ](chunk) + this[WRITING] = false + return ret + } + } + + this[WRITING] = true + if (this[UNZIP]) + this[UNZIP].write(chunk) + else + this[CONSUMECHUNK](chunk) + this[WRITING] = false + + // return false if there's a queue, or if the current entry isn't flowing + const ret = + this[QUEUE].length ? false : + this[READENTRY] ? this[READENTRY].flowing : + true + + // if we have no queue, then that means a clogged READENTRY + if (!ret && !this[QUEUE].length) + this[READENTRY].once('drain', _ => this.emit('drain')) + + return ret + } + + [BUFFERCONCAT] (c) { + if (c && !this[ABORTED]) + this[BUFFER] = this[BUFFER] ? Buffer.concat([this[BUFFER], c]) : c + } + + [MAYBEEND] () { + if (this[ENDED] && + !this[EMITTEDEND] && + !this[ABORTED] && + !this[CONSUMING]) { + this[EMITTEDEND] = true + const entry = this[WRITEENTRY] + if (entry && entry.blockRemain) { + const have = this[BUFFER] ? this[BUFFER].length : 0 + this.warn('Truncated input (needed ' + entry.blockRemain + + ' more bytes, only ' + have + ' available)', entry) + if (this[BUFFER]) + entry.write(this[BUFFER]) + entry.end() + } + this[EMIT](DONE) + } + } + + [CONSUMECHUNK] (chunk) { + if (this[CONSUMING]) { + this[BUFFERCONCAT](chunk) + } else if (!chunk && !this[BUFFER]) { + this[MAYBEEND]() + } else { + this[CONSUMING] = true + if (this[BUFFER]) { + this[BUFFERCONCAT](chunk) + const c = this[BUFFER] + this[BUFFER] = null + this[CONSUMECHUNKSUB](c) + } else { + this[CONSUMECHUNKSUB](chunk) + } + + while (this[BUFFER] && this[BUFFER].length >= 512 && !this[ABORTED]) { + const c = this[BUFFER] + this[BUFFER] = null + this[CONSUMECHUNKSUB](c) + } + this[CONSUMING] = false + } + + if (!this[BUFFER] || this[ENDED]) + this[MAYBEEND]() + } + + [CONSUMECHUNKSUB] (chunk) { + // we know that we are in CONSUMING mode, so anything written goes into + // the buffer. Advance the position and put any remainder in the buffer. + let position = 0 + let length = chunk.length + while (position + 512 <= length && !this[ABORTED]) { + switch (this[STATE]) { + case 'begin': + this[CONSUMEHEADER](chunk, position) + position += 512 + break + + case 'ignore': + case 'body': + position += this[CONSUMEBODY](chunk, position) + break + + case 'meta': + position += this[CONSUMEMETA](chunk, position) + break + + /* istanbul ignore next */ + default: + throw new Error('invalid state: ' + this[STATE]) + } + } + + if (position < length) { + if (this[BUFFER]) + this[BUFFER] = Buffer.concat([chunk.slice(position), this[BUFFER]]) + else + this[BUFFER] = chunk.slice(position) + } + } + + end (chunk) { + if (!this[ABORTED]) { + if (this[UNZIP]) + this[UNZIP].end(chunk) + else { + this[ENDED] = true + this.write(chunk) + } + } + } +}) + + +/***/ }), +/* 298 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const Buffer = __webpack_require__(277) + +// tar -r +const hlo = __webpack_require__(275) +const Pack = __webpack_require__(276) +const Parse = __webpack_require__(297) +const fs = __webpack_require__(55) +const fsm = __webpack_require__(295) +const t = __webpack_require__(296) +const path = __webpack_require__(57) + +// starting at the head of the file, read a Header +// If the checksum is invalid, that's our position to start writing +// If it is, jump forward by the specified size (round up to 512) +// and try again. +// Write the new Pack stream starting there. + +const Header = __webpack_require__(290) + +const r = module.exports = (opt_, files, cb) => { + const opt = hlo(opt_) + + if (!opt.file) + throw new TypeError('file is required') + + if (opt.gzip) + throw new TypeError('cannot append to compressed archives') + + if (!files || !Array.isArray(files) || !files.length) + throw new TypeError('no files or directories specified') + + files = Array.from(files) + + return opt.sync ? replaceSync(opt, files) + : replace(opt, files, cb) +} + +const replaceSync = (opt, files) => { + const p = new Pack.Sync(opt) + + let threw = true + let fd + let position + + try { + try { + fd = fs.openSync(opt.file, 'r+') + } catch (er) { + if (er.code === 'ENOENT') + fd = fs.openSync(opt.file, 'w+') + else + throw er + } + + const st = fs.fstatSync(fd) + const headBuf = Buffer.alloc(512) + + POSITION: for (position = 0; position < st.size; position += 512) { + for (let bufPos = 0, bytes = 0; bufPos < 512; bufPos += bytes) { + bytes = fs.readSync( + fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos + ) + + if (position === 0 && headBuf[0] === 0x1f && headBuf[1] === 0x8b) + throw new Error('cannot append to compressed archives') + + if (!bytes) + break POSITION + } + + let h = new Header(headBuf) + if (!h.cksumValid) + break + let entryBlockSize = 512 * Math.ceil(h.size / 512) + if (position + entryBlockSize + 512 > st.size) + break + // the 512 for the header we just parsed will be added as well + // also jump ahead all the blocks for the body + position += entryBlockSize + if (opt.mtimeCache) + opt.mtimeCache.set(h.path, h.mtime) + } + threw = false + + streamSync(opt, p, position, fd, files) + } finally { + if (threw) + try { fs.closeSync(fd) } catch (er) {} + } +} + +const streamSync = (opt, p, position, fd, files) => { + const stream = new fsm.WriteStreamSync(opt.file, { + fd: fd, + start: position + }) + p.pipe(stream) + addFilesSync(p, files) +} + +const replace = (opt, files, cb) => { + files = Array.from(files) + const p = new Pack(opt) + + const getPos = (fd, size, cb_) => { + const cb = (er, pos) => { + if (er) + fs.close(fd, _ => cb_(er)) + else + cb_(null, pos) + } + + let position = 0 + if (size === 0) + return cb(null, 0) + + let bufPos = 0 + const headBuf = Buffer.alloc(512) + const onread = (er, bytes) => { + if (er) + return cb(er) + bufPos += bytes + if (bufPos < 512 && bytes) + return fs.read( + fd, headBuf, bufPos, headBuf.length - bufPos, + position + bufPos, onread + ) + + if (position === 0 && headBuf[0] === 0x1f && headBuf[1] === 0x8b) + return cb(new Error('cannot append to compressed archives')) + + // truncated header + if (bufPos < 512) + return cb(null, position) + + const h = new Header(headBuf) + if (!h.cksumValid) + return cb(null, position) + + const entryBlockSize = 512 * Math.ceil(h.size / 512) + if (position + entryBlockSize + 512 > size) + return cb(null, position) + + position += entryBlockSize + 512 + if (position >= size) + return cb(null, position) + + if (opt.mtimeCache) + opt.mtimeCache.set(h.path, h.mtime) + bufPos = 0 + fs.read(fd, headBuf, 0, 512, position, onread) + } + fs.read(fd, headBuf, 0, 512, position, onread) + } + + const promise = new Promise((resolve, reject) => { + p.on('error', reject) + let flag = 'r+' + const onopen = (er, fd) => { + if (er && er.code === 'ENOENT' && flag === 'r+') { + flag = 'w+' + return fs.open(opt.file, flag, onopen) + } + + if (er) + return reject(er) + + fs.fstat(fd, (er, st) => { + if (er) + return reject(er) + getPos(fd, st.size, (er, position) => { + if (er) + return reject(er) + const stream = new fsm.WriteStream(opt.file, { + fd: fd, + start: position + }) + p.pipe(stream) + stream.on('error', reject) + stream.on('close', resolve) + addFilesAsync(p, files) + }) + }) + } + fs.open(opt.file, flag, onopen) + }) + + return cb ? promise.then(cb, cb) : promise +} + +const addFilesSync = (p, files) => { + files.forEach(file => { + if (file.charAt(0) === '@') + t({ + file: path.resolve(p.cwd, file.substr(1)), + sync: true, + noResume: true, + onentry: entry => p.add(entry) + }) + else + p.add(file) + }) + p.end() +} + +const addFilesAsync = (p, files) => { + while (files.length) { + const file = files.shift() + if (file.charAt(0) === '@') + return t({ + file: path.resolve(p.cwd, file.substr(1)), + noResume: true, + onentry: entry => p.add(entry) + }).then(_ => addFilesAsync(p, files)) + else + p.add(file) + } + p.end() +} + + +/***/ }), +/* 299 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// tar -u + +const hlo = __webpack_require__(275) +const r = __webpack_require__(298) +// just call tar.r with the filter and mtimeCache + +const u = module.exports = (opt_, files, cb) => { + const opt = hlo(opt_) + + if (!opt.file) + throw new TypeError('file is required') + + if (opt.gzip) + throw new TypeError('cannot append to compressed archives') + + if (!files || !Array.isArray(files) || !files.length) + throw new TypeError('no files or directories specified') + + files = Array.from(files) + + mtimeFilter(opt) + return r(opt, files, cb) +} + +const mtimeFilter = opt => { + const filter = opt.filter + + if (!opt.mtimeCache) + opt.mtimeCache = new Map() + + opt.filter = filter ? (path, stat) => + filter(path, stat) && !(opt.mtimeCache.get(path) > stat.mtime) + : (path, stat) => !(opt.mtimeCache.get(path) > stat.mtime) +} + + +/***/ }), +/* 300 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// tar -x +const hlo = __webpack_require__(275) +const Unpack = __webpack_require__(301) +const fs = __webpack_require__(55) +const fsm = __webpack_require__(295) +const path = __webpack_require__(57) + +const x = module.exports = (opt_, files, cb) => { + if (typeof opt_ === 'function') + cb = opt_, files = null, opt_ = {} + else if (Array.isArray(opt_)) + files = opt_, opt_ = {} + + if (typeof files === 'function') + cb = files, files = null + + if (!files) + files = [] + else + files = Array.from(files) + + const opt = hlo(opt_) + + if (opt.sync && typeof cb === 'function') + throw new TypeError('callback not supported for sync tar functions') + + if (!opt.file && typeof cb === 'function') + throw new TypeError('callback only supported with file option') + + if (files.length) + filesFilter(opt, files) + + return opt.file && opt.sync ? extractFileSync(opt) + : opt.file ? extractFile(opt, cb) + : opt.sync ? extractSync(opt) + : extract(opt) +} + +// construct a filter that limits the file entries listed +// include child entries if a dir is included +const filesFilter = (opt, files) => { + const map = new Map(files.map(f => [f.replace(/\/+$/, ''), true])) + const filter = opt.filter + + const mapHas = (file, r) => { + const root = r || path.parse(file).root || '.' + const ret = file === root ? false + : map.has(file) ? map.get(file) + : mapHas(path.dirname(file), root) + + map.set(file, ret) + return ret + } + + opt.filter = filter + ? (file, entry) => filter(file, entry) && mapHas(file.replace(/\/+$/, '')) + : file => mapHas(file.replace(/\/+$/, '')) +} + +const extractFileSync = opt => { + const u = new Unpack.Sync(opt) + + const file = opt.file + let threw = true + let fd + const stat = fs.statSync(file) + // This trades a zero-byte read() syscall for a stat + // However, it will usually result in less memory allocation + const readSize = opt.maxReadSize || 16*1024*1024 + const stream = new fsm.ReadStreamSync(file, { + readSize: readSize, + size: stat.size + }) + stream.pipe(u) +} + +const extractFile = (opt, cb) => { + const u = new Unpack(opt) + const readSize = opt.maxReadSize || 16*1024*1024 + + const file = opt.file + const p = new Promise((resolve, reject) => { + u.on('error', reject) + u.on('close', resolve) + + // This trades a zero-byte read() syscall for a stat + // However, it will usually result in less memory allocation + fs.stat(file, (er, stat) => { + if (er) + reject(er) + else { + const stream = new fsm.ReadStream(file, { + readSize: readSize, + size: stat.size + }) + stream.on('error', reject) + stream.pipe(u) + } + }) + }) + return cb ? p.then(cb, cb) : p +} + +const extractSync = opt => { + return new Unpack.Sync(opt) +} + +const extract = opt => { + return new Unpack(opt) +} + + +/***/ }), +/* 301 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const assert = __webpack_require__(101) +const EE = __webpack_require__(49).EventEmitter +const Parser = __webpack_require__(297) +const fs = __webpack_require__(55) +const fsm = __webpack_require__(295) +const path = __webpack_require__(57) +const mkdir = __webpack_require__(302) +const mkdirSync = mkdir.sync +const wc = __webpack_require__(293) + +const ONENTRY = Symbol('onEntry') +const CHECKFS = Symbol('checkFs') +const ISREUSABLE = Symbol('isReusable') +const MAKEFS = Symbol('makeFs') +const FILE = Symbol('file') +const DIRECTORY = Symbol('directory') +const LINK = Symbol('link') +const SYMLINK = Symbol('symlink') +const HARDLINK = Symbol('hardlink') +const UNSUPPORTED = Symbol('unsupported') +const UNKNOWN = Symbol('unknown') +const CHECKPATH = Symbol('checkPath') +const MKDIR = Symbol('mkdir') +const ONERROR = Symbol('onError') +const PENDING = Symbol('pending') +const PEND = Symbol('pend') +const UNPEND = Symbol('unpend') +const ENDED = Symbol('ended') +const MAYBECLOSE = Symbol('maybeClose') +const SKIP = Symbol('skip') +const DOCHOWN = Symbol('doChown') +const UID = Symbol('uid') +const GID = Symbol('gid') +const crypto = __webpack_require__(159) + +// Unlinks on Windows are not atomic. +// +// This means that if you have a file entry, followed by another +// file entry with an identical name, and you cannot re-use the file +// (because it's a hardlink, or because unlink:true is set, or it's +// Windows, which does not have useful nlink values), then the unlink +// will be committed to the disk AFTER the new file has been written +// over the old one, deleting the new file. +// +// To work around this, on Windows systems, we rename the file and then +// delete the renamed file. It's a sloppy kludge, but frankly, I do not +// know of a better way to do this, given windows' non-atomic unlink +// semantics. +// +// See: https://github.com/npm/node-tar/issues/183 +/* istanbul ignore next */ +const unlinkFile = (path, cb) => { + if (process.platform !== 'win32') + return fs.unlink(path, cb) + + const name = path + '.DELETE.' + crypto.randomBytes(16).toString('hex') + fs.rename(path, name, er => { + if (er) + return cb(er) + fs.unlink(name, cb) + }) +} + +/* istanbul ignore next */ +const unlinkFileSync = path => { + if (process.platform !== 'win32') + return fs.unlinkSync(path) + + const name = path + '.DELETE.' + crypto.randomBytes(16).toString('hex') + fs.renameSync(path, name) + fs.unlinkSync(name) +} + +// this.gid, entry.gid, this.processUid +const uint32 = (a, b, c) => + a === a >>> 0 ? a + : b === b >>> 0 ? b + : c + +class Unpack extends Parser { + constructor (opt) { + if (!opt) + opt = {} + + opt.ondone = _ => { + this[ENDED] = true + this[MAYBECLOSE]() + } + + super(opt) + + this.transform = typeof opt.transform === 'function' ? opt.transform : null + + this.writable = true + this.readable = false + + this[PENDING] = 0 + this[ENDED] = false + + this.dirCache = opt.dirCache || new Map() + + if (typeof opt.uid === 'number' || typeof opt.gid === 'number') { + // need both or neither + if (typeof opt.uid !== 'number' || typeof opt.gid !== 'number') + throw new TypeError('cannot set owner without number uid and gid') + if (opt.preserveOwner) + throw new TypeError( + 'cannot preserve owner in archive and also set owner explicitly') + this.uid = opt.uid + this.gid = opt.gid + this.setOwner = true + } else { + this.uid = null + this.gid = null + this.setOwner = false + } + + // default true for root + if (opt.preserveOwner === undefined && typeof opt.uid !== 'number') + this.preserveOwner = process.getuid && process.getuid() === 0 + else + this.preserveOwner = !!opt.preserveOwner + + this.processUid = (this.preserveOwner || this.setOwner) && process.getuid ? + process.getuid() : null + this.processGid = (this.preserveOwner || this.setOwner) && process.getgid ? + process.getgid() : null + + // mostly just for testing, but useful in some cases. + // Forcibly trigger a chown on every entry, no matter what + this.forceChown = opt.forceChown === true + + // turn > this[ONENTRY](entry)) + } + + [MAYBECLOSE] () { + if (this[ENDED] && this[PENDING] === 0) { + this.emit('prefinish') + this.emit('finish') + this.emit('end') + this.emit('close') + } + } + + [CHECKPATH] (entry) { + if (this.strip) { + const parts = entry.path.split(/\/|\\/) + if (parts.length < this.strip) + return false + entry.path = parts.slice(this.strip).join('/') + + if (entry.type === 'Link') { + const linkparts = entry.linkpath.split(/\/|\\/) + if (linkparts.length >= this.strip) + entry.linkpath = linkparts.slice(this.strip).join('/') + } + } + + if (!this.preservePaths) { + const p = entry.path + if (p.match(/(^|\/|\\)\.\.(\\|\/|$)/)) { + this.warn('path contains \'..\'', p) + return false + } + + // absolutes on posix are also absolutes on win32 + // so we only need to test this one to get both + if (path.win32.isAbsolute(p)) { + const parsed = path.win32.parse(p) + this.warn('stripping ' + parsed.root + ' from absolute path', p) + entry.path = p.substr(parsed.root.length) + } + } + + // only encode : chars that aren't drive letter indicators + if (this.win32) { + const parsed = path.win32.parse(entry.path) + entry.path = parsed.root === '' ? wc.encode(entry.path) + : parsed.root + wc.encode(entry.path.substr(parsed.root.length)) + } + + if (path.isAbsolute(entry.path)) + entry.absolute = entry.path + else + entry.absolute = path.resolve(this.cwd, entry.path) + + return true + } + + [ONENTRY] (entry) { + if (!this[CHECKPATH](entry)) + return entry.resume() + + assert.equal(typeof entry.absolute, 'string') + + switch (entry.type) { + case 'Directory': + case 'GNUDumpDir': + if (entry.mode) + entry.mode = entry.mode | 0o700 + + case 'File': + case 'OldFile': + case 'ContiguousFile': + case 'Link': + case 'SymbolicLink': + return this[CHECKFS](entry) + + case 'CharacterDevice': + case 'BlockDevice': + case 'FIFO': + return this[UNSUPPORTED](entry) + } + } + + [ONERROR] (er, entry) { + // Cwd has to exist, or else nothing works. That's serious. + // Other errors are warnings, which raise the error in strict + // mode, but otherwise continue on. + if (er.name === 'CwdError') + this.emit('error', er) + else { + this.warn(er.message, er) + this[UNPEND]() + entry.resume() + } + } + + [MKDIR] (dir, mode, cb) { + mkdir(dir, { + uid: this.uid, + gid: this.gid, + processUid: this.processUid, + processGid: this.processGid, + umask: this.processUmask, + preserve: this.preservePaths, + unlink: this.unlink, + cache: this.dirCache, + cwd: this.cwd, + mode: mode + }, cb) + } + + [DOCHOWN] (entry) { + // in preserve owner mode, chown if the entry doesn't match process + // in set owner mode, chown if setting doesn't match process + return this.forceChown || + this.preserveOwner && + ( typeof entry.uid === 'number' && entry.uid !== this.processUid || + typeof entry.gid === 'number' && entry.gid !== this.processGid ) + || + ( typeof this.uid === 'number' && this.uid !== this.processUid || + typeof this.gid === 'number' && this.gid !== this.processGid ) + } + + [UID] (entry) { + return uint32(this.uid, entry.uid, this.processUid) + } + + [GID] (entry) { + return uint32(this.gid, entry.gid, this.processGid) + } + + [FILE] (entry) { + const mode = entry.mode & 0o7777 || this.fmode + const stream = new fsm.WriteStream(entry.absolute, { + mode: mode, + autoClose: false + }) + stream.on('error', er => this[ONERROR](er, entry)) + + let actions = 1 + const done = er => { + if (er) + return this[ONERROR](er, entry) + + if (--actions === 0) + fs.close(stream.fd, _ => this[UNPEND]()) + } + + stream.on('finish', _ => { + // if futimes fails, try utimes + // if utimes fails, fail with the original error + // same for fchown/chown + const abs = entry.absolute + const fd = stream.fd + + if (entry.mtime && !this.noMtime) { + actions++ + const atime = entry.atime || new Date() + const mtime = entry.mtime + fs.futimes(fd, atime, mtime, er => + er ? fs.utimes(abs, atime, mtime, er2 => done(er2 && er)) + : done()) + } + + if (this[DOCHOWN](entry)) { + actions++ + const uid = this[UID](entry) + const gid = this[GID](entry) + fs.fchown(fd, uid, gid, er => + er ? fs.chown(abs, uid, gid, er2 => done(er2 && er)) + : done()) + } + + done() + }) + + const tx = this.transform ? this.transform(entry) || entry : entry + if (tx !== entry) { + tx.on('error', er => this[ONERROR](er, entry)) + entry.pipe(tx) + } + tx.pipe(stream) + } + + [DIRECTORY] (entry) { + const mode = entry.mode & 0o7777 || this.dmode + this[MKDIR](entry.absolute, mode, er => { + if (er) + return this[ONERROR](er, entry) + + let actions = 1 + const done = _ => { + if (--actions === 0) { + this[UNPEND]() + entry.resume() + } + } + + if (entry.mtime && !this.noMtime) { + actions++ + fs.utimes(entry.absolute, entry.atime || new Date(), entry.mtime, done) + } + + if (this[DOCHOWN](entry)) { + actions++ + fs.chown(entry.absolute, this[UID](entry), this[GID](entry), done) + } + + done() + }) + } + + [UNSUPPORTED] (entry) { + this.warn('unsupported entry type: ' + entry.type, entry) + entry.resume() + } + + [SYMLINK] (entry) { + this[LINK](entry, entry.linkpath, 'symlink') + } + + [HARDLINK] (entry) { + this[LINK](entry, path.resolve(this.cwd, entry.linkpath), 'link') + } + + [PEND] () { + this[PENDING]++ + } + + [UNPEND] () { + this[PENDING]-- + this[MAYBECLOSE]() + } + + [SKIP] (entry) { + this[UNPEND]() + entry.resume() + } + + // Check if we can reuse an existing filesystem entry safely and + // overwrite it, rather than unlinking and recreating + // Windows doesn't report a useful nlink, so we just never reuse entries + [ISREUSABLE] (entry, st) { + return entry.type === 'File' && + !this.unlink && + st.isFile() && + st.nlink <= 1 && + process.platform !== 'win32' + } + + // check if a thing is there, and if so, try to clobber it + [CHECKFS] (entry) { + this[PEND]() + this[MKDIR](path.dirname(entry.absolute), this.dmode, er => { + if (er) + return this[ONERROR](er, entry) + fs.lstat(entry.absolute, (er, st) => { + if (st && (this.keep || this.newer && st.mtime > entry.mtime)) + this[SKIP](entry) + else if (er || this[ISREUSABLE](entry, st)) + this[MAKEFS](null, entry) + else if (st.isDirectory()) { + if (entry.type === 'Directory') { + if (!entry.mode || (st.mode & 0o7777) === entry.mode) + this[MAKEFS](null, entry) + else + fs.chmod(entry.absolute, entry.mode, er => this[MAKEFS](er, entry)) + } else + fs.rmdir(entry.absolute, er => this[MAKEFS](er, entry)) + } else + unlinkFile(entry.absolute, er => this[MAKEFS](er, entry)) + }) + }) + } + + [MAKEFS] (er, entry) { + if (er) + return this[ONERROR](er, entry) + + switch (entry.type) { + case 'File': + case 'OldFile': + case 'ContiguousFile': + return this[FILE](entry) + + case 'Link': + return this[HARDLINK](entry) + + case 'SymbolicLink': + return this[SYMLINK](entry) + + case 'Directory': + case 'GNUDumpDir': + return this[DIRECTORY](entry) + } + } + + [LINK] (entry, linkpath, link) { + // XXX: get the type ('file' or 'dir') for windows + fs[link](linkpath, entry.absolute, er => { + if (er) + return this[ONERROR](er, entry) + this[UNPEND]() + entry.resume() + }) + } +} + +class UnpackSync extends Unpack { + constructor (opt) { + super(opt) + } + + [CHECKFS] (entry) { + const er = this[MKDIR](path.dirname(entry.absolute), this.dmode) + if (er) + return this[ONERROR](er, entry) + try { + const st = fs.lstatSync(entry.absolute) + if (this.keep || this.newer && st.mtime > entry.mtime) + return this[SKIP](entry) + else if (this[ISREUSABLE](entry, st)) + return this[MAKEFS](null, entry) + else { + try { + if (st.isDirectory()) { + if (entry.type === 'Directory') { + if (entry.mode && (st.mode & 0o7777) !== entry.mode) + fs.chmodSync(entry.absolute, entry.mode) + } else + fs.rmdirSync(entry.absolute) + } else + unlinkFileSync(entry.absolute) + return this[MAKEFS](null, entry) + } catch (er) { + return this[ONERROR](er, entry) + } + } + } catch (er) { + return this[MAKEFS](null, entry) + } + } + + [FILE] (entry) { + const mode = entry.mode & 0o7777 || this.fmode + + const oner = er => { + try { fs.closeSync(fd) } catch (_) {} + if (er) + this[ONERROR](er, entry) + } + + let stream + let fd + try { + fd = fs.openSync(entry.absolute, 'w', mode) + } catch (er) { + return oner(er) + } + const tx = this.transform ? this.transform(entry) || entry : entry + if (tx !== entry) { + tx.on('error', er => this[ONERROR](er, entry)) + entry.pipe(tx) + } + + tx.on('data', chunk => { + try { + fs.writeSync(fd, chunk, 0, chunk.length) + } catch (er) { + oner(er) + } + }) + + tx.on('end', _ => { + let er = null + // try both, falling futimes back to utimes + // if either fails, handle the first error + if (entry.mtime && !this.noMtime) { + const atime = entry.atime || new Date() + const mtime = entry.mtime + try { + fs.futimesSync(fd, atime, mtime) + } catch (futimeser) { + try { + fs.utimesSync(entry.absolute, atime, mtime) + } catch (utimeser) { + er = futimeser + } + } + } + + if (this[DOCHOWN](entry)) { + const uid = this[UID](entry) + const gid = this[GID](entry) + + try { + fs.fchownSync(fd, uid, gid) + } catch (fchowner) { + try { + fs.chownSync(entry.absolute, uid, gid) + } catch (chowner) { + er = er || fchowner + } + } + } + + oner(er) + }) + } + + [DIRECTORY] (entry) { + const mode = entry.mode & 0o7777 || this.dmode + const er = this[MKDIR](entry.absolute, mode) + if (er) + return this[ONERROR](er, entry) + if (entry.mtime && !this.noMtime) { + try { + fs.utimesSync(entry.absolute, entry.atime || new Date(), entry.mtime) + } catch (er) {} + } + if (this[DOCHOWN](entry)) { + try { + fs.chownSync(entry.absolute, this[UID](entry), this[GID](entry)) + } catch (er) {} + } + entry.resume() + } + + [MKDIR] (dir, mode) { + try { + return mkdir.sync(dir, { + uid: this.uid, + gid: this.gid, + processUid: this.processUid, + processGid: this.processGid, + umask: this.processUmask, + preserve: this.preservePaths, + unlink: this.unlink, + cache: this.dirCache, + cwd: this.cwd, + mode: mode + }) + } catch (er) { + return er + } + } + + [LINK] (entry, linkpath, link) { + try { + fs[link + 'Sync'](linkpath, entry.absolute) + entry.resume() + } catch (er) { + return this[ONERROR](er, entry) + } + } +} + +Unpack.Sync = UnpackSync +module.exports = Unpack + + +/***/ }), +/* 302 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// wrapper around mkdirp for tar's needs. + +// TODO: This should probably be a class, not functionally +// passing around state in a gazillion args. + +const mkdirp = __webpack_require__(179) +const fs = __webpack_require__(55) +const path = __webpack_require__(57) +const chownr = __webpack_require__(303) + +class SymlinkError extends Error { + constructor (symlink, path) { + super('Cannot extract through symbolic link') + this.path = path + this.symlink = symlink + } + + get name () { + return 'SylinkError' + } +} + +class CwdError extends Error { + constructor (path, code) { + super(code + ': Cannot cd into \'' + path + '\'') + this.path = path + this.code = code + } + + get name () { + return 'CwdError' + } +} + +const mkdir = module.exports = (dir, opt, cb) => { + // if there's any overlap between mask and mode, + // then we'll need an explicit chmod + const umask = opt.umask + const mode = opt.mode | 0o0700 + const needChmod = (mode & umask) !== 0 + + const uid = opt.uid + const gid = opt.gid + const doChown = typeof uid === 'number' && + typeof gid === 'number' && + ( uid !== opt.processUid || gid !== opt.processGid ) + + const preserve = opt.preserve + const unlink = opt.unlink + const cache = opt.cache + const cwd = opt.cwd + + const done = (er, created) => { + if (er) + cb(er) + else { + cache.set(dir, true) + if (created && doChown) + chownr(created, uid, gid, er => done(er)) + else if (needChmod) + fs.chmod(dir, mode, cb) + else + cb() + } + } + + if (cache && cache.get(dir) === true) + return done() + + if (dir === cwd) + return fs.stat(dir, (er, st) => { + if (er || !st.isDirectory()) + er = new CwdError(dir, er && er.code || 'ENOTDIR') + done(er) + }) + + if (preserve) + return mkdirp(dir, mode, done) + + const sub = path.relative(cwd, dir) + const parts = sub.split(/\/|\\/) + mkdir_(cwd, parts, mode, cache, unlink, cwd, null, done) +} + +const mkdir_ = (base, parts, mode, cache, unlink, cwd, created, cb) => { + if (!parts.length) + return cb(null, created) + const p = parts.shift() + const part = base + '/' + p + if (cache.get(part)) + return mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) + fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb)) +} + +const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => { + if (er) { + if (er.path && path.dirname(er.path) === cwd && + (er.code === 'ENOTDIR' || er.code === 'ENOENT')) + return cb(new CwdError(cwd, er.code)) + + fs.lstat(part, (statEr, st) => { + if (statEr) + cb(statEr) + else if (st.isDirectory()) + mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) + else if (unlink) + fs.unlink(part, er => { + if (er) + return cb(er) + fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb)) + }) + else if (st.isSymbolicLink()) + return cb(new SymlinkError(part, part + '/' + parts.join('/'))) + else + cb(er) + }) + } else { + created = created || part + mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) + } +} + +const mkdirSync = module.exports.sync = (dir, opt) => { + // if there's any overlap between mask and mode, + // then we'll need an explicit chmod + const umask = opt.umask + const mode = opt.mode | 0o0700 + const needChmod = (mode & umask) !== 0 + + const uid = opt.uid + const gid = opt.gid + const doChown = typeof uid === 'number' && + typeof gid === 'number' && + ( uid !== opt.processUid || gid !== opt.processGid ) + + const preserve = opt.preserve + const unlink = opt.unlink + const cache = opt.cache + const cwd = opt.cwd + + const done = (created) => { + cache.set(dir, true) + if (created && doChown) + chownr.sync(created, uid, gid) + if (needChmod) + fs.chmodSync(dir, mode) + } + + if (cache && cache.get(dir) === true) + return done() + + if (dir === cwd) { + let ok = false + let code = 'ENOTDIR' + try { + ok = fs.statSync(dir).isDirectory() + } catch (er) { + code = er.code + } finally { + if (!ok) + throw new CwdError(dir, code) + } + done() + return + } + + if (preserve) + return done(mkdirp.sync(dir, mode)) + + const sub = path.relative(cwd, dir) + const parts = sub.split(/\/|\\/) + let created = null + for (let p = parts.shift(), part = cwd; + p && (part += '/' + p); + p = parts.shift()) { + + if (cache.get(part)) + continue + + try { + fs.mkdirSync(part, mode) + created = created || part + cache.set(part, true) + } catch (er) { + if (er.path && path.dirname(er.path) === cwd && + (er.code === 'ENOTDIR' || er.code === 'ENOENT')) + return new CwdError(cwd, er.code) + + const st = fs.lstatSync(part) + if (st.isDirectory()) { + cache.set(part, true) + continue + } else if (unlink) { + fs.unlinkSync(part) + fs.mkdirSync(part, mode) + created = created || part + cache.set(part, true) + continue + } else if (st.isSymbolicLink()) + return new SymlinkError(part, part + '/' + parts.join('/')) + } + } + + return done(created) +} + + +/***/ }), +/* 303 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const fs = __webpack_require__(55) +const path = __webpack_require__(57) + +/* istanbul ignore next */ +const LCHOWN = fs.lchown ? 'lchown' : 'chown' +/* istanbul ignore next */ +const LCHOWNSYNC = fs.lchownSync ? 'lchownSync' : 'chownSync' + +// fs.readdir could only accept an options object as of node v6 +const nodeVersion = process.version +let readdir = (path, options, cb) => fs.readdir(path, options, cb) +let readdirSync = (path, options) => fs.readdirSync(path, options) +/* istanbul ignore next */ +if (/^v4\./.test(nodeVersion)) + readdir = (path, options, cb) => fs.readdir(path, cb) + +const chownrKid = (p, child, uid, gid, cb) => { + if (typeof child === 'string') + return fs.lstat(path.resolve(p, child), (er, stats) => { + if (er) + return cb(er) + stats.name = child + chownrKid(p, stats, uid, gid, cb) + }) + + if (child.isDirectory()) { + chownr(path.resolve(p, child.name), uid, gid, er => { + if (er) + return cb(er) + fs[LCHOWN](path.resolve(p, child.name), uid, gid, cb) + }) + } else + fs[LCHOWN](path.resolve(p, child.name), uid, gid, cb) +} + + +const chownr = (p, uid, gid, cb) => { + readdir(p, { withFileTypes: true }, (er, children) => { + // any error other than ENOTDIR or ENOTSUP means it's not readable, + // or doesn't exist. give up. + if (er && er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP') + return cb(er) + if (er || !children.length) return fs[LCHOWN](p, uid, gid, cb) + + let len = children.length + let errState = null + const then = er => { + if (errState) return + if (er) return cb(errState = er) + if (-- len === 0) return fs[LCHOWN](p, uid, gid, cb) + } + + children.forEach(child => chownrKid(p, child, uid, gid, then)) + }) +} + +const chownrKidSync = (p, child, uid, gid) => { + if (typeof child === 'string') { + const stats = fs.lstatSync(path.resolve(p, child)) + stats.name = child + child = stats + } + + if (child.isDirectory()) + chownrSync(path.resolve(p, child.name), uid, gid) + + fs[LCHOWNSYNC](path.resolve(p, child.name), uid, gid) +} + +const chownrSync = (p, uid, gid) => { + let children + try { + children = readdirSync(p, { withFileTypes: true }) + } catch (er) { + if (er && er.code === 'ENOTDIR' && er.code !== 'ENOTSUP') + return fs[LCHOWNSYNC](p, uid, gid) + throw er + } + + if (children.length) + children.forEach(child => chownrKidSync(p, child, uid, gid)) + + return fs[LCHOWNSYNC](p, uid, gid) +} + +module.exports = chownr +chownr.sync = chownrSync + + +/***/ }), +/* 304 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const follow_redirects_1 = __webpack_require__(266); +const tunnel_1 = tslib_1.__importDefault(__webpack_require__(305)); +const url_1 = __webpack_require__(264); +const zlib_1 = tslib_1.__importDefault(__webpack_require__(137)); +const is_1 = __webpack_require__(191); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('model-fetch'); +function getAgent(endpoint) { + let proxy = workspace_1.default.getConfiguration('http').get('proxy', ''); + let key = endpoint.protocol.startsWith('https') ? 'HTTPS_PROXY' : 'HTTP_PROXY'; + let env = process.env[key]; + if (!proxy && env && env.startsWith('http')) { + proxy = env.replace(/^https?:\/\//, '').replace(/\/$/, ''); + } + const noProxy = process.env.NO_PROXY || process.env.no_proxy || null; + if (noProxy === '*') { + proxy = null; + } + else if (noProxy !== null) { + // canonicalize the hostname, so that 'oogle.com' won't match 'google.com' + const hostname = endpoint.hostname.replace(/^\.*/, '.').toLowerCase(); + const port = endpoint.port || endpoint.protocol.startsWith('https') ? '443' : '80'; + const noProxyList = noProxy.split(','); + for (let i = 0, len = noProxyList.length; i < len; i++) { + let noProxyItem = noProxyList[i].trim().toLowerCase(); + // no_proxy can be granular at the port level, which complicates things a bit. + if (noProxyItem.indexOf(':') > -1) { + let noProxyItemParts = noProxyItem.split(':', 2); + let noProxyHost = noProxyItemParts[0].replace(/^\.*/, '.'); + let noProxyPort = noProxyItemParts[1]; + if (port === noProxyPort && hostname.endsWith(noProxyHost)) { + proxy = null; + break; + } + } + else { + noProxyItem = noProxyItem.replace(/^\.*/, '.'); + if (hostname.endsWith(noProxyItem)) { + proxy = null; + break; + } + } + } + } + if (proxy) { + let auth = proxy.includes('@') ? proxy.split('@', 2)[0] : ''; + let parts = auth.length ? proxy.slice(auth.length + 1).split(':') : proxy.split(':'); + logger.info(`Using proxy from: ${proxy}`); + if (parts.length > 1) { + let agent = tunnel_1.default.httpsOverHttp({ + proxy: { + headers: {}, + host: parts[0], + port: parseInt(parts[1], 10), + proxyAuth: auth + } + }); + return agent; + } + } +} +exports.getAgent = getAgent; +/** + * Fetch text from server + */ +function fetch(url, data, options = {}) { + logger.info('fetch:', url); + let mod = url.startsWith('https') ? follow_redirects_1.https : follow_redirects_1.http; + let endpoint = url_1.parse(url); + let agent = getAgent(endpoint); + let opts = Object.assign({ + method: 'GET', + hostname: endpoint.hostname, + port: endpoint.port ? parseInt(endpoint.port, 10) : (endpoint.protocol === 'https:' ? 443 : 80), + path: endpoint.path, + protocol: url.startsWith('https') ? 'https:' : 'http:', + agent, + headers: { + 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64)', + 'Accept-Encoding': 'gzip' + } + }, options); + if (data && is_1.objectLiteral(data)) { + opts.headers['Content-Type'] = 'application/json'; + } + if (data && !opts.method) { + opts.method = 'POST'; + } + return new Promise((resolve, reject) => { + // tslint:disable-next-line: only-arrow-functions + try { + const req = mod.request(opts, res => { + let readable = res; + if (res.statusCode != 200) { + reject(new Error(`Invalid response from ${url}: ${res.statusCode}`)); + return; + } + let chunks = []; + let contentType = res.headers['content-type']; + let contentEncoding = res.headers['content-encoding']; + let ms = contentType.match(/charset=(\S+)/); + let encoding = ms ? ms[1] : 'utf8'; + if (contentEncoding == 'gzip') { + const unzip = zlib_1.default.createGunzip(); + readable = res.pipe(unzip); + } + readable.on('data', chunk => { + chunks.push(chunk); + }); + readable.on('end', () => { + let buf = Buffer.concat(chunks); + let rawData = buf.toString(encoding); + if (/^application\/json/.test(contentType)) { + try { + const parsedData = JSON.parse(rawData); + resolve(parsedData); + } + catch (e) { + reject(`Parse error: ${e}`); + } + } + else { + resolve(rawData); + } + }); + }); + req.on('error', reject); + if (data) { + if (typeof data == 'string') { + req.write(data); + } + else { + req.write(JSON.stringify(data)); + } + } + req.end(); + } + catch (e) { + logger.error(e); + reject(e); + } + }); +} +exports.default = fetch; +//# sourceMappingURL=fetch.js.map + +/***/ }), +/* 305 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(306); + + +/***/ }), +/* 306 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var net = __webpack_require__(6); +var tls = __webpack_require__(307); +var http = __webpack_require__(267); +var https = __webpack_require__(268); +var events = __webpack_require__(49); +var assert = __webpack_require__(101); +var util = __webpack_require__(40); + + +exports.httpOverHttp = httpOverHttp; +exports.httpsOverHttp = httpsOverHttp; +exports.httpOverHttps = httpOverHttps; +exports.httpsOverHttps = httpsOverHttps; + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + + +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; + + self.on('free', function onFree(socket, host, port, localAddress) { + var options = toOptions(host, port, localAddress); + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === options.host && pending.port === options.port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } + } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); + +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { + var self = this; + var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push(options); + return; + } + + // If we are under maxSockets create a new one. + self.createSocket(options, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, options); + } + + function onCloseOrRemove(err) { + self.removeSocket(socket); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); + } + }); +}; + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); + + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false, + headers: { + host: options.host + ':' + options.port + } + }); + if (options.localAddress) { + connectOptions.localAddress = options.localAddress; + } + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); + } + + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); + + if (res.statusCode !== 200) { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + socket.destroy(); + var error = new Error('tunneling socket could not be established, ' + + 'statusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + if (head.length > 0) { + debug('got illegal response body from proxy'); + socket.destroy(); + var error = new Error('got illegal response body from proxy'); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + return cb(socket); + } + + function onError(cause) { + connectReq.removeAllListeners(); + + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } +}; + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; + } + this.sockets.splice(pos, 1); + + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; + +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + var hostHeader = options.request.getHeader('host'); + var tlsOptions = mergeOptions({}, self.options, { + socket: socket, + servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host + }); + + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, tlsOptions); + self.sockets[self.sockets.indexOf(socket)] = secureSocket; + cb(secureSocket); + }); +} + + +function toOptions(host, port, localAddress) { + if (typeof host === 'string') { // since v0.10 + return { + host: host, + port: port, + localAddress: localAddress + }; + } + return host; // for v0.11 or later +} + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; +} + + +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); + } +} else { + debug = function() {}; +} +exports.debug = debug; // for test + + +/***/ }), +/* 307 */ +/***/ (function(module, exports) { + +module.exports = require("tls"); + +/***/ }), +/* 308 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const object_1 = __webpack_require__(190); +const logger = __webpack_require__(186)('model-memos'); +class Memos { + constructor(filepath) { + this.filepath = filepath; + if (!fs_1.default.existsSync(filepath)) { + fs_1.default.writeFileSync(filepath, '{}', 'utf8'); + } + } + fetchContent(id, key) { + try { + let content = fs_1.default.readFileSync(this.filepath, 'utf8'); + let res = JSON.parse(content); + let obj = res[id]; + if (!obj) + return undefined; + return obj[key]; + } + catch (e) { + return undefined; + } + } + async update(id, key, value) { + let { filepath } = this; + try { + let content = fs_1.default.readFileSync(filepath, 'utf8'); + let current = content ? JSON.parse(content) : {}; + current[id] = current[id] || {}; + if (value !== undefined) { + current[id][key] = object_1.deepClone(value); + } + else { + delete current[id][key]; + } + content = JSON.stringify(current, null, 2); + fs_1.default.writeFileSync(filepath, content, 'utf8'); + } + catch (e) { + logger.error(`Error on update memos:`, e); + } + } + createMemento(id) { + return { + get: (key, defaultValue) => { + let res = this.fetchContent(id, key); + return res === undefined ? defaultValue : res; + }, + update: async (key, value) => { + await this.update(id, key, value); + } + }; + } +} +exports.default = Memos; +//# sourceMappingURL=memos.js.map + +/***/ }), +/* 309 */ +/***/ (function(module, exports, __webpack_require__) { + +const logger = __webpack_require__(186)('extensions'); +/** + * Explicitly tells that promise should be run asynchonously. + */ +Promise.prototype.logError = function () { + // tslint:disable-next-line:no-empty + this.catch(e => { + logger.error(e); + }); +}; +//# sourceMappingURL=extensions.js.map + +/***/ }), +/* 310 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const path = tslib_1.__importStar(__webpack_require__(57)); +const vm = tslib_1.__importStar(__webpack_require__(311)); +const lodash_1 = __webpack_require__(312); +const createLogger = __webpack_require__(186); +const logger = createLogger('util-factoroy'); +const requireFunc = true ? require : undefined; +const Module = __webpack_require__(313); +const REMOVED_GLOBALS = [ + 'reallyExit', + 'abort', + 'chdir', + 'umask', + 'setuid', + 'setgid', + 'setgroups', + '_fatalException', + 'exit', + 'kill', +]; +function removedGlobalStub(name) { + return () => { + throw new Error(`process.${name}() is not allowed in extension sandbox`); + }; +} +// @see node/lib/internal/module.js +function makeRequireFunction() { + const req = (p) => { + if (p === 'coc.nvim') { + return __webpack_require__(314); + } + return this.require(p); + }; + req.resolve = (request) => Module._resolveFilename(request, this); + req.main = process.mainModule; + // Enable support to add extra extension types + req.extensions = Module._extensions; + req.cache = Module._cache; + return req; +} +// @see node/lib/module.js +function compileInSandbox(sandbox) { + // eslint-disable-next-line + return function (content, filename) { + const require = makeRequireFunction.call(this); + const dirname = path.dirname(filename); + // remove shebang + // eslint-disable-next-line + const newContent = content.replace(/^\#\!.*/, ''); + const wrapper = Module.wrap(newContent); + const compiledWrapper = vm.runInContext(wrapper, sandbox, { filename }); + const args = [this.exports, require, this, filename, dirname]; + return compiledWrapper.apply(this.exports, args); + }; +} +function createSandbox(filename, logger) { + const module = new Module(filename); + module.paths = Module._nodeModulePaths(filename); + const sandbox = vm.createContext({ + module, + Buffer, + console: { + log: (...args) => { + logger.debug.apply(logger, args); + }, + error: (...args) => { + logger.error.apply(logger, args); + }, + info: (...args) => { + logger.info.apply(logger, args); + }, + warn: (...args) => { + logger.warn.apply(logger, args); + } + } + }); + lodash_1.defaults(sandbox, global); + sandbox.Reflect = Reflect; + sandbox.require = function sandboxRequire(p) { + const oldCompile = Module.prototype._compile; + Module.prototype._compile = compileInSandbox(sandbox); + const moduleExports = sandbox.module.require(p); + Module.prototype._compile = oldCompile; + return moduleExports; + }; + // patch `require` in sandbox to run loaded module in sandbox context + // if you need any of these, it might be worth discussing spawning separate processes + sandbox.process = new process.constructor(); + for (let key of Object.keys(process)) { + sandbox.process[key] = process[key]; + } + REMOVED_GLOBALS.forEach(name => { + sandbox.process[name] = removedGlobalStub(name); + }); + // read-only umask + sandbox.process.umask = (mask) => { + if (typeof mask !== 'undefined') { + throw new Error('Cannot use process.umask() to change mask (read-only)'); + } + return process.umask(); + }; + return sandbox; +} +// inspiration drawn from Module +function createExtension(id, filename) { + if (!fs_1.default.existsSync(filename)) { + // tslint:disable-next-line:no-empty + return { activate: () => { }, deactivate: null }; + } + const sandbox = createSandbox(filename, createLogger(`extension-${id}`)); + delete Module._cache[requireFunc.resolve(filename)]; + // attempt to import plugin + // Require plugin to export activate & deactivate + const defaultImport = sandbox.require(filename); + const activate = (defaultImport && defaultImport.activate) || defaultImport; + if (typeof activate !== 'function') { + // tslint:disable-next-line:no-empty + return { activate: () => { }, deactivate: null }; + } + return { + activate, + deactivate: typeof defaultImport.deactivate === 'function' ? defaultImport.deactivate : null + }; +} +exports.createExtension = createExtension; +//# sourceMappingURL=factory.js.map + +/***/ }), +/* 311 */ +/***/ (function(module, exports) { + +module.exports = require("vm"); + +/***/ }), +/* 312 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** Used for built-in method references. */ +const objectProto = Object.prototype; +/** Used to check objects for own properties. */ +const hasOwnProperty = objectProto.hasOwnProperty; +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @since 0.1.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see defaultsDeep + * @example + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }) + * // => { 'a': 1, 'b': 2 } + */ +function defaults(obj, ...sources) { + obj = Object(obj); + sources.forEach(source => { + if (source != null) { + source = Object(source); + for (const key in source) { // tslint:disable-line + const value = obj[key]; + if (value === undefined || + (value === objectProto[key] && !hasOwnProperty.call(obj, key))) { + obj[key] = source[key]; + } + } + } + }); + return obj; +} +exports.defaults = defaults; +function omit(obj, properties) { + let o = {}; + for (let key of Object.keys(obj)) { + if (properties.indexOf(key) == -1) { + o[key] = obj[key]; + } + } + return o; +} +exports.omit = omit; +//# sourceMappingURL=lodash.js.map + +/***/ }), +/* 313 */ +/***/ (function(module, exports) { + +module.exports = require("module"); + +/***/ }), +/* 314 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const commands_1 = tslib_1.__importDefault(__webpack_require__(232)); +exports.commands = commands_1.default; +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +exports.events = events_1.default; +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +exports.languages = languages_1.default; +const document_1 = tslib_1.__importDefault(__webpack_require__(207)); +exports.Document = document_1.default; +const mru_1 = tslib_1.__importDefault(__webpack_require__(215)); +exports.Mru = mru_1.default; +const floatBuffer_1 = tslib_1.__importDefault(__webpack_require__(318)); +exports.FloatBuffer = floatBuffer_1.default; +const floatFactory_1 = tslib_1.__importDefault(__webpack_require__(317)); +exports.FloatFactory = floatFactory_1.default; +const fetch_1 = tslib_1.__importDefault(__webpack_require__(304)); +exports.fetch = fetch_1.default; +const download_1 = tslib_1.__importDefault(__webpack_require__(265)); +exports.download = download_1.default; +const highligher_1 = tslib_1.__importDefault(__webpack_require__(349)); +exports.Highligher = highligher_1.default; +const fileSystemWatcher_1 = tslib_1.__importDefault(__webpack_require__(214)); +exports.FileSystemWatcher = fileSystemWatcher_1.default; +const services_1 = tslib_1.__importDefault(__webpack_require__(351)); +exports.services = services_1.default; +const sources_1 = tslib_1.__importDefault(__webpack_require__(237)); +exports.sources = sources_1.default; +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +exports.workspace = workspace_1.default; +const extensions_1 = tslib_1.__importDefault(__webpack_require__(238)); +exports.extensions = extensions_1.default; +const manager_1 = tslib_1.__importDefault(__webpack_require__(364)); +exports.listManager = manager_1.default; +const manager_2 = tslib_1.__importDefault(__webpack_require__(233)); +exports.snippetManager = manager_2.default; +const basic_1 = tslib_1.__importDefault(__webpack_require__(371)); +exports.BasicList = basic_1.default; +const manager_3 = tslib_1.__importDefault(__webpack_require__(316)); +exports.diagnosticManager = manager_3.default; +const ansiparse_1 = __webpack_require__(350); +exports.ansiparse = ansiparse_1.ansiparse; +const watchman_1 = tslib_1.__importDefault(__webpack_require__(227)); +exports.Watchman = watchman_1.default; +const vscode_uri_1 = __webpack_require__(180); +exports.Uri = vscode_uri_1.URI; +const neovim_1 = __webpack_require__(4); +exports.Neovim = neovim_1.Neovim; +exports.Buffer = neovim_1.Buffer; +exports.Window = neovim_1.Window; +const vscode_languageserver_protocol_1 = __webpack_require__(149); +exports.Disposable = vscode_languageserver_protocol_1.Disposable; +exports.Event = vscode_languageserver_protocol_1.Event; +exports.Emitter = vscode_languageserver_protocol_1.Emitter; +tslib_1.__exportStar(__webpack_require__(189), exports); +tslib_1.__exportStar(__webpack_require__(352), exports); +var util_1 = __webpack_require__(174); +exports.disposeAll = util_1.disposeAll; +exports.runCommand = util_1.runCommand; +exports.isRunning = util_1.isRunning; +exports.executable = util_1.executable; +//# sourceMappingURL=index.js.map + +/***/ }), +/* 315 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const commands_1 = tslib_1.__importDefault(__webpack_require__(232)); +const manager_1 = tslib_1.__importDefault(__webpack_require__(316)); +const codeActionmanager_1 = tslib_1.__importDefault(__webpack_require__(327)); +const codeLensManager_1 = tslib_1.__importDefault(__webpack_require__(329)); +const declarationManager_1 = tslib_1.__importDefault(__webpack_require__(330)); +const definitionManager_1 = tslib_1.__importDefault(__webpack_require__(331)); +const documentColorManager_1 = tslib_1.__importDefault(__webpack_require__(332)); +const documentHighlightManager_1 = tslib_1.__importDefault(__webpack_require__(333)); +const documentLinkManager_1 = tslib_1.__importDefault(__webpack_require__(334)); +const documentSymbolManager_1 = tslib_1.__importDefault(__webpack_require__(335)); +const foldingRangeManager_1 = tslib_1.__importDefault(__webpack_require__(336)); +const formatManager_1 = tslib_1.__importDefault(__webpack_require__(337)); +const formatRangeManager_1 = tslib_1.__importDefault(__webpack_require__(338)); +const hoverManager_1 = tslib_1.__importDefault(__webpack_require__(339)); +const implementationManager_1 = tslib_1.__importDefault(__webpack_require__(340)); +const onTypeFormatManager_1 = tslib_1.__importDefault(__webpack_require__(341)); +const rangeManager_1 = tslib_1.__importDefault(__webpack_require__(342)); +const referenceManager_1 = tslib_1.__importDefault(__webpack_require__(343)); +const renameManager_1 = tslib_1.__importDefault(__webpack_require__(344)); +const signatureManager_1 = tslib_1.__importDefault(__webpack_require__(345)); +const typeDefinitionManager_1 = tslib_1.__importDefault(__webpack_require__(346)); +const workspaceSymbolsManager_1 = tslib_1.__importDefault(__webpack_require__(347)); +const manager_2 = tslib_1.__importDefault(__webpack_require__(233)); +const sources_1 = tslib_1.__importDefault(__webpack_require__(237)); +const types_1 = __webpack_require__(189); +const util_1 = __webpack_require__(174); +const complete = tslib_1.__importStar(__webpack_require__(348)); +const position_1 = __webpack_require__(213); +const string_1 = __webpack_require__(210); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('languages'); +function fixDocumentation(str) { + return str.replace(/ /g, ' '); +} +function check(_target, key, descriptor) { + let fn = descriptor.value; + if (typeof fn !== 'function') { + return; + } + descriptor.value = function (...args) { + let { cancelTokenSource } = this; + this.cancelTokenSource = new vscode_languageserver_protocol_1.CancellationTokenSource(); + return new Promise((resolve, reject) => { + let resolved = false; + let timer = setTimeout(() => { + cancelTokenSource.cancel(); + logger.error(`${key} timeout after 5s`); + if (!resolved) + reject(new Error(`${key} timeout after 5s`)); + }, 5000); + Promise.resolve(fn.apply(this, args)).then(res => { + clearTimeout(timer); + resolve(res); + }, e => { + clearTimeout(timer); + reject(e); + }); + }); + }; +} +exports.check = check; +class Languages { + constructor() { + this.onTypeFormatManager = new onTypeFormatManager_1.default(); + this.documentLinkManager = new documentLinkManager_1.default(); + this.documentColorManager = new documentColorManager_1.default(); + this.foldingRangeManager = new foldingRangeManager_1.default(); + this.renameManager = new renameManager_1.default(); + this.formatManager = new formatManager_1.default(); + this.codeActionManager = new codeActionmanager_1.default(); + this.workspaceSymbolsManager = new workspaceSymbolsManager_1.default(); + this.formatRangeManager = new formatRangeManager_1.default(); + this.hoverManager = new hoverManager_1.default(); + this.signatureManager = new signatureManager_1.default(); + this.documentSymbolManager = new documentSymbolManager_1.default(); + this.documentHighlightManager = new documentHighlightManager_1.default(); + this.definitionManager = new definitionManager_1.default(); + this.declarationManager = new declarationManager_1.default(); + this.typeDefinitionManager = new typeDefinitionManager_1.default(); + this.referenceManager = new referenceManager_1.default(); + this.implementationManager = new implementationManager_1.default(); + this.codeLensManager = new codeLensManager_1.default(); + this.selectionRangeManager = new rangeManager_1.default(); + this.cancelTokenSource = new vscode_languageserver_protocol_1.CancellationTokenSource(); + workspace_1.default.onWillSaveUntil(event => { + let { languageId } = event.document; + let config = workspace_1.default.getConfiguration('coc.preferences', event.document.uri); + let filetypes = config.get('formatOnSaveFiletypes', []); + if (filetypes.indexOf(languageId) !== -1 || filetypes.some(item => item === '*')) { + let willSaveWaitUntil = async () => { + let options = await workspace_1.default.getFormatOptions(event.document.uri); + let textEdits = await this.provideDocumentFormattingEdits(event.document, options); + return textEdits; + }; + event.waitUntil(willSaveWaitUntil()); + } + }, null, 'languageserver'); + workspace_1.default.ready.then(() => { + this.loadCompleteConfig(); + }, _e => { + // noop + }); + workspace_1.default.onDidChangeConfiguration(this.loadCompleteConfig, this); + } + get nvim() { + return workspace_1.default.nvim; + } + loadCompleteConfig() { + let config = workspace_1.default.getConfiguration('coc.preferences'); + let suggest = workspace_1.default.getConfiguration('suggest'); + function getConfig(key, defaultValue) { + return config.get(key, suggest.get(key, defaultValue)); + } + let labels = suggest.get('completionItemKindLabels', {}); + this.completionItemKindMap = new Map([ + [vscode_languageserver_protocol_1.CompletionItemKind.Text, labels['text'] || 'v'], + [vscode_languageserver_protocol_1.CompletionItemKind.Method, labels['method'] || 'f'], + [vscode_languageserver_protocol_1.CompletionItemKind.Function, labels['function'] || 'f'], + [vscode_languageserver_protocol_1.CompletionItemKind.Constructor, typeof labels['constructor'] == 'function' ? 'f' : labels['con' + 'structor']], + [vscode_languageserver_protocol_1.CompletionItemKind.Field, labels['field'] || 'm'], + [vscode_languageserver_protocol_1.CompletionItemKind.Variable, labels['variable'] || 'v'], + [vscode_languageserver_protocol_1.CompletionItemKind.Class, labels['class'] || 'C'], + [vscode_languageserver_protocol_1.CompletionItemKind.Interface, labels['interface'] || 'I'], + [vscode_languageserver_protocol_1.CompletionItemKind.Module, labels['module'] || 'M'], + [vscode_languageserver_protocol_1.CompletionItemKind.Property, labels['property'] || 'm'], + [vscode_languageserver_protocol_1.CompletionItemKind.Unit, labels['unit'] || 'U'], + [vscode_languageserver_protocol_1.CompletionItemKind.Value, labels['value'] || 'v'], + [vscode_languageserver_protocol_1.CompletionItemKind.Enum, labels['enum'] || 'E'], + [vscode_languageserver_protocol_1.CompletionItemKind.Keyword, labels['keyword'] || 'k'], + [vscode_languageserver_protocol_1.CompletionItemKind.Snippet, labels['snippet'] || 'S'], + [vscode_languageserver_protocol_1.CompletionItemKind.Color, labels['color'] || 'v'], + [vscode_languageserver_protocol_1.CompletionItemKind.File, labels['file'] || 'F'], + [vscode_languageserver_protocol_1.CompletionItemKind.Reference, labels['reference'] || 'r'], + [vscode_languageserver_protocol_1.CompletionItemKind.Folder, labels['folder'] || 'F'], + [vscode_languageserver_protocol_1.CompletionItemKind.EnumMember, labels['enumMember'] || 'm'], + [vscode_languageserver_protocol_1.CompletionItemKind.Constant, labels['constant'] || 'v'], + [vscode_languageserver_protocol_1.CompletionItemKind.Struct, labels['struct'] || 'S'], + [vscode_languageserver_protocol_1.CompletionItemKind.Event, labels['event'] || 'E'], + [vscode_languageserver_protocol_1.CompletionItemKind.Operator, labels['operator'] || 'O'], + [vscode_languageserver_protocol_1.CompletionItemKind.TypeParameter, labels['typeParameter'] || 'T'], + ]); + this.completeConfig = { + defaultKindText: labels['default'] || '', + priority: getConfig('languageSourcePriority', 99), + echodocSupport: getConfig('echodocSupport', false), + waitTime: getConfig('triggerCompletionWait', 60), + detailField: getConfig('detailField', 'abbr'), + detailMaxLength: getConfig('detailMaxLength', 50), + invalidInsertCharacters: getConfig('invalidInsertCharacters', [' ', '(', '<', '{', '[', '\r', '\n']), + }; + } + registerOnTypeFormattingEditProvider(selector, provider, triggerCharacters) { + return this.onTypeFormatManager.register(selector, provider, triggerCharacters); + } + registerCompletionItemProvider(name, shortcut, languageIds, provider, triggerCharacters = [], priority) { + languageIds = typeof languageIds == 'string' ? [languageIds] : languageIds; + let source = this.createCompleteSource(name, shortcut, provider, languageIds, triggerCharacters, priority); + sources_1.default.addSource(source); + logger.debug('created service source', name); + return { + dispose: () => { + sources_1.default.removeSource(source); + } + }; + } + registerCodeActionProvider(selector, provider, clientId, codeActionKinds) { + return this.codeActionManager.register(selector, provider, clientId, codeActionKinds); + } + registerHoverProvider(selector, provider) { + return this.hoverManager.register(selector, provider); + } + registerSelectionRangeProvider(selector, provider) { + return this.selectionRangeManager.register(selector, provider); + } + registerSignatureHelpProvider(selector, provider, triggerCharacters) { + return this.signatureManager.register(selector, provider, triggerCharacters); + } + registerDocumentSymbolProvider(selector, provider) { + return this.documentSymbolManager.register(selector, provider); + } + registerFoldingRangeProvider(selector, provider) { + return this.foldingRangeManager.register(selector, provider); + } + registerDocumentHighlightProvider(selector, provider) { + return this.documentHighlightManager.register(selector, provider); + } + registerCodeLensProvider(selector, provider) { + return this.codeLensManager.register(selector, provider); + } + registerDocumentLinkProvider(selector, provider) { + return this.documentLinkManager.register(selector, provider); + } + registerDocumentColorProvider(selector, provider) { + return this.documentColorManager.register(selector, provider); + } + registerDefinitionProvider(selector, provider) { + return this.definitionManager.register(selector, provider); + } + registerDeclarationProvider(selector, provider) { + return this.declarationManager.register(selector, provider); + } + registerTypeDefinitionProvider(selector, provider) { + return this.typeDefinitionManager.register(selector, provider); + } + registerImplementationProvider(selector, provider) { + return this.implementationManager.register(selector, provider); + } + registerReferencesProvider(selector, provider) { + return this.referenceManager.register(selector, provider); + } + registerRenameProvider(selector, provider) { + return this.renameManager.register(selector, provider); + } + registerWorkspaceSymbolProvider(selector, provider) { + return this.workspaceSymbolsManager.register(selector, provider); + } + registerDocumentFormatProvider(selector, provider, priority = 0) { + return this.formatManager.register(selector, provider, priority); + } + registerDocumentRangeFormatProvider(selector, provider, priority = 0) { + return this.formatRangeManager.register(selector, provider, priority); + } + shouldTriggerSignatureHelp(document, triggerCharacter) { + return this.signatureManager.shouldTrigger(document, triggerCharacter); + } + async getHover(document, position) { + return await this.hoverManager.provideHover(document, position, this.token); + } + async getSignatureHelp(document, position, token) { + return await this.signatureManager.provideSignatureHelp(document, position, token); + } + async getDefinition(document, position) { + if (!this.definitionManager.hasProvider(document)) + return null; + return await this.definitionManager.provideDefinition(document, position, this.token); + } + async getDeclaration(document, position) { + if (!this.declarationManager.hasProvider(document)) + return null; + return await this.declarationManager.provideDeclaration(document, position, this.token); + } + async getTypeDefinition(document, position) { + if (!this.typeDefinitionManager.hasProvider(document)) + return null; + return await this.typeDefinitionManager.provideTypeDefinition(document, position, this.token); + } + async getImplementation(document, position) { + if (!this.implementationManager.hasProvider(document)) + return null; + return await this.implementationManager.provideReferences(document, position, this.token); + } + async getReferences(document, context, position) { + if (!this.referenceManager.hasProvider(document)) + return null; + return await this.referenceManager.provideReferences(document, position, context, this.token); + } + async getDocumentSymbol(document) { + return await this.documentSymbolManager.provideDocumentSymbols(document, this.token); + } + async getSelectionRanges(document, positions) { + return await this.selectionRangeManager.provideSelectionRanges(document, positions, this.token); + } + async getWorkspaceSymbols(document, query) { + query = query || ''; + return await this.workspaceSymbolsManager.provideWorkspaceSymbols(document, query, this.token); + } + async resolveWorkspaceSymbol(symbol) { + return await this.workspaceSymbolsManager.resolveWorkspaceSymbol(symbol, this.token); + } + async provideRenameEdits(document, position, newName) { + return await this.renameManager.provideRenameEdits(document, position, newName, this.token); + } + async prepareRename(document, position) { + return await this.renameManager.prepareRename(document, position, this.token); + } + async provideDocumentFormattingEdits(document, options) { + if (!this.formatManager.hasProvider(document)) { + let hasRangeFormater = this.formatRangeManager.hasProvider(document); + if (!hasRangeFormater) { + logger.error('Format provider not found for current document', 'error'); + return null; + } + let end = document.positionAt(document.getText().length); + let range = vscode_languageserver_protocol_1.Range.create(vscode_languageserver_protocol_1.Position.create(0, 0), end); + return await this.provideDocumentRangeFormattingEdits(document, range, options); + } + return await this.formatManager.provideDocumentFormattingEdits(document, options, this.token); + } + async provideDocumentRangeFormattingEdits(document, range, options) { + if (!this.formatRangeManager.hasProvider(document)) + return null; + return await this.formatRangeManager.provideDocumentRangeFormattingEdits(document, range, options, this.token); + } + /** + * Get CodeAction list for current document + * + * @public + * @param {TextDocument} document + * @param {Range} range + * @param {CodeActionContext} context + * @returns {Promise} + */ + async getCodeActions(document, range, context, silent = false) { + if (!silent && !this.codeActionManager.hasProvider(document)) { + return null; + } + return await this.codeActionManager.provideCodeActions(document, range, context, this.token); + } + async getDocumentHighLight(document, position) { + return await this.documentHighlightManager.provideDocumentHighlights(document, position, this.token); + } + async getDocumentLinks(document) { + if (!this.documentLinkManager.hasProvider(document)) { + return null; + } + return (await this.documentLinkManager.provideDocumentLinks(document, this.token)) || []; + } + async resolveDocumentLink(link) { + return await this.documentLinkManager.resolveDocumentLink(link, this.token); + } + async provideDocumentColors(document) { + return await this.documentColorManager.provideDocumentColors(document, this.token); + } + async provideFoldingRanges(document, context) { + if (!this.formatRangeManager.hasProvider(document)) { + return null; + } + return await this.foldingRangeManager.provideFoldingRanges(document, context, this.token); + } + async provideColorPresentations(color, document) { + return await this.documentColorManager.provideColorPresentations(color, document, this.token); + } + async getCodeLens(document) { + return await this.codeLensManager.provideCodeLenses(document, this.token); + } + async resolveCodeLens(codeLens) { + return await this.codeLensManager.resolveCodeLens(codeLens, this.token); + } + async provideDocumentOnTypeEdits(character, document, position) { + return this.onTypeFormatManager.onCharacterType(character, document, position, this.token); + } + hasOnTypeProvider(character, document) { + return this.onTypeFormatManager.getProvider(document, character) != null; + } + hasProvider(id, document) { + switch (id) { + case 'rename': + return this.renameManager.hasProvider(document); + case 'onTypeEdit': + return this.onTypeFormatManager.hasProvider(document); + case 'documentLink': + return this.documentLinkManager.hasProvider(document); + case 'documentColor': + return this.documentColorManager.hasProvider(document); + case 'foldingRange': + return this.foldingRangeManager.hasProvider(document); + case 'format': + return this.formatManager.hasProvider(document); + case 'codeAction': + return this.codeActionManager.hasProvider(document); + case 'workspaceSymbols': + return this.workspaceSymbolsManager.hasProvider(document); + case 'formatRange': + return this.formatRangeManager.hasProvider(document); + case 'hover': + return this.hoverManager.hasProvider(document); + case 'signature': + return this.signatureManager.hasProvider(document); + case 'documentSymbol': + return this.documentSymbolManager.hasProvider(document); + case 'documentHighlight': + return this.documentHighlightManager.hasProvider(document); + case 'definition': + return this.definitionManager.hasProvider(document); + case 'declaration': + return this.declarationManager.hasProvider(document); + case 'typeDefinition': + return this.typeDefinitionManager.hasProvider(document); + case 'reference': + return this.referenceManager.hasProvider(document); + case 'implementation': + return this.implementationManager.hasProvider(document); + case 'codeLens': + return this.codeLensManager.hasProvider(document); + case 'selectionRange': + return this.selectionRangeManager.hasProvider(document); + default: + throw new Error(`${id} not supported.`); + } + } + dispose() { + // noop + } + createDiagnosticCollection(owner) { + return manager_1.default.create(owner); + } + createCompleteSource(name, shortcut, provider, languageIds, triggerCharacters, priority) { + // track them for resolve + let completeItems = []; + // line used for TextEdit + let hasResolve = typeof provider.resolveCompletionItem === 'function'; + priority = priority == null ? this.completeConfig.priority : priority; + // index set of resolved items + let resolvedIndexes = new Set(); + let waitTime = Math.min(Math.max(50, this.completeConfig.waitTime), 300); + let source = { + name, + priority, + shortcut, + enable: true, + sourceType: types_1.SourceType.Service, + filetypes: languageIds, + triggerCharacters: triggerCharacters || [], + doComplete: async (opt, token) => { + let { triggerCharacter, bufnr } = opt; + resolvedIndexes = new Set(); + let isTrigger = triggerCharacters && triggerCharacters.indexOf(triggerCharacter) != -1; + let triggerKind = vscode_languageserver_protocol_1.CompletionTriggerKind.Invoked; + if (opt.triggerForInComplete) { + triggerKind = vscode_languageserver_protocol_1.CompletionTriggerKind.TriggerForIncompleteCompletions; + } + else if (isTrigger) { + triggerKind = vscode_languageserver_protocol_1.CompletionTriggerKind.TriggerCharacter; + } + if (opt.triggerCharacter) + await util_1.wait(waitTime); + if (token.isCancellationRequested) + return null; + let position = complete.getPosition(opt); + let context = { triggerKind, option: opt }; + if (isTrigger) + context.triggerCharacter = triggerCharacter; + let result; + try { + let doc = workspace_1.default.getDocument(bufnr); + result = await Promise.resolve(provider.provideCompletionItems(doc.textDocument, position, token, context)); + } + catch (e) { + // don't disturb user + logger.error(`Source "${name}" complete error:`, e); + return null; + } + if (!result || token.isCancellationRequested) + return null; + completeItems = Array.isArray(result) ? result : result.items; + if (!completeItems || completeItems.length == 0) + return null; + // used for fixed col + let option = Object.assign({}, opt); + if (typeof result.startcol == 'number') { + option.col = result.startcol; + } + let items = completeItems.map((o, index) => { + let item = this.convertVimCompleteItem(o, shortcut, option); + item.index = index; + return item; + }); + return { + startcol: result.startcol, + isIncomplete: !!result.isIncomplete, + items + }; + }, + onCompleteResolve: async (item, token) => { + let resolving = completeItems[item.index]; + if (!resolving) + return; + if (hasResolve && !resolvedIndexes.has(item.index)) { + let resolved = await Promise.resolve(provider.resolveCompletionItem(resolving, token)); + if (token.isCancellationRequested) + return; + resolvedIndexes.add(item.index); + if (resolved) + Object.assign(resolving, resolved); + } + if (item.documentation == null) { + let { documentation, detail } = resolving; + if (!documentation && !detail) + return; + let docs = []; + if (detail && !item.detailShown && detail != item.word) { + detail = detail.replace(/\n\s*/g, ' '); + if (detail.length) { + let isText = /^[\w-\s.,\t]+$/.test(detail); + let filetype = isText ? 'txt' : await workspace_1.default.nvim.eval('&filetype'); + docs.push({ filetype: isText ? 'txt' : filetype, content: detail }); + } + } + if (documentation) { + if (typeof documentation == 'string') { + docs.push({ + filetype: 'markdown', + content: fixDocumentation(documentation) + }); + } + else if (documentation.value) { + docs.push({ + filetype: documentation.kind == 'markdown' ? 'markdown' : 'txt', + content: fixDocumentation(documentation.value) + }); + } + } + item.documentation = docs; + } + }, + onCompleteDone: async (vimItem, opt) => { + let item = completeItems[vimItem.index]; + if (!item) + return; + let line = opt.linenr - 1; + // tslint:disable-next-line: deprecation + if (item.insertText && !item.textEdit) { + item.textEdit = { + range: vscode_languageserver_protocol_1.Range.create(line, opt.col, line, opt.colnr - 1), + // tslint:disable-next-line: deprecation + newText: item.insertText + }; + } + if (vimItem.line) + Object.assign(opt, { line: vimItem.line }); + try { + let isSnippet = await this.applyTextEdit(item, opt); + if (isSnippet && manager_2.default.isPlainText(item.textEdit.newText)) { + isSnippet = false; + } + let { additionalTextEdits } = item; + if (additionalTextEdits && item.textEdit) { + let r = item.textEdit.range; + additionalTextEdits = additionalTextEdits.filter(edit => { + if (position_1.rangeOverlap(r, edit.range)) { + logger.error('Filtered overlap additionalTextEdit:', edit); + return false; + } + return true; + }); + } + await this.applyAdditionalEdits(additionalTextEdits, opt.bufnr, isSnippet); + if (isSnippet) + await manager_2.default.selectCurrentPlaceholder(); + if (item.command) + commands_1.default.execute(item.command); + } + catch (e) { + logger.error('Error on CompleteDone:', e); + } + }, + shouldCommit: (item, character) => { + let completeItem = completeItems[item.index]; + if (!completeItem) + return false; + let { commitCharacters } = completeItem; + if (commitCharacters && commitCharacters.indexOf(character) !== -1) { + return true; + } + return false; + } + }; + return source; + } + get token() { + this.cancelTokenSource = new vscode_languageserver_protocol_1.CancellationTokenSource(); + return this.cancelTokenSource.token; + } + async applyTextEdit(item, option) { + let { nvim } = this; + let { textEdit } = item; + if (!textEdit) + return false; + let { line, bufnr, linenr } = option; + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return false; + let { range, newText } = textEdit; + let isSnippet = item.insertTextFormat === vscode_languageserver_protocol_1.InsertTextFormat.Snippet; + // replace inserted word + let start = line.substr(0, range.start.character); + let end = line.substr(range.end.character); + if (isSnippet) { + await doc.applyEdits(nvim, [{ + range: vscode_languageserver_protocol_1.Range.create(linenr - 1, 0, linenr, 0), + newText: `${start}${end}\n` + }]); + // can't select, since additionalTextEdits would break selection + let pos = vscode_languageserver_protocol_1.Position.create(linenr - 1, range.start.character); + return await manager_2.default.insertSnippet(newText, false, vscode_languageserver_protocol_1.Range.create(pos, pos)); + } + let newLines = `${start}${newText}${end}`.split('\n'); + if (newLines.length == 1) { + await nvim.call('coc#util#setline', [linenr, newLines[0]]); + await workspace_1.default.moveTo(vscode_languageserver_protocol_1.Position.create(linenr - 1, (start + newText).length)); + } + else { + let buffer = nvim.createBuffer(bufnr); + await buffer.setLines(newLines, { + start: linenr - 1, + end: linenr, + strictIndexing: false + }); + let line = linenr - 1 + newLines.length - 1; + let character = newLines[newLines.length - 1].length - end.length; + await workspace_1.default.moveTo({ line, character }); + } + return false; + } + async applyAdditionalEdits(textEdits, bufnr, snippet) { + if (!textEdits || textEdits.length == 0) + return; + let document = workspace_1.default.getDocument(bufnr); + if (!document) + return; + await document._fetchContent(); + // how to move cursor after edit + let changed = null; + let pos = await workspace_1.default.getCursorPosition(); + if (!snippet) + changed = position_1.getChangedFromEdits(pos, textEdits); + await document.applyEdits(this.nvim, textEdits); + if (changed) + await workspace_1.default.moveTo(vscode_languageserver_protocol_1.Position.create(pos.line + changed.line, pos.character + changed.character)); + } + convertVimCompleteItem(item, shortcut, opt) { + let { echodocSupport, detailField, detailMaxLength, invalidInsertCharacters } = this.completeConfig; + let hasAdditionalEdit = item.additionalTextEdits && item.additionalTextEdits.length > 0; + let isSnippet = item.insertTextFormat === vscode_languageserver_protocol_1.InsertTextFormat.Snippet || hasAdditionalEdit; + let label = item.label.trim(); + // tslint:disable-next-line:deprecation + if (isSnippet && item.insertText && item.insertText.indexOf('$') == -1 && !hasAdditionalEdit) { + // fix wrong insert format + isSnippet = false; + item.insertTextFormat = vscode_languageserver_protocol_1.InsertTextFormat.PlainText; + } + let obj = { + word: complete.getWord(item, opt, invalidInsertCharacters), + abbr: label, + menu: `[${shortcut}]`, + kind: complete.completionKindString(item.kind, this.completionItemKindMap, this.completeConfig.defaultKindText), + sortText: item.sortText || null, + filterText: item.filterText || label, + isSnippet, + dup: item.data && item.data.dup == 0 ? 0 : 1 + }; + if (item && item.detail && detailField != 'preview') { + let detail = item.detail.replace(/\n\s*/g, ' '); + if (string_1.byteLength(detail) < detailMaxLength) { + if (detailField == 'menu') { + obj.menu = `${detail} ${obj.menu}`; + } + else if (detailField == 'abbr') { + obj.abbr = `${obj.abbr} - ${detail}`; + } + obj.detailShown = 1; + } + } + if (item.documentation) { + obj.info = typeof item.documentation == 'string' ? item.documentation : item.documentation.value; + } + else { + obj.info = ''; + } + if (!obj.word) + obj.empty = 1; + if (item.textEdit) + obj.line = opt.line; + if (item.kind == vscode_languageserver_protocol_1.CompletionItemKind.Folder && !obj.abbr.endsWith('/')) { + obj.abbr = obj.abbr + '/'; + } + if (echodocSupport && item.kind >= 2 && item.kind <= 4) { + let fields = [item.detail || '', obj.abbr, obj.word]; + for (let s of fields) { + if (s.indexOf('(') !== -1) { + obj.signature = s; + break; + } + } + } + if (item.preselect) + obj.preselect = true; + item.data = item.data || {}; + if (item.data.optional) + obj.abbr = obj.abbr + '?'; + return obj; + } +} +tslib_1.__decorate([ + check +], Languages.prototype, "getHover", null); +tslib_1.__decorate([ + check +], Languages.prototype, "getDefinition", null); +tslib_1.__decorate([ + check +], Languages.prototype, "getDeclaration", null); +tslib_1.__decorate([ + check +], Languages.prototype, "getTypeDefinition", null); +tslib_1.__decorate([ + check +], Languages.prototype, "getImplementation", null); +tslib_1.__decorate([ + check +], Languages.prototype, "getReferences", null); +tslib_1.__decorate([ + check +], Languages.prototype, "getDocumentSymbol", null); +tslib_1.__decorate([ + check +], Languages.prototype, "getSelectionRanges", null); +tslib_1.__decorate([ + check +], Languages.prototype, "getWorkspaceSymbols", null); +tslib_1.__decorate([ + check +], Languages.prototype, "resolveWorkspaceSymbol", null); +tslib_1.__decorate([ + check +], Languages.prototype, "provideRenameEdits", null); +tslib_1.__decorate([ + check +], Languages.prototype, "prepareRename", null); +tslib_1.__decorate([ + check +], Languages.prototype, "provideDocumentFormattingEdits", null); +tslib_1.__decorate([ + check +], Languages.prototype, "provideDocumentRangeFormattingEdits", null); +tslib_1.__decorate([ + check +], Languages.prototype, "getCodeActions", null); +tslib_1.__decorate([ + check +], Languages.prototype, "getDocumentHighLight", null); +tslib_1.__decorate([ + check +], Languages.prototype, "getDocumentLinks", null); +tslib_1.__decorate([ + check +], Languages.prototype, "resolveDocumentLink", null); +tslib_1.__decorate([ + check +], Languages.prototype, "provideDocumentColors", null); +tslib_1.__decorate([ + check +], Languages.prototype, "provideFoldingRanges", null); +tslib_1.__decorate([ + check +], Languages.prototype, "provideColorPresentations", null); +tslib_1.__decorate([ + check +], Languages.prototype, "getCodeLens", null); +tslib_1.__decorate([ + check +], Languages.prototype, "resolveCodeLens", null); +tslib_1.__decorate([ + check +], Languages.prototype, "provideDocumentOnTypeEdits", null); +exports.default = new Languages(); +//# sourceMappingURL=languages.js.map + +/***/ }), +/* 316 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const vscode_uri_1 = __webpack_require__(180); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const floatFactory_1 = tslib_1.__importDefault(__webpack_require__(317)); +const util_1 = __webpack_require__(174); +const position_1 = __webpack_require__(213); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const buffer_1 = __webpack_require__(323); +const collection_1 = tslib_1.__importDefault(__webpack_require__(326)); +const util_2 = __webpack_require__(325); +const logger = __webpack_require__(186)('diagnostic-manager'); +class DiagnosticManager { + constructor() { + this.enabled = true; + this.buffers = []; + this.lastMessage = ''; + this.collections = []; + this.disposables = []; + this.lastChanageTs = 0; + } + init() { + this.setConfiguration(); + let { nvim } = workspace_1.default; + let { maxWindowHeight, maxWindowWidth } = this.config; + this.floatFactory = new floatFactory_1.default(nvim, workspace_1.default.env, false, maxWindowHeight, maxWindowWidth); + this.disposables.push(vscode_languageserver_protocol_1.Disposable.create(() => { + if (this.timer) + clearTimeout(this.timer); + })); + events_1.default.on('CursorMoved', async () => { + if (this.timer) + clearTimeout(this.timer); + this.timer = setTimeout(async () => { + if (this.config.enableMessage != 'always') + return; + await this.echoMessage(true); + }, this.config.messageDelay); + }, null, this.disposables); + events_1.default.on('InsertEnter', async () => { + if (this.timer) + clearTimeout(this.timer); + this.floatFactory.close(); + }, null, this.disposables); + events_1.default.on('InsertLeave', async (bufnr) => { + this.floatFactory.close(); + let doc = workspace_1.default.getDocument(bufnr); + if (!doc || !this.shouldValidate(doc)) + return; + let { refreshOnInsertMode, refreshAfterSave } = this.config; + if (!refreshOnInsertMode && !refreshAfterSave) { + if (doc.dirty) { + doc.forceSync(); + await util_1.wait(50); + } + let d = 300 - (Date.now() - this.lastChanageTs); + if (d > 0) + await util_1.wait(d); + this.refreshBuffer(doc.uri); + } + }, null, this.disposables); + events_1.default.on('BufEnter', async () => { + if (this.timer) + clearTimeout(this.timer); + if (!this.enabled || !this.config.locationlist) + return; + let doc = await workspace_1.default.document; + if (!doc || doc.buftype == 'quickfix') + return; + if (this.shouldValidate(doc)) { + let refreshed = this.refreshBuffer(doc.uri); + if (refreshed) + return; + } + let curr = await nvim.eval(`getloclist(win_getid(),{'title':1})`); + if (curr.title && curr.title.indexOf('Diagnostics of coc') != -1) { + await nvim.eval(`setloclist(win_getid(),[],'f')`); + } + }, null, this.disposables); + events_1.default.on('BufWritePost', async (bufnr) => { + let buf = this.buffers.find(buf => buf.bufnr == bufnr); + if (buf) + await buf.checkSigns(); + await util_1.wait(100); + if (this.config.refreshAfterSave) { + this.refreshBuffer(buf.uri); + } + }, null, this.disposables); + events_1.default.on(['TextChanged', 'TextChangedI'], () => { + this.lastChanageTs = Date.now(); + }, null, this.disposables); + workspace_1.default.onDidChangeConfiguration(async (e) => { + this.setConfiguration(e); + }, null, this.disposables); + // create buffers + for (let doc of workspace_1.default.documents) { + this.createDiagnosticBuffer(doc); + } + workspace_1.default.onDidOpenTextDocument(textDocument => { + let doc = workspace_1.default.getDocument(textDocument.uri); + this.createDiagnosticBuffer(doc); + }, null, this.disposables); + workspace_1.default.onDidCloseTextDocument(({ uri }) => { + let doc = workspace_1.default.getDocument(uri); + if (!doc) + return; + this.disposeBuffer(doc.bufnr); + }, null, this.disposables); + this.setConfigurationErrors(true); + workspace_1.default.configurations.onError(async () => { + this.setConfigurationErrors(); + }, null, this.disposables); + let { errorSign, warningSign, infoSign, hintSign } = this.config; + nvim.pauseNotification(); + nvim.command(`sign define CocError text=${errorSign} linehl=CocErrorLine texthl=CocErrorSign`, true); + nvim.command(`sign define CocWarning text=${warningSign} linehl=CocWarningLine texthl=CocWarningSign`, true); + nvim.command(`sign define CocInfo text=${infoSign} linehl=CocInfoLine texthl=CocInfoSign`, true); + nvim.command(`sign define CocHint text=${hintSign} linehl=CocHintLine texthl=CocHintSign`, true); + if (this.config.virtualText && workspace_1.default.isNvim) { + nvim.call('coc#util#init_virtual_hl', [], true); + } + nvim.resumeNotification(false, true).logError(); + } + createDiagnosticBuffer(doc) { + if (!this.shouldValidate(doc)) + return; + let idx = this.buffers.findIndex(b => b.bufnr == doc.bufnr); + if (idx == -1) { + let buf = new buffer_1.DiagnosticBuffer(doc.bufnr, this.config); + this.buffers.push(buf); + buf.onDidRefresh(() => { + if (workspace_1.default.insertMode) + return; + this.echoMessage(true).logError(); + }); + } + } + setConfigurationErrors(init) { + let collections = this.collections; + let collection = collections.find(o => o.name == 'config'); + if (!collection) { + collection = this.create('config'); + } + else { + collection.clear(); + } + let { errorItems } = workspace_1.default.configurations; + if (errorItems && errorItems.length) { + if (init) + workspace_1.default.showMessage(`settings file parse error, run ':CocList diagnostics'`, 'error'); + let entries = new Map(); + for (let item of errorItems) { + let { uri } = item.location; + let diagnostics = entries.get(uri) || []; + diagnostics.push(vscode_languageserver_protocol_1.Diagnostic.create(item.location.range, item.message, vscode_languageserver_protocol_1.DiagnosticSeverity.Error)); + entries.set(uri, diagnostics); + } + collection.set(Array.from(entries)); + } + } + /** + * Create collection by name + */ + create(name) { + let collection = new collection_1.default(name); + this.collections.push(collection); + collection.onDidDiagnosticsChange(async (uri) => { + if (this.config.refreshAfterSave) + return; + this.refreshBuffer(uri); + }); + collection.onDidDiagnosticsClear(uris => { + for (let uri of uris) { + this.refreshBuffer(uri); + } + }); + collection.onDispose(() => { + let idx = this.collections.findIndex(o => o == collection); + if (idx !== -1) + this.collections.splice(idx, 1); + }); + return collection; + } + /** + * Get diagnostics ranges from document + */ + getSortedRanges(uri, severity) { + let collections = this.getCollections(uri); + let res = []; + let level = severity ? util_2.severityLevel(severity) : 0; + for (let collection of collections) { + let diagnostics = collection.get(uri); + if (level) + diagnostics = diagnostics.filter(o => o.severity == level); + let ranges = diagnostics.map(o => o.range); + res.push(...ranges); + } + res.sort((a, b) => { + if (a.start.line != b.start.line) { + return a.start.line - b.start.line; + } + return a.start.character - b.start.character; + }); + return res; + } + /** + * Get readonly diagnostics for a buffer + */ + getDiagnostics(uri) { + let collections = this.getCollections(uri); + let { level } = this.config; + let res = []; + for (let collection of collections) { + let items = collection.get(uri); + if (!items) + continue; + if (level && level < vscode_languageserver_protocol_1.DiagnosticSeverity.Hint) { + items = items.filter(s => s.severity == null || s.severity <= level); + } + res.push(...items); + } + res.sort((a, b) => { + if (a.severity == b.severity) { + let d = position_1.comparePosition(a.range.start, b.range.start); + if (d != 0) + return d; + if (a.source == b.source) + return a.message > b.message ? 1 : -1; + return a.source > b.source ? 1 : -1; + } + return a.severity - b.severity; + }); + return res; + } + getDiagnosticsInRange(document, range) { + let collections = this.getCollections(document.uri); + let res = []; + for (let collection of collections) { + let items = collection.get(document.uri); + if (!items) + continue; + for (let item of items) { + if (position_1.rangeIntersect(item.range, range)) { + res.push(item); + } + } + } + return res; + } + /** + * Jump to previouse diagnostic position + */ + async jumpPrevious(severity) { + let buffer = await this.nvim.buffer; + let document = workspace_1.default.getDocument(buffer.id); + if (!document) + return; + let offset = await workspace_1.default.getOffset(); + if (offset == null) + return; + let ranges = this.getSortedRanges(document.uri, severity); + if (ranges.length == 0) { + workspace_1.default.showMessage('Empty diagnostics', 'warning'); + return; + } + let { textDocument } = document; + for (let i = ranges.length - 1; i >= 0; i--) { + if (textDocument.offsetAt(ranges[i].end) < offset) { + await workspace_1.default.moveTo(ranges[i].start); + return; + } + } + await workspace_1.default.moveTo(ranges[ranges.length - 1].start); + } + /** + * Jump to next diagnostic position + */ + async jumpNext(severity) { + let buffer = await this.nvim.buffer; + let document = workspace_1.default.getDocument(buffer.id); + let offset = await workspace_1.default.getOffset(); + let ranges = this.getSortedRanges(document.uri, severity); + if (ranges.length == 0) { + workspace_1.default.showMessage('Empty diagnostics', 'warning'); + return; + } + let { textDocument } = document; + for (let i = 0; i <= ranges.length - 1; i++) { + if (textDocument.offsetAt(ranges[i].start) > offset) { + await workspace_1.default.moveTo(ranges[i].start); + return; + } + } + await workspace_1.default.moveTo(ranges[0].start); + } + /** + * All diagnostics of current workspace + */ + getDiagnosticList() { + let res = []; + for (let collection of this.collections) { + collection.forEach((uri, diagnostics) => { + let file = vscode_uri_1.URI.parse(uri).fsPath; + for (let diagnostic of diagnostics) { + let { start } = diagnostic.range; + let o = { + file, + lnum: start.line + 1, + col: start.character + 1, + message: `[${diagnostic.source || collection.name}${diagnostic.code ? ' ' + diagnostic.code : ''}] ${diagnostic.message}`, + severity: util_2.getSeverityName(diagnostic.severity), + level: diagnostic.severity || 0, + location: vscode_languageserver_protocol_1.Location.create(uri, diagnostic.range) + }; + res.push(o); + } + }); + } + res.sort((a, b) => { + if (a.level !== b.level) { + return a.level - b.level; + } + if (a.file !== b.file) { + return a.file > b.file ? 1 : -1; + } + else { + if (a.lnum != b.lnum) { + return a.lnum - b.lnum; + } + return a.col - b.col; + } + }); + return res; + } + async getDiagnosticsAt(bufnr, cursor) { + let pos = vscode_languageserver_protocol_1.Position.create(cursor[0], cursor[1]); + let buffer = this.buffers.find(o => o.bufnr == bufnr); + if (!buffer) + return []; + let { checkCurrentLine } = this.config; + let diagnostics = buffer.diagnostics.filter(o => { + if (checkCurrentLine) + return position_1.lineInRange(pos.line, o.range); + return position_1.positionInRange(pos, o.range) == 0; + }); + diagnostics.sort((a, b) => a.severity - b.severity); + return diagnostics; + } + async getCurrentDiagnostics() { + let [bufnr, cursor] = await this.nvim.eval('[bufnr("%"),coc#util#cursor()]'); + return await this.getDiagnosticsAt(bufnr, cursor); + } + /** + * Echo diagnostic message of currrent position + */ + async echoMessage(truncate = false) { + const config = this.config; + if (!this.enabled || config.enableMessage == 'never') + return; + if (this.timer) + clearTimeout(this.timer); + let useFloat = config.messageTarget == 'float'; + let [bufnr, cursor] = await this.nvim.eval('[bufnr("%"),coc#util#cursor()]'); + if (useFloat) { + let { buffer } = this.floatFactory; + if (buffer && bufnr == buffer.id) + return; + } + let diagnostics = await this.getDiagnosticsAt(bufnr, cursor); + if (diagnostics.length == 0) { + if (useFloat) { + this.floatFactory.close(); + } + else { + let echoLine = await this.nvim.call('coc#util#echo_line'); + if (this.lastMessage && echoLine.startsWith(this.lastMessage)) { + this.nvim.command('echo ""', true); + } + } + return; + } + if (truncate && workspace_1.default.insertMode) + return; + let docs = []; + let ft = ''; + if (Object.keys(config.filetypeMap).length > 0) { + const filetype = await this.nvim.eval('&filetype'); + const defaultFiletype = config.filetypeMap['default'] || ''; + ft = config.filetypeMap[filetype] || (defaultFiletype == 'bufferType' ? filetype : defaultFiletype); + } + diagnostics.forEach(diagnostic => { + let { source, code, severity, message } = diagnostic; + let s = util_2.getSeverityName(severity)[0]; + let str = `[${source}${code ? ' ' + code : ''}] [${s}] ${message}`; + let filetype = 'Error'; + if (ft === '') { + switch (diagnostic.severity) { + case vscode_languageserver_protocol_1.DiagnosticSeverity.Hint: + filetype = 'Hint'; + break; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Warning: + filetype = 'Warning'; + break; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Information: + filetype = 'Info'; + break; + } + } + else { + filetype = ft; + } + docs.push({ filetype, content: str }); + }); + if (useFloat) { + await this.floatFactory.create(docs); + } + else { + let lines = docs.map(d => d.content).join('\n').split(/\r?\n/); + if (lines.length) { + await this.nvim.command('echo ""'); + this.lastMessage = lines[0].slice(0, 30); + await workspace_1.default.echoLines(lines, truncate); + } + } + } + async jumpRelated() { + let diagnostics = await this.getCurrentDiagnostics(); + if (!diagnostics) + return; + let diagnostic = diagnostics.find(o => o.relatedInformation != null); + if (!diagnostic) + return; + let locations = diagnostic.relatedInformation.map(o => o.location); + if (locations.length == 1) { + await workspace_1.default.jumpTo(locations[0].uri, locations[0].range.start); + } + else if (locations.length > 1) { + await workspace_1.default.showLocations(locations); + } + } + disposeBuffer(bufnr) { + let idx = this.buffers.findIndex(buf => buf.bufnr == bufnr); + if (idx == -1) + return; + let buf = this.buffers[idx]; + buf.dispose(); + this.buffers.splice(idx, 1); + for (let collection of this.collections) { + collection.delete(buf.uri); + } + buf.clear().logError(); + } + hideFloat() { + if (this.floatFactory) { + this.floatFactory.close(); + } + } + dispose() { + for (let collection of this.collections) { + collection.dispose(); + } + if (this.floatFactory) { + this.floatFactory.dispose(); + } + this.buffers.splice(0, this.buffers.length); + this.collections = []; + util_1.disposeAll(this.disposables); + } + get nvim() { + return workspace_1.default.nvim; + } + setConfiguration(event) { + if (event && !event.affectsConfiguration('diagnostic')) + return; + let preferences = workspace_1.default.getConfiguration('coc.preferences.diagnostic'); + let config = workspace_1.default.getConfiguration('diagnostic'); + function getConfig(key, defaultValue) { + return preferences.get(key, config.get(key, defaultValue)); + } + let messageTarget = getConfig('messageTarget', 'float'); + if (messageTarget == 'float' && !workspace_1.default.env.floating && !workspace_1.default.env.textprop) { + messageTarget = 'echo'; + } + this.config = { + messageTarget, + srcId: workspace_1.default.createNameSpace('coc-diagnostic') || 1000, + virtualTextSrcId: workspace_1.default.createNameSpace('diagnostic-virtualText'), + checkCurrentLine: getConfig('checkCurrentLine', false), + enableSign: getConfig('enableSign', true), + maxWindowHeight: getConfig('maxWindowHeight', 10), + maxWindowWidth: getConfig('maxWindowWidth', 80), + enableMessage: getConfig('enableMessage', 'always'), + joinMessageLines: getConfig('joinMessageLines', false), + messageDelay: getConfig('messageDelay', 250), + virtualText: getConfig('virtualText', false), + virtualTextPrefix: getConfig('virtualTextPrefix', " "), + virtualTextLineSeparator: getConfig('virtualTextLineSeparator', " \\ "), + virtualTextLines: getConfig('virtualTextLines', 3), + displayByAle: getConfig('displayByAle', false), + level: util_2.severityLevel(getConfig('level', 'hint')), + locationlist: getConfig('locationlist', true), + signOffset: getConfig('signOffset', 1000), + errorSign: getConfig('errorSign', '>>'), + warningSign: getConfig('warningSign', '>>'), + infoSign: getConfig('infoSign', '>>'), + hintSign: getConfig('hintSign', '>>'), + refreshAfterSave: getConfig('refreshAfterSave', false), + refreshOnInsertMode: getConfig('refreshOnInsertMode', false), + filetypeMap: getConfig('filetypeMap', {}), + }; + this.enabled = getConfig('enable', true); + if (this.config.displayByAle) { + this.enabled = false; + } + if (event) { + for (let severity of ['error', 'info', 'warning', 'hint']) { + let key = `diagnostic.${severity}Sign`; + if (event.affectsConfiguration(key)) { + let text = config.get(`${severity}Sign`, '>>'); + let name = severity[0].toUpperCase() + severity.slice(1); + this.nvim.command(`sign define Coc${name} text=${text} linehl=Coc${name}Line texthl=Coc${name}Sign`, true); + } + } + } + } + getCollections(uri) { + return this.collections.filter(c => c.has(uri)); + } + shouldValidate(doc) { + return doc != null && doc.buftype == ''; + } + refreshBuffer(uri) { + let { insertMode } = workspace_1.default; + if (insertMode && !this.config.refreshOnInsertMode) + return; + let buf = this.buffers.find(buf => buf.uri == uri); + if (!buf) + return; + let { displayByAle } = this.config; + if (!displayByAle) { + let diagnostics = this.getDiagnostics(uri); + if (this.enabled) { + buf.refresh(diagnostics); + return true; + } + } + else { + let { nvim } = this; + nvim.pauseNotification(); + for (let collection of this.collections) { + let diagnostics = collection.get(uri); + const { level } = this.config; + if (level) { + diagnostics = diagnostics.filter(o => o.severity && o.severity <= level); + } + let aleItems = diagnostics.map(o => { + let { range } = o; + return { + text: o.message, + code: o.code, + lnum: range.start.line + 1, + col: range.start.character + 1, + end_lnum: range.end.line + 1, + end_col: range.end.character, + type: util_2.getSeverityType(o.severity) + }; + }); + nvim.call('ale#other_source#ShowResults', [buf.bufnr, collection.name, aleItems], true); + } + nvim.resumeNotification(false, true).logError(); + } + return false; + } +} +exports.DiagnosticManager = DiagnosticManager; +exports.default = new DiagnosticManager(); +//# sourceMappingURL=manager.js.map + +/***/ }), +/* 317 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const manager_1 = tslib_1.__importDefault(__webpack_require__(233)); +const util_1 = __webpack_require__(174); +const object_1 = __webpack_require__(190); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const floatBuffer_1 = tslib_1.__importDefault(__webpack_require__(318)); +const debounce_1 = tslib_1.__importDefault(__webpack_require__(176)); +const popup_1 = tslib_1.__importDefault(__webpack_require__(322)); +const array_1 = __webpack_require__(212); +const logger = __webpack_require__(186)('model-float'); +// factory class for floating window +class FloatFactory { + constructor(nvim, env, preferTop = false, maxHeight = 999, maxWidth, autoHide = true) { + this.nvim = nvim; + this.env = env; + this.preferTop = preferTop; + this.maxHeight = maxHeight; + this.maxWidth = maxWidth; + this.autoHide = autoHide; + this.disposables = []; + this.alignTop = false; + this.pumAlignTop = false; + this.createTs = 0; + this.cursor = [0, 0]; + this.shown = false; + if (!env.floating && !env.textprop) + return; + this.maxWidth = Math.min(maxWidth || 80, this.columns - 10); + events_1.default.on('BufEnter', bufnr => { + if (this.buffer && bufnr == this.buffer.id) + return; + if (bufnr == this.targetBufnr) + return; + this.close(); + }, null, this.disposables); + events_1.default.on('InsertLeave', bufnr => { + if (this.buffer && bufnr == this.buffer.id) + return; + if (manager_1.default.isActived(bufnr)) + return; + this.close(); + }, null, this.disposables); + events_1.default.on('MenuPopupChanged', async (ev, cursorline) => { + let pumAlignTop = this.pumAlignTop = cursorline > ev.row; + if (pumAlignTop == this.alignTop) { + this.close(); + } + }, null, this.disposables); + events_1.default.on('CursorMoved', debounce_1.default((bufnr, cursor) => { + if (Date.now() - this.createTs < 100) + return; + this.onCursorMoved(false, bufnr, cursor); + }, 100), null, this.disposables); + events_1.default.on('CursorMovedI', this.onCursorMoved.bind(this, true), null, this.disposables); + } + onCursorMoved(insertMode, bufnr, cursor) { + if (!this.window || this.buffer && bufnr == this.buffer.id) + return; + if (bufnr == this.targetBufnr && object_1.equals(cursor, this.cursor)) + return; + if (this.autoHide) { + this.close(); + return; + } + if (!insertMode || bufnr != this.targetBufnr || (this.cursor && cursor[0] != this.cursor[0])) { + this.close(); + return; + } + } + async checkFloatBuffer() { + let { floatBuffer, nvim, window } = this; + if (this.env.textprop) { + let valid = await this.activated(); + if (!valid) + window = null; + if (!window) { + this.popup = await popup_1.default(nvim, [''], { + padding: [0, 1, 0, 1], + highlight: 'CocFloating', + tab: -1, + }); + let win = this.window = nvim.createWindow(this.popup.id); + nvim.pauseNotification(); + win.setVar('float', 1, true); + win.setOption('linebreak', true, true); + win.setOption('showbreak', '', true); + win.setOption('conceallevel', 2, true); + await nvim.resumeNotification(); + } + let buffer = this.nvim.createBuffer(this.popup.bufferId); + this.floatBuffer = new floatBuffer_1.default(nvim, buffer, nvim.createWindow(this.popup.id)); + } + else { + if (floatBuffer) { + let valid = await floatBuffer.valid; + if (valid) + return; + } + let buf = await this.nvim.createNewBuffer(false, true); + await buf.setOption('buftype', 'nofile'); + await buf.setOption('bufhidden', 'hide'); + this.floatBuffer = new floatBuffer_1.default(this.nvim, buf); + } + } + get columns() { + return this.env.columns; + } + get lines() { + return this.env.lines - this.env.cmdheight - 1; + } + async getBoundings(docs, offsetX = 0) { + let { nvim, preferTop } = this; + let { columns, lines } = this; + let alignTop = false; + let [row, col] = await nvim.call('coc#util#win_position'); + let maxWidth = this.maxWidth; + let height = this.floatBuffer.getHeight(docs, maxWidth); + height = Math.min(height, this.maxHeight); + if (!preferTop) { + if (lines - row < height && row > height) { + alignTop = true; + } + } + else { + if (row >= height || row >= lines - row) { + alignTop = true; + } + } + if (alignTop) + docs.reverse(); + await this.floatBuffer.setDocuments(docs, maxWidth); + let { width } = this.floatBuffer; + if (offsetX) { + offsetX = Math.min(col - 1, offsetX); + if (col - offsetX + width > columns) { + offsetX = col - offsetX + width - columns; + } + } + this.alignTop = alignTop; + return { + height: alignTop ? Math.max(1, Math.min(row, height)) : Math.max(1, Math.min(height, (lines - row))), + width: Math.min(columns, width), + row: alignTop ? -height : 1, + col: offsetX == 0 ? 0 : -offsetX, + relative: 'cursor' + }; + } + async create(docs, allowSelection = false, offsetX = 0) { + let shown = await this.createPopup(docs, allowSelection, offsetX); + if (!shown) + this.close(false); + } + async createPopup(docs, allowSelection = false, offsetX = 0) { + if (this.tokenSource) { + this.tokenSource.cancel(); + } + if (docs.length == 0) + return false; + this.createTs = Date.now(); + this.targetBufnr = workspace_1.default.bufnr; + let tokenSource = this.tokenSource = new vscode_languageserver_protocol_1.CancellationTokenSource(); + let token = tokenSource.token; + await this.checkFloatBuffer(); + let config = await this.getBoundings(docs, offsetX); + let [mode, line, col, visible] = await this.nvim.eval('[mode(),line("."),col("."),pumvisible()]'); + this.cursor = [line, col]; + if (visible && this.alignTop == this.pumAlignTop) + return false; + if (!config || token.isCancellationRequested) + return false; + if (!this.checkMode(mode, allowSelection)) + return false; + let { nvim, alignTop } = this; + if (mode == 's') + await nvim.call('feedkeys', ['\x1b', 'in']); + // helps to fix undo issue, don't know why. + if (workspace_1.default.isNvim && mode.startsWith('i')) + await nvim.eval('feedkeys("\\u", "n")'); + let reuse = false; + if (workspace_1.default.isNvim) { + reuse = this.window && await this.window.valid; + if (!reuse) + this.window = await nvim.openFloatWindow(this.buffer, false, config); + } + if (token.isCancellationRequested) + return false; + nvim.pauseNotification(); + if (workspace_1.default.isNvim) { + if (!reuse) { + nvim.command(`noa call win_gotoid(${this.window.id})`, true); + this.window.setVar('float', 1, true); + nvim.command(`setl nospell nolist wrap linebreak foldcolumn=1`, true); + nvim.command(`setl nonumber norelativenumber nocursorline nocursorcolumn colorcolumn=`, true); + nvim.command(`setl signcolumn=no conceallevel=2 concealcursor=n`, true); + nvim.command(`setl winhl=Normal:CocFloating,NormalNC:CocFloating,FoldColumn:CocFloating`, true); + nvim.call('coc#util#do_autocmd', ['CocOpenFloat'], true); + } + else { + this.window.setConfig(config, true); + nvim.command(`noa call win_gotoid(${this.window.id})`, true); + } + this.floatBuffer.setLines(); + nvim.command(`normal! ${alignTop ? 'G' : 'gg'}0`, true); + nvim.command('noa wincmd p', true); + } + else { + let filetypes = array_1.distinct(docs.map(d => d.filetype)); + if (filetypes.length == 1) { + this.popup.setFiletype(filetypes[0]); + } + this.popup.move({ + line: cursorPostion(config.row), + col: cursorPostion(config.col), + minwidth: config.width - 2, + minheight: config.height, + maxwidth: config.width - 2, + maxheight: config.height, + firstline: alignTop ? -1 : 1 + }); + this.floatBuffer.setLines(); + nvim.command('redraw', true); + } + let [, err] = await nvim.resumeNotification(); + if (err) { + workspace_1.default.showMessage(`Error on ${err[0]}: ${err[1]} - ${err[2]}`, 'error'); + return false; + } + if (mode == 's') + await manager_1.default.selectCurrentPlaceholder(false); + return true; + } + checkMode(mode, allowSelection) { + if (mode == 's' && allowSelection) { + return true; + } + return ['i', 'n', 'ic'].indexOf(mode) != -1; + } + /** + * Close float window + */ + close(cancel = true) { + if (cancel && this.tokenSource) { + if (this.tokenSource) { + this.tokenSource.cancel(); + this.tokenSource = null; + } + } + let { window, popup } = this; + this.shown = false; + if (this.env.textprop) { + if (popup) + popup.dispose(); + } + else if (window) { + window.close(true, true); + } + } + dispose() { + if (this.tokenSource) { + this.tokenSource.cancel(); + } + util_1.disposeAll(this.disposables); + } + get buffer() { + return this.floatBuffer ? this.floatBuffer.buffer : null; + } + async activated() { + if (this.env.textprop) { + if (!this.popup) + return false; + return await this.popup.visible(); + } + if (!this.window) + return false; + let valid = await this.window.valid; + return valid; + } +} +exports.default = FloatFactory; +function cursorPostion(n) { + if (n == 0) + return 'cursor'; + if (n < 0) + return `cursor${n}`; + return `cursor+${n}`; +} +//# sourceMappingURL=floatFactory.js.map + +/***/ }), +/* 318 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const highlight_1 = __webpack_require__(319); +const string_1 = __webpack_require__(210); +const array_1 = __webpack_require__(212); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('model-floatBuffer'); +class FloatBuffer { + constructor(nvim, buffer, window) { + this.nvim = nvim; + this.buffer = buffer; + this.window = window; + this.lines = []; + this.positions = []; + this.enableHighlight = true; + this.tabstop = 2; + this.width = 0; + let config = workspace_1.default.getConfiguration('coc.preferences'); + this.enableHighlight = config.get('enableFloatHighlight', true); + buffer.getOption('tabstop').then(val => { + this.tabstop = val; + }, _e => { + // noop + }); + } + getHeight(docs, maxWidth) { + let l = 0; + for (let doc of docs) { + let lines = doc.content.split(/\r?\n/); + if (doc.filetype == 'markdown') { + lines = lines.filter(s => !s.startsWith('```')); + } + for (let line of lines) { + l = l + Math.max(1, Math.ceil(string_1.byteLength(line) / (maxWidth - 4))); + } + } + return l + docs.length - 1; + } + get valid() { + return this.buffer.valid; + } + calculateFragments(docs, maxWidth) { + let fragments = []; + let idx = 0; + let currLine = 0; + let newLines = []; + let fill = false; + let positions = this.positions = []; + for (let doc of docs) { + let lines = []; + let content = doc.content.replace(/\s+$/, ''); + let arr = content.split(/\r?\n/); + if (['Error', 'Info', 'Warning', 'Hint'].indexOf(doc.filetype) !== -1) { + fill = true; + } + // let [start, end] = doc.active || [] + for (let str of arr) { + lines.push(str); + if (doc.active) { + let part = str.slice(doc.active[0], doc.active[1]); + positions.push([currLine + 1, doc.active[0] + 1, string_1.byteLength(part)]); + } + } + fragments.push({ + start: currLine, + lines, + filetype: doc.filetype + }); + newLines.push(...lines.filter(s => !/^\s*```/.test(s))); + if (idx != docs.length - 1) { + newLines.push('—'); + currLine = newLines.length; + } + idx = idx + 1; + } + let width = this.width = Math.min(Math.max(...newLines.map(s => this.getWidth(s))) + 2, maxWidth); + this.lines = newLines.map(s => { + if (s == '—') + return '—'.repeat(width - 2); + return s; + }); + return fragments; + } + getWidth(line) { + let { tabstop } = this; + line = line.replace(/\t/g, ' '.repeat(tabstop)); + return string_1.byteLength(line); + } + async setDocuments(docs, maxWidth) { + let fragments = this.calculateFragments(docs, maxWidth); + let filetype = await this.nvim.eval('&filetype'); + if (workspace_1.default.isNvim) { + fragments = fragments.reduce((p, c) => { + p.push(...this.splitFragment(c, filetype)); + return p; + }, []); + } + if (this.enableHighlight) { + let arr = await Promise.all(fragments.map(f => { + return highlight_1.getHiglights(f.lines, f.filetype).then(highlights => { + return highlights.map(highlight => { + return Object.assign({}, highlight, { line: highlight.line + f.start }); + }); + }); + })); + this.highlights = arr.reduce((p, c) => p.concat(c), []); + } + else { + this.highlights = []; + } + } + splitFragment(fragment, defaultFileType) { + let res = []; + let filetype = fragment.filetype; + let lines = []; + let curr = fragment.start; + let inBlock = false; + for (let line of fragment.lines) { + let ms = line.match(/^\s*```\s*(\w+)?/); + if (ms != null) { + if (lines.length) { + res.push({ lines, filetype: this.fixFiletype(filetype), start: curr - lines.length }); + lines = []; + } + inBlock = !inBlock; + filetype = inBlock ? ms[1] || defaultFileType : fragment.filetype; + } + else { + lines.push(line); + curr = curr + 1; + } + } + if (lines.length) { + res.push({ lines, filetype: this.fixFiletype(filetype), start: curr - lines.length }); + lines = []; + } + return res; + } + fixFiletype(filetype) { + if (filetype == 'ts') + return 'typescript'; + if (filetype == 'js') + return 'javascript'; + if (filetype == 'bash') + return 'sh'; + return filetype; + } + setLines() { + let { buffer, lines, nvim, highlights } = this; + if (this.window) { + nvim.call('win_execute', [this.window.id, 'call clearmatches([])'], true); + } + else { + nvim.call('clearmatches', [], true); + } + buffer.clearNamespace(-1, 0, -1); + buffer.setLines(lines, { start: 0, end: -1, strictIndexing: false }, true); + if (highlights.length) { + let positions = []; + for (let highlight of highlights) { + buffer.addHighlight(Object.assign({ srcId: workspace_1.default.createNameSpace('coc-float') }, highlight)).catch(_e => { + // noop + }); + if (highlight.isMarkdown) { + let line = lines[highlight.line]; + if (line) { + let before = line[string_1.characterIndex(line, highlight.colStart)]; + let after = line[string_1.characterIndex(line, highlight.colEnd) - 1]; + if (before == after && ['_', '`', '*'].indexOf(before) !== -1) { + positions.push([highlight.line + 1, highlight.colStart + 1]); + positions.push([highlight.line + 1, highlight.colEnd]); + } + if (highlight.colEnd - highlight.colStart == 2 && before == '\\') { + positions.push([highlight.line + 1, highlight.colStart + 1]); + } + } + } + } + for (let arr of array_1.group(positions, 8)) { + if (this.window) { + nvim.call('win_execute', [this.window.id, `call matchaddpos('Conceal', ${JSON.stringify(arr)},11)`], true); + } + else { + nvim.call('matchaddpos', ['Conceal', arr, 11], true); + } + } + } + for (let arr of array_1.group(this.positions || [], 8)) { + arr = arr.filter(o => o[2] != 0); + if (arr.length) { + if (this.window) { + nvim.call('win_execute', [this.window.id, `call matchaddpos('CocUnderline', ${JSON.stringify(arr)},12)`], true); + } + else { + nvim.call('matchaddpos', ['CocUnderline', arr, 12], true); + } + } + } + } +} +exports.default = FloatBuffer; +//# sourceMappingURL=floatBuffer.js.map + +/***/ }), +/* 319 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const neovim_1 = __webpack_require__(4); +const cp = tslib_1.__importStar(__webpack_require__(175)); +const crypto_1 = __webpack_require__(159); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const lodash_1 = __webpack_require__(312); +const os_1 = tslib_1.__importDefault(__webpack_require__(56)); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const string_1 = __webpack_require__(210); +const processes_1 = __webpack_require__(320); +const uuid = __webpack_require__(321); +const logger = __webpack_require__(186)('util-highlights'); +const diagnosticFiletypes = ['Error', 'Warning', 'Info', 'Hint']; +const cache = {}; +let env = null; +// get highlights by send text to another neovim instance. +function getHiglights(lines, filetype) { + const hlMap = new Map(); + const content = lines.join('\n'); + if (diagnosticFiletypes.indexOf(filetype) != -1) { + let highlights = lines.map((line, i) => { + return { + line: i, + colStart: 0, + colEnd: string_1.byteLength(line), + hlGroup: `Coc${filetype}Float` + }; + }); + return Promise.resolve(highlights); + } + if (filetype == 'javascriptreact') { + filetype = 'javascript'; + } + if (filetype == 'typescriptreact') { + filetype = 'typescript'; + } + const id = crypto_1.createHash('md5').update(content).digest('hex'); + if (cache[id]) + return Promise.resolve(cache[id]); + if (workspace_1.default.env.isVim) + return Promise.resolve([]); + const res = []; + let nvim; + return new Promise(async (resolve) => { + if (!env) { + env = await workspace_1.default.nvim.call('coc#util#highlight_options'); + if (!env) + resolve([]); + let paths = env.runtimepath.split(','); + let dirs = paths.filter(p => { + if (env.colorscheme) { + let schemeFile = path_1.default.join(p, `colors/${env.colorscheme}.vim`); + if (fs_1.default.existsSync(schemeFile)) + return true; + } + if (fs_1.default.existsSync(path_1.default.join(p, 'syntax'))) + return true; + if (fs_1.default.existsSync(path_1.default.join(p, 'after/syntax'))) + return true; + return false; + }); + env.runtimepath = dirs.join(','); + } + let prog = workspace_1.default.env.progpath || 'nvim'; + let proc = cp.spawn(prog, ['-u', 'NORC', '-i', 'NONE', '--embed', '--noplugin', uuid()], { + shell: false, + cwd: os_1.default.tmpdir(), + env: lodash_1.omit(process.env, ['NVIM_LISTEN_ADDRESS', 'VIM_NODE_RPC']) + }); + proc.on('error', error => { + logger.info('highlight error:', error); + resolve([]); + }); + let timer; + let exited = false; + const exit = () => { + if (exited) + return; + exited = true; + if (timer) + clearTimeout(timer); + if (nvim) { + nvim.command('qa!').catch(() => { + let killed = processes_1.terminate(proc); + if (!killed) { + setTimeout(() => { + processes_1.terminate(proc); + }, 50); + } + }); + } + }; + try { + proc.once('exit', () => { + if (exited) + return; + logger.info('highlight nvim exited.'); + resolve([]); + }); + timer = setTimeout(() => { + exit(); + resolve([]); + }, 500); + nvim = neovim_1.attach({ proc }, null, false); + const callback = (method, args) => { + if (method == 'redraw') { + for (let arr of args) { + let [name, ...list] = arr; + if (name == 'hl_attr_define') { + for (let item of list) { + let id = item[0]; + let { hi_name } = item[item.length - 1][0]; + hlMap.set(id, hi_name); + } + } + if (name == 'grid_line') { + // logger.debug('list:', JSON.stringify(list, null, 2)) + for (let def of list) { + let [, line, col, cells] = def; + if (line >= lines.length) + continue; + let colStart = 0; + let hlGroup = ''; + let currId = 0; + // tslint:disable-next-line: prefer-for-of + for (let i = 0; i < cells.length; i++) { + let cell = cells[i]; + let [ch, hlId, repeat] = cell; + repeat = repeat || 1; + let len = string_1.byteLength(ch.repeat(repeat)); + // append result + if (hlId == 0 || (hlId > 0 && hlId != currId)) { + if (hlGroup) { + res.push({ + line, + hlGroup, + colStart, + colEnd: col, + isMarkdown: filetype == 'markdown' + }); + } + colStart = col; + hlGroup = hlId == 0 ? '' : hlMap.get(hlId); + } + if (hlId != null) + currId = hlId; + col = col + len; + } + if (hlGroup) { + res.push({ + hlGroup, + line, + colStart, + colEnd: col, + isMarkdown: filetype == 'markdown' + }); + } + } + cache[id] = res; + exit(); + resolve(res); + } + } + } + }; + nvim.on('notification', callback); + await nvim.callAtomic([ + ['nvim_set_option', ['runtimepath', env.runtimepath]], + ['nvim_command', [`runtime syntax/${filetype}.vim`]], + ['nvim_command', [`colorscheme ${env.colorscheme || 'default'}`]], + ['nvim_command', [`set background=${env.background}`]], + ['nvim_command', ['set nowrap']], + ['nvim_command', ['set noswapfile']], + ['nvim_command', ['set nobackup']], + ['nvim_command', ['set noshowmode']], + ['nvim_command', ['set noruler']], + ['nvim_command', ['set laststatus=0']], + ]); + let buf = await nvim.buffer; + await buf.setLines(lines, { start: 0, end: -1, strictIndexing: false }); + await buf.setOption('filetype', filetype); + await nvim.uiAttach(200, lines.length + 1, { + ext_hlstate: true, + ext_linegrid: true + }); + } + catch (e) { + logger.error(e); + exit(); + resolve([]); + } + }); +} +exports.getHiglights = getHiglights; +//# sourceMappingURL=highlight.js.map + +/***/ }), +/* 320 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +const cp = tslib_1.__importStar(__webpack_require__(175)); +const path_1 = __webpack_require__(57); +const isWebpack = typeof __webpack_require__ === "function"; +const isWindows = process.platform === 'win32'; +const isMacintosh = process.platform === 'darwin'; +const isLinux = process.platform === 'linux'; +const pluginRoot = isWebpack ? path_1.dirname(__dirname) : path_1.resolve(__dirname, '../..'); +function terminate(process, cwd) { + if (isWindows) { + try { + // This we run in Atom execFileSync is available. + // Ignore stderr since this is otherwise piped to parent.stderr + // which might be already closed. + let options = { + stdio: ['pipe', 'pipe', 'ignore'] + }; + if (cwd) { + options.cwd = cwd; + } + cp.execFileSync('taskkill', ['/T', '/F', '/PID', process.pid.toString()], options); + return true; + } + catch (err) { + return false; + } + } + else if (isLinux || isMacintosh) { + try { + let cmd = path_1.join(pluginRoot, 'bin/terminateProcess.sh'); + let result = cp.spawnSync(cmd, [process.pid.toString()]); + return result.error ? false : true; + } + catch (err) { + return false; + } + } + else { + process.kill('SIGKILL'); + return true; + } +} +exports.terminate = terminate; +//# sourceMappingURL=processes.js.map + +/***/ }), +/* 321 */ +/***/ (function(module, exports, __webpack_require__) { + +var rng = __webpack_require__(221); +var bytesToUuid = __webpack_require__(222); + +function v4(options, buf, offset) { + var i = buf && offset || 0; + + if (typeof(options) == 'string') { + buf = options === 'binary' ? new Array(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ++ii) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || bytesToUuid(rnds); +} + +module.exports = v4; + + +/***/ }), +/* 322 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +class Popup { + constructor(nvim) { + this.nvim = nvim; + } + async create(text, options) { + let { nvim } = this; + this.id = await nvim.call('popup_create', [text, options]); + this.bufferId = await nvim.call('winbufnr', [this.id]); + } + hide() { + if (!this.id) + return; + this.nvim.call('popup_hide', [this.id], true); + } + async valid() { + if (!this.bufferId) + return false; + await this.nvim.call('bufexists', [this.bufferId]); + } + async visible() { + if (!this.id) + return false; + let opt = await this.nvim.call('popup_getpos', [this.id]); + return opt && opt.visible == 1; + } + show() { + if (!this.id) + return; + this.nvim.call('popup_show', [this.id], true); + } + move(options) { + if (!this.id) + return; + this.nvim.call('popup_move', [this.id, options], true); + } + async getPosition() { + return await this.nvim.call('popup_getpos', [this.id]); + } + setFiletype(filetype) { + if (!this.id) + return; + let { nvim } = this; + // nvim.call('win_execute', [this.id, 'syntax enable'], true) + nvim.call('setbufvar', [this.bufferId, '&filetype', filetype], true); + } + dispose() { + if (this.id) { + this.nvim.call('popup_close', [this.id], true); + } + } +} +exports.Popup = Popup; +async function createPopup(nvim, text, options) { + let popup = new Popup(nvim); + await popup.create(text, options); + return popup; +} +exports.default = createPopup; +//# sourceMappingURL=popup.js.map + +/***/ }), +/* 323 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const callSequence_1 = tslib_1.__importDefault(__webpack_require__(324)); +const object_1 = __webpack_require__(190); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const util_1 = __webpack_require__(325); +const logger = __webpack_require__(186)('diagnostic-buffer'); +const severityNames = ['CocError', 'CocWarning', 'CocInfo', 'CocHint']; +// maintains sign and highlightId +class DiagnosticBuffer { + constructor(bufnr, config) { + this.config = config; + this.signIds = new Set(); + this.sequence = null; + this._onDidRefresh = new vscode_languageserver_protocol_1.Emitter(); + this.matchIds = new Set(); + this.diagnostics = []; + this.onDidRefresh = this._onDidRefresh.event; + this.bufnr = bufnr; + this.srdId = workspace_1.default.createNameSpace('coc-diagnostic'); + let timer = null; + let time = Date.now(); + this.refresh = (diagnostics) => { + time = Date.now(); + if (timer) + clearTimeout(timer); + timer = setTimeout(async () => { + let current = time; + if (this.sequence) { + await this.sequence.cancel(); + } + // staled + if (current != time || !this.document) + return; + diagnostics.forEach(o => { + o.range = this.fixRange(o.range); + }); + this._refresh(diagnostics); + }, 30); + }; + } + _refresh(diagnostics) { + if (object_1.equals(this.diagnostics, diagnostics)) + return; + let { nvim } = this; + let sequence = this.sequence = new callSequence_1.default(); + let winid; + let bufnr; + sequence.addFunction(async () => { + let arr = await nvim.eval(`[coc#util#valid_state(), bufwinid(${this.bufnr}), bufnr("%")]`); + if (arr[0] == 0 || !this.document) + return false; + winid = arr[1]; + bufnr = arr[2]; + }); + sequence.addFunction(async () => { + nvim.pauseNotification(); + this.setDiagnosticInfo(bufnr, diagnostics); + this.addSigns(diagnostics); + this.setLocationlist(diagnostics, winid); + this.addHighlight(diagnostics, winid); + this.addDiagnosticVText(diagnostics); + let [, err] = await this.nvim.resumeNotification(); + if (err) + logger.error('Diagnostic error:', err); + }); + sequence.start().then(async (canceled) => { + if (!canceled) { + this.diagnostics = diagnostics; + this._onDidRefresh.fire(void 0); + } + }, e => { + logger.error(e); + }); + } + setLocationlist(diagnostics, winid) { + if (!this.config.locationlist) + return; + let { nvim, bufnr } = this; + // not shown + if (winid == -1) + return; + let items = []; + for (let diagnostic of diagnostics) { + let item = util_1.getLocationListItem(diagnostic.source, bufnr, diagnostic); + items.push(item); + } + nvim.call('setloclist', [winid, [], ' ', { title: 'Diagnostics of coc', items }], true); + } + clearSigns() { + let { nvim, signIds, bufnr } = this; + if (signIds.size > 0) { + nvim.call('coc#util#unplace_signs', [bufnr, Array.from(signIds)], true); + signIds.clear(); + } + } + async checkSigns() { + let { nvim, bufnr, signIds } = this; + try { + let content = await this.nvim.call('execute', [`sign place buffer=${bufnr}`]); + let lines = content.split('\n'); + let ids = []; + for (let line of lines) { + let ms = line.match(/^\s*line=\d+\s+id=(\d+)\s+name=(\w+)/); + if (!ms) + continue; + let [, id, name] = ms; + if (!signIds.has(Number(id)) && severityNames.indexOf(name) != -1) { + ids.push(id); + } + } + await nvim.call('coc#util#unplace_signs', [bufnr, ids]); + } + catch (e) { + // noop + } + } + addSigns(diagnostics) { + if (!this.config.enableSign) + return; + this.clearSigns(); + let { nvim, bufnr, signIds } = this; + let signId = this.config.signOffset; + signIds.clear(); + let lines = new Set(); + for (let diagnostic of diagnostics) { + let { range, severity } = diagnostic; + let line = range.start.line; + if (lines.has(line)) + continue; + lines.add(line); + let name = util_1.getNameFromSeverity(severity); + nvim.command(`sign place ${signId} line=${line + 1} name=${name} buffer=${bufnr}`, true); + signIds.add(signId); + signId = signId + 1; + } + } + setDiagnosticInfo(bufnr, diagnostics) { + let lnums = [0, 0, 0, 0]; + let info = { error: 0, warning: 0, information: 0, hint: 0, lnums }; + for (let diagnostic of diagnostics) { + switch (diagnostic.severity) { + case vscode_languageserver_protocol_1.DiagnosticSeverity.Warning: + info.warning = info.warning + 1; + lnums[1] = lnums[1] || diagnostic.range.start.line + 1; + break; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Information: + info.information = info.information + 1; + lnums[2] = lnums[2] || diagnostic.range.start.line + 1; + break; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Hint: + info.hint = info.hint + 1; + lnums[3] = lnums[3] || diagnostic.range.start.line + 1; + break; + default: + lnums[0] = lnums[0] || diagnostic.range.start.line + 1; + info.error = info.error + 1; + } + } + this.nvim.call('coc#util#set_buf_var', [this.bufnr, 'coc_diagnostic_info', info], true); + if (bufnr == this.bufnr) { + this.nvim.command('redraws', true); + this.nvim.call('coc#util#do_autocmd', ['CocDiagnosticChange'], true); + } + } + addDiagnosticVText(diagnostics) { + let { bufnr, nvim } = this; + if (!this.config.virtualText) + return; + if (!nvim.hasFunction('nvim_buf_set_virtual_text')) + return; + let buffer = this.nvim.createBuffer(bufnr); + let lines = new Set(); + let srcId = this.config.virtualTextSrcId; + let prefix = this.config.virtualTextPrefix; + buffer.clearNamespace(srcId); + for (let diagnostic of diagnostics) { + let { line } = diagnostic.range.start; + if (lines.has(line)) + continue; + lines.add(line); + let highlight = util_1.getNameFromSeverity(diagnostic.severity) + 'VirtualText'; + let msg = diagnostic.message.split(/\n/) + .map((l) => l.trim()) + .filter((l) => l.length > 0) + .slice(0, this.config.virtualTextLines) + .join(this.config.virtualTextLineSeparator); + buffer.setVirtualText(srcId, line, [[prefix + msg, highlight]], {}).logError(); + } + } + clearHighlight() { + let { matchIds } = this; + if (!this.document) + return; + this.document.clearMatchIds(matchIds); + this.matchIds.clear(); + } + addHighlight(diagnostics, winid) { + this.clearHighlight(); + if (diagnostics.length == 0) + return; + if (winid == -1 && workspace_1.default.isVim && !workspace_1.default.env.textprop) + return; + const highlights = new Map(); + for (let diagnostic of diagnostics) { + let { range, severity } = diagnostic; + let hlGroup = util_1.getNameFromSeverity(severity) + 'Highlight'; + let ranges = highlights.get(hlGroup) || []; + ranges.push(range); + highlights.set(hlGroup, ranges); + } + for (let [hlGroup, ranges] of highlights.entries()) { + let matchIds = this.document.highlightRanges(ranges, hlGroup, this.srdId); + for (let id of matchIds) + this.matchIds.add(id); + } + } + // fix range out of total characters + fixRange(range) { + let { start, end } = range; + if (start.line != end.line) + return range; + let line = this.document.getline(start.line); + if (start.character < line.length) + return range; + return vscode_languageserver_protocol_1.Range.create(start.line, line.length - 1, start.line, line.length); + } + /** + * Used on buffer unload + * + * @public + * @returns {Promise} + */ + async clear() { + if (this.sequence) + this.sequence.cancel().logError(); + let { nvim } = this; + nvim.pauseNotification(); + this.clearHighlight(); + this.clearSigns(); + if (this.config.virtualText + && nvim.hasFunction('nvim_buf_set_virtual_text') + && this.document) { + this.document.buffer.clearNamespace(this.config.virtualTextSrcId); + } + this.setDiagnosticInfo(workspace_1.default.bufnr, []); + await nvim.resumeNotification(false, true); + } + dispose() { + if (this.sequence) { + this.sequence.cancel().logError(); + } + this._onDidRefresh.dispose(); + } + get document() { + if (!this.bufnr) + return null; + return workspace_1.default.getDocument(this.bufnr); + } + get uri() { + if (!this.document) + return null; + return this.document.uri; + } + get nvim() { + return workspace_1.default.nvim; + } +} +exports.DiagnosticBuffer = DiagnosticBuffer; +//# sourceMappingURL=buffer.js.map + +/***/ }), +/* 324 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +class CallSequence { + constructor() { + this.funcs = new Set(); + this._canceled = false; + this._resolved = false; + } + addFunction(fn) { + this.funcs.add(fn); + } + start() { + this.promise = new Promise(async (resolve, reject) => { + for (let fn of this.funcs) { + if (this._canceled) + return resolve(true); + try { + let cancel = await Promise.resolve(fn()); + if (cancel === true) { + this._canceled = true; + return resolve(true); + } + } + catch (e) { + reject(e); + } + } + this._resolved = true; + resolve(false); + }); + return this.promise; + } + ready() { + return this.promise; + } + cancel() { + if (this._resolved) + return Promise.resolve(void 0); + if (this._canceled) + return this.promise; + this._canceled = true; + return this.promise; + } +} +exports.default = CallSequence; +//# sourceMappingURL=callSequence.js.map + +/***/ }), +/* 325 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +function getSeverityName(severity) { + switch (severity) { + case vscode_languageserver_protocol_1.DiagnosticSeverity.Error: + return 'Error'; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Warning: + return 'Warning'; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Information: + return 'Information'; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Hint: + return 'Hint'; + default: + return 'Error'; + } +} +exports.getSeverityName = getSeverityName; +function getSeverityType(severity) { + switch (severity) { + case vscode_languageserver_protocol_1.DiagnosticSeverity.Error: + return 'E'; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Warning: + return 'W'; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Information: + return 'I'; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Hint: + return 'I'; + default: + return 'Error'; + } +} +exports.getSeverityType = getSeverityType; +function severityLevel(level) { + switch (level) { + case 'hint': + return vscode_languageserver_protocol_1.DiagnosticSeverity.Hint; + case 'information': + return vscode_languageserver_protocol_1.DiagnosticSeverity.Information; + case 'warning': + return vscode_languageserver_protocol_1.DiagnosticSeverity.Warning; + case 'error': + return vscode_languageserver_protocol_1.DiagnosticSeverity.Error; + default: + return vscode_languageserver_protocol_1.DiagnosticSeverity.Hint; + } +} +exports.severityLevel = severityLevel; +function getNameFromSeverity(severity) { + switch (severity) { + case vscode_languageserver_protocol_1.DiagnosticSeverity.Error: + return 'CocError'; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Warning: + return 'CocWarning'; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Information: + return 'CocInfo'; + case vscode_languageserver_protocol_1.DiagnosticSeverity.Hint: + return 'CocHint'; + default: + return 'CocError'; + } +} +exports.getNameFromSeverity = getNameFromSeverity; +function getLocationListItem(owner, bufnr, diagnostic) { + let { start } = diagnostic.range; + let msg = diagnostic.message.split('\n')[0]; + let type = getSeverityName(diagnostic.severity).slice(0, 1).toUpperCase(); + return { + bufnr, + lnum: start.line + 1, + col: start.character + 1, + text: `[${owner}${diagnostic.code ? ' ' + diagnostic.code : ''}] ${msg} [${type}]`, + type + }; +} +exports.getLocationListItem = getLocationListItem; +//# sourceMappingURL=util.js.map + +/***/ }), +/* 326 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const vscode_uri_1 = __webpack_require__(180); +const position_1 = __webpack_require__(213); +const logger = __webpack_require__(186)('diagnostic-collection'); +class Collection { + constructor(owner) { + this.diagnosticsMap = new Map(); + this._onDispose = new vscode_languageserver_protocol_1.Emitter(); + this._onDidDiagnosticsChange = new vscode_languageserver_protocol_1.Emitter(); + this._onDidDiagnosticsClear = new vscode_languageserver_protocol_1.Emitter(); + this.onDispose = this._onDispose.event; + this.onDidDiagnosticsChange = this._onDidDiagnosticsChange.event; + this.onDidDiagnosticsClear = this._onDidDiagnosticsClear.event; + this.name = owner; + } + set(entries, diagnostics) { + if (Array.isArray(entries)) { + let map = new Map(); + for (let item of entries) { + let [file, diagnostics] = item; + let exists = map.get(file) || []; + if (diagnostics != null) { + for (let diagnostic of diagnostics) { + exists.push(diagnostic); + } + } + else { + exists = []; + } + map.set(file, exists); + } + for (let key of map.keys()) { + this.set(key, map.get(key)); + } + return; + } + let uri = entries; + uri = vscode_uri_1.URI.parse(uri).toString(); + if (diagnostics) { + diagnostics.forEach(o => { + if (position_1.emptyRange(o.range)) { + o.range.end = { + line: o.range.end.line, + character: o.range.end.character + 1 + }; + } + o.source = o.source || this.name; + }); + } + this.diagnosticsMap.set(uri, diagnostics || []); + this._onDidDiagnosticsChange.fire(uri); + return; + } + delete(uri) { + this.diagnosticsMap.delete(uri); + this._onDidDiagnosticsChange.fire(uri); + } + clear() { + let uris = Array.from(this.diagnosticsMap.keys()); + this.diagnosticsMap.clear(); + this._onDidDiagnosticsClear.fire(uris); + } + forEach(callback, thisArg) { + for (let uri of this.diagnosticsMap.keys()) { + let diagnostics = this.diagnosticsMap.get(uri); + callback.call(thisArg, uri, diagnostics, this); + } + } + get(uri) { + let arr = this.diagnosticsMap.get(uri); + return arr == null ? [] : arr; + } + has(uri) { + return this.diagnosticsMap.has(uri); + } + dispose() { + this.clear(); + this._onDispose.fire(void 0); + this._onDispose.dispose(); + this._onDidDiagnosticsClear.dispose(); + this._onDidDiagnosticsChange.dispose(); + } +} +exports.default = Collection; +//# sourceMappingURL=collection.js.map + +/***/ }), +/* 327 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +const logger = __webpack_require__(186)('codeActionManager'); +class CodeActionManager extends manager_1.default { + register(selector, provider, clientId, codeActionKinds) { + let item = { + id: uuid(), + selector, + provider, + kinds: codeActionKinds, + clientId + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideCodeActions(document, range, context, token) { + let providers = this.getProviders(document); + if (!providers.length) + return null; + if (context.only) { + let { only } = context; + providers = providers.filter(p => { + if (p.kinds && !p.kinds.some(kind => only.indexOf(kind) != -1)) { + return false; + } + return true; + }); + } + let res = new Map(); + await Promise.all(providers.map(item => { + let { provider, clientId } = item; + clientId = clientId || uuid(); + return Promise.resolve(provider.provideCodeActions(document, range, context, token)).then(actions => { + if (!actions || actions.length == 0) + return; + let codeActions = res.get(clientId) || []; + for (let action of actions) { + if (vscode_languageserver_protocol_1.Command.is(action)) { + codeActions.push(vscode_languageserver_protocol_1.CodeAction.create(action.title, action)); + } + else { + if (context.only) { + if (!action.kind || context.only.indexOf(action.kind) == -1) { + continue; + } + } + let idx = codeActions.findIndex(o => o.title == action.title); + if (idx == -1) + codeActions.push(action); + } + } + res.set(clientId, codeActions); + }); + })); + return res; + } + dispose() { + this.providers = new Set(); + } +} +exports.default = CodeActionManager; +//# sourceMappingURL=codeActionmanager.js.map + +/***/ }), +/* 328 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('provider-manager'); +class Manager { + constructor() { + this.providers = new Set(); + } + hasProvider(document) { + return this.getProvider(document) != null; + } + getProvider(document) { + let currScore = 0; + let providerItem; + for (let item of this.providers) { + let { selector, priority } = item; + let score = workspace_1.default.match(selector, document); + if (score == 0) + continue; + if (typeof priority == 'number') { + score = priority; + } + if (score < currScore) + continue; + currScore = score; + providerItem = item; + } + return providerItem; + } + poviderById(id) { + let item = Array.from(this.providers).find(o => o.id == id); + return item ? item.provider : null; + } + getProviders(document) { + let items = Array.from(this.providers); + items = items.filter(item => { + return workspace_1.default.match(item.selector, document) > 0; + }); + return items.sort((a, b) => { + return workspace_1.default.match(b.selector, document) - workspace_1.default.match(a.selector, document); + }); + } + mergeDefinitions(arr) { + let res = []; + for (let def of arr) { + if (!def) + continue; + if (vscode_languageserver_protocol_1.Location.is(def)) { + let { uri, range } = def; + let idx = res.findIndex(l => l.uri == uri && l.range.start.line == range.start.line); + if (idx == -1) { + res.push(def); + } + } + else if (Array.isArray(def)) { + for (let d of def) { + let { uri, range } = d; + let idx = res.findIndex(l => l.uri == uri && l.range.start.line == range.start.line); + if (idx == -1) { + res.push(d); + } + } + } + else { + workspace_1.default.showMessage(`Bad definition ${JSON.stringify(def)}`, 'error'); + } + } + return res; + } +} +exports.default = Manager; +//# sourceMappingURL=manager.js.map + +/***/ }), +/* 329 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +const lodash_1 = __webpack_require__(312); +// const logger = require('../util/logger')('codeActionManager') +class CodeLensManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideCodeLenses(document, token) { + let providers = this.getProviders(document); + if (!providers.length) + return null; + let arr = await Promise.all(providers.map(item => { + let { provider, id } = item; + return Promise.resolve(provider.provideCodeLenses(document, token)).then(res => { + if (Array.isArray(res)) { + for (let item of res) { + item.source = id; + } + } + return res || []; + }); + })); + return [].concat(...arr); + } + async resolveCodeLens(codeLens, token) { + // no need to resolve + if (codeLens.command) + return codeLens; + let { source } = codeLens; + let provider = this.poviderById(source); + if (!provider || typeof provider.resolveCodeLens != 'function') { + // tslint:disable-next-line:no-console + console.error(`CodeLens Resolve not supported`); + return codeLens; + } + let res = await Promise.resolve(provider.resolveCodeLens(lodash_1.omit(codeLens, ['source']), token)); + Object.assign(codeLens, res); + return codeLens; + } + dispose() { + this.providers = new Set(); + } +} +exports.default = CodeLensManager; +//# sourceMappingURL=codeLensManager.js.map + +/***/ }), +/* 330 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +const logger = __webpack_require__(186)('definitionManager'); +class DeclarationManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideDeclaration(document, position, token) { + let item = this.getProvider(document); + if (!item) + return null; + let { provider } = item; + return await Promise.resolve(provider.provideDeclaration(document, position, token)); + } + dispose() { + this.providers = new Set(); + } +} +exports.default = DeclarationManager; +//# sourceMappingURL=declarationManager.js.map + +/***/ }), +/* 331 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +const logger = __webpack_require__(186)('definitionManager'); +class DefinitionManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideDefinition(document, position, token) { + let providers = this.getProviders(document); + if (!providers.length) + return null; + let arr = await Promise.all(providers.map(item => { + let { provider } = item; + return Promise.resolve(provider.provideDefinition(document, position, token)); + })); + return this.mergeDefinitions(arr); + } + dispose() { + this.providers = new Set(); + } +} +exports.default = DefinitionManager; +//# sourceMappingURL=definitionManager.js.map + +/***/ }), +/* 332 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class DocumentColorManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideDocumentColors(document, token) { + let item = this.getProvider(document); + if (!item) + return null; + let { provider } = item; + let res = await Promise.resolve(provider.provideDocumentColors(document, token)); + return res; + } + async provideColorPresentations(colorInformation, document, token) { + let { range, color } = colorInformation; + let item = this.getProvider(document); + if (!item) + return null; + let { provider } = item; + let res = await Promise.resolve(provider.provideColorPresentations(color, { document, range }, token)); + return res; + } + dispose() { + this.providers = new Set(); + } +} +exports.default = DocumentColorManager; +//# sourceMappingURL=documentColorManager.js.map + +/***/ }), +/* 333 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class DocumentHighlightManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideDocumentHighlights(document, position, token) { + let item = this.getProvider(document); + if (!item) + return null; + let { provider } = item; + return await Promise.resolve(provider.provideDocumentHighlights(document, position, token)); + } + dispose() { + this.providers = new Set(); + } +} +exports.default = DocumentHighlightManager; +//# sourceMappingURL=documentHighlightManager.js.map + +/***/ }), +/* 334 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class DocumentLinkManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async _provideDocumentLinks(item, document, token) { + let { provider, id } = item; + let items = await Promise.resolve(provider.provideDocumentLinks(document, token)); + if (!items || !items.length) + return []; + items.forEach(item => { + item.data = item.data || {}; + item.data.source = id; + }); + return items; + } + async provideDocumentLinks(document, token) { + let items = this.getProviders(document); + if (items.length == 0) + return []; + const arr = await Promise.all(items.map(item => { + return this._provideDocumentLinks(item, document, token); + })); + return [].concat(...arr); + } + async resolveDocumentLink(link, token) { + let { data } = link; + if (!data || !data.source) + return null; + for (let item of this.providers) { + if (item.id == data.source) { + let { provider } = item; + link = await Promise.resolve(provider.resolveDocumentLink(link, token)); + return link; + } + } + return null; + } + dispose() { + this.providers = new Set(); + } +} +exports.default = DocumentLinkManager; +//# sourceMappingURL=documentLinkManager.js.map + +/***/ }), +/* 335 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class DocumentSymbolManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideDocumentSymbols(document, token) { + let item = this.getProvider(document); + if (!item) + return null; + let { provider } = item; + return (await Promise.resolve(provider.provideDocumentSymbols(document, token))) || []; + } + dispose() { + this.providers = new Set(); + } +} +exports.default = DocumentSymbolManager; +//# sourceMappingURL=documentSymbolManager.js.map + +/***/ }), +/* 336 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class FoldingRangeManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideFoldingRanges(document, context, token) { + let item = this.getProvider(document); + if (!item) + return null; + let { provider } = item; + return (await Promise.resolve(provider.provideFoldingRanges(document, context, token)) || []); + } + dispose() { + this.providers = new Set(); + } +} +exports.default = FoldingRangeManager; +//# sourceMappingURL=foldingRangeManager.js.map + +/***/ }), +/* 337 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class FormatManager extends manager_1.default { + register(selector, provider, priority = 0) { + let item = { + id: uuid(), + selector, + priority, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideDocumentFormattingEdits(document, options, token) { + let item = this.getProvider(document); + if (!item) + return null; + let { provider } = item; + return await Promise.resolve(provider.provideDocumentFormattingEdits(document, options, token)); + } + dispose() { + this.providers = new Set(); + } +} +exports.default = FormatManager; +//# sourceMappingURL=formatManager.js.map + +/***/ }), +/* 338 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class FormatRangeManager extends manager_1.default { + register(selector, provider, priority = 0) { + let item = { + id: uuid(), + selector, + provider, + priority + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideDocumentRangeFormattingEdits(document, range, options, token) { + let item = this.getProvider(document); + if (!item) + return null; + let { provider } = item; + return await Promise.resolve(provider.provideDocumentRangeFormattingEdits(document, range, options, token)); + } + dispose() { + this.providers = new Set(); + } +} +exports.default = FormatRangeManager; +//# sourceMappingURL=formatRangeManager.js.map + +/***/ }), +/* 339 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class HoverManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideHover(document, position, token) { + let items = this.getProviders(document); + if (items.length === 0) + return null; + let res = []; + for (let i = 0, len = items.length; i < len; i += 1) { + const item = items[i]; + let hover = await Promise.resolve(item.provider.provideHover(document, position, token)); + if (hover && hover.contents != '') + res.push(hover); + } + return res; + } + dispose() { + this.providers = new Set(); + } +} +exports.default = HoverManager; +//# sourceMappingURL=hoverManager.js.map + +/***/ }), +/* 340 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class ImplementationManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideReferences(document, position, token) { + let providers = this.getProviders(document); + if (!providers.length) + return null; + let arr = await Promise.all(providers.map(item => { + let { provider } = item; + return Promise.resolve(provider.provideImplementation(document, position, token)); + })); + return this.mergeDefinitions(arr); + } + dispose() { + this.providers = new Set(); + } +} +exports.default = ImplementationManager; +//# sourceMappingURL=implementationManager.js.map + +/***/ }), +/* 341 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const string_1 = __webpack_require__(210); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('onTypeFormatManager'); +class OnTypeFormatManager { + constructor() { + this.providers = new Set(); + } + register(selector, provider, triggerCharacters) { + let item = { + triggerCharacters, + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + hasProvider(document) { + for (let o of this.providers) { + let { selector } = o; + if (workspace_1.default.match(selector, document) > 0) { + return true; + } + } + return false; + } + getProvider(document, triggerCharacter) { + for (let o of this.providers) { + let { triggerCharacters, selector } = o; + if (workspace_1.default.match(selector, document) > 0 && triggerCharacters.indexOf(triggerCharacter) > -1) { + return o.provider; + } + } + return null; + } + async onCharacterType(character, document, position, token) { + if (string_1.isWord(character)) + return; + let provider = this.getProvider(document, character); + if (!provider) + return; + let formatOpts = await workspace_1.default.getFormatOptions(document.uri); + return await Promise.resolve(provider.provideOnTypeFormattingEdits(document, position, character, formatOpts, token)); + } + dispose() { + this.providers = new Set(); + } +} +exports.default = OnTypeFormatManager; +//# sourceMappingURL=onTypeFormatManager.js.map + +/***/ }), +/* 342 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class SelectionRangeManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideSelectionRanges(document, positions, token) { + let item = this.getProvider(document); + if (!item) + return null; + let { provider } = item; + return (await Promise.resolve(provider.provideSelectionRanges(document, positions, token)) || []); + } + dispose() { + this.providers = new Set(); + } +} +exports.default = SelectionRangeManager; +//# sourceMappingURL=rangeManager.js.map + +/***/ }), +/* 343 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class ReferenceManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideReferences(document, position, context, token) { + let providers = this.getProviders(document); + if (!providers.length) + return null; + let arr = await Promise.all(providers.map(item => { + let { provider } = item; + return Promise.resolve(provider.provideReferences(document, position, context, token)); + })); + return this.mergeDefinitions(arr); + } + dispose() { + this.providers = new Set(); + } +} +exports.default = ReferenceManager; +//# sourceMappingURL=referenceManager.js.map + +/***/ }), +/* 344 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class RenameManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideRenameEdits(document, position, newName, token) { + let item = this.getProvider(document); + if (!item) + return null; + let { provider } = item; + return await Promise.resolve(provider.provideRenameEdits(document, position, newName, token)); + } + async prepareRename(document, position, token) { + let item = this.getProvider(document); + if (!item) + return null; + let { provider } = item; + if (provider.prepareRename == null) + return null; + let res = await Promise.resolve(provider.prepareRename(document, position, token)); + // can not rename + if (res == null) + false; + return res; + } + dispose() { + this.providers = new Set(); + } +} +exports.default = RenameManager; +//# sourceMappingURL=renameManager.js.map + +/***/ }), +/* 345 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class SignatureManager extends manager_1.default { + register(selector, provider, triggerCharacters) { + let characters = triggerCharacters.reduce((p, c) => { + return p.concat(c.split(/\s*/g)); + }, []); + let item = { + id: uuid(), + selector, + provider, + triggerCharacters: characters + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + shouldTrigger(document, triggerCharacter) { + let item = this.getProvider(document); + if (!item) + return false; + let { triggerCharacters } = item; + return triggerCharacters && triggerCharacters.indexOf(triggerCharacter) != -1; + } + async provideSignatureHelp(document, position, token) { + let item = this.getProvider(document); + if (!item) + return null; + let res = await Promise.resolve(item.provider.provideSignatureHelp(document, position, token)); + if (res && res.signatures && res.signatures.length) + return res; + return null; + } + dispose() { + this.providers = new Set(); + } +} +exports.default = SignatureManager; +//# sourceMappingURL=signatureManager.js.map + +/***/ }), +/* 346 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class TypeDefinitionManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideTypeDefinition(document, position, token) { + let providers = this.getProviders(document); + if (!providers.length) + return null; + let arr = await Promise.all(providers.map(item => { + let { provider } = item; + return Promise.resolve(provider.provideTypeDefinition(document, position, token)); + })); + return this.mergeDefinitions(arr); + } + dispose() { + this.providers = new Set(); + } +} +exports.default = TypeDefinitionManager; +//# sourceMappingURL=typeDefinitionManager.js.map + +/***/ }), +/* 347 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const manager_1 = tslib_1.__importDefault(__webpack_require__(328)); +const uuid = __webpack_require__(321); +class WorkspaceSymbolManager extends manager_1.default { + register(selector, provider) { + let item = { + id: uuid(), + selector, + provider + }; + this.providers.add(item); + return vscode_languageserver_protocol_1.Disposable.create(() => { + this.providers.delete(item); + }); + } + async provideWorkspaceSymbols(document, query, token) { + let item = this.getProvider(document); + if (!item) + return null; + let { provider } = item; + let res = await Promise.resolve(provider.provideWorkspaceSymbols(query, token)); + res = res || []; + for (let sym of res) { + sym.source = item.id; + } + return res; + } + async resolveWorkspaceSymbol(symbolInfo, token) { + let item = Array.from(this.providers).find(o => o.id == symbolInfo.source); + if (!item) + return; + let { provider } = item; + if (typeof provider.resolveWorkspaceSymbol != 'function') { + return Promise.resolve(symbolInfo); + } + return await Promise.resolve(provider.resolveWorkspaceSymbol(symbolInfo, token)); + } + dispose() { + this.providers = new Set(); + } +} +exports.default = WorkspaceSymbolManager; +//# sourceMappingURL=workspaceSymbolsManager.js.map + +/***/ }), +/* 348 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_languageserver_types_1 = __webpack_require__(161); +const parser_1 = __webpack_require__(234); +const string_1 = __webpack_require__(210); +const logger = __webpack_require__(186)('util-complete'); +function getPosition(opt) { + let { line, linenr, colnr } = opt; + let part = string_1.byteSlice(line, 0, colnr - 1); + return { + line: linenr - 1, + character: part.length + }; +} +exports.getPosition = getPosition; +function getWord(item, opt, invalidInsertCharacters) { + // tslint:disable-next-line: deprecation + let { label, data, insertTextFormat, insertText, textEdit } = item; + let word; + let newText; + if (data && data.word) + return data.word; + if (textEdit) { + let { range } = textEdit; + newText = textEdit.newText; + if (range && range.start.line == range.end.line) { + let { line, col, colnr } = opt; + let character = string_1.characterIndex(line, col); + if (range.start.character > character) { + let before = line.slice(character - range.start.character); + newText = before + newText; + } + else { + let start = line.slice(range.start.character, character); + if (start.length && newText.startsWith(start)) { + newText = newText.slice(start.length); + } + } + character = string_1.characterIndex(line, colnr - 1); + if (range.end.character > character) { + let end = line.slice(character, range.end.character); + if (newText.endsWith(end)) { + newText = newText.slice(0, -end.length); + } + } + } + } + else { + newText = insertText; + } + if (insertTextFormat == vscode_languageserver_types_1.InsertTextFormat.Snippet + && newText + && newText.indexOf('$') !== -1) { + let parser = new parser_1.SnippetParser(); + let snippet = parser.text(newText); + word = snippet ? getValidWord(snippet, invalidInsertCharacters) : label; + } + else { + word = getValidWord(newText, invalidInsertCharacters) || label; + } + return word; +} +exports.getWord = getWord; +function getDocumentation(item) { + let { documentation } = item; + if (!documentation) + return ''; + if (typeof documentation === 'string') + return documentation; + return documentation.value; +} +exports.getDocumentation = getDocumentation; +function completionKindString(kind, map, defaultValue = '') { + return map.get(kind) || defaultValue; +} +exports.completionKindString = completionKindString; +function getSnippetDocumentation(languageId, body) { + languageId = languageId.replace(/react$/, ''); + let str = body.replace(/\$\d+/g, '').replace(/\$\{\d+(?::([^{]+))?\}/, '$1'); + str = '``` ' + languageId + '\n' + str + '\n' + '```'; + return str; +} +exports.getSnippetDocumentation = getSnippetDocumentation; +function getValidWord(text, invalidChars) { + if (!text) + return ''; + for (let i = 0; i < text.length; i++) { + let c = text[i]; + if (invalidChars.indexOf(c) !== -1) { + return text.slice(0, i); + } + } + return text; +} +exports.getValidWord = getValidWord; +//# sourceMappingURL=complete.js.map + +/***/ }), +/* 349 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const ansiparse_1 = __webpack_require__(350); +const string_1 = __webpack_require__(210); +/** + * Build highlights, with lines and highlights + */ +class Highlighter { + constructor(srcId = -1) { + this.srcId = srcId; + this.lines = []; + this.highlights = []; + } + addLine(line, hlGroup) { + if (line.indexOf('\n') !== -1) { + for (let content of line.split(/\r?\n/)) { + this.addLine(content, hlGroup); + } + return; + } + if (hlGroup) { + this.highlights.push({ + line: this.lines.length, + colStart: line.match(/^\s*/)[0].length, + colEnd: string_1.byteLength(line), + hlGroup + }); + } // '\x1b' + if (line.indexOf('\x1b') !== -1) { + let res = ansiparse_1.parseAnsiHighlights(line); + for (let hl of res.highlights) { + let { span, hlGroup } = hl; + if (span[0] != span[1]) { + this.highlights.push({ + line: this.lines.length, + colStart: span[0], + colEnd: span[1], + hlGroup + }); + } + } + this.lines.push(res.line); + } + else { + this.lines.push(line); + } + } + addLines(lines) { + this.lines.push(...lines); + } + addText(text, hlGroup) { + let { lines } = this; + let pre = lines[lines.length - 1] || ''; + if (hlGroup) { + let colStart = string_1.byteLength(pre); + this.highlights.push({ + line: lines.length ? lines.length - 1 : 0, + colStart, + colEnd: colStart + string_1.byteLength(text), + hlGroup + }); + } + if (lines.length) { + lines[lines.length - 1] = `${pre}${text}`; + } + else { + lines.push(text); + } + } + get length() { + return this.lines.length; + } + getline(line) { + return this.lines[line] || ''; + } + // default to replace + render(buffer, start = 0, end = -1) { + buffer.setLines(this.lines, { start, end, strictIndexing: false }, true); + for (let item of this.highlights) { + buffer.addHighlight({ + hlGroup: item.hlGroup, + colStart: item.colStart, + colEnd: item.colEnd == null ? -1 : item.colEnd, + line: start + item.line, + srcId: this.srcId + }).logError(); + } + } +} +exports.default = Highlighter; +//# sourceMappingURL=highligher.js.map + +/***/ }), +/* 350 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const string_1 = __webpack_require__(210); +const foregroundColors = { + 30: 'black', + 31: 'red', + 32: 'green', + 33: 'yellow', + 34: 'blue', + 35: 'magenta', + 36: 'cyan', + 37: 'white', + 90: 'grey' +}; +const backgroundColors = { + 40: 'black', + 41: 'red', + 42: 'green', + 43: 'yellow', + 44: 'blue', + 45: 'magenta', + 46: 'cyan', + 47: 'white' +}; +const styles = { + 1: 'bold', + 3: 'italic', + 4: 'underline' +}; +function parseAnsiHighlights(line) { + let items = ansiparse(line); + let highlights = []; + let newLabel = ''; + for (let item of items) { + if (!item.text) + continue; + let { foreground, background } = item; + let len = string_1.byteLength(newLabel); + if (foreground || background) { + let span = [len, len + string_1.byteLength(item.text)]; + let hlGroup = ''; + if (foreground && background) { + hlGroup = `CocList${string_1.upperFirst(foreground)}${string_1.upperFirst(background)}`; + } + else if (foreground) { + hlGroup = `CocListFg${string_1.upperFirst(foreground)}`; + } + else if (background) { + hlGroup = `CocListBg${string_1.upperFirst(background)}`; + } + highlights.push({ span, hlGroup }); + } + newLabel = newLabel + item.text; + } + return { line: newLabel, highlights }; +} +exports.parseAnsiHighlights = parseAnsiHighlights; +function ansiparse(str) { + // + // I'm terrible at writing parsers. + // + let matchingControl = null; + let matchingData = null; + let matchingText = ''; + let ansiState = []; + let result = []; + let state = {}; + let eraseChar; + // + // General workflow for this thing is: + // \033\[33mText + // | | | + // | | matchingText + // | matchingData + // matchingControl + // + // \033\[K or \033\[m + // + // In further steps we hope it's all going to be fine. It usually is. + // + // + // Erases a char from the output + // + eraseChar = () => { + let index; + let text; + if (matchingText.length) { + matchingText = matchingText.substr(0, matchingText.length - 1); + } + else if (result.length) { + index = result.length - 1; + text = result[index].text; + if (text.length === 1) { + // + // A result bit was fully deleted, pop it out to simplify the final output + // + result.pop(); + } + else { + result[index].text = text.substr(0, text.length - 1); + } + } + }; + for (let i = 0; i < str.length; i++) { // tslint:disable-line + if (matchingControl != null) { + if (matchingControl == '\x1b' && str[i] == '\[') { + // + // We've matched full control code. Lets start matching formating data. + // + // + // "emit" matched text with correct state + // + if (matchingText) { + state.text = matchingText; + result.push(state); + state = {}; + matchingText = ''; + } + if (matchingText == '' && (str[i + 1] == 'm' || str[i + 1] == 'K')) { + if (state.foreground || state.background) { + state.text = ''; + result.push(state); + } + state = {}; + } + matchingControl = null; + matchingData = ''; + } + else { + // + // We failed to match anything - most likely a bad control code. We + // go back to matching regular strings. + // + matchingText += matchingControl + str[i]; + matchingControl = null; + } + continue; + } + else if (matchingData != null) { + if (str[i] == ';') { + // + // `;` separates many formatting codes, for example: `\033[33;43m` + // means that both `33` and `43` should be applied. + // + // TODO: this can be simplified by modifying state here. + // + ansiState.push(matchingData); + matchingData = ''; + } + else if (str[i] == 'm' || str[i] == 'K') { + // + // `m` finished whole formatting code. We can proceed to matching + // formatted text. + // + ansiState.push(matchingData); + matchingData = null; + matchingText = ''; + // + // Convert matched formatting data into user-friendly state object. + // + // TODO: DRY. + // + ansiState.forEach(ansiCode => { + if (foregroundColors[ansiCode]) { + state.foreground = foregroundColors[ansiCode]; + } + else if (backgroundColors[ansiCode]) { + state.background = backgroundColors[ansiCode]; + } + else if (ansiCode == 39) { + delete state.foreground; + } + else if (ansiCode == 49) { + delete state.background; + } + else if (styles[ansiCode]) { + state[styles[ansiCode]] = true; + } + else if (ansiCode == 22) { + state.bold = false; + } + else if (ansiCode == 23) { + state.italic = false; + } + else if (ansiCode == 24) { + state.underline = false; + } + }); + ansiState = []; + } + else { + matchingData += str[i]; + } + continue; + } + if (str[i] == '\x1b') { + matchingControl = str[i]; + } + else if (str[i] == '\u0008') { + eraseChar(); + } + else { + matchingText += str[i]; + } + } + if (matchingText) { + state.text = matchingText + (matchingControl ? matchingControl : ''); + result.push(state); + } + return result; +} +exports.ansiparse = ansiparse; +//# sourceMappingURL=ansiparse.js.map + +/***/ }), +/* 351 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const events_1 = __webpack_require__(49); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const net_1 = tslib_1.__importDefault(__webpack_require__(6)); +const os_1 = tslib_1.__importDefault(__webpack_require__(56)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const language_client_1 = __webpack_require__(352); +const types_1 = __webpack_require__(189); +const util_1 = __webpack_require__(174); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('services'); +function getStateName(state) { + switch (state) { + case types_1.ServiceStat.Initial: + return 'init'; + case types_1.ServiceStat.Running: + return 'running'; + case types_1.ServiceStat.Starting: + return 'starting'; + case types_1.ServiceStat.StartFailed: + return 'startFailed'; + case types_1.ServiceStat.Stopping: + return 'stopping'; + case types_1.ServiceStat.Stopped: + return 'stopped'; + default: + return 'unknown'; + } +} +exports.getStateName = getStateName; +class ServiceManager extends events_1.EventEmitter { + constructor() { + super(...arguments); + this.registered = new Map(); + this.disposables = []; + } + init() { + workspace_1.default.onDidOpenTextDocument(document => { + this.start(document); + }, null, this.disposables); + workspace_1.default.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('languageserver')) { + this.createCustomServices(); + } + }, null, this.disposables); + this.createCustomServices(); + } + dispose() { + this.removeAllListeners(); + util_1.disposeAll(this.disposables); + for (let service of this.registered.values()) { + service.dispose(); + } + } + regist(service) { + let { id } = service; + if (!id) + logger.error('invalid service configuration. ', service.name); + if (this.registered.get(id)) + return; + this.registered.set(id, service); + logger.info(`registered service "${id}"`); + if (this.shouldStart(service)) { + service.start(); // tslint:disable-line + } + if (service.state == types_1.ServiceStat.Running) { + this.emit('ready', id); + } + service.onServiceReady(() => { + logger.info(`service ${id} started`); + this.emit('ready', id); + }, null, this.disposables); + return vscode_languageserver_protocol_1.Disposable.create(() => { + service.stop(); + service.dispose(); + this.registered.delete(id); + }); + } + getService(id) { + let service = this.registered.get(id); + if (!service) + service = this.registered.get(`languageserver.${id}`); + return service; + } + hasService(id) { + return this.registered.has(id); + } + shouldStart(service) { + if (service.state != types_1.ServiceStat.Initial) { + return false; + } + let selector = service.selector; + for (let doc of workspace_1.default.documents) { + if (workspace_1.default.match(selector, doc.textDocument)) { + return true; + } + } + return false; + } + start(document) { + let services = this.getServices(document); + for (let service of services) { + if (service.state == types_1.ServiceStat.Initial) { + service.start(); // tslint:disable-line + } + } + } + getServices(document) { + let res = []; + for (let service of this.registered.values()) { + if (workspace_1.default.match(service.selector, document) > 0) { + res.push(service); + } + } + return res; + } + stop(id) { + let service = this.registered.get(id); + if (!service) { + workspace_1.default.showMessage(`Service ${id} not found`, 'error'); + return; + } + return Promise.resolve(service.stop()); + } + async stopAll() { + for (let service of this.registered.values()) { + await Promise.resolve(service.stop()); + } + } + async toggle(id) { + let service = this.registered.get(id); + if (!service) { + workspace_1.default.showMessage(`Service ${id} not found`, 'error'); + return; + } + let { state } = service; + try { + if (state == types_1.ServiceStat.Running) { + await Promise.resolve(service.stop()); + } + else if (state == types_1.ServiceStat.Initial) { + await service.start(); + } + else if (state == types_1.ServiceStat.Stopped) { + await service.restart(); + } + } + catch (e) { + workspace_1.default.showMessage(`Service error: ${e.message}`, 'error'); + } + } + getServiceStats() { + let res = []; + for (let [id, service] of this.registered) { + res.push({ + id, + languageIds: documentSelectorToLanguageIds(service.selector), + state: getStateName(service.state) + }); + } + return res; + } + createCustomServices() { + let base = 'languageserver'; + let lspConfig = workspace_1.default.getConfiguration().get(base, {}); + for (let key of Object.keys(lspConfig)) { + if (this.registered.get(key)) + continue; + let config = lspConfig[key]; + let id = `${base}.${key}`; + if (config.enable === false || this.hasService(id)) + continue; + let opts = getLanguageServerOptions(id, key, config); + if (!opts) + continue; + let client = new language_client_1.LanguageClient(id, key, opts[1], opts[0]); + this.registLanguageClient(client); + } + } + waitClient(id) { + let service = this.getService(id); + if (service && service.state == types_1.ServiceStat.Running) + return Promise.resolve(); + if (service) + return new Promise(resolve => { + service.onServiceReady(() => { + resolve(); + }); + }); + return new Promise(resolve => { + let listener = clientId => { + if (clientId == id || clientId == `languageserver.${id}`) { + this.off('ready', listener); + resolve(); + } + }; + this.on('ready', listener); + }); + } + async registNotification(id, method) { + await this.waitClient(id); + let service = this.getService(id); + if (!service.client) { + workspace_1.default.showMessage(`Not a language client: ${id}`, 'error'); + return; + } + let client = service.client; + client.onNotification(method, async (result) => { + await workspace_1.default.nvim.call('coc#do_notify', [id, method, result]); + }); + } + async sendRequest(id, method, params) { + if (!method) { + throw new Error(`method required for sendRequest`); + } + let service = this.getService(id); + // wait for extension activate + if (!service) + await util_1.wait(100); + service = this.getService(id); + if (!service || !service.client) { + throw new Error(`Language server ${id} not found`); + } + if (service.state == types_1.ServiceStat.Starting) { + await service.client.onReady(); + } + if (service.state != types_1.ServiceStat.Running) { + throw new Error(`Language server ${id} not running`); + } + return await Promise.resolve(service.client.sendRequest(method, params)); + } + registLanguageClient(client) { + let disposables = []; + let onDidServiceReady = new vscode_languageserver_protocol_1.Emitter(); + let service = { + client, + id: client.id, + name: client.name, + selector: client.clientOptions.documentSelector, + state: types_1.ServiceStat.Initial, + onServiceReady: onDidServiceReady.event, + start: () => { + if (service.state != types_1.ServiceStat.Initial && service.state != types_1.ServiceStat.Stopped) { + return Promise.resolve(); + } + if (client.getPublicState() == language_client_1.State.Starting) { + return Promise.resolve(); + } + service.state = types_1.ServiceStat.Starting; + logger.debug(`starting service: ${client.name}`); + let disposable = client.start(); + disposables.push(disposable); + return new Promise(resolve => { + client.onReady().then(() => { + onDidServiceReady.fire(void 0); + resolve(); + }, e => { + workspace_1.default.showMessage(`Server ${client.name} failed to start: ${e ? e.message : ''}`, 'error'); + service.state = types_1.ServiceStat.StartFailed; + resolve(); + }); + }); + }, + dispose: () => { + client.stop(); + onDidServiceReady.dispose(); + util_1.disposeAll(disposables); + }, + stop: async () => { + return await Promise.resolve(client.stop()); + }, + restart: async () => { + if (service.state == types_1.ServiceStat.Running) { + await service.stop(); + } + service.state = types_1.ServiceStat.Starting; + client.restart(); + }, + }; + client.onDidChangeState(changeEvent => { + let { oldState, newState } = changeEvent; + if (newState == language_client_1.State.Starting) { + service.state = types_1.ServiceStat.Starting; + } + else if (newState == language_client_1.State.Running) { + service.state = types_1.ServiceStat.Running; + } + else if (newState == language_client_1.State.Stopped) { + service.state = types_1.ServiceStat.Stopped; + } + let oldStr = stateString(oldState); + let newStr = stateString(newState); + logger.info(`${client.name} state change: ${oldStr} => ${newStr}`); + }, null, disposables); + return this.regist(service); + } +} +exports.ServiceManager = ServiceManager; +function documentSelectorToLanguageIds(documentSelector) { + let res = documentSelector.map(filter => { + if (typeof filter == 'string') { + return filter; + } + return filter.language; + }); + res = res.filter(s => typeof s == 'string'); + return res; +} +exports.documentSelectorToLanguageIds = documentSelectorToLanguageIds; +// convert config to options +function getLanguageServerOptions(id, name, config) { + let { command, module, port, args, filetypes } = config; + args = args || []; + if (!filetypes) { + workspace_1.default.showMessage(`Wrong configuration of LS "${name}", filetypes not found`, 'error'); + return null; + } + if (!command && !module && !port) { + workspace_1.default.showMessage(`Wrong configuration of LS "${name}", no command or module specified.`, 'error'); + return null; + } + if (module && !fs_1.default.existsSync(module)) { + workspace_1.default.showMessage(`Module file "${module}" not found for LS "${name}"`, 'error'); + return null; + } + if (filetypes.length == 0) + return; + let isModule = module != null; + let serverOptions; + if (isModule) { + serverOptions = { + module: module.toString(), + runtime: config.runtime || process.execPath, + args, + transport: getTransportKind(config), + options: getForkOptions(config) + }; + } + else if (command) { + serverOptions = { + command, + args, + options: getSpawnOptions(config) + }; + } + else if (port) { + serverOptions = () => { + return new Promise((resolve, reject) => { + let client = new net_1.default.Socket(); + client.connect(port, config.host || '127.0.0.1', () => { + resolve({ + reader: client, + writer: client + }); + }); + client.on('error', e => { + reject(new Error(`Connection error for ${id}: ${e.message}`)); + }); + }); + }; + } + let documentSelector = []; + config.filetypes.forEach(filetype => { + let schemes = ['file', 'untitled'].concat(config.additionalSchemes || []); + documentSelector.push(...schemes.map(scheme => { + return { language: filetype, scheme }; + })); + }); + if (documentSelector.length == 0) { + documentSelector = [{ scheme: 'file' }, { scheme: 'untitled' }]; + } + let disableWorkspaceFolders = !!config.disableWorkspaceFolders; + let ignoredRootPaths = config.ignoredRootPaths || []; + ignoredRootPaths = ignoredRootPaths.map(s => s.replace(/^~/, os_1.default.homedir())); + let clientOptions = { + ignoredRootPaths, + disableWorkspaceFolders, + disableDynamicRegister: !!config.disableDynamicRegister, + disableCompletion: !!config.disableCompletion, + disableDiagnostics: !!config.disableDiagnostics, + documentSelector, + revealOutputChannelOn: getRevealOutputChannelOn(config.revealOutputChannelOn), + synchronize: { + configurationSection: `${id}.settings` + }, + diagnosticCollectionName: name, + outputChannelName: id, + stdioEncoding: config.stdioEncoding || 'utf8', + initializationOptions: config.initializationOptions || {} + }; + return [clientOptions, serverOptions]; +} +exports.getLanguageServerOptions = getLanguageServerOptions; +function getRevealOutputChannelOn(revealOn) { + switch (revealOn) { + case 'info': + return language_client_1.RevealOutputChannelOn.Info; + case 'warn': + return language_client_1.RevealOutputChannelOn.Warn; + case 'error': + return language_client_1.RevealOutputChannelOn.Error; + case 'never': + return language_client_1.RevealOutputChannelOn.Never; + default: + return language_client_1.RevealOutputChannelOn.Never; + } +} +exports.getRevealOutputChannelOn = getRevealOutputChannelOn; +function getTransportKind(config) { + let { transport, transportPort } = config; + if (!transport || transport == 'ipc') + return language_client_1.TransportKind.ipc; + if (transport == 'stdio') + return language_client_1.TransportKind.stdio; + if (transport == 'pipe') + return language_client_1.TransportKind.pipe; + return { kind: language_client_1.TransportKind.socket, port: transportPort }; +} +exports.getTransportKind = getTransportKind; +function getForkOptions(config) { + return { + cwd: config.cwd, + execArgv: config.execArgv || [], + env: config.env || undefined + }; +} +function getSpawnOptions(config) { + return { + cwd: config.cwd, + detached: !!config.detached, + shell: !!config.shell, + env: config.env || undefined + }; +} +function stateString(state) { + switch (state) { + case language_client_1.State.Running: + return 'running'; + case language_client_1.State.Starting: + return 'starting'; + case language_client_1.State.Stopped: + return 'stopped'; + } + return 'unknown'; +} +exports.default = new ServiceManager(); +//# sourceMappingURL=services.js.map + +/***/ }), +/* 352 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +const child_process_1 = tslib_1.__importDefault(__webpack_require__(175)); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const os_1 = tslib_1.__importDefault(__webpack_require__(56)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const types_1 = __webpack_require__(189); +const util_1 = __webpack_require__(174); +const Is = tslib_1.__importStar(__webpack_require__(191)); +const processes_1 = __webpack_require__(320); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const which_1 = tslib_1.__importDefault(__webpack_require__(181)); +const client_1 = __webpack_require__(353); +const colorProvider_1 = __webpack_require__(357); +const configuration_1 = __webpack_require__(358); +const declaration_1 = __webpack_require__(359); +const foldingRange_1 = __webpack_require__(360); +const implementation_1 = __webpack_require__(361); +const typeDefinition_1 = __webpack_require__(362); +const workspaceFolders_1 = __webpack_require__(363); +const string_1 = __webpack_require__(210); +const logger = __webpack_require__(186)('language-client-index'); +tslib_1.__exportStar(__webpack_require__(353), exports); +var Executable; +(function (Executable) { + function is(value) { + return Is.string(value.command); + } + Executable.is = is; +})(Executable || (Executable = {})); +var TransportKind; +(function (TransportKind) { + TransportKind[TransportKind["stdio"] = 0] = "stdio"; + TransportKind[TransportKind["ipc"] = 1] = "ipc"; + TransportKind[TransportKind["pipe"] = 2] = "pipe"; + TransportKind[TransportKind["socket"] = 3] = "socket"; +})(TransportKind = exports.TransportKind || (exports.TransportKind = {})); +var Transport; +(function (Transport) { + function isSocket(value) { + let candidate = value; + return (candidate && + candidate.kind === TransportKind.socket && + Is.number(candidate.port)); + } + Transport.isSocket = isSocket; +})(Transport || (Transport = {})); +var NodeModule; +(function (NodeModule) { + function is(value) { + return Is.string(value.module); + } + NodeModule.is = is; +})(NodeModule || (NodeModule = {})); +var StreamInfo; +(function (StreamInfo) { + function is(value) { + let candidate = value; + return (candidate && candidate.writer !== void 0 && candidate.reader !== void 0); + } + StreamInfo.is = is; +})(StreamInfo || (StreamInfo = {})); +var ChildProcessInfo; +(function (ChildProcessInfo) { + function is(value) { + let candidate = value; + return (candidate && + candidate.process !== void 0 && + typeof candidate.detached === 'boolean'); + } + ChildProcessInfo.is = is; +})(ChildProcessInfo || (ChildProcessInfo = {})); +class LanguageClient extends client_1.BaseLanguageClient { + constructor(arg1, arg2, arg3, arg4, arg5) { + let id; + let name; + let serverOptions; + let clientOptions; + let forceDebug; + if (Is.string(arg2)) { + id = arg1; + name = arg2; + serverOptions = arg3; + clientOptions = arg4; + forceDebug = !!arg5; + } + else { + id = arg1.toLowerCase(); + name = arg1; + serverOptions = arg2; + clientOptions = arg3; + forceDebug = arg4; + } + if (forceDebug === void 0) { + forceDebug = false; + } + super(id, name, clientOptions); + this._serverOptions = serverOptions; + this._forceDebug = forceDebug; + this.registerProposedFeatures(); + } + stop() { + return super.stop().then(() => { + if (this._serverProcess) { + let toCheck = this._serverProcess; + this._serverProcess = undefined; + if (this._isDetached === void 0 || !this._isDetached) { + this.checkProcessDied(toCheck); + } + this._isDetached = undefined; + } + }); + } + get serviceState() { + let state = this._state; + switch (state) { + case client_1.ClientState.Initial: + return types_1.ServiceStat.Initial; + case client_1.ClientState.Running: + return types_1.ServiceStat.Running; + case client_1.ClientState.StartFailed: + return types_1.ServiceStat.StartFailed; + case client_1.ClientState.Starting: + return types_1.ServiceStat.Starting; + case client_1.ClientState.Stopped: + return types_1.ServiceStat.Stopped; + case client_1.ClientState.Stopping: + return types_1.ServiceStat.Stopping; + default: + logger.error(`Unknown state: ${state}`); + return types_1.ServiceStat.Stopped; + } + } + static stateName(state) { + switch (state) { + case client_1.ClientState.Initial: + return 'Initial'; + case client_1.ClientState.Running: + return 'Running'; + case client_1.ClientState.StartFailed: + return 'StartFailed'; + case client_1.ClientState.Starting: + return 'Starting'; + case client_1.ClientState.Stopped: + return 'Stopped'; + case client_1.ClientState.Stopping: + return 'Stopping'; + default: + return 'Unknonw'; + } + } + checkProcessDied(childProcess) { + if (!childProcess || global.hasOwnProperty('__TEST__')) + return; + setTimeout(() => { + // Test if the process is still alive. Throws an exception if not + try { + process.kill(childProcess.pid, 0); + processes_1.terminate(childProcess); + } + catch (error) { + // All is fine. + } + }, 1000); + } + handleConnectionClosed() { + this._serverProcess = undefined; + super.handleConnectionClosed(); + } + async createMessageTransports(encoding) { + function getEnvironment(env) { + if (!env) + return process.env; + return Object.assign({}, process.env, env); + } + function startedInDebugMode() { + let args = process.execArgv; + if (args) { + return args.some(arg => /^--debug=?/.test(arg) || + /^--debug-brk=?/.test(arg) || + /^--inspect=?/.test(arg) || + /^--inspect-brk=?/.test(arg)); + } + return false; + } + let server = this._serverOptions; + // We got a function. + if (Is.func(server)) { + let result = await Promise.resolve(server()); + if (client_1.MessageTransports.is(result)) { + this._isDetached = !!result.detached; + return result; + } + else if (StreamInfo.is(result)) { + this._isDetached = !!result.detached; + return { + reader: new vscode_languageserver_protocol_1.StreamMessageReader(result.reader), + writer: new vscode_languageserver_protocol_1.StreamMessageWriter(result.writer) + }; + } + else { + let cp; + if (ChildProcessInfo.is(result)) { + cp = result.process; + this._isDetached = result.detached; + } + else { + cp = result; + this._isDetached = false; + } + cp.stderr.on('data', data => this.appendOutput(data, encoding)); + return { + reader: new vscode_languageserver_protocol_1.StreamMessageReader(cp.stdout), + writer: new vscode_languageserver_protocol_1.StreamMessageWriter(cp.stdin) + }; + } + } + let json = server; + let runDebug = server; + if (runDebug.run || runDebug.debug) { + // We are under debugging. So use debug as well. + if (typeof v8debug === 'object' || this._forceDebug || startedInDebugMode()) { + json = runDebug.debug; + } + else { + json = runDebug.run; + } + } + else { + json = server; + } + let serverWorkingDir = await this._getServerWorkingDir(json.options); + if (NodeModule.is(json) && json.module) { + let node = json; + let transport = node.transport || TransportKind.stdio; + let args = []; + let options = node.options || Object.create(null); + let runtime = node.runtime || process.execPath; + if (options.execArgv) + options.execArgv.forEach(element => args.push(element)); + if (transport != TransportKind.ipc) + args.push(node.module); + if (node.args) + node.args.forEach(element => args.push(element)); + let execOptions = Object.create(null); + execOptions.cwd = serverWorkingDir; + execOptions.env = getEnvironment(options.env); + let pipeName; + if (transport === TransportKind.ipc) { + execOptions.stdio = [null, null, null]; + args.push('--node-ipc'); + } + else if (transport === TransportKind.stdio) { + args.push('--stdio'); + } + else if (transport === TransportKind.pipe) { + pipeName = vscode_languageserver_protocol_1.generateRandomPipeName(); + args.push(`--pipe=${pipeName}`); + } + else if (Transport.isSocket(transport)) { + args.push(`--socket=${transport.port}`); + } + args.push(`--clientProcessId=${process.pid.toString()}`); + if (transport === TransportKind.ipc) { + let forkOptions = { + cwd: serverWorkingDir, + env: getEnvironment(options.env), + stdio: [null, null, null, 'ipc'], + execPath: runtime, + execArgv: options.execArgv || [], + }; + let serverProcess = child_process_1.default.fork(node.module, args, forkOptions); + if (!serverProcess || !serverProcess.pid) { + throw new Error(`Launching server ${node.module} failed.`); + } + logger.info(`${this.id} started with ${serverProcess.pid}`); + this._serverProcess = serverProcess; + serverProcess.stdout.on('data', data => this.appendOutput(data, encoding)); + serverProcess.stderr.on('data', data => this.appendOutput(data, encoding)); + return { + reader: new vscode_languageserver_protocol_1.IPCMessageReader(serverProcess), + writer: new vscode_languageserver_protocol_1.IPCMessageWriter(serverProcess) + }; + } + else if (transport === TransportKind.stdio) { + let serverProcess = child_process_1.default.spawn(runtime, args, execOptions); + if (!serverProcess || !serverProcess.pid) { + throw new Error(`Launching server ${node.module} failed.`); + } + logger.info(`${this.id} started with ${serverProcess.pid}`); + this._serverProcess = serverProcess; + serverProcess.stderr.on('data', data => this.appendOutput(data, encoding)); + return { + reader: new vscode_languageserver_protocol_1.StreamMessageReader(serverProcess.stdout), + writer: new vscode_languageserver_protocol_1.StreamMessageWriter(serverProcess.stdin) + }; + } + else if (transport == TransportKind.pipe) { + let transport = await Promise.resolve(vscode_languageserver_protocol_1.createClientPipeTransport(pipeName)); + let process = child_process_1.default.spawn(runtime, args, execOptions); + if (!process || !process.pid) { + throw new Error(`Launching server ${node.module} failed.`); + } + logger.info(`${this.id} started with ${process.pid}`); + this._serverProcess = process; + process.stderr.on('data', data => this.appendOutput(data, encoding)); + process.stdout.on('data', data => this.appendOutput(data, encoding)); + let protocol = await Promise.resolve(transport.onConnected()); + return { reader: protocol[0], writer: protocol[1] }; + } + else if (Transport.isSocket(node.transport)) { + let transport = await Promise.resolve(vscode_languageserver_protocol_1.createClientSocketTransport(node.transport.port)); + let process = child_process_1.default.spawn(runtime, args, execOptions); + if (!process || !process.pid) { + throw new Error(`Launching server ${node.module} failed.`); + } + logger.info(`${this.id} started with ${process.pid}`); + this._serverProcess = process; + process.stderr.on('data', data => this.appendOutput(data, encoding)); + process.stdout.on('data', data => this.appendOutput(data, encoding)); + let protocol = await Promise.resolve(transport.onConnected()); + return { reader: protocol[0], writer: protocol[1] }; + } + } + else if (Executable.is(json) && json.command) { + let command = json; + let args = command.args || []; + let options = Object.assign({}, command.options); + options.env = options.env ? Object.assign(options.env, process.env) : process.env; + options.cwd = options.cwd || serverWorkingDir; + let cmd = json.command; + if (cmd.startsWith('~')) { + cmd = os_1.default.homedir() + cmd.slice(1); + } + if (cmd.indexOf('$') !== -1) { + cmd = string_1.resolveVariables(cmd, { workspaceFolder: workspace_1.default.rootPath }); + } + if (path_1.default.isAbsolute(cmd) && !fs_1.default.existsSync(cmd)) { + logger.info(`${cmd} of ${this.id} not exists`); + return; + } + try { + which_1.default.sync(cmd); + } + catch (e) { + throw new Error(`Command "${cmd}" of ${this.id} is not executable: ${e}`); + } + let serverProcess = child_process_1.default.spawn(cmd, args, options); + if (!serverProcess || !serverProcess.pid) { + throw new Error(`Launching server using command ${command.command} failed.`); + } + logger.info(`${this.id} started with ${serverProcess.pid}`); + serverProcess.on('exit', code => { + if (code != 0) + this.error(`${command.command} exited with code: ${code}`); + }); + serverProcess.stderr.on('data', data => this.appendOutput(data, encoding)); + this._serverProcess = serverProcess; + this._isDetached = !!options.detached; + return { + reader: new vscode_languageserver_protocol_1.StreamMessageReader(serverProcess.stdout), + writer: new vscode_languageserver_protocol_1.StreamMessageWriter(serverProcess.stdin) + }; + } + throw new Error(`Unsupported server configuration ` + JSON.stringify(server, null, 4)); + } + registerProposedFeatures() { + this.registerFeatures(ProposedFeatures.createAll(this)); + } + registerBuiltinFeatures() { + super.registerBuiltinFeatures(); + this.registerFeature(new configuration_1.ConfigurationFeature(this)); + this.registerFeature(new typeDefinition_1.TypeDefinitionFeature(this)); + this.registerFeature(new implementation_1.ImplementationFeature(this)); + this.registerFeature(new declaration_1.DeclarationFeature(this)); + this.registerFeature(new colorProvider_1.ColorProviderFeature(this)); + this.registerFeature(new foldingRange_1.FoldingRangeFeature(this)); + if (!this.clientOptions.disableWorkspaceFolders) { + this.registerFeature(new workspaceFolders_1.WorkspaceFoldersFeature(this)); + } + } + _getServerWorkingDir(options) { + let cwd = options && options.cwd; + if (cwd && !path_1.default.isAbsolute(cwd)) + cwd = path_1.default.join(workspace_1.default.cwd, cwd); + if (!cwd) + cwd = workspace_1.default.cwd; + if (cwd) { + // make sure the folder exists otherwise creating the process will fail + return new Promise(s => { + fs_1.default.lstat(cwd, (err, stats) => { + s(!err && stats.isDirectory() ? cwd : undefined); + }); + }); + } + return Promise.resolve(undefined); + } + appendOutput(data, encoding) { + let msg = Is.string(data) ? data : data.toString(encoding); + if (global.hasOwnProperty('__TEST__')) { + console.log(msg); // tslint:disable-line + return; + } + if (process.env.NVIM_COC_LOG_LEVEL == 'debug') { + logger.debug(`[${this.id}]`, msg); + } + this.outputChannel.append(msg.endsWith('\n') ? msg : msg + '\n'); + } +} +exports.LanguageClient = LanguageClient; +class SettingMonitor { + constructor(_client, _setting) { + this._client = _client; + this._setting = _setting; + this._listeners = []; + } + start() { + workspace_1.default.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(this._setting)) { + this.onDidChangeConfiguration(); + } + }, null, this._listeners); + this.onDidChangeConfiguration(); + return { + dispose: () => { + util_1.disposeAll(this._listeners); + if (this._client.needsStop()) { + this._client.stop(); + } + } + }; + } + onDidChangeConfiguration() { + let index = this._setting.indexOf('.'); + let primary = index >= 0 ? this._setting.substr(0, index) : this._setting; + let rest = index >= 0 ? this._setting.substr(index + 1) : undefined; + let enabled = rest + ? workspace_1.default.getConfiguration(primary).get(rest, true) + : workspace_1.default.getConfiguration(primary); + if (enabled && this._client.needsStart()) { + this._client.start(); + } + else if (!enabled && this._client.needsStop()) { + this._client.stop(); + } + } +} +exports.SettingMonitor = SettingMonitor; +// Exporting proposed protocol. +var ProposedFeatures; +(function (ProposedFeatures) { + function createAll(_client) { + let result = []; + return result; + } + ProposedFeatures.createAll = createAll; +})(ProposedFeatures = exports.ProposedFeatures || (exports.ProposedFeatures = {})); +//# sourceMappingURL=index.js.map + +/***/ }), +/* 353 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +/*tslint:disable*/ +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const vscode_uri_1 = __webpack_require__(180); +const commands_1 = tslib_1.__importDefault(__webpack_require__(232)); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const fs_1 = __webpack_require__(200); +const Is = tslib_1.__importStar(__webpack_require__(191)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const async_1 = __webpack_require__(354); +const cv = tslib_1.__importStar(__webpack_require__(355)); +const UUID = tslib_1.__importStar(__webpack_require__(356)); +const lodash_1 = __webpack_require__(312); +const logger = __webpack_require__(186)('language-client-client'); +class ConsoleLogger { + error(message) { + logger.error(message); + } + warn(message) { + logger.warn(message); + } + info(message) { + logger.info(message); + } + log(message) { + logger.log(message); + } +} +function createConnection(input, output, errorHandler, closeHandler) { + let logger = new ConsoleLogger(); + let connection = vscode_languageserver_protocol_1.createProtocolConnection(input, output, logger); + connection.onError(data => { + errorHandler(data[0], data[1], data[2]); + }); + connection.onClose(closeHandler); + let result = { + listen: () => connection.listen(), + sendRequest: (type, ...params) => connection.sendRequest(Is.string(type) ? type : type.method, ...params), + onRequest: (type, handler) => connection.onRequest(Is.string(type) ? type : type.method, handler), + sendNotification: (type, params) => connection.sendNotification(Is.string(type) ? type : type.method, params), + onNotification: (type, handler) => connection.onNotification(Is.string(type) ? type : type.method, handler), + trace: (value, tracer, sendNotificationOrTraceOptions) => { + const defaultTraceOptions = { + sendNotification: false, + traceFormat: vscode_languageserver_protocol_1.TraceFormat.Text + }; + if (sendNotificationOrTraceOptions === void 0) { + connection.trace(value, tracer, defaultTraceOptions); + } + else if (Is.boolean(sendNotificationOrTraceOptions)) { + connection.trace(value, tracer, sendNotificationOrTraceOptions); + } + else { + connection.trace(value, tracer, sendNotificationOrTraceOptions); + } + }, + initialize: (params) => connection.sendRequest(vscode_languageserver_protocol_1.InitializeRequest.type, params), + shutdown: () => connection.sendRequest(vscode_languageserver_protocol_1.ShutdownRequest.type, undefined), + exit: () => connection.sendNotification(vscode_languageserver_protocol_1.ExitNotification.type), + onLogMessage: (handler) => connection.onNotification(vscode_languageserver_protocol_1.LogMessageNotification.type, handler), + onShowMessage: (handler) => connection.onNotification(vscode_languageserver_protocol_1.ShowMessageNotification.type, handler), + onTelemetry: (handler) => connection.onNotification(vscode_languageserver_protocol_1.TelemetryEventNotification.type, handler), + didChangeConfiguration: (params) => connection.sendNotification(vscode_languageserver_protocol_1.DidChangeConfigurationNotification.type, params), + didChangeWatchedFiles: (params) => connection.sendNotification(vscode_languageserver_protocol_1.DidChangeWatchedFilesNotification.type, params), + didOpenTextDocument: (params) => connection.sendNotification(vscode_languageserver_protocol_1.DidOpenTextDocumentNotification.type, params), + didChangeTextDocument: (params) => connection.sendNotification(vscode_languageserver_protocol_1.DidChangeTextDocumentNotification.type, params), + didCloseTextDocument: (params) => connection.sendNotification(vscode_languageserver_protocol_1.DidCloseTextDocumentNotification.type, params), + didSaveTextDocument: (params) => connection.sendNotification(vscode_languageserver_protocol_1.DidSaveTextDocumentNotification.type, params), + onDiagnostics: (handler) => connection.onNotification(vscode_languageserver_protocol_1.PublishDiagnosticsNotification.type, handler), + dispose: () => connection.dispose() + }; + return result; +} +/** + * An action to be performed when the connection is producing errors. + */ +var ErrorAction; +(function (ErrorAction) { + /** + * Continue running the server. + */ + ErrorAction[ErrorAction["Continue"] = 1] = "Continue"; + /** + * Shutdown the server. + */ + ErrorAction[ErrorAction["Shutdown"] = 2] = "Shutdown"; +})(ErrorAction = exports.ErrorAction || (exports.ErrorAction = {})); +/** + * An action to be performed when the connection to a server got closed. + */ +var CloseAction; +(function (CloseAction) { + /** + * Don't restart the server. The connection stays closed. + */ + CloseAction[CloseAction["DoNotRestart"] = 1] = "DoNotRestart"; + /** + * Restart the server. + */ + CloseAction[CloseAction["Restart"] = 2] = "Restart"; +})(CloseAction = exports.CloseAction || (exports.CloseAction = {})); +class DefaultErrorHandler { + constructor(name) { + this.name = name; + this.restarts = []; + } + error(_error, _message, count) { + if (count && count <= 3) { + return ErrorAction.Continue; + } + return ErrorAction.Shutdown; + } + closed() { + this.restarts.push(Date.now()); + if (this.restarts.length < 5) { + return CloseAction.Restart; + } + else { + let diff = this.restarts[this.restarts.length - 1] - this.restarts[0]; + if (diff <= 3 * 60 * 1000) { + logger.error(`The ${this.name} server crashed 5 times in the last 3 minutes. The server will not be restarted.`); + return CloseAction.DoNotRestart; + } + else { + this.restarts.shift(); + return CloseAction.Restart; + } + } + } +} +var RevealOutputChannelOn; +(function (RevealOutputChannelOn) { + RevealOutputChannelOn[RevealOutputChannelOn["Info"] = 1] = "Info"; + RevealOutputChannelOn[RevealOutputChannelOn["Warn"] = 2] = "Warn"; + RevealOutputChannelOn[RevealOutputChannelOn["Error"] = 3] = "Error"; + RevealOutputChannelOn[RevealOutputChannelOn["Never"] = 4] = "Never"; +})(RevealOutputChannelOn = exports.RevealOutputChannelOn || (exports.RevealOutputChannelOn = {})); +var State; +(function (State) { + State[State["Stopped"] = 1] = "Stopped"; + State[State["Running"] = 2] = "Running"; + State[State["Starting"] = 3] = "Starting"; +})(State = exports.State || (exports.State = {})); +var ClientState; +(function (ClientState) { + ClientState[ClientState["Initial"] = 0] = "Initial"; + ClientState[ClientState["Starting"] = 1] = "Starting"; + ClientState[ClientState["StartFailed"] = 2] = "StartFailed"; + ClientState[ClientState["Running"] = 3] = "Running"; + ClientState[ClientState["Stopping"] = 4] = "Stopping"; + ClientState[ClientState["Stopped"] = 5] = "Stopped"; +})(ClientState = exports.ClientState || (exports.ClientState = {})); +const SupporedSymbolKinds = [ + vscode_languageserver_protocol_1.SymbolKind.File, + vscode_languageserver_protocol_1.SymbolKind.Module, + vscode_languageserver_protocol_1.SymbolKind.Namespace, + vscode_languageserver_protocol_1.SymbolKind.Package, + vscode_languageserver_protocol_1.SymbolKind.Class, + vscode_languageserver_protocol_1.SymbolKind.Method, + vscode_languageserver_protocol_1.SymbolKind.Property, + vscode_languageserver_protocol_1.SymbolKind.Field, + vscode_languageserver_protocol_1.SymbolKind.Constructor, + vscode_languageserver_protocol_1.SymbolKind.Enum, + vscode_languageserver_protocol_1.SymbolKind.Interface, + vscode_languageserver_protocol_1.SymbolKind.Function, + vscode_languageserver_protocol_1.SymbolKind.Variable, + vscode_languageserver_protocol_1.SymbolKind.Constant, + vscode_languageserver_protocol_1.SymbolKind.String, + vscode_languageserver_protocol_1.SymbolKind.Number, + vscode_languageserver_protocol_1.SymbolKind.Boolean, + vscode_languageserver_protocol_1.SymbolKind.Array, + vscode_languageserver_protocol_1.SymbolKind.Object, + vscode_languageserver_protocol_1.SymbolKind.Key, + vscode_languageserver_protocol_1.SymbolKind.Null, + vscode_languageserver_protocol_1.SymbolKind.EnumMember, + vscode_languageserver_protocol_1.SymbolKind.Struct, + vscode_languageserver_protocol_1.SymbolKind.Event, + vscode_languageserver_protocol_1.SymbolKind.Operator, + vscode_languageserver_protocol_1.SymbolKind.TypeParameter +]; +const SupportedCompletionItemKinds = [ + vscode_languageserver_protocol_1.CompletionItemKind.Text, + vscode_languageserver_protocol_1.CompletionItemKind.Method, + vscode_languageserver_protocol_1.CompletionItemKind.Function, + vscode_languageserver_protocol_1.CompletionItemKind.Constructor, + vscode_languageserver_protocol_1.CompletionItemKind.Field, + vscode_languageserver_protocol_1.CompletionItemKind.Variable, + vscode_languageserver_protocol_1.CompletionItemKind.Class, + vscode_languageserver_protocol_1.CompletionItemKind.Interface, + vscode_languageserver_protocol_1.CompletionItemKind.Module, + vscode_languageserver_protocol_1.CompletionItemKind.Property, + vscode_languageserver_protocol_1.CompletionItemKind.Unit, + vscode_languageserver_protocol_1.CompletionItemKind.Value, + vscode_languageserver_protocol_1.CompletionItemKind.Enum, + vscode_languageserver_protocol_1.CompletionItemKind.Keyword, + vscode_languageserver_protocol_1.CompletionItemKind.Snippet, + vscode_languageserver_protocol_1.CompletionItemKind.Color, + vscode_languageserver_protocol_1.CompletionItemKind.File, + vscode_languageserver_protocol_1.CompletionItemKind.Reference, + vscode_languageserver_protocol_1.CompletionItemKind.Folder, + vscode_languageserver_protocol_1.CompletionItemKind.EnumMember, + vscode_languageserver_protocol_1.CompletionItemKind.Constant, + vscode_languageserver_protocol_1.CompletionItemKind.Struct, + vscode_languageserver_protocol_1.CompletionItemKind.Event, + vscode_languageserver_protocol_1.CompletionItemKind.Operator, + vscode_languageserver_protocol_1.CompletionItemKind.TypeParameter +]; +function ensure(target, key) { + if (target[key] == null) { + target[key] = {}; + } + return target[key]; +} +var DynamicFeature; +(function (DynamicFeature) { + function is(value) { + let candidate = value; + return (candidate && + Is.func(candidate.register) && + Is.func(candidate.unregister) && + Is.func(candidate.dispose) && + candidate.messages != null); + } + DynamicFeature.is = is; +})(DynamicFeature || (DynamicFeature = {})); +class OnReady { + constructor(_resolve, _reject) { + this._resolve = _resolve; + this._reject = _reject; + this._used = false; + } + get isUsed() { + return this._used; + } + resolve() { + this._used = true; + this._resolve(); + } + reject(error) { + this._used = true; + this._reject(error); + } +} +class DocumentNotifiactions { + constructor(_client, _event, _type, _middleware, _createParams, _selectorFilter) { + this._client = _client; + this._event = _event; + this._type = _type; + this._middleware = _middleware; + this._createParams = _createParams; + this._selectorFilter = _selectorFilter; + this._selectors = new Map(); + } + static textDocumentFilter(selectors, textDocument) { + for (const selector of selectors) { + if (workspace_1.default.match(selector, textDocument) > 0) { + return true; + } + } + return false; + } + register(_message, data) { + if (!data.registerOptions.documentSelector) { + return; + } + if (!this._listener) { + this._listener = this._event(this.callback, this); + } + this._selectors.set(data.id, data.registerOptions.documentSelector); + } + callback(data) { + if (!this._selectorFilter || + this._selectorFilter(this._selectors.values(), data)) { + if (this._middleware) { + this._middleware(data, data => this._client.sendNotification(this._type, this._createParams(data))); + } + else { + this._client.sendNotification(this._type, this._createParams(data)); + } + this.notificationSent(data); + } + } + notificationSent(_data) { } + unregister(id) { + this._selectors.delete(id); + if (this._selectors.size === 0 && this._listener) { + this._listener.dispose(); + this._listener = undefined; + } + } + dispose() { + this._selectors.clear(); + if (this._listener) { + this._listener.dispose(); + this._listener = undefined; + } + } +} +class DidOpenTextDocumentFeature extends DocumentNotifiactions { + constructor(client, _syncedDocuments) { + super(client, workspace_1.default.onDidOpenTextDocument, vscode_languageserver_protocol_1.DidOpenTextDocumentNotification.type, client.clientOptions.middleware.didOpen, (textDocument) => { + return { textDocument: cv.convertToTextDocumentItem(textDocument) }; + }, DocumentNotifiactions.textDocumentFilter); + this._syncedDocuments = _syncedDocuments; + } + get messages() { + return vscode_languageserver_protocol_1.DidOpenTextDocumentNotification.type; + } + fillClientCapabilities(capabilities) { + ensure(ensure(capabilities, 'textDocument'), 'synchronization').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + let textDocumentSyncOptions = capabilities.resolvedTextDocumentSync; + if (documentSelector && + textDocumentSyncOptions && + textDocumentSyncOptions.openClose) { + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: { documentSelector: documentSelector } + }); + } + } + register(message, data) { + super.register(message, data); + if (!data.registerOptions.documentSelector) { + return; + } + let documentSelector = data.registerOptions.documentSelector; + workspace_1.default.textDocuments.forEach(textDocument => { + let uri = textDocument.uri.toString(); + if (this._syncedDocuments.has(uri)) { + return; + } + if (workspace_1.default.match(documentSelector, textDocument) > 0) { + let middleware = this._client.clientOptions.middleware; + let didOpen = (textDocument) => { + this._client.sendNotification(this._type, this._createParams(textDocument)); + }; + if (middleware.didOpen) { + middleware.didOpen(textDocument, didOpen); + } + else { + didOpen(textDocument); + } + this._syncedDocuments.set(uri, textDocument); + } + }); + } + notificationSent(textDocument) { + super.notificationSent(textDocument); + this._syncedDocuments.set(textDocument.uri.toString(), textDocument); + } +} +class DidCloseTextDocumentFeature extends DocumentNotifiactions { + constructor(client, _syncedDocuments) { + super(client, workspace_1.default.onDidCloseTextDocument, vscode_languageserver_protocol_1.DidCloseTextDocumentNotification.type, client.clientOptions.middleware.didClose, (textDocument) => cv.asCloseTextDocumentParams(textDocument), DocumentNotifiactions.textDocumentFilter); + this._syncedDocuments = _syncedDocuments; + } + get messages() { + return vscode_languageserver_protocol_1.DidCloseTextDocumentNotification.type; + } + fillClientCapabilities(capabilities) { + ensure(ensure(capabilities, 'textDocument'), 'synchronization').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + let textDocumentSyncOptions = capabilities.resolvedTextDocumentSync; + if (documentSelector && + textDocumentSyncOptions && + textDocumentSyncOptions.openClose) { + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: { documentSelector: documentSelector } + }); + } + } + notificationSent(textDocument) { + super.notificationSent(textDocument); + this._syncedDocuments.delete(textDocument.uri.toString()); + } + unregister(id) { + let selector = this._selectors.get(id); + // The super call removed the selector from the map + // of selectors. + super.unregister(id); + let selectors = this._selectors.values(); + this._syncedDocuments.forEach(textDocument => { + if (workspace_1.default.match(selector, textDocument) > 0 && + !this._selectorFilter(selectors, textDocument)) { + let middleware = this._client.clientOptions.middleware; + let didClose = (textDocument) => { + this._client.sendNotification(this._type, this._createParams(textDocument)); + }; + this._syncedDocuments.delete(textDocument.uri.toString()); + if (middleware.didClose) { + middleware.didClose(textDocument, didClose); + } + else { + didClose(textDocument); + } + } + }); + } +} +class DidChangeTextDocumentFeature { + constructor(_client) { + this._client = _client; + this._changeData = new Map(); + } + get messages() { + return vscode_languageserver_protocol_1.DidChangeTextDocumentNotification.type; + } + fillClientCapabilities(capabilities) { + ensure(ensure(capabilities, 'textDocument'), 'synchronization').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + let textDocumentSyncOptions = capabilities.resolvedTextDocumentSync; + if (documentSelector && + textDocumentSyncOptions && + textDocumentSyncOptions.change != null && + textDocumentSyncOptions.change !== vscode_languageserver_protocol_1.TextDocumentSyncKind.None) { + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }, { syncKind: textDocumentSyncOptions.change }) + }); + } + } + register(_message, data) { + if (!data.registerOptions.documentSelector) { + return; + } + if (!this._listener) { + this._listener = workspace_1.default.onDidChangeTextDocument(this.callback, this); + } + this._changeData.set(data.id, { + documentSelector: data.registerOptions.documentSelector, + syncKind: data.registerOptions.syncKind + }); + } + callback(event) { + // Text document changes are send for dirty changes as well. We don't + // have dirty / undirty events in the LSP so we ignore content changes + // with length zero. + if (event.contentChanges.length === 0) { + return; + } + let doc = workspace_1.default.getDocument(event.textDocument.uri); + if (!doc) + return; + let { textDocument } = doc; + for (const changeData of this._changeData.values()) { + if (workspace_1.default.match(changeData.documentSelector, textDocument) > 0) { + let middleware = this._client.clientOptions.middleware; + if (changeData.syncKind === vscode_languageserver_protocol_1.TextDocumentSyncKind.Incremental) { + if (middleware.didChange) { + middleware.didChange(event, () => this._client.sendNotification(vscode_languageserver_protocol_1.DidChangeTextDocumentNotification.type, lodash_1.omit(event, ['bufnr', 'original']))); + } + else { + this._client.sendNotification(vscode_languageserver_protocol_1.DidChangeTextDocumentNotification.type, lodash_1.omit(event, ['bufnr', 'original'])); + } + } + else if (changeData.syncKind === vscode_languageserver_protocol_1.TextDocumentSyncKind.Full) { + let didChange = event => { + let { textDocument } = workspace_1.default.getDocument(event.textDocument.uri); + this._client.sendNotification(vscode_languageserver_protocol_1.DidChangeTextDocumentNotification.type, cv.asChangeTextDocumentParams(textDocument)); + }; + if (middleware.didChange) { + middleware.didChange(event, didChange); + } + else { + didChange(event); + } + } + } + } + } + unregister(id) { + this._changeData.delete(id); + if (this._changeData.size === 0 && this._listener) { + this._listener.dispose(); + this._listener = undefined; + } + } + dispose() { + this._changeData.clear(); + if (this._listener) { + this._listener.dispose(); + this._listener = undefined; + } + } +} +class WillSaveFeature extends DocumentNotifiactions { + constructor(client) { + super(client, workspace_1.default.onWillSaveTextDocument, vscode_languageserver_protocol_1.WillSaveTextDocumentNotification.type, client.clientOptions.middleware.willSave, willSaveEvent => cv.asWillSaveTextDocumentParams(willSaveEvent), (selectors, willSaveEvent) => DocumentNotifiactions.textDocumentFilter(selectors, willSaveEvent.document)); + } + get messages() { + return vscode_languageserver_protocol_1.WillSaveTextDocumentNotification.type; + } + fillClientCapabilities(capabilities) { + let value = ensure(ensure(capabilities, 'textDocument'), 'synchronization'); + value.willSave = true; + } + initialize(capabilities, documentSelector) { + let textDocumentSyncOptions = capabilities.resolvedTextDocumentSync; + if (documentSelector && + textDocumentSyncOptions && + textDocumentSyncOptions.willSave) { + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: { documentSelector: documentSelector } + }); + } + } +} +class WillSaveWaitUntilFeature { + constructor(_client) { + this._client = _client; + this._selectors = new Map(); + } + get messages() { + return vscode_languageserver_protocol_1.WillSaveTextDocumentWaitUntilRequest.type; + } + fillClientCapabilities(capabilities) { + let value = ensure(ensure(capabilities, 'textDocument'), 'synchronization'); + value.willSaveWaitUntil = true; + } + initialize(capabilities, documentSelector) { + let textDocumentSyncOptions = capabilities.resolvedTextDocumentSync; + if (documentSelector && + textDocumentSyncOptions && + textDocumentSyncOptions.willSaveWaitUntil) { + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: { documentSelector: documentSelector } + }); + } + } + register(_message, data) { + if (!data.registerOptions.documentSelector) { + return; + } + if (!this._listener) { + this._listener = workspace_1.default.onWillSaveUntil(this.callback, this, this._client.id); + } + this._selectors.set(data.id, data.registerOptions.documentSelector); + } + callback(event) { + if (DocumentNotifiactions.textDocumentFilter(this._selectors.values(), event.document)) { + let middleware = this._client.clientOptions.middleware; + let willSaveWaitUntil = (event) => { + return this._client + .sendRequest(vscode_languageserver_protocol_1.WillSaveTextDocumentWaitUntilRequest.type, cv.asWillSaveTextDocumentParams(event)) + .then(edits => { + return edits ? edits : []; + }, e => { + workspace_1.default.showMessage(`Error on willSaveWaitUntil: ${e}`, 'error'); + logger.error(e); + return []; + }); + }; + event.waitUntil(middleware.willSaveWaitUntil + ? middleware.willSaveWaitUntil(event, willSaveWaitUntil) + : willSaveWaitUntil(event)); + } + } + unregister(id) { + this._selectors.delete(id); + if (this._selectors.size === 0 && this._listener) { + this._listener.dispose(); + this._listener = undefined; + } + } + dispose() { + this._selectors.clear(); + if (this._listener) { + this._listener.dispose(); + this._listener = undefined; + } + } +} +class DidSaveTextDocumentFeature extends DocumentNotifiactions { + constructor(client) { + super(client, workspace_1.default.onDidSaveTextDocument, vscode_languageserver_protocol_1.DidSaveTextDocumentNotification.type, client.clientOptions.middleware.didSave, textDocument => cv.asSaveTextDocumentParams(textDocument, this._includeText), DocumentNotifiactions.textDocumentFilter); + } + get messages() { + return vscode_languageserver_protocol_1.DidSaveTextDocumentNotification.type; + } + fillClientCapabilities(capabilities) { + ensure(ensure(capabilities, 'textDocument'), 'synchronization').didSave = true; + } + initialize(capabilities, documentSelector) { + let textDocumentSyncOptions = capabilities.resolvedTextDocumentSync; + if (documentSelector && + textDocumentSyncOptions && + textDocumentSyncOptions.save) { + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }, { includeText: !!textDocumentSyncOptions.save.includeText }) + }); + } + } + register(method, data) { + this._includeText = !!data.registerOptions.includeText; + super.register(method, data); + } +} +class FileSystemWatcherFeature { + constructor(_client, _notifyFileEvent) { + this._notifyFileEvent = _notifyFileEvent; + this._watchers = new Map(); + } + get messages() { + return vscode_languageserver_protocol_1.DidChangeWatchedFilesNotification.type; + } + fillClientCapabilities(capabilities) { + ensure(ensure(capabilities, 'workspace'), 'didChangeWatchedFiles').dynamicRegistration = true; + } + initialize(_capabilities, _documentSelector) { } + register(_method, data) { + if (!Array.isArray(data.registerOptions.watchers)) { + return; + } + let disposables = []; + for (let watcher of data.registerOptions.watchers) { + if (!Is.string(watcher.globPattern)) { + continue; + } + let watchCreate = true, watchChange = true, watchDelete = true; + if (watcher.kind != null) { + watchCreate = (watcher.kind & vscode_languageserver_protocol_1.WatchKind.Create) !== 0; + watchChange = (watcher.kind & vscode_languageserver_protocol_1.WatchKind.Change) != 0; + watchDelete = (watcher.kind & vscode_languageserver_protocol_1.WatchKind.Delete) != 0; + } + let fileSystemWatcher = workspace_1.default.createFileSystemWatcher(watcher.globPattern, !watchCreate, !watchChange, !watchDelete); + this.hookListeners(fileSystemWatcher, watchCreate, watchChange, watchDelete, disposables); + disposables.push(fileSystemWatcher); + } + this._watchers.set(data.id, disposables); + } + registerRaw(id, fileSystemWatchers) { + let disposables = []; + for (let fileSystemWatcher of fileSystemWatchers) { + disposables.push(fileSystemWatcher); + this.hookListeners(fileSystemWatcher, true, true, true, disposables); + } + this._watchers.set(id, disposables); + } + hookListeners(fileSystemWatcher, watchCreate, watchChange, watchDelete, listeners) { + if (watchCreate) { + fileSystemWatcher.onDidCreate(resource => this._notifyFileEvent({ + uri: cv.asUri(resource), + type: vscode_languageserver_protocol_1.FileChangeType.Created + }), null, listeners); + } + if (watchChange) { + fileSystemWatcher.onDidChange(resource => this._notifyFileEvent({ + uri: cv.asUri(resource), + type: vscode_languageserver_protocol_1.FileChangeType.Changed + }), null, listeners); + } + if (watchDelete) { + fileSystemWatcher.onDidDelete(resource => this._notifyFileEvent({ + uri: cv.asUri(resource), + type: vscode_languageserver_protocol_1.FileChangeType.Deleted + }), null, listeners); + } + } + unregister(id) { + let disposables = this._watchers.get(id); + if (disposables) { + for (let disposable of disposables) { + disposable.dispose(); + } + } + } + dispose() { + this._watchers.forEach(disposables => { + for (let disposable of disposables) { + disposable.dispose(); + } + }); + this._watchers.clear(); + } +} +class TextDocumentFeature { + constructor(_client, _message) { + this._client = _client; + this._message = _message; + this._providers = new Map(); + } + get messages() { + return this._message; + } + register(message, data) { + if (message.method !== this.messages.method) { + throw new Error(`Register called on wrong feature. Requested ${message.method} but reached feature ${this.messages.method}`); + } + if (!data.registerOptions.documentSelector) { + return; + } + let provider = this.registerLanguageProvider(data.registerOptions); + if (provider) { + this._providers.set(data.id, provider); + } + } + unregister(id) { + let provider = this._providers.get(id); + if (provider) { + provider.dispose(); + } + } + dispose() { + this._providers.forEach(value => { + value.dispose(); + }); + this._providers.clear(); + } +} +exports.TextDocumentFeature = TextDocumentFeature; +class WorkspaceFeature { + constructor(_client, _message) { + this._client = _client; + this._message = _message; + this._providers = new Map(); + } + get messages() { + return this._message; + } + register(message, data) { + if (message.method !== this.messages.method) { + throw new Error(`Register called on wrong feature. Requested ${message.method} but reached feature ${this.messages.method}`); + } + let provider = this.registerLanguageProvider(data.registerOptions); + if (provider) { + this._providers.set(data.id, provider); + } + } + unregister(id) { + let provider = this._providers.get(id); + if (provider) { + provider.dispose(); + } + } + dispose() { + this._providers.forEach(value => { + value.dispose(); + }); + this._providers.clear(); + } +} +class CompletionItemFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.CompletionRequest.type); + } + fillClientCapabilities(capabilites) { + let completion = ensure(ensure(capabilites, 'textDocument'), 'completion'); + completion.dynamicRegistration = true; + completion.contextSupport = true; + completion.completionItem = { + snippetSupport: true, + commitCharactersSupport: true, + documentationFormat: [vscode_languageserver_protocol_1.MarkupKind.Markdown, vscode_languageserver_protocol_1.MarkupKind.PlainText], + deprecatedSupport: true, + preselectSupport: true + }; + completion.completionItemKind = { valueSet: SupportedCompletionItemKinds }; + } + initialize(capabilities, documentSelector) { + if (!capabilities.completionProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }, capabilities.completionProvider) + }); + } + registerLanguageProvider(options) { + let triggerCharacters = options.triggerCharacters || []; + let client = this._client; + let provideCompletionItems = (document, position, context, token) => { + return client + .sendRequest(vscode_languageserver_protocol_1.CompletionRequest.type, cv.asCompletionParams(document, position, context), token) + .then(result => { + // logger.debug('result', result) + return result; + }, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.CompletionRequest.type, error); + return Promise.resolve([]); + }); + }; + let resolveCompletionItem = (item, token) => { + return client + .sendRequest(vscode_languageserver_protocol_1.CompletionResolveRequest.type, item, token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.CompletionResolveRequest.type, error); + return Promise.resolve(item); + }); + }; + let middleware = this._client.clientOptions.middleware; + let languageIds = cv.asLanguageIds(options.documentSelector); + return languages_1.default.registerCompletionItemProvider(this._client.id, 'LS', languageIds, { + provideCompletionItems: (document, position, token, context) => { + return middleware.provideCompletionItem + ? middleware.provideCompletionItem(document, position, context, token, provideCompletionItems) + : provideCompletionItems(document, position, context, token); + }, + resolveCompletionItem: options.resolveProvider + ? (item, token) => { + return middleware.resolveCompletionItem + ? middleware.resolveCompletionItem(item, token, resolveCompletionItem) + : resolveCompletionItem(item, token); + } + : undefined + }, triggerCharacters); + } +} +class HoverFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.HoverRequest.type); + } + fillClientCapabilities(capabilites) { + const hoverCapability = ensure(ensure(capabilites, 'textDocument'), 'hover'); + hoverCapability.dynamicRegistration = true; + hoverCapability.contentFormat = [vscode_languageserver_protocol_1.MarkupKind.Markdown, vscode_languageserver_protocol_1.MarkupKind.PlainText]; + } + initialize(capabilities, documentSelector) { + if (!capabilities.hoverProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let provideHover = (document, position, token) => { + return client + .sendRequest(vscode_languageserver_protocol_1.HoverRequest.type, cv.asTextDocumentPositionParams(document, position), token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.HoverRequest.type, error); + return Promise.resolve(null); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerHoverProvider(options.documentSelector, { + provideHover: (document, position, token) => { + return middleware.provideHover + ? middleware.provideHover(document, position, token, provideHover) + : provideHover(document, position, token); + } + }); + } +} +class SignatureHelpFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.SignatureHelpRequest.type); + } + fillClientCapabilities(capabilites) { + let config = ensure(ensure(capabilites, 'textDocument'), 'signatureHelp'); + config.dynamicRegistration = true; + config.signatureInformation = { + documentationFormat: [vscode_languageserver_protocol_1.MarkupKind.Markdown, vscode_languageserver_protocol_1.MarkupKind.PlainText], + parameterInformation: { + labelOffsetSupport: true + } + }; + } + initialize(capabilities, documentSelector) { + if (!capabilities.signatureHelpProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }, capabilities.signatureHelpProvider) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let providerSignatureHelp = (document, position, token) => { + return client + .sendRequest(vscode_languageserver_protocol_1.SignatureHelpRequest.type, cv.asTextDocumentPositionParams(document, position), token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.SignatureHelpRequest.type, error); + return Promise.resolve(null); + }); + }; + let middleware = client.clientOptions.middleware; + let triggerCharacters = options.triggerCharacters || []; + return languages_1.default.registerSignatureHelpProvider(options.documentSelector, { + provideSignatureHelp: (document, position, token) => { + return middleware.provideSignatureHelp + ? middleware.provideSignatureHelp(document, position, token, providerSignatureHelp) + : providerSignatureHelp(document, position, token); + } + }, triggerCharacters); + } +} +class DefinitionFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.DefinitionRequest.type); + } + fillClientCapabilities(capabilites) { + let definitionSupport = ensure(ensure(capabilites, 'textDocument'), 'definition'); + definitionSupport.dynamicRegistration = true; + // definitionSupport.linkSupport = true + } + initialize(capabilities, documentSelector) { + if (!capabilities.definitionProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let provideDefinition = (document, position, token) => { + return client + .sendRequest(vscode_languageserver_protocol_1.DefinitionRequest.type, cv.asTextDocumentPositionParams(document, position), token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.DefinitionRequest.type, error); + return Promise.resolve(null); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerDefinitionProvider(options.documentSelector, { + provideDefinition: (document, position, token) => { + return middleware.provideDefinition + ? middleware.provideDefinition(document, position, token, provideDefinition) + : provideDefinition(document, position, token); + } + }); + } +} +class ReferencesFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.ReferencesRequest.type); + } + fillClientCapabilities(capabilites) { + ensure(ensure(capabilites, 'textDocument'), 'references').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + if (!capabilities.referencesProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let providerReferences = (document, position, options, token) => { + return client + .sendRequest(vscode_languageserver_protocol_1.ReferencesRequest.type, cv.asReferenceParams(document, position, options), token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.ReferencesRequest.type, error); + return Promise.resolve([]); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerReferencesProvider(options.documentSelector, { + provideReferences: (document, position, options, token) => { + return middleware.provideReferences + ? middleware.provideReferences(document, position, options, token, providerReferences) + : providerReferences(document, position, options, token); + } + }); + } +} +class DocumentHighlightFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.DocumentHighlightRequest.type); + } + fillClientCapabilities(capabilites) { + ensure(ensure(capabilites, 'textDocument'), 'documentHighlight').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + if (!capabilities.documentHighlightProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let provideDocumentHighlights = (document, position, token) => { + return client + .sendRequest(vscode_languageserver_protocol_1.DocumentHighlightRequest.type, cv.asTextDocumentPositionParams(document, position), token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.DocumentHighlightRequest.type, error); + return Promise.resolve([]); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerDocumentHighlightProvider(options.documentSelector, { + provideDocumentHighlights: (document, position, token) => { + return middleware.provideDocumentHighlights + ? middleware.provideDocumentHighlights(document, position, token, provideDocumentHighlights) + : provideDocumentHighlights(document, position, token); + } + }); + } +} +class DocumentSymbolFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.DocumentSymbolRequest.type); + } + fillClientCapabilities(capabilites) { + let symbolCapabilities = ensure(ensure(capabilites, 'textDocument'), 'documentSymbol'); + symbolCapabilities.dynamicRegistration = true; + symbolCapabilities.symbolKind = { + valueSet: SupporedSymbolKinds + }; + } + initialize(capabilities, documentSelector) { + if (!capabilities.documentSymbolProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let provideDocumentSymbols = (document, token) => { + return client + .sendRequest(vscode_languageserver_protocol_1.DocumentSymbolRequest.type, cv.asDocumentSymbolParams(document), token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.DocumentSymbolRequest.type, error); + return Promise.resolve([]); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerDocumentSymbolProvider(options.documentSelector, { + provideDocumentSymbols: (document, token) => { + return middleware.provideDocumentSymbols + ? middleware.provideDocumentSymbols(document, token, provideDocumentSymbols) + : provideDocumentSymbols(document, token); + } + }); + } +} +class WorkspaceSymbolFeature extends WorkspaceFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.WorkspaceSymbolRequest.type); + } + fillClientCapabilities(capabilites) { + let symbolCapabilities = ensure(ensure(capabilites, 'workspace'), 'symbol'); + symbolCapabilities.dynamicRegistration = true; + symbolCapabilities.symbolKind = { + valueSet: SupporedSymbolKinds + }; + } + initialize(capabilities, documentSelector) { + if (!capabilities.workspaceSymbolProvider) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let provideWorkspaceSymbols = (query, token) => { + return client + .sendRequest(vscode_languageserver_protocol_1.WorkspaceSymbolRequest.type, { query }, token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.WorkspaceSymbolRequest.type, error); + return Promise.resolve([]); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerWorkspaceSymbolProvider(options.documentSelector, { + provideWorkspaceSymbols: (query, token) => { + return middleware.provideWorkspaceSymbols + ? middleware.provideWorkspaceSymbols(query, token, provideWorkspaceSymbols) + : provideWorkspaceSymbols(query, token); + } + }); + } +} +class CodeActionFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.CodeActionRequest.type); + } + fillClientCapabilities(capabilites) { + const cap = ensure(ensure(capabilites, 'textDocument'), 'codeAction'); + cap.dynamicRegistration = true; + cap.codeActionLiteralSupport = { + codeActionKind: { + valueSet: [ + '', + vscode_languageserver_protocol_1.CodeActionKind.QuickFix, + vscode_languageserver_protocol_1.CodeActionKind.Refactor, + vscode_languageserver_protocol_1.CodeActionKind.RefactorExtract, + vscode_languageserver_protocol_1.CodeActionKind.RefactorInline, + vscode_languageserver_protocol_1.CodeActionKind.RefactorRewrite, + vscode_languageserver_protocol_1.CodeActionKind.Source, + vscode_languageserver_protocol_1.CodeActionKind.SourceOrganizeImports + ] + } + }; + } + initialize(capabilities, documentSelector) { + if (!capabilities.codeActionProvider || !documentSelector) { + return; + } + let codeActionKinds; + if (!Is.boolean(capabilities.codeActionProvider)) { + codeActionKinds = capabilities.codeActionProvider.codeActionKinds; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector, codeActionKinds }) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let provideCodeActions = (document, range, context, token) => { + let params = { + textDocument: { + uri: document.uri + }, + range, + context, + }; + return client.sendRequest(vscode_languageserver_protocol_1.CodeActionRequest.type, params, token).then(values => { + if (values == null) + return null; + return values; + }, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.CodeActionRequest.type, error); + return Promise.resolve([]); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerCodeActionProvider(options.documentSelector, { + provideCodeActions: (document, range, context, token) => { + return middleware.provideCodeActions + ? middleware.provideCodeActions(document, range, context, token, provideCodeActions) + : provideCodeActions(document, range, context, token); + } + }, client.id, options.codeActionKinds); + } +} +class CodeLensFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.CodeLensRequest.type); + } + fillClientCapabilities(capabilites) { + ensure(ensure(capabilites, 'textDocument'), 'codeLens').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + if (!capabilities.codeLensProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }, capabilities.codeLensProvider) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let provideCodeLenses = (document, token) => { + return client + .sendRequest(vscode_languageserver_protocol_1.CodeLensRequest.type, cv.asCodeLensParams(document), token).then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.CodeLensRequest.type, error); + return Promise.resolve([]); + }); + }; + let resolveCodeLens = (codeLens, token) => { + return client + .sendRequest(vscode_languageserver_protocol_1.CodeLensResolveRequest.type, codeLens, token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.CodeLensResolveRequest.type, error); + return codeLens; + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerCodeLensProvider(options.documentSelector, { + provideCodeLenses: (document, token) => { + return middleware.provideCodeLenses + ? middleware.provideCodeLenses(document, token, provideCodeLenses) + : provideCodeLenses(document, token); + }, + resolveCodeLens: options.resolveProvider + ? (codeLens, token) => { + return middleware.resolveCodeLens + ? middleware.resolveCodeLens(codeLens, token, resolveCodeLens) + : resolveCodeLens(codeLens, token); + } + : undefined + }); + } +} +class DocumentFormattingFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.DocumentFormattingRequest.type); + } + fillClientCapabilities(capabilites) { + ensure(ensure(capabilites, 'textDocument'), 'formatting').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + if (!capabilities.documentFormattingProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let provideDocumentFormattingEdits = (document, options, token) => { + let params = { + textDocument: { + uri: document.uri + }, + options + }; + return client + .sendRequest(vscode_languageserver_protocol_1.DocumentFormattingRequest.type, params, token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.DocumentFormattingRequest.type, error); + return Promise.resolve([]); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerDocumentFormatProvider(options.documentSelector, { + provideDocumentFormattingEdits: (document, options, token) => { + return middleware.provideDocumentFormattingEdits + ? middleware.provideDocumentFormattingEdits(document, options, token, provideDocumentFormattingEdits) + : provideDocumentFormattingEdits(document, options, token); + } + }); + } +} +class DocumentRangeFormattingFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.DocumentRangeFormattingRequest.type); + } + fillClientCapabilities(capabilites) { + ensure(ensure(capabilites, 'textDocument'), 'rangeFormatting').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + if (!capabilities.documentRangeFormattingProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let provideDocumentRangeFormattingEdits = (document, range, options, token) => { + let params = { + textDocument: { + uri: document.uri + }, + range, + options, + }; + return client + .sendRequest(vscode_languageserver_protocol_1.DocumentRangeFormattingRequest.type, params, token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.DocumentRangeFormattingRequest.type, error); + return Promise.resolve([]); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerDocumentRangeFormatProvider(options.documentSelector, { + provideDocumentRangeFormattingEdits: (document, range, options, token) => { + return middleware.provideDocumentRangeFormattingEdits + ? middleware.provideDocumentRangeFormattingEdits(document, range, options, token, provideDocumentRangeFormattingEdits) + : provideDocumentRangeFormattingEdits(document, range, options, token); + } + }); + } +} +class DocumentOnTypeFormattingFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.DocumentOnTypeFormattingRequest.type); + } + fillClientCapabilities(capabilites) { + ensure(ensure(capabilites, 'textDocument'), 'onTypeFormatting').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + if (!capabilities.documentOnTypeFormattingProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }, capabilities.documentOnTypeFormattingProvider) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let moreTriggerCharacter = options.moreTriggerCharacter || []; + let provideOnTypeFormattingEdits = (document, position, ch, options, token) => { + let params = { + textDocument: cv.asVersionedTextDocumentIdentifier(document), + position, + ch, + options + }; + return client.sendRequest(vscode_languageserver_protocol_1.DocumentOnTypeFormattingRequest.type, params, token).then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.DocumentOnTypeFormattingRequest.type, error); + return Promise.resolve([]); + }); + }; + let middleware = client.clientOptions.middleware; + let characters = [options.firstTriggerCharacter, ...moreTriggerCharacter]; + return languages_1.default.registerOnTypeFormattingEditProvider(options.documentSelector, { + provideOnTypeFormattingEdits: (document, position, ch, options, token) => { + return middleware.provideOnTypeFormattingEdits + ? middleware.provideOnTypeFormattingEdits(document, position, ch, options, token, provideOnTypeFormattingEdits) + : provideOnTypeFormattingEdits(document, position, ch, options, token); + } + }, characters); + } +} +class RenameFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.RenameRequest.type); + } + fillClientCapabilities(capabilites) { + let rename = ensure(ensure(capabilites, 'textDocument'), 'rename'); + rename.dynamicRegistration = true; + rename.prepareSupport = true; + } + initialize(capabilities, documentSelector) { + if (!capabilities.renameProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }, capabilities.renameProvider || {}) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let provideRenameEdits = (document, position, newName, token) => { + let params = { + textDocument: { + uri: document.uri + }, + position, + newName: newName + }; + return client + .sendRequest(vscode_languageserver_protocol_1.RenameRequest.type, params, token) + .then(res => res, (error) => { + client.logFailedRequest(vscode_languageserver_protocol_1.RenameRequest.type, error); + return Promise.reject(new Error(error.message)); + }); + }; + let prepareRename = (document, position, token) => { + let params = { + textDocument: cv.asTextDocumentIdentifier(document), + position + }; + return client.sendRequest(vscode_languageserver_protocol_1.PrepareRenameRequest.type, params, token).then(result => { + return result; + }, (error) => { + client.logFailedRequest(vscode_languageserver_protocol_1.PrepareRenameRequest.type, error); + return Promise.reject(new Error(error.message)); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerRenameProvider(options.documentSelector, { + provideRenameEdits: (document, position, newName, token) => { + return middleware.provideRenameEdits + ? middleware.provideRenameEdits(document, position, newName, token, provideRenameEdits) + : provideRenameEdits(document, position, newName, token); + }, + prepareRename: options.prepareProvider + ? (document, position, token) => { + return middleware.prepareRename + ? middleware.prepareRename(document, position, token, prepareRename) + : prepareRename(document, position, token); + } : undefined + }); + } +} +class DocumentLinkFeature extends TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.DocumentLinkRequest.type); + } + fillClientCapabilities(capabilites) { + ensure(ensure(capabilites, 'textDocument'), 'documentLink').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + if (!capabilities.documentLinkProvider || !documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector: documentSelector }, capabilities.documentLinkProvider) + }); + } + registerLanguageProvider(options) { + let client = this._client; + let provideDocumentLinks = (document, token) => { + return client.sendRequest(vscode_languageserver_protocol_1.DocumentLinkRequest.type, { + textDocument: { + uri: document.uri + } + }, token).then(res => res, (error) => { + client.logFailedRequest(vscode_languageserver_protocol_1.DocumentLinkRequest.type, error); + Promise.resolve(new Error(error.message)); + }); + }; + let resolveDocumentLink = (link, token) => { + return client + .sendRequest(vscode_languageserver_protocol_1.DocumentLinkResolveRequest.type, link, token) + .then(res => res, (error) => { + client.logFailedRequest(vscode_languageserver_protocol_1.DocumentLinkResolveRequest.type, error); + Promise.resolve(new Error(error.message)); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerDocumentLinkProvider(options.documentSelector, { + provideDocumentLinks: (document, token) => { + return middleware.provideDocumentLinks + ? middleware.provideDocumentLinks(document, token, provideDocumentLinks) + : provideDocumentLinks(document, token); + }, + resolveDocumentLink: options.resolveProvider + ? (link, token) => { + return middleware.resolveDocumentLink + ? middleware.resolveDocumentLink(link, token, resolveDocumentLink) + : resolveDocumentLink(link, token); + } + : undefined + }); + } +} +class ConfigurationFeature { + constructor(_client) { + this._client = _client; + this._listeners = new Map(); + } + get messages() { + return vscode_languageserver_protocol_1.DidChangeConfigurationNotification.type; + } + fillClientCapabilities(capabilities) { + ensure(ensure(capabilities, 'workspace'), 'didChangeConfiguration').dynamicRegistration = true; + } + initialize() { + let section = this._client.clientOptions.synchronize.configurationSection; + if (section != null) { + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: { + section: section + } + }); + } + } + register(_message, data) { + let { section } = data.registerOptions; + let disposable = workspace_1.default.onDidChangeConfiguration(() => { + if (section != null) { + this.onDidChangeConfiguration(data.registerOptions.section); + } + }); + this._listeners.set(data.id, disposable); + if (Is.string(section) && section.endsWith('.settings')) { + let settings = this.getConfiguredSettings(section); + if (!settings || Is.emptyObject(settings)) + return; + } + if (section != null) { + this.onDidChangeConfiguration(data.registerOptions.section); + } + } + unregister(id) { + let disposable = this._listeners.get(id); + if (disposable) { + this._listeners.delete(id); + disposable.dispose(); + } + } + dispose() { + for (let disposable of this._listeners.values()) { + disposable.dispose(); + } + this._listeners.clear(); + } + onDidChangeConfiguration(configurationSection) { + let sections; + if (Is.string(configurationSection)) { + sections = [configurationSection]; + } + else { + sections = configurationSection; + } + let isConfigured = sections.length == 1 && /^languageserver\..+\.settings$/.test(sections[0]); + let didChangeConfiguration = (sections) => { + if (sections == null) { + this._client.sendNotification(vscode_languageserver_protocol_1.DidChangeConfigurationNotification.type, { + settings: null + }); + return; + } + this._client.sendNotification(vscode_languageserver_protocol_1.DidChangeConfigurationNotification.type, { + settings: isConfigured ? this.getConfiguredSettings(sections[0]) : this.extractSettingsInformation(sections) + }); + }; + let middleware = this.getMiddleware(); + middleware + ? middleware(sections, didChangeConfiguration) + : didChangeConfiguration(sections); + } + getConfiguredSettings(key) { + let len = '.settings'.length; + let config = workspace_1.default.getConfiguration(key.slice(0, -len)); + return config.get('settings', {}); + } + extractSettingsInformation(keys) { + function ensurePath(config, path) { + let current = config; + for (let i = 0; i < path.length - 1; i++) { + let obj = current[path[i]]; + if (!obj) { + obj = Object.create(null); + current[path[i]] = obj; + } + current = obj; + } + return current; + } + let result = Object.create(null); + for (let i = 0; i < keys.length; i++) { + let key = keys[i]; + let index = key.indexOf('.'); + let config = null; + if (index >= 0) { + config = workspace_1.default.getConfiguration(key.substr(0, index)).get(key.substr(index + 1)); + } + else { + config = workspace_1.default.getConfiguration(key); + } + if (config) { + let path = keys[i].split('.'); + ensurePath(result, path)[path[path.length - 1]] = config; + } + } + return result; + } + getMiddleware() { + let middleware = this._client.clientOptions.middleware; + if (middleware.workspace && middleware.workspace.didChangeConfiguration) { + return middleware.workspace.didChangeConfiguration; + } + else { + return undefined; + } + } +} +class ExecuteCommandFeature { + constructor(_client) { + this._client = _client; + this._commands = new Map(); + } + get messages() { + return vscode_languageserver_protocol_1.ExecuteCommandRequest.type; + } + fillClientCapabilities(capabilities) { + ensure(ensure(capabilities, 'workspace'), 'executeCommand').dynamicRegistration = true; + } + initialize(capabilities) { + if (!capabilities.executeCommandProvider) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, capabilities.executeCommandProvider) + }); + } + register(_message, data) { + let client = this._client; + if (data.registerOptions.commands) { + let disposables = []; + for (const command of data.registerOptions.commands) { + disposables.push(commands_1.default.registerCommand(command, (...args) => { + let params = { + command, + arguments: args + }; + return client + .sendRequest(vscode_languageserver_protocol_1.ExecuteCommandRequest.type, params) + .then(undefined, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.ExecuteCommandRequest.type, error); + }); + }, null, true)); + } + this._commands.set(data.id, disposables); + } + } + unregister(id) { + let disposables = this._commands.get(id); + if (disposables) { + disposables.forEach(disposable => disposable.dispose()); + } + } + dispose() { + this._commands.forEach(value => { + value.forEach(disposable => disposable.dispose()); + }); + this._commands.clear(); + } +} +var MessageTransports; +(function (MessageTransports) { + function is(value) { + let candidate = value; + return (candidate && + vscode_languageserver_protocol_1.MessageReader.is(value.reader) && + vscode_languageserver_protocol_1.MessageWriter.is(value.writer)); + } + MessageTransports.is = is; +})(MessageTransports = exports.MessageTransports || (exports.MessageTransports = {})); +class BaseLanguageClient { + constructor(id, name, clientOptions) { + this._features = []; + this._method2Message = new Map(); + this._dynamicFeatures = new Map(); + this._id = id; + this._name = name; + clientOptions = clientOptions || {}; + this._clientOptions = { + disableWorkspaceFolders: clientOptions.disableWorkspaceFolders, + disableDynamicRegister: clientOptions.disableDynamicRegister, + disableDiagnostics: clientOptions.disableDiagnostics, + disableCompletion: clientOptions.disableCompletion, + ignoredRootPaths: clientOptions.ignoredRootPaths, + documentSelector: clientOptions.documentSelector || [], + synchronize: clientOptions.synchronize || {}, + diagnosticCollectionName: clientOptions.diagnosticCollectionName, + outputChannelName: clientOptions.outputChannelName || this._id, + revealOutputChannelOn: clientOptions.revealOutputChannelOn || RevealOutputChannelOn.Never, + stdioEncoding: clientOptions.stdioEncoding || 'utf8', + initializationOptions: clientOptions.initializationOptions, + initializationFailedHandler: clientOptions.initializationFailedHandler, + errorHandler: clientOptions.errorHandler || new DefaultErrorHandler(this._id), + middleware: clientOptions.middleware || {}, + workspaceFolder: clientOptions.workspaceFolder + }; + this._clientOptions.synchronize = this._clientOptions.synchronize || {}; + this.state = ClientState.Initial; + this._connectionPromise = undefined; + this._resolvedConnection = undefined; + this._initializeResult = undefined; + if (clientOptions.outputChannel) { + this._outputChannel = clientOptions.outputChannel; + this._disposeOutputChannel = false; + } + else { + this._outputChannel = undefined; + this._disposeOutputChannel = true; + } + this._listeners = undefined; + this._providers = undefined; + this._diagnostics = undefined; + this._fileEvents = []; + this._fileEventDelayer = new async_1.Delayer(250); + this._onReady = new Promise((resolve, reject) => { + this._onReadyCallbacks = new OnReady(resolve, reject); + }); + this._onStop = undefined; + this._stateChangeEmitter = new vscode_languageserver_protocol_1.Emitter(); + this._tracer = { + log: (messageOrDataObject, data) => { + if (Is.string(messageOrDataObject)) { + this.logTrace(messageOrDataObject, data); + } + else { + this.logObjectTrace(messageOrDataObject); + } + } + }; + this._syncedDocuments = new Map(); + this.registerBuiltinFeatures(); + } + get state() { + return this._state; + } + get id() { + return this._id; + } + get name() { + return this._name; + } + set state(value) { + let oldState = this.getPublicState(); + this._state = value; + let newState = this.getPublicState(); + if (newState !== oldState) { + this._stateChangeEmitter.fire({ oldState, newState }); + } + } + getPublicState() { + if (this.state === ClientState.Running) { + return State.Running; + } + else if (this.state === ClientState.Starting) { + return State.Starting; + } + else { + return State.Stopped; + } + } + get initializeResult() { + return this._initializeResult; + } + sendRequest(type, ...params) { + if (!this.isConnectionActive()) { + throw new Error('Language client is not ready yet'); + } + this.forceDocumentSync(); + try { + return this._resolvedConnection.sendRequest(type, ...params); + } + catch (error) { + this.error(`Sending request ${Is.string(type) ? type : type.method} failed.`, error); + throw error; + } + } + onRequest(type, handler) { + if (!this.isConnectionActive()) { + throw new Error('Language client is not ready yet'); + } + try { + this._resolvedConnection.onRequest(type, handler); + } + catch (error) { + this.error(`Registering request handler ${Is.string(type) ? type : type.method} failed.`, error); + throw error; + } + } + sendNotification(type, params) { + if (!this.isConnectionActive()) { + throw new Error('Language client is not ready yet'); + } + this.forceDocumentSync(); + try { + this._resolvedConnection.sendNotification(type, params); + } + catch (error) { + this.error(`Sending notification ${Is.string(type) ? type : type.method} failed.`, error); + throw error; + } + } + onNotification(type, handler) { + if (!this.isConnectionActive()) { + throw new Error('Language client is not ready yet'); + } + try { + this._resolvedConnection.onNotification(type, handler); + } + catch (error) { + this.error(`Registering notification handler ${Is.string(type) ? type : type.method} failed.`, error); + throw error; + } + } + get clientOptions() { + return this._clientOptions; + } + get onDidChangeState() { + return this._stateChangeEmitter.event; + } + get outputChannel() { + if (!this._outputChannel) { + let { outputChannelName } = this._clientOptions; + this._outputChannel = workspace_1.default.createOutputChannel(outputChannelName ? outputChannelName : this._name); + } + return this._outputChannel; + } + get diagnostics() { + return this._diagnostics; + } + createDefaultErrorHandler() { + return new DefaultErrorHandler(this._id); + } + set trace(value) { + this._trace = value; + this.onReady().then(() => { + this.resolveConnection().then(connection => { + connection.trace(this._trace, this._tracer, { + sendNotification: false, + traceFormat: this._traceFormat + }); + }); + }, () => { }); + } + logObjectTrace(data) { + if (data.isLSPMessage && data.type) { + this.outputChannel.append(`[LSP - ${(new Date().toLocaleTimeString())}] `); + } + else { + this.outputChannel.append(`[Trace - ${(new Date().toLocaleTimeString())}] `); + } + if (data) { + this.outputChannel.appendLine(`${JSON.stringify(data)}`); + } + } + data2String(data) { + if (data instanceof vscode_languageserver_protocol_1.ResponseError) { + const responseError = data; + return ` Message: ${responseError.message}\n Code: ${responseError.code} ${responseError.data ? '\n' + responseError.data.toString() : ''}`; + } + if (data instanceof Error) { + if (Is.string(data.stack)) { + return data.stack; + } + return data.message; + } + if (Is.string(data)) { + return data; + } + return data.toString(); + } + _appendOutput(type, message, data) { + let level = RevealOutputChannelOn.Error; + switch (type) { + case 'Info': + level = RevealOutputChannelOn.Info; + break; + case 'Warn': + level = RevealOutputChannelOn.Warn; + break; + } + this.outputChannel.appendLine(`[${type} - ${(new Date().toLocaleTimeString())}] ${message}`); + let dataString; + if (data) { + dataString = this.data2String(data); + this.outputChannel.appendLine(dataString); + } + if (this._clientOptions.revealOutputChannelOn <= level) { + this.outputChannel.show(true); + } + } + info(message, data) { + this._appendOutput('Info', message, data); + } + warn(message, data) { + this._appendOutput('Warn', message, data); + } + error(message, data) { + this._appendOutput('Error', message, data); + } + logTrace(message, data) { + this.outputChannel.appendLine(`[Trace - ${(new Date().toLocaleTimeString())}] ${message}`); + if (data) { + this.outputChannel.appendLine(this.data2String(data)); + } + } + needsStart() { + return (this.state === ClientState.Initial || + this.state === ClientState.Stopping || + this.state === ClientState.Stopped); + } + needsStop() { + return (this.state === ClientState.Starting || this.state === ClientState.Running); + } + onReady() { + return this._onReady; + } + get started() { + return this.state != ClientState.Initial; + } + isConnectionActive() { + return this.state === ClientState.Running && !!this._resolvedConnection; + } + start() { + if (this._onReadyCallbacks.isUsed) { + this._onReady = new Promise((resolve, reject) => { + this._onReadyCallbacks = new OnReady(resolve, reject); + }); + } + this._listeners = []; + this._providers = []; + // If we restart then the diagnostics collection is reused. + if (!this._diagnostics) { + this._diagnostics = this._clientOptions.diagnosticCollectionName + ? languages_1.default.createDiagnosticCollection(this._clientOptions.diagnosticCollectionName) + : languages_1.default.createDiagnosticCollection(this._id); + } + this.state = ClientState.Starting; + this.resolveConnection() + .then(connection => { + connection.onLogMessage(message => { + switch (message.type) { + case vscode_languageserver_protocol_1.MessageType.Error: + this.error(message.message); + break; + case vscode_languageserver_protocol_1.MessageType.Warning: + this.warn(message.message); + break; + case vscode_languageserver_protocol_1.MessageType.Info: + this.info(message.message); + break; + default: + this.outputChannel.appendLine(message.message); + } + }); + connection.onShowMessage(message => { + switch (message.type) { + case vscode_languageserver_protocol_1.MessageType.Error: + workspace_1.default.showMessage(message.message, 'error'); + break; + case vscode_languageserver_protocol_1.MessageType.Warning: + workspace_1.default.showMessage(message.message, 'warning'); + break; + case vscode_languageserver_protocol_1.MessageType.Info: + workspace_1.default.showMessage(message.message); + break; + default: + workspace_1.default.showMessage(message.message); + } + }); + connection.onRequest(vscode_languageserver_protocol_1.ShowMessageRequest.type, params => { + if (!params.actions || params.actions.length == 0) { + let msgType = params.type == vscode_languageserver_protocol_1.MessageType.Error + ? 'error' : params.type == vscode_languageserver_protocol_1.MessageType.Warning ? 'warning' : 'more'; + workspace_1.default.showMessage(params.message, msgType); + return Promise.resolve(null); + } + let items = params.actions.map(o => typeof o === 'string' ? o : o.title); + return workspace_1.default.showQuickpick(items, params.message).then(idx => { + return params.actions[idx]; + }); + }); + connection.onTelemetry(_data => { + // ignored + }); + connection.listen(); + // Error is handled in the intialize call. + return this.initialize(connection); + }).then(undefined, error => { + this.state = ClientState.StartFailed; + this._onReadyCallbacks.reject(error); + this.error('Starting client failed: ', error); + }); + return vscode_languageserver_protocol_1.Disposable.create(() => { + if (this.needsStop()) { + this.stop(); + } + }); + } + resolveConnection() { + if (!this._connectionPromise) { + this._connectionPromise = this.createConnection(); + } + return this._connectionPromise; + } + resolveRootPath() { + if (this._clientOptions.workspaceFolder) { + return vscode_uri_1.URI.parse(this._clientOptions.workspaceFolder.uri).fsPath; + } + let { ignoredRootPaths } = this._clientOptions; + let config = workspace_1.default.getConfiguration(this.id); + let rootPatterns = config.get('rootPatterns', []); + let required = config.get('requireRootPattern', false); + let resolved; + if (rootPatterns && rootPatterns.length) { + let doc = workspace_1.default.getDocument(workspace_1.default.bufnr); + if (doc && doc.schema == 'file') { + let dir = path_1.default.dirname(vscode_uri_1.URI.parse(doc.uri).fsPath); + resolved = fs_1.resolveRoot(dir, rootPatterns, workspace_1.default.cwd); + } + } + if (required && !resolved) + return null; + let rootPath = resolved || workspace_1.default.rootPath || workspace_1.default.cwd; + if (ignoredRootPaths && ignoredRootPaths.indexOf(rootPath) !== -1) { + workspace_1.default.showMessage(`Ignored rootPath ${rootPath} of client "${this._id}"`, 'warning'); + return null; + } + return rootPath; + } + initialize(connection) { + this.refreshTrace(connection, false); + let initOption = this._clientOptions.initializationOptions; + let rootPath = this.resolveRootPath(); + if (!rootPath) + return; + let initParams = { + processId: process.pid, + rootPath: rootPath ? rootPath : null, + rootUri: rootPath ? cv.asUri(vscode_uri_1.URI.file(rootPath)) : null, + capabilities: this.computeClientCapabilities(), + initializationOptions: Is.func(initOption) ? initOption() : initOption, + trace: vscode_languageserver_protocol_1.Trace.toString(this._trace), + }; + this.fillInitializeParams(initParams); + return connection + .initialize(initParams) + .then(result => { + this._resolvedConnection = connection; + this._initializeResult = result; + this.state = ClientState.Running; + let textDocumentSyncOptions = undefined; + if (Is.number(result.capabilities.textDocumentSync)) { + if (result.capabilities.textDocumentSync === vscode_languageserver_protocol_1.TextDocumentSyncKind.None) { + textDocumentSyncOptions = { + openClose: false, + change: vscode_languageserver_protocol_1.TextDocumentSyncKind.None, + save: undefined + }; + } + else { + textDocumentSyncOptions = { + openClose: true, + change: result.capabilities.textDocumentSync, + save: { + includeText: false + } + }; + } + } + else if (result.capabilities.textDocumentSync != null) { + textDocumentSyncOptions = result.capabilities.textDocumentSync; + } + this._capabilities = Object.assign({}, result.capabilities, { + resolvedTextDocumentSync: textDocumentSyncOptions + }); + if (!this._clientOptions.disableDiagnostics) { + connection.onDiagnostics(params => this.handleDiagnostics(params)); + } + connection.onRequest(vscode_languageserver_protocol_1.RegistrationRequest.type, params => this.handleRegistrationRequest(params)); + // See https://github.com/Microsoft/vscode-languageserver-node/issues/199 + connection.onRequest('client/registerFeature', params => this.handleRegistrationRequest(params)); + connection.onRequest(vscode_languageserver_protocol_1.UnregistrationRequest.type, params => this.handleUnregistrationRequest(params)); + // See https://github.com/Microsoft/vscode-languageserver-node/issues/199 + connection.onRequest('client/unregisterFeature', params => this.handleUnregistrationRequest(params)); + connection.onRequest(vscode_languageserver_protocol_1.ApplyWorkspaceEditRequest.type, params => this.handleApplyWorkspaceEdit(params)); + connection.sendNotification(vscode_languageserver_protocol_1.InitializedNotification.type, {}); + this.hookFileEvents(connection); + this.hookConfigurationChanged(connection); + this.initializeFeatures(connection); + this._onReadyCallbacks.resolve(); + return result; + }).then(undefined, error => { + if (this._clientOptions.initializationFailedHandler) { + if (this._clientOptions.initializationFailedHandler(error)) { + this.initialize(connection); + } + else { + this.stop(); + this._onReadyCallbacks.reject(error); + } + } + else if (error instanceof vscode_languageserver_protocol_1.ResponseError && + error.data && + error.data.retry) { + workspace_1.default.showPrompt(error.message + ' Retry?').then(confirmed => { + if (confirmed) { + this.initialize(connection); + } + else { + this.stop(); + this._onReadyCallbacks.reject(error); + } + }); + } + else { + if (error && error.message) { + workspace_1.default.showMessage(error.message, 'error'); + } + this.error('Server initialization failed.', error); + this.stop(); + this._onReadyCallbacks.reject(error); + } + }); + } + stop() { + this._initializeResult = undefined; + if (!this._connectionPromise) { + this.state = ClientState.Stopped; + return Promise.resolve(); + } + if (this.state === ClientState.Stopping && this._onStop) { + return this._onStop; + } + this.state = ClientState.Stopping; + this.cleanUp(); + // unkook listeners + return (this._onStop = this.resolveConnection().then(connection => { + return connection.shutdown().then(() => { + connection.exit(); + connection.dispose(); + this.state = ClientState.Stopped; + this._onStop = undefined; + this._connectionPromise = undefined; + this._resolvedConnection = undefined; + }); + })); + } + cleanUp(channel = true, diagnostics = true) { + if (this._listeners) { + this._listeners.forEach(listener => listener.dispose()); + this._listeners = undefined; + } + if (this._providers) { + this._providers.forEach(provider => provider.dispose()); + this._providers = undefined; + } + if (this._syncedDocuments) { + this._syncedDocuments.clear(); + } + for (let handler of this._dynamicFeatures.values()) { + handler.dispose(); + } + if (channel && this._outputChannel && this._disposeOutputChannel) { + this._outputChannel.dispose(); + this._outputChannel = undefined; + } + if (diagnostics && this._diagnostics) { + this._diagnostics.dispose(); + this._diagnostics = undefined; + } + } + notifyFileEvent(event) { + this._fileEvents.push(event); + this._fileEventDelayer.trigger(() => { + this.onReady().then(() => { + this.resolveConnection().then(connection => { + if (this.isConnectionActive()) { + connection.didChangeWatchedFiles({ changes: this._fileEvents }); + } + this._fileEvents = []; + }); + }, error => { + this.error(`Notify file events failed.`, error); + }); + }); + } + forceDocumentSync() { + let doc = workspace_1.default.getDocument(workspace_1.default.bufnr); + if (doc) + doc.forceSync(false); + } + handleDiagnostics(params) { + if (!this._diagnostics) { + return; + } + let { uri, diagnostics } = params; + let middleware = this.clientOptions.middleware.handleDiagnostics; + if (middleware) { + middleware(uri, diagnostics, (uri, diagnostics) => this.setDiagnostics(uri, diagnostics)); + } + else { + this.setDiagnostics(uri, diagnostics); + } + } + setDiagnostics(uri, diagnostics) { + if (!this._diagnostics) { + return; + } + this._diagnostics.set(uri, diagnostics); + } + createConnection() { + let errorHandler = (error, message, count) => { + logger.error('connection error:', error, message); + this.handleConnectionError(error, message, count); + }; + let closeHandler = () => { + this.handleConnectionClosed(); + }; + return this.createMessageTransports(this._clientOptions.stdioEncoding || 'utf8').then(transports => { + return createConnection(transports.reader, transports.writer, errorHandler, closeHandler); + }); + } + handleConnectionClosed() { + // Check whether this is a normal shutdown in progress or the client stopped normally. + if (this.state === ClientState.Stopping || + this.state === ClientState.Stopped) { + return; + } + try { + if (this._resolvedConnection) { + this._resolvedConnection.dispose(); + } + } + catch (error) { + // Disposing a connection could fail if error cases. + } + let action = CloseAction.DoNotRestart; + try { + action = this._clientOptions.errorHandler.closed(); + } + catch (error) { + // Ignore errors coming from the error handler. + } + this._connectionPromise = undefined; + this._resolvedConnection = undefined; + if (action === CloseAction.DoNotRestart) { + this.error('Connection to server got closed. Server will not be restarted.'); + this.state = ClientState.Stopped; + this.cleanUp(false, true); + } + else if (action === CloseAction.Restart) { + this.info('Connection to server got closed. Server will restart.'); + this.cleanUp(false, false); + this.state = ClientState.Initial; + this.start(); + } + } + restart() { + this.cleanUp(true, false); + this.start(); + } + handleConnectionError(error, message, count) { + let action = this._clientOptions.errorHandler.error(error, message, count); + if (action === ErrorAction.Shutdown) { + this.error('Connection to server is erroring. Shutting down server.'); + this.stop(); + } + } + hookConfigurationChanged(connection) { + workspace_1.default.onDidChangeConfiguration(() => { + this.refreshTrace(connection, true); + }); + } + refreshTrace(connection, sendNotification = false) { + let config = workspace_1.default.getConfiguration(this._id); + let trace = vscode_languageserver_protocol_1.Trace.Off; + let traceFormat = vscode_languageserver_protocol_1.TraceFormat.Text; + if (config) { + const traceConfig = config.get('trace.server', 'off'); + if (typeof traceConfig === 'string') { + trace = vscode_languageserver_protocol_1.Trace.fromString(traceConfig); + } + else { + trace = vscode_languageserver_protocol_1.Trace.fromString(config.get('trace.server.verbosity', 'off')); + traceFormat = vscode_languageserver_protocol_1.TraceFormat.fromString(config.get('trace.server.format', 'text')); + } + } + this._trace = trace; + this._traceFormat = traceFormat; + connection.trace(this._trace, this._tracer, { + sendNotification, + traceFormat: this._traceFormat + }); + } + hookFileEvents(_connection) { + let fileEvents = this._clientOptions.synchronize.fileEvents; + if (!fileEvents) + return; + let watchers; + if (Array.isArray(fileEvents)) { + watchers = fileEvents; + } + else { + watchers = [fileEvents]; + } + if (!watchers) { + return; + } + this._dynamicFeatures.get(vscode_languageserver_protocol_1.DidChangeWatchedFilesNotification.type.method).registerRaw(UUID.generateUuid(), watchers); + } + registerFeatures(features) { + for (let feature of features) { + this.registerFeature(feature); + } + } + registerFeature(feature) { + this._features.push(feature); + if (DynamicFeature.is(feature)) { + let messages = feature.messages; + if (Array.isArray(messages)) { + for (let message of messages) { + this._method2Message.set(message.method, message); + this._dynamicFeatures.set(message.method, feature); + } + } + else { + this._method2Message.set(messages.method, messages); + this._dynamicFeatures.set(messages.method, feature); + } + } + } + registerBuiltinFeatures() { + this.registerFeature(new ConfigurationFeature(this)); + this.registerFeature(new DidOpenTextDocumentFeature(this, this._syncedDocuments)); + this.registerFeature(new DidChangeTextDocumentFeature(this)); + this.registerFeature(new WillSaveFeature(this)); + this.registerFeature(new WillSaveWaitUntilFeature(this)); + this.registerFeature(new DidSaveTextDocumentFeature(this)); + this.registerFeature(new DidCloseTextDocumentFeature(this, this._syncedDocuments)); + this.registerFeature(new FileSystemWatcherFeature(this, event => this.notifyFileEvent(event))); + if (!this._clientOptions.disableCompletion) { + this.registerFeature(new CompletionItemFeature(this)); + } + this.registerFeature(new HoverFeature(this)); + this.registerFeature(new SignatureHelpFeature(this)); + this.registerFeature(new DefinitionFeature(this)); + this.registerFeature(new ReferencesFeature(this)); + this.registerFeature(new DocumentHighlightFeature(this)); + this.registerFeature(new DocumentSymbolFeature(this)); + this.registerFeature(new WorkspaceSymbolFeature(this)); + this.registerFeature(new CodeActionFeature(this)); + this.registerFeature(new CodeLensFeature(this)); + this.registerFeature(new DocumentFormattingFeature(this)); + this.registerFeature(new DocumentRangeFormattingFeature(this)); + this.registerFeature(new DocumentOnTypeFormattingFeature(this)); + this.registerFeature(new RenameFeature(this)); + this.registerFeature(new DocumentLinkFeature(this)); + this.registerFeature(new ExecuteCommandFeature(this)); + } + fillInitializeParams(params) { + for (let feature of this._features) { + if (Is.func(feature.fillInitializeParams)) { + feature.fillInitializeParams(params); + } + } + } + computeClientCapabilities() { + let result = {}; + ensure(result, 'workspace').applyEdit = true; + let workspaceEdit = ensure(ensure(result, 'workspace'), 'workspaceEdit'); + workspaceEdit.documentChanges = true; + workspaceEdit.resourceOperations = [vscode_languageserver_protocol_1.ResourceOperationKind.Create, vscode_languageserver_protocol_1.ResourceOperationKind.Rename, vscode_languageserver_protocol_1.ResourceOperationKind.Delete]; + workspaceEdit.failureHandling = vscode_languageserver_protocol_1.FailureHandlingKind.TextOnlyTransactional; + ensure(ensure(result, 'textDocument'), 'publishDiagnostics').relatedInformation = true; + for (let feature of this._features) { + feature.fillClientCapabilities(result); + } + return result; + } + initializeFeatures(_connection) { + let documentSelector = this._clientOptions.documentSelector; + for (let feature of this._features) { + feature.initialize(this._capabilities, documentSelector); + } + } + handleRegistrationRequest(params) { + if (this.clientOptions.disableDynamicRegister) + return Promise.resolve(); + return new Promise((resolve, reject) => { + for (let registration of params.registrations) { + const feature = this._dynamicFeatures.get(registration.method); + if (!feature) { + reject(new Error(`No feature implementation for ${registration.method} found. Registration failed.`)); + return; + } + const options = registration.registerOptions || {}; + options.documentSelector = + options.documentSelector || this._clientOptions.documentSelector; + const data = { + id: registration.id, + registerOptions: options + }; + feature.register(this._method2Message.get(registration.method), data); + } + resolve(); + }); + } + handleUnregistrationRequest(params) { + return new Promise((resolve, reject) => { + for (let unregistration of params.unregisterations) { + const feature = this._dynamicFeatures.get(unregistration.method); + if (!feature) { + reject(new Error(`No feature implementation for ${unregistration.method} found. Unregistration failed.`)); + return; + } + feature.unregister(unregistration.id); + } + resolve(); + }); + } + handleApplyWorkspaceEdit(params) { + return workspace_1.default.applyEdit(params.edit).then(value => { + return { applied: value }; + }); + } + logFailedRequest(type, error) { + // If we get a request cancel don't log anything. + if (error instanceof vscode_languageserver_protocol_1.ResponseError && + error.code === vscode_languageserver_protocol_1.ErrorCodes.RequestCancelled) { + return; + } + this.error(`Request ${type.method} failed.`, error); + } +} +exports.BaseLanguageClient = BaseLanguageClient; +//# sourceMappingURL=client.js.map + +/***/ }), +/* 354 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * A helper to delay execution of a task that is being requested often. + * + * Following the throttler, now imagine the mail man wants to optimize the number of + * trips proactively. The trip itself can be long, so he decides not to make the trip + * as soon as a letter is submitted. Instead he waits a while, in case more + * letters are submitted. After said waiting period, if no letters were submitted, he + * decides to make the trip. Imagine that N more letters were submitted after the first + * one, all within a short period of time between each other. Even though N+1 + * submissions occurred, only 1 delivery was made. + * + * The delayer offers this behavior via the trigger() method, into which both the task + * to be executed and the waiting period (delay) must be passed in as arguments. Following + * the example: + * + * const delayer = new Delayer(WAITING_PERIOD) + * const letters = [] + * + * function letterReceived(l) { + * letters.push(l) + * delayer.trigger(() => { return makeTheTrip(); }) + * } + */ +class Delayer { + constructor(defaultDelay) { + this.defaultDelay = defaultDelay; + this.timeout = null; + this.completionPromise = null; + this.doResolve = null; + this.task = null; + } + trigger(task, delay = this.defaultDelay) { + this.task = task; + this.cancelTimeout(); + if (!this.completionPromise) { + this.completionPromise = new Promise((c, e) => { + this.doResolve = c; + this.doReject = e; + }).then(() => { + this.completionPromise = null; + this.doResolve = null; + const task = this.task; + this.task = null; + return task(); + }); + } + this.timeout = setTimeout(() => { + this.timeout = null; + this.doResolve(null); + }, delay); + return this.completionPromise; + } + isTriggered() { + return this.timeout !== null; + } + cancel() { + this.cancelTimeout(); + if (this.completionPromise) { + this.doReject(new Error('Canceled')); + this.completionPromise = null; + } + } + cancelTimeout() { + if (this.timeout !== null) { + clearTimeout(this.timeout); + this.timeout = null; + } + } + dispose() { + this.cancelTimeout(); + } +} +exports.Delayer = Delayer; +//# sourceMappingURL=async.js.map + +/***/ }), +/* 355 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const lodash_1 = __webpack_require__(312); +function asLanguageIds(documentSelector) { + let res = documentSelector.map(filter => { + if (typeof filter == 'string') { + return filter; + } + return filter.language; + }); + res = res.filter(s => s != null); + return res.length == 0 ? null : res; +} +exports.asLanguageIds = asLanguageIds; +function convertToTextDocumentItem(document) { + return { + uri: document.uri, + languageId: document.languageId, + version: document.version, + text: document.getText() + }; +} +exports.convertToTextDocumentItem = convertToTextDocumentItem; +function asCloseTextDocumentParams(document) { + return { + textDocument: { + uri: document.uri + } + }; +} +exports.asCloseTextDocumentParams = asCloseTextDocumentParams; +function asChangeTextDocumentParams(document) { + let result = { + textDocument: { + uri: document.uri, + version: document.version + }, + contentChanges: [{ text: document.getText() }] + }; + return result; +} +exports.asChangeTextDocumentParams = asChangeTextDocumentParams; +function asWillSaveTextDocumentParams(event) { + return { + textDocument: asVersionedTextDocumentIdentifier(event.document), + reason: event.reason + }; +} +exports.asWillSaveTextDocumentParams = asWillSaveTextDocumentParams; +function asVersionedTextDocumentIdentifier(textDocument) { + return { + uri: textDocument.uri, + version: textDocument.version + }; +} +exports.asVersionedTextDocumentIdentifier = asVersionedTextDocumentIdentifier; +function asSaveTextDocumentParams(document, includeText) { + let result = { + textDocument: asVersionedTextDocumentIdentifier(document) + }; + if (includeText) { + result.text = document.getText(); + } + return result; +} +exports.asSaveTextDocumentParams = asSaveTextDocumentParams; +function asUri(resource) { + return resource.toString(); +} +exports.asUri = asUri; +function asCompletionParams(textDocument, position, context) { + return { + textDocument: { + uri: textDocument.uri, + }, + position, + context: lodash_1.omit(context, ['option']), + }; +} +exports.asCompletionParams = asCompletionParams; +function asTextDocumentPositionParams(textDocument, position) { + return { + textDocument: { + uri: textDocument.uri, + }, + position + }; +} +exports.asTextDocumentPositionParams = asTextDocumentPositionParams; +function asTextDocumentIdentifier(textDocument) { + return { + uri: textDocument.uri + }; +} +exports.asTextDocumentIdentifier = asTextDocumentIdentifier; +function asReferenceParams(textDocument, position, options) { + return { + textDocument: { + uri: textDocument.uri, + }, + position, + context: { includeDeclaration: options.includeDeclaration } + }; +} +exports.asReferenceParams = asReferenceParams; +function asDocumentSymbolParams(textDocument) { + return { + textDocument: { + uri: textDocument.uri + } + }; +} +exports.asDocumentSymbolParams = asDocumentSymbolParams; +function asCodeLensParams(textDocument) { + return { + textDocument: { + uri: textDocument.uri + } + }; +} +exports.asCodeLensParams = asCodeLensParams; +//# sourceMappingURL=converter.js.map + +/***/ }), +/* 356 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const uuidv4 = __webpack_require__(321); +function generateUuid() { + return uuidv4(); +} +exports.generateUuid = generateUuid; +//# sourceMappingURL=uuid.js.map + +/***/ }), +/* 357 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const Is = tslib_1.__importStar(__webpack_require__(191)); +const client_1 = __webpack_require__(353); +const UUID = tslib_1.__importStar(__webpack_require__(356)); +function ensure(target, key) { + if (target[key] === void 0) { + target[key] = {}; + } + return target[key]; +} +class ColorProviderFeature extends client_1.TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.DocumentColorRequest.type); + } + fillClientCapabilities(capabilites) { + ensure(ensure(capabilites, 'textDocument'), 'colorProvider').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + if (!capabilities.colorProvider) { + return; + } + const implCapabilities = capabilities.colorProvider; + const id = Is.string(implCapabilities.id) && implCapabilities.id.length > 0 + ? implCapabilities.id + : UUID.generateUuid(); + const selector = implCapabilities.documentSelector || documentSelector; + if (selector) { + this.register(this.messages, { + id, + registerOptions: Object.assign({}, { documentSelector: selector }) + }); + } + } + registerLanguageProvider(options) { + let client = this._client; + let provideColorPresentations = (color, context, token) => { + const requestParams = { + color, + textDocument: { + uri: context.document.uri + }, + range: context.range + }; + return client + .sendRequest(vscode_languageserver_protocol_1.ColorPresentationRequest.type, requestParams, token) + .then(res => res, (error) => { + client.logFailedRequest(vscode_languageserver_protocol_1.ColorPresentationRequest.type, error); + return Promise.resolve(null); + }); + }; + let provideDocumentColors = (document, token) => { + const requestParams = { + textDocument: { + uri: document.uri + } + }; + return client + .sendRequest(vscode_languageserver_protocol_1.DocumentColorRequest.type, requestParams, token) + .then(res => res, (error) => { + client.logFailedRequest(vscode_languageserver_protocol_1.ColorPresentationRequest.type, error); + return Promise.resolve(null); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerDocumentColorProvider(options.documentSelector, { + provideColorPresentations: (color, context, token) => { + return middleware.provideColorPresentations + ? middleware.provideColorPresentations(color, context, token, provideColorPresentations) + : provideColorPresentations(color, context, token); + }, + provideDocumentColors: (document, token) => { + return middleware.provideDocumentColors + ? middleware.provideDocumentColors(document, token, provideDocumentColors) + : provideDocumentColors(document, token); + } + }); + } +} +exports.ColorProviderFeature = ColorProviderFeature; +//# sourceMappingURL=colorProvider.js.map + +/***/ }), +/* 358 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('languageclient-configuration'); +class ConfigurationFeature { + constructor(_client) { + this._client = _client; + } + fillClientCapabilities(capabilities) { + capabilities.workspace = capabilities.workspace || {}; + capabilities.workspace.configuration = true; + } + initialize() { + let client = this._client; + client.onRequest(vscode_languageserver_protocol_1.ConfigurationRequest.type, (params, token) => { + let configuration = params => { + let result = []; + for (let item of params.items) { + result.push(this.getConfiguration(item.scopeUri, item.section)); + } + return result; + }; + let middleware = client.clientOptions.middleware.workspace; + return middleware && middleware.configuration + ? middleware.configuration(params, token, configuration) + : configuration(params, token); + }); + } + getConfiguration(resource, section) { + let result = null; + let { id } = this._client; + if (section) { + if (id.startsWith('languageserver')) { + let config = workspace_1.default.getConfiguration(id, resource).get('settings'); + if (config && config[section] != null) + return config[section]; + } + let index = section.lastIndexOf('.'); + if (index === -1) { + result = workspace_1.default.getConfiguration(undefined, resource).get(section, {}); + } + else { + let config = workspace_1.default.getConfiguration(section.substr(0, index), resource); + if (config) { + result = config.get(section.substr(index + 1)); + } + } + } + else { + let config = workspace_1.default.getConfiguration(undefined, resource); + result = {}; + for (let key of Object.keys(config)) { + if (config.has(key)) { + result[key] = config.get(key); + } + } + } + return result; + } +} +exports.ConfigurationFeature = ConfigurationFeature; +//# sourceMappingURL=configuration.js.map + +/***/ }), +/* 359 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const Is = tslib_1.__importStar(__webpack_require__(191)); +const UUID = tslib_1.__importStar(__webpack_require__(356)); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const converter_1 = __webpack_require__(355); +const client_1 = __webpack_require__(353); +function ensure(target, key) { + if (target[key] === void 0) { + target[key] = {}; + } + return target[key]; +} +class DeclarationFeature extends client_1.TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.DeclarationRequest.type); + } + fillClientCapabilities(capabilites) { + let declarationSupport = ensure(ensure(capabilites, 'textDocument'), 'declaration'); + declarationSupport.dynamicRegistration = true; + // declarationSupport.linkSupport = true + } + initialize(capabilities, documentSelector) { + if (!capabilities.declarationProvider) { + return; + } + if (capabilities.declarationProvider === true) { + if (!documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector }) + }); + } + else { + const declCapabilities = capabilities.declarationProvider; + const id = Is.string(declCapabilities.id) && declCapabilities.id.length > 0 ? declCapabilities.id : UUID.generateUuid(); + const selector = declCapabilities.documentSelector || documentSelector; + if (selector) { + this.register(this.messages, { + id, + registerOptions: Object.assign({}, { documentSelector: selector }) + }); + } + } + } + registerLanguageProvider(options) { + let client = this._client; + let provideDeclaration = (document, position, token) => { + return client.sendRequest(vscode_languageserver_protocol_1.DeclarationRequest.type, converter_1.asTextDocumentPositionParams(document, position), token).then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.DeclarationRequest.type, error); + return Promise.resolve(null); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerDeclarationProvider(options.documentSelector, { + provideDeclaration: (document, position, token) => { + return middleware.provideDeclaration + ? middleware.provideDeclaration(document, position, token, provideDeclaration) + : provideDeclaration(document, position, token); + } + }); + } +} +exports.DeclarationFeature = DeclarationFeature; +//# sourceMappingURL=declaration.js.map + +/***/ }), +/* 360 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const Is = tslib_1.__importStar(__webpack_require__(191)); +const client_1 = __webpack_require__(353); +const UUID = tslib_1.__importStar(__webpack_require__(356)); +function ensure(target, key) { + if (target[key] === void 0) { + target[key] = {}; + } + return target[key]; +} +class FoldingRangeFeature extends client_1.TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.FoldingRangeRequest.type); + } + fillClientCapabilities(capabilites) { + let capability = ensure(ensure(capabilites, 'textDocument'), 'foldingRange'); + capability.dynamicRegistration = true; + capability.rangeLimit = 5000; + capability.lineFoldingOnly = true; + } + initialize(capabilities, documentSelector) { + if (!capabilities.foldingRangeProvider) { + return; + } + const implCapabilities = capabilities.foldingRangeProvider; + const id = Is.string(implCapabilities.id) && implCapabilities.id.length > 0 + ? implCapabilities.id + : UUID.generateUuid(); + const selector = implCapabilities.documentSelector || documentSelector; + if (selector) { + this.register(this.messages, { + id, + registerOptions: Object.assign({}, { documentSelector: selector }) + }); + } + } + registerLanguageProvider(options) { + let client = this._client; + let provideFoldingRanges = (document, _, token) => { + const requestParams = { + textDocument: { + uri: document.uri + } + }; + return client + .sendRequest(vscode_languageserver_protocol_1.FoldingRangeRequest.type, requestParams, token) + .then(res => res, (error) => { + client.logFailedRequest(vscode_languageserver_protocol_1.FoldingRangeRequest.type, error); + return Promise.resolve(null); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerFoldingRangeProvider(options.documentSelector, { + provideFoldingRanges(document, context, token) { + return middleware.provideFoldingRanges + ? middleware.provideFoldingRanges(document, context, token, provideFoldingRanges) + : provideFoldingRanges(document, context, token); + } + }); + } +} +exports.FoldingRangeFeature = FoldingRangeFeature; +//# sourceMappingURL=foldingRange.js.map + +/***/ }), +/* 361 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const Is = tslib_1.__importStar(__webpack_require__(191)); +const client_1 = __webpack_require__(353); +const UUID = tslib_1.__importStar(__webpack_require__(356)); +const cv = tslib_1.__importStar(__webpack_require__(355)); +function ensure(target, key) { + if (target[key] === void 0) { + target[key] = {}; + } + return target[key]; +} +class ImplementationFeature extends client_1.TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.ImplementationRequest.type); + } + fillClientCapabilities(capabilites) { + ensure(ensure(capabilites, 'textDocument'), 'implementation').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + if (!capabilities.implementationProvider) { + return; + } + if (capabilities.implementationProvider === true) { + if (!documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector }) + }); + } + else { + const implCapabilities = capabilities.implementationProvider; + const id = Is.string(implCapabilities.id) && implCapabilities.id.length > 0 ? implCapabilities.id : UUID.generateUuid(); + const selector = implCapabilities.documentSelector || documentSelector; + if (selector) { + this.register(this.messages, { + id, + registerOptions: Object.assign({}, { documentSelector: selector }) + }); + } + } + } + registerLanguageProvider(options) { + let client = this._client; + let provideImplementation = (document, position, token) => { + return client.sendRequest(vscode_languageserver_protocol_1.ImplementationRequest.type, cv.asTextDocumentPositionParams(document, position), token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.ImplementationRequest.type, error); + return Promise.resolve(null); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerImplementationProvider(options.documentSelector, { + provideImplementation: (document, position, token) => { + return middleware.provideImplementation + ? middleware.provideImplementation(document, position, token, provideImplementation) + : provideImplementation(document, position, token); + } + }); + } +} +exports.ImplementationFeature = ImplementationFeature; +//# sourceMappingURL=implementation.js.map + +/***/ }), +/* 362 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const Is = tslib_1.__importStar(__webpack_require__(191)); +const client_1 = __webpack_require__(353); +const UUID = tslib_1.__importStar(__webpack_require__(356)); +const cv = tslib_1.__importStar(__webpack_require__(355)); +function ensure(target, key) { + if (target[key] === void 0) { + target[key] = {}; + } + return target[key]; +} +class TypeDefinitionFeature extends client_1.TextDocumentFeature { + constructor(client) { + super(client, vscode_languageserver_protocol_1.TypeDefinitionRequest.type); + } + fillClientCapabilities(capabilites) { + ensure(ensure(capabilites, 'textDocument'), 'typeDefinition').dynamicRegistration = true; + } + initialize(capabilities, documentSelector) { + if (!capabilities.typeDefinitionProvider) { + return; + } + if (capabilities.typeDefinitionProvider === true) { + if (!documentSelector) { + return; + } + this.register(this.messages, { + id: UUID.generateUuid(), + registerOptions: Object.assign({}, { documentSelector }) + }); + } + else { + const implCapabilities = capabilities.typeDefinitionProvider; + const id = Is.string(implCapabilities.id) && implCapabilities.id.length > 0 + ? implCapabilities.id + : UUID.generateUuid(); + const selector = implCapabilities.documentSelector || documentSelector; + if (selector) { + this.register(this.messages, { + id, + registerOptions: Object.assign({}, { documentSelector: selector }) + }); + } + } + } + registerLanguageProvider(options) { + let client = this._client; + let provideTypeDefinition = (document, position, token) => { + return client.sendRequest(vscode_languageserver_protocol_1.TypeDefinitionRequest.type, cv.asTextDocumentPositionParams(document, position), token) + .then(res => res, error => { + client.logFailedRequest(vscode_languageserver_protocol_1.TypeDefinitionRequest.type, error); + return Promise.resolve(null); + }); + }; + let middleware = client.clientOptions.middleware; + return languages_1.default.registerTypeDefinitionProvider(options.documentSelector, { + provideTypeDefinition: (document, position, token) => { + return middleware.provideTypeDefinition + ? middleware.provideTypeDefinition(document, position, token, provideTypeDefinition) + : provideTypeDefinition(document, position, token); + } + }); + } +} +exports.TypeDefinitionFeature = TypeDefinitionFeature; +//# sourceMappingURL=typeDefinition.js.map + +/***/ }), +/* 363 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const UUID = tslib_1.__importStar(__webpack_require__(356)); +const logger = __webpack_require__(186)('language-client-workspaceFolder'); +function access(target, key) { + if (target === void 0) { + return undefined; + } + return target[key]; +} +class WorkspaceFoldersFeature { + constructor(_client) { + this._client = _client; + this._listeners = new Map(); + } + get messages() { + return vscode_languageserver_protocol_1.DidChangeWorkspaceFoldersNotification.type; + } + fillInitializeParams(params) { + params.workspaceFolders = workspace_1.default.workspaceFolders; + } + fillClientCapabilities(capabilities) { + capabilities.workspace = capabilities.workspace || {}; + capabilities.workspace.workspaceFolders = true; + } + initialize(capabilities) { + let client = this._client; + client.onRequest(vscode_languageserver_protocol_1.WorkspaceFoldersRequest.type, (token) => { + let workspaceFolders = () => { + let { workspaceFolders } = workspace_1.default; + return workspaceFolders.length ? workspaceFolders : null; + }; + let middleware = client.clientOptions.middleware.workspace; + return middleware && middleware.workspaceFolders + ? middleware.workspaceFolders(token, workspaceFolders) + : workspaceFolders(token); + }); + let value = access(access(access(capabilities, 'workspace'), 'workspaceFolders'), 'changeNotifications'); + let id; + if (typeof value === 'string') { + id = value; + } + else if (value === true) { + id = UUID.generateUuid(); + } + if (id) { + this.register(this.messages, { + id, + registerOptions: undefined + }); + } + } + register(_message, data) { + let id = data.id; + let client = this._client; + let disposable = workspace_1.default.onDidChangeWorkspaceFolders(event => { + let didChangeWorkspaceFolders = (event) => { + let params = { event }; + this._client.sendNotification(vscode_languageserver_protocol_1.DidChangeWorkspaceFoldersNotification.type, params); + }; + let middleware = client.clientOptions.middleware.workspace; + middleware && middleware.didChangeWorkspaceFolders + ? middleware.didChangeWorkspaceFolders(event, didChangeWorkspaceFolders) + : didChangeWorkspaceFolders(event); + }); + this._listeners.set(id, disposable); + } + unregister(id) { + let disposable = this._listeners.get(id); + if (disposable === void 0) { + return; + } + this._listeners.delete(id); + disposable.dispose(); + } + dispose() { + for (let disposable of this._listeners.values()) { + disposable.dispose(); + } + this._listeners.clear(); + } +} +exports.WorkspaceFoldersFeature = WorkspaceFoldersFeature; +//# sourceMappingURL=workspaceFolders.js.map + +/***/ }), +/* 364 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const debounce_1 = tslib_1.__importDefault(__webpack_require__(176)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const extensions_1 = tslib_1.__importDefault(__webpack_require__(238)); +const util_1 = __webpack_require__(174); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const highligher_1 = tslib_1.__importDefault(__webpack_require__(349)); +const configuration_1 = tslib_1.__importDefault(__webpack_require__(365)); +const history_1 = tslib_1.__importDefault(__webpack_require__(366)); +const mappings_1 = tslib_1.__importDefault(__webpack_require__(368)); +const prompt_1 = tslib_1.__importDefault(__webpack_require__(369)); +const commands_1 = tslib_1.__importDefault(__webpack_require__(370)); +const diagnostics_1 = tslib_1.__importDefault(__webpack_require__(372)); +const extensions_2 = tslib_1.__importDefault(__webpack_require__(374)); +const folders_1 = tslib_1.__importDefault(__webpack_require__(375)); +const links_1 = tslib_1.__importDefault(__webpack_require__(376)); +const lists_1 = tslib_1.__importDefault(__webpack_require__(377)); +const location_1 = tslib_1.__importDefault(__webpack_require__(373)); +const outline_1 = tslib_1.__importDefault(__webpack_require__(378)); +const output_1 = tslib_1.__importDefault(__webpack_require__(380)); +const services_1 = tslib_1.__importDefault(__webpack_require__(381)); +const sources_1 = tslib_1.__importDefault(__webpack_require__(382)); +const symbols_1 = tslib_1.__importDefault(__webpack_require__(383)); +const actions_1 = tslib_1.__importDefault(__webpack_require__(385)); +const ui_1 = tslib_1.__importDefault(__webpack_require__(386)); +const worker_1 = tslib_1.__importDefault(__webpack_require__(387)); +const logger = __webpack_require__(186)('list-manager'); +const mouseKeys = ['', '', '', '<2-LeftMouse>']; +class ListManager { + constructor() { + this.plugTs = 0; + this.disposables = []; + this.args = []; + this.listArgs = []; + this.listMap = new Map(); + this.activated = false; + this.executing = false; + } + init(nvim) { + this.nvim = nvim; + this.config = new configuration_1.default(); + this.prompt = new prompt_1.default(nvim, this.config); + this.history = new history_1.default(this); + this.mappings = new mappings_1.default(this, nvim, this.config); + this.worker = new worker_1.default(nvim, this); + this.ui = new ui_1.default(nvim, this.config); + events_1.default.on('VimResized', () => { + if (this.isActivated) + nvim.command('redraw!', true); + }, null, this.disposables); + events_1.default.on('InputChar', this.onInputChar, this, this.disposables); + events_1.default.on('FocusGained', debounce_1.default(async () => { + if (this.activated) + this.prompt.drawPrompt(); + }, 100), null, this.disposables); + events_1.default.on('BufEnter', debounce_1.default(async () => { + let { bufnr } = this.ui; + if (!bufnr) + return; + if (!this.activated) { + this.ui.hide(); + return; + } + let curr = await nvim.call('bufnr', '%'); + if (curr == bufnr) { + this.prompt.start(); + } + else { + nvim.pauseNotification(); + this.prompt.cancel(); + await nvim.resumeNotification(); + } + }, 100), null, this.disposables); + this.ui.onDidChangeLine(debounce_1.default(async () => { + if (!this.activated) + return; + let previewing = await nvim.call('coc#util#has_preview'); + let mode = await this.nvim.mode; + if (mode.blocking || mode.mode != 'n') + return; + if (previewing) + await this.doAction('preview'); + }, 100), null, this.disposables); + this.ui.onDidLineChange(debounce_1.default(async () => { + let { autoPreview } = this.listOptions; + if (!autoPreview || !this.activated) + return; + await this.doAction('preview'); + }, 100), null, this.disposables); + this.ui.onDidChangeLine(this.resolveItem, this, this.disposables); + this.ui.onDidLineChange(this.resolveItem, this, this.disposables); + this.ui.onDidOpen(() => { + if (this.currList) { + if (typeof this.currList.doHighlight == 'function') { + this.currList.doHighlight(); + } + } + }, null, this.disposables); + this.ui.onDidClose(async () => { + await this.cancel(); + }, null, this.disposables); + this.ui.onDidChange(async () => { + if (this.activated) { + this.updateStatus(); + } + this.prompt.drawPrompt(); + }, null, this.disposables); + this.ui.onDidDoubleClick(async () => { + await this.doAction(); + }, null, this.disposables); + this.worker.onDidChangeItems(async ({ items, highlights, reload, append }) => { + if (!this.activated) + return; + if (append) { + this.ui.addHighlights(highlights, true); + await this.ui.appendItems(items); + } + else { + this.ui.addHighlights(highlights); + await this.ui.drawItems(items, this.name, this.listOptions, reload); + } + }, null, this.disposables); + this.registerList(new links_1.default(nvim)); + this.registerList(new location_1.default(nvim)); + this.registerList(new symbols_1.default(nvim)); + this.registerList(new outline_1.default(nvim)); + this.registerList(new commands_1.default(nvim)); + this.registerList(new extensions_2.default(nvim)); + this.registerList(new diagnostics_1.default(nvim)); + this.registerList(new sources_1.default(nvim)); + this.registerList(new services_1.default(nvim)); + this.registerList(new output_1.default(nvim)); + this.registerList(new lists_1.default(nvim, this.listMap)); + this.registerList(new folders_1.default(nvim)); + this.registerList(new actions_1.default(nvim)); + } + async start(args) { + if (this.activated) + return; + let res = this.parseArgs(args); + if (!res) + return; + this.args = args; + this.activated = true; + let { list, options, listArgs } = res; + try { + this.reset(); + this.listOptions = options; + this.currList = list; + this.listArgs = listArgs; + this.cwd = workspace_1.default.cwd; + await this.getCharMap(); + this.history.load(); + this.window = await this.nvim.window; + this.savedHeight = await this.window.height; + this.prompt.start(options); + await this.worker.loadItems(); + } + catch (e) { + await this.cancel(); + let msg = e instanceof Error ? e.message : e.toString(); + workspace_1.default.showMessage(`Error on "CocList ${list.name}": ${msg}`, 'error'); + logger.error(e); + } + } + async resume() { + let { name, ui, currList, nvim } = this; + if (!currList) + return; + this.activated = true; + this.window = await nvim.window; + this.prompt.start(); + await ui.resume(name, this.listOptions); + if (this.listOptions.autoPreview) { + await this.doAction('preview'); + } + } + async doAction(name) { + let { currList } = this; + name = name || currList.defaultAction; + let action = currList.actions.find(o => o.name == name); + if (!action) { + workspace_1.default.showMessage(`Action ${name} not found`, 'error'); + return; + } + let items; + if (name == 'preview') { + let item = await this.ui.item; + items = item ? [item] : []; + } + else { + items = await this.ui.getItems(); + } + if (items.length) + await this.doItemAction(items, action); + } + async previous() { + let { ui } = this; + let item = ui.getItem(-1); + if (!item) + return; + ui.index = ui.index - 1; + await this.doItemAction([item], this.defaultAction); + await ui.echoMessage(item); + } + async next() { + let { ui } = this; + let item = ui.getItem(1); + if (!item) + return; + ui.index = ui.index + 1; + await this.doItemAction([item], this.defaultAction); + await ui.echoMessage(item); + } + async cancel(close = true) { + let { nvim, ui, savedHeight } = this; + if (!this.activated) { + nvim.call('coc#list#stop_prompt', [], true); + return; + } + this.activated = false; + this.worker.stop(); + this.history.add(); + nvim.pauseNotification(); + nvim.command('pclose', true); + this.prompt.cancel(); + if (close) { + ui.hide(); + if (this.window) { + nvim.call('coc#list#restore', [this.window.id, savedHeight], true); + } + } + await nvim.resumeNotification(); + } + async switchMatcher() { + let { matcher, interactive } = this.listOptions; + if (interactive) + return; + const list = ['fuzzy', 'strict', 'regex']; + let idx = list.indexOf(matcher) + 1; + if (idx >= list.length) + idx = 0; + this.listOptions.matcher = list[idx]; + this.prompt.matcher = list[idx]; + await this.worker.drawItems(); + } + async togglePreview() { + let { nvim } = this; + let has = await nvim.call('coc#list#has_preview'); + if (has) { + await nvim.command('pclose'); + await nvim.command('redraw'); + } + else { + await this.doAction('preview'); + } + } + async chooseAction() { + let { nvim, currList } = this; + if (!this.activated) + return; + let { actions, defaultAction } = currList; + let names = actions.map(o => o.name); + let idx = names.indexOf(defaultAction); + if (idx != -1) { + names.splice(idx, 1); + names.unshift(defaultAction); + } + let shortcuts = new Set(); + let choices = []; + for (let name of names) { + let i = 0; + for (let ch of name) { + if (!shortcuts.has(ch)) { + shortcuts.add(ch); + choices.push(`${name.slice(0, i)}&${name.slice(i)}`); + break; + } + i++; + } + } + await nvim.call('coc#list#stop_prompt'); + let n = await nvim.call('confirm', ['Choose action:', choices.join('\n')]); + await util_1.wait(10); + this.prompt.start(); + if (n) + await this.doAction(names[n - 1]); + } + get name() { + let { currList } = this; + return currList ? currList.name : 'anonymous'; + } + get list() { + return this.currList; + } + parseArgs(args) { + let options = []; + let interactive = false; + let autoPreview = false; + let numberSelect = false; + let name; + let input = ''; + let matcher = 'fuzzy'; + let position = 'bottom'; + let listArgs = []; + let listOptions = []; + for (let arg of args) { + if (!name && arg.startsWith('-')) { + listOptions.push(arg); + } + else if (!name) { + if (!/^\w+$/.test(arg)) { + workspace_1.default.showMessage(`Invalid list option: "${arg}"`, 'error'); + return null; + } + name = arg; + } + else { + listArgs.push(arg); + } + } + name = name || 'lists'; + let config = workspace_1.default.getConfiguration(`list.source.${name}`); + if (!listOptions.length && !listArgs.length) + listOptions = config.get('defaultOptions', []); + if (!listArgs.length) + listArgs = config.get('defaultArgs', []); + for (let opt of listOptions) { + if (opt.startsWith('--input')) { + input = opt.slice(8); + } + else if (opt == '--number-select' || opt == '-N') { + numberSelect = true; + } + else if (opt == '--auto-preview' || opt == '-A') { + autoPreview = true; + } + else if (opt == '--regex' || opt == '-R') { + matcher = 'regex'; + } + else if (opt == '--strict' || opt == '-S') { + matcher = 'strict'; + } + else if (opt == '--interactive' || opt == '-I') { + interactive = true; + } + else if (opt == '--top') { + position = 'top'; + } + else if (opt == '--tab') { + position = 'tab'; + } + else if (opt == '--ignore-case' || opt == '--normal' || opt == '--no-sort') { + options.push(opt.slice(2)); + } + else { + workspace_1.default.showMessage(`Invalid option "${opt}" of list`, 'error'); + return null; + } + } + let list = this.listMap.get(name); + if (!list) { + workspace_1.default.showMessage(`List ${name} not found`, 'error'); + return null; + } + if (interactive && !list.interactive) { + workspace_1.default.showMessage(`Interactive mode of "${name}" list not supported`, 'error'); + return null; + } + return { + list, + listArgs, + options: { + numberSelect, + autoPreview, + input, + interactive, + matcher, + position, + ignorecase: options.indexOf('ignore-case') != -1 ? true : false, + mode: options.indexOf('normal') == -1 ? 'insert' : 'normal', + sort: options.indexOf('no-sort') == -1 ? true : false + }, + }; + } + updateStatus() { + let { ui, currList, activated, nvim } = this; + if (!activated) + return; + let buf = nvim.createBuffer(ui.bufnr); + let status = { + mode: this.prompt.mode.toUpperCase(), + args: this.args.join(' '), + name: currList.name, + total: this.worker.length, + cwd: this.cwd, + }; + buf.setVar('list_status', status, true); + if (ui.window) + nvim.command('redraws', true); + } + async onInputChar(ch, charmod) { + let { mode } = this.prompt; + let mapped = this.charMap.get(ch); + let now = Date.now(); + if (mapped == '' || now - this.plugTs < 2) { + this.plugTs = now; + return; + } + if (!ch) + return; + if (ch == '\x1b') { + await this.cancel(); + return; + } + if (!this.activated) { + this.nvim.call('coc#list#stop_prompt', [], true); + return; + } + try { + if (mode == 'insert') { + await this.onInsertInput(ch, charmod); + } + else { + await this.onNormalInput(ch, charmod); + } + } + catch (e) { + workspace_1.default.showMessage(`Error on input ${ch}: ${e}`); + logger.error(e); + } + } + async onInsertInput(ch, charmod) { + let { nvim } = this; + let inserted = this.charMap.get(ch) || ch; + if (mouseKeys.indexOf(inserted) !== -1) { + await this.onMouseEvent(inserted); + return; + } + if (this.listOptions.numberSelect) { + let code = ch.charCodeAt(0); + if (code >= 48 && code <= 57) { + let n = Number(ch); + if (n == 0) + n = 10; + if (this.ui.length >= n) { + nvim.pauseNotification(); + this.ui.setCursor(Number(ch), 0); + await nvim.resumeNotification(); + await this.doAction(); + } + return; + } + } + let done = await this.mappings.doInsertKeymap(inserted); + if (done || charmod || this.charMap.has(ch)) + return; + for (let s of ch) { + let code = s.codePointAt(0); + if (code == 65533) + return; + // exclude control characer + if (code < 32 || code >= 127 && code <= 159) + return; + await this.prompt.acceptCharacter(s); + } + } + async onNormalInput(ch, _charmod) { + let inserted = this.charMap.get(ch) || ch; + if (mouseKeys.indexOf(inserted) !== -1) { + await this.onMouseEvent(inserted); + return; + } + let done = await this.mappings.doNormalKeymap(inserted); + if (!done) + await this.feedkeys(inserted); + } + onMouseEvent(key) { + switch (key) { + case '': + return this.ui.onMouse('mouseDown'); + case '': + return this.ui.onMouse('mouseDrag'); + case '': + return this.ui.onMouse('mouseUp'); + case '<2-LeftMouse>': + return this.ui.onMouse('doubleClick'); + } + } + async feedkeys(key) { + let { nvim } = this; + key = key.startsWith('<') && key.endsWith('>') ? `\\${key}` : key; + await nvim.call('coc#list#stop_prompt', [1]); + await nvim.eval(`feedkeys("${key}")`); + this.prompt.start(); + } + async command(command) { + let { nvim } = this; + await nvim.call('coc#list#stop_prompt', [1]); + await nvim.command(command); + this.prompt.start(); + } + async normal(command, bang = true) { + let { nvim } = this; + await nvim.call('coc#list#stop_prompt', [1]); + await nvim.command(`normal${bang ? '!' : ''} ${command}`); + this.prompt.start(); + } + async call(fname) { + if (!this.currList || !this.window) + return; + await this.nvim.call('coc#list#stop_prompt', []); + let buf = await this.window.buffer; + let targets = await this.ui.getItems(); + let context = { + name: this.currList.name, + args: this.listArgs, + input: this.prompt.input, + winid: this.window.id, + bufnr: buf.id, + targets + }; + let res = await this.nvim.call(fname, [context]); + this.prompt.start(); + return res; + } + async showHelp() { + // echo help + await this.cancel(); + let { list, nvim } = this; + if (!list) + return; + let previewHeight = await nvim.eval('&previewheight'); + nvim.pauseNotification(); + nvim.command(`belowright ${previewHeight}sp +setl\\ previewwindow [LIST HELP]`, true); + nvim.command('setl nobuflisted noswapfile buftype=nofile bufhidden=wipe', true); + await nvim.resumeNotification(); + let hasOptions = list.options && list.options.length; + let buf = await nvim.buffer; + let highligher = new highligher_1.default(); + highligher.addLine('NAME', 'Label'); + highligher.addLine(` ${list.name} - ${list.description || ''}\n`); + highligher.addLine('SYNOPSIS', 'Label'); + highligher.addLine(` :CocList [LIST OPTIONS] ${list.name}${hasOptions ? ' [ARGUMENTS]' : ''}\n`); + if (list.detail) { + highligher.addLine('DESCRIPTION', 'Label'); + let lines = list.detail.split('\n').map(s => ' ' + s); + highligher.addLine(lines.join('\n') + '\n'); + } + if (hasOptions) { + highligher.addLine('ARGUMENTS', 'Label'); + highligher.addLine(''); + for (let opt of list.options) { + highligher.addLine(opt.name, 'Special'); + highligher.addLine(` ${opt.description}`); + highligher.addLine(''); + } + highligher.addLine(''); + } + let config = workspace_1.default.getConfiguration(`list.source.${list.name}`); + if (Object.keys(config).length) { + highligher.addLine('CONFIGURATIONS', 'Label'); + highligher.addLine(''); + let props = {}; + extensions_1.default.all.forEach(extension => { + let { packageJSON } = extension; + let { contributes } = packageJSON; + if (!contributes) + return; + let { configuration } = contributes; + if (configuration) { + let { properties } = configuration; + if (properties) { + for (let key of Object.keys(properties)) { + props[key] = properties[key]; + } + } + } + }); + for (let key of Object.keys(config)) { + let val = config[key]; + let name = `list.source.${list.name}.${key}`; + let description = props[name] && props[name].description ? props[name].description : key; + highligher.addLine(` "${name}"`, 'MoreMsg'); + highligher.addText(` - ${description}, current value: `); + highligher.addText(JSON.stringify(val), 'Special'); + } + highligher.addLine(''); + } + highligher.addLine('ACTIONS', 'Label'); + highligher.addLine(` ${list.actions.map(o => o.name).join(', ')}`); + highligher.addLine(''); + highligher.addLine(`see ':h coc-list-options' for available list options.`, 'Comment'); + nvim.pauseNotification(); + highligher.render(buf, 0, -1); + nvim.command('setl nomod', true); + nvim.command('setl nomodifiable', true); + nvim.command('normal! gg', true); + nvim.command('nnoremap q :bd!', true); + await nvim.resumeNotification(); + } + get context() { + return { + options: this.listOptions, + args: this.listArgs, + input: this.prompt.input, + window: this.window, + listWindow: this.ui.window, + cwd: this.cwd + }; + } + registerList(list) { + const { name } = list; + let exists = this.listMap.get(name); + if (this.listMap.has(name)) { + if (exists) { + if (typeof exists.dispose == 'function') { + exists.dispose(); + } + this.listMap.delete(name); + } + workspace_1.default.showMessage(`list "${name}" recreated.`); + } + this.listMap.set(name, list); + extensions_1.default.addSchemeProperty(`list.source.${name}.defaultOptions`, { + type: 'array', + default: list.interactive ? ['--interactive'] : [], + description: `Default list options of "${name}" list, only used when both list option and argument are empty.`, + uniqueItems: true, + items: { + type: 'string', + enum: ['--top', '--normal', '--no-sort', '--input', '--tab', + '--strict', '--regex', '--ignore-case', '--number-select', + '--interactive', '--auto-preview'] + } + }); + extensions_1.default.addSchemeProperty(`list.source.${name}.defaultArgs`, { + type: 'array', + default: [], + description: `Default argument list of "${name}" list, only used when list argument is empty.`, + uniqueItems: true, + items: { type: 'string' } + }); + return vscode_languageserver_protocol_1.Disposable.create(() => { + if (typeof list.dispose == 'function') { + list.dispose(); + } + this.listMap.delete(name); + }); + } + get names() { + return Array.from(this.listMap.keys()); + } + toggleMode() { + let { mode } = this.prompt; + this.prompt.mode = mode == 'normal' ? 'insert' : 'normal'; + this.updateStatus(); + } + getConfig(key, defaultValue) { + return this.config.get(key, defaultValue); + } + get isActivated() { + return this.activated; + } + stop() { + this.worker.stop(); + } + reset() { + this.window = null; + this.listOptions = null; + this.prompt.reset(); + this.worker.stop(); + this.ui.reset(); + } + dispose() { + if (this.config) { + this.config.dispose(); + } + util_1.disposeAll(this.disposables); + } + async getCharMap() { + if (this.charMap) + return; + this.charMap = new Map(); + let chars = await this.nvim.call('coc#list#get_chars'); + Object.keys(chars).forEach(key => { + this.charMap.set(chars[key], key); + }); + return; + } + async doItemAction(items, action) { + if (this.executing) + return; + this.executing = true; + let { nvim } = this; + let shouldCancel = action.persist !== true && action.name != 'preview'; + try { + if (shouldCancel) { + await this.cancel(); + } + else if (action.name != 'preview') { + await nvim.call('coc#list#stop_prompt'); + } + if (!shouldCancel && !this.isActivated) + return; + if (action.multiple) { + await Promise.resolve(action.execute(items, this.context)); + } + else if (action.parallel) { + await Promise.all(items.map(item => { + return Promise.resolve(action.execute(item, this.context)); + })); + } + else { + for (let item of items) { + await Promise.resolve(action.execute(item, this.context)); + } + } + if (!shouldCancel) { + if (!this.isActivated) { + this.nvim.command('pclose', true); + return; + } + nvim.pauseNotification(); + if (action.name != 'preview') { + this.prompt.start(); + } + this.ui.restoreWindow(); + nvim.resumeNotification(false, true).logError(); + if (action.reload) + await this.worker.loadItems(true); + } + } + catch (e) { + // tslint:disable-next-line: no-console + console.error(e); + if (!shouldCancel && this.activated) { + this.prompt.start(); + } + } + this.executing = false; + } + async resolveItem() { + if (!this.activated) + return; + let index = this.ui.index; + let item = this.ui.getItem(0); + if (!item || item.resolved) + return; + let { list } = this; + if (typeof list.resolveItem == 'function') { + let resolved = await list.resolveItem(item); + if (resolved && index == this.ui.index) { + await this.ui.updateItem(resolved, index); + } + } + } + get defaultAction() { + let { currList } = this; + let { defaultAction } = currList; + return currList.actions.find(o => o.name == defaultAction); + } +} +exports.ListManager = ListManager; +exports.default = new ListManager(); +//# sourceMappingURL=manager.js.map + +/***/ }), +/* 365 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +exports.validKeys = [ + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '<2-LeftMouse>', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', +]; +class ListConfiguration { + constructor() { + this.configuration = workspace_1.default.getConfiguration('list'); + this.disposable = workspace_1.default.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('list')) { + this.configuration = workspace_1.default.getConfiguration('list'); + } + }); + } + get(key, defaultValue) { + return this.configuration.get(key, defaultValue); + } + get previousKey() { + return this.fixKey(this.configuration.get('previousKeymap', '')); + } + get nextKey() { + return this.fixKey(this.configuration.get('nextKeymap', '')); + } + dispose() { + this.disposable.dispose(); + } + fixKey(key) { + if (exports.validKeys.indexOf(key) !== -1) + return key; + let find = exports.validKeys.find(s => s.toLowerCase() == key.toLowerCase()); + if (find) + return find; + workspace_1.default.showMessage(`Configured key "${key}" invalid.`, 'error'); + return null; + } +} +exports.default = ListConfiguration; +//# sourceMappingURL=configuration.js.map + +/***/ }), +/* 366 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fuzzy_1 = __webpack_require__(367); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('list-history'); +class History { + constructor(manager) { + this.manager = manager; + this.index = -1; + this.loaded = []; + this.current = []; + this.db = workspace_1.default.createDatabase('history'); + let { prompt } = manager; + prompt.onDidChangeInput(input => { + if (input == this.curr) + return; + let codes = fuzzy_1.getCharCodes(input); + this.current = this.loaded.filter(s => fuzzy_1.fuzzyMatch(codes, s)); + this.index = -1; + }); + } + get curr() { + return this.index == -1 ? null : this.current[this.index]; + } + load() { + let { db } = this; + let { input } = this.manager.prompt; + let { name } = this.manager; + let arr = db.fetch(`${name}.${encodeURIComponent(workspace_1.default.cwd)}`); + if (!arr || !Array.isArray(arr)) { + this.loaded = []; + } + else { + this.loaded = arr; + } + this.index = -1; + this.current = this.loaded.filter(s => s.startsWith(input)); + } + add() { + let { loaded, db } = this; + let { name, prompt } = this.manager; + let { input } = prompt; + if (!input || input.length < 2) + return; + let idx = loaded.indexOf(input); + if (idx != -1) + loaded.splice(idx, 1); + loaded.push(input); + if (loaded.length > 200) { + loaded = loaded.slice(-200); + } + db.push(`${name}.${encodeURIComponent(workspace_1.default.cwd)}`, loaded); + } + previous() { + let { current, index } = this; + if (!current || !current.length) + return; + if (index <= 0) { + this.index = current.length - 1; + } + else { + this.index = index - 1; + } + this.manager.prompt.input = current[this.index] || ''; + } + next() { + let { current, index } = this; + if (!current || !current.length) + return; + if (index == current.length - 1) { + this.index = 0; + } + else { + this.index = index + 1; + } + this.manager.prompt.input = current[this.index] || ''; + } +} +exports.default = History; +//# sourceMappingURL=history.js.map + +/***/ }), +/* 367 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function getCharCodes(str) { + let res = []; + for (let i = 0, l = str.length; i < l; i++) { + res.push(str.charCodeAt(i)); + } + return res; +} +exports.getCharCodes = getCharCodes; +function wordChar(ch) { + return (ch >= 97 && ch <= 122) || (ch >= 65 && ch <= 90); +} +exports.wordChar = wordChar; +function caseMatch(input, code) { + if (input == code) + return true; + if (input >= 97 && input <= 122 && code + 32 === input) + return true; + return false; +} +exports.caseMatch = caseMatch; +function fuzzyChar(a, b) { + let ca = a.charCodeAt(0); + let cb = b.charCodeAt(0); + if (ca === cb) + return true; + if (ca >= 97 && ca <= 122 && cb + 32 === ca) + return true; + return false; +} +exports.fuzzyChar = fuzzyChar; +// upper case must match, lower case ignore case +function fuzzyMatch(needle, text) { + let totalCount = needle.length; + if (needle.length > text.length) + return false; + let i = 0; + for (let j = 0; j < text.length; j++) { + if (i === totalCount) + break; + let code = text.charCodeAt(j); + let m = needle[i]; + if (code === m) { + i = i + 1; + continue; + } + // upper case match lower case + if ((m >= 97 && m <= 122) && code + 32 === m) { + i = i + 1; + continue; + } + } + return i === totalCount; +} +exports.fuzzyMatch = fuzzyMatch; +//# sourceMappingURL=fuzzy.js.map + +/***/ }), +/* 368 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +__webpack_require__(309); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const configuration_1 = __webpack_require__(365); +const logger = __webpack_require__(186)('list-mappings'); +class Mappings { + constructor(manager, nvim, config) { + this.manager = manager; + this.nvim = nvim; + this.config = config; + this.insertMappings = new Map(); + this.normalMappings = new Map(); + this.userInsertMappings = new Map(); + this.userNormalMappings = new Map(); + let { prompt } = manager; + this.add('insert', '', () => { + prompt.removeTail(); + }); + this.add('insert', '', () => { + manager.history.next(); + }); + this.add('insert', '', () => { + manager.history.previous(); + }); + this.add('insert', '', () => { + return manager.switchMatcher(); + }); + this.add('insert', ['', ''], async () => { + await manager.doAction(); + }); + this.add('insert', ['', '', '\t'], () => { + return manager.chooseAction(); + }); + this.add('insert', '', () => { + manager.toggleMode(); + }); + this.add('insert', '', async () => { + manager.stop(); + manager.prompt.start(); + return; + }); + this.add('insert', '', () => { + return manager.cancel(); + }); + this.add('insert', '', async () => { + await manager.worker.loadItems(true); + }); + this.add('insert', '', () => { + prompt.moveLeft(); + }); + this.add('insert', '', () => { + prompt.moveRight(); + }); + this.add('insert', ['', ''], () => { + prompt.moveToEnd(); + }); + this.add('insert', ['', ''], () => { + prompt.moveToStart(); + }); + this.add('insert', ['', ''], () => { + prompt.onBackspace(); + }); + this.add('insert', '', () => { + prompt.removeWord(); + }); + this.add('insert', '', () => { + prompt.removeAhead(); + }); + this.add('insert', '', () => { + return prompt.insertRegister(); + }); + this.add('insert', '', () => { + return manager.feedkeys(''); + }); + this.add('insert', '', () => { + return manager.feedkeys(''); + }); + this.add('insert', '', () => { + return manager.feedkeys(''); + }); + this.add('insert', '', () => { + return manager.normal('j'); + }); + this.add('insert', '', () => { + return manager.normal('k'); + }); + this.add('insert', [''], this.doScroll.bind(this, '')); + this.add('insert', [''], this.doScroll.bind(this, '')); + this.add('insert', [''], this.doScroll.bind(this, '')); + this.add('insert', [''], this.doScroll.bind(this, '')); + this.add('normal', '', () => { + // do nothing, avoid buffer switch by accident + }); + this.add('normal', 't', () => { + return manager.doAction('tabe'); + }); + this.add('normal', 's', () => { + return manager.doAction('split'); + }); + this.add('normal', 'd', () => { + return manager.doAction('drop'); + }); + this.add('normal', ['', '', '\r'], () => { + return manager.doAction(); + }); + this.add('normal', '', () => { + return manager.ui.selectAll(); + }); + this.add('normal', ' ', () => { + return manager.ui.toggleSelection(); + }); + this.add('normal', 'p', () => { + return manager.togglePreview(); + }); + this.add('normal', ['', '\t', ''], () => { + return manager.chooseAction(); + }); + this.add('normal', '', () => { + manager.stop(); + }); + this.add('normal', '', () => { + return manager.cancel(); + }); + this.add('normal', '', () => { + return manager.worker.loadItems(true); + }); + this.add('normal', ['i', 'I', 'o', 'O', 'a', 'A'], () => { + return manager.toggleMode(); + }); + this.add('normal', '?', () => { + return manager.showHelp(); + }); + this.add('normal', ':', async () => { + await manager.cancel(false); + await nvim.eval('feedkeys(":")'); + }); + this.add('normal', [''], this.doScroll.bind(this, '')); + this.add('normal', [''], this.doScroll.bind(this, '')); + let insertMappings = this.manager.getConfig('insertMappings', {}); + this.userInsertMappings = this.fixUserMappings(insertMappings); + let normalMappings = this.manager.getConfig('normalMappings', {}); + this.userNormalMappings = this.fixUserMappings(normalMappings); + workspace_1.default.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('list')) { + let config = workspace_1.default.getConfiguration('list'); + let insertMappings = config.get('insertMappings', {}); + this.userInsertMappings = this.fixUserMappings(insertMappings); + let normalMappings = config.get('normalMappings', {}); + this.userNormalMappings = this.fixUserMappings(normalMappings); + } + }); + } + fixUserMappings(mappings) { + let res = new Map(); + for (let [key, value] of Object.entries(mappings)) { + if (key.length == 1) { + res.set(key, value); + } + else if (key.startsWith('<') && key.endsWith('>')) { + if (configuration_1.validKeys.indexOf(key) != -1) { + res.set(key, value); + } + else { + let find = false; + // tslint:disable-next-line: prefer-for-of + for (let i = 0; i < configuration_1.validKeys.length; i++) { + if (configuration_1.validKeys[i].toLowerCase() == key.toLowerCase()) { + find = true; + res.set(configuration_1.validKeys[i], value); + break; + } + } + if (!find) + workspace_1.default.showMessage(`Invalid mappings key: ${key}`, 'error'); + } + } + else { + // tslint:disable-next-line: no-console + workspace_1.default.showMessage(`Invalid mappings key: ${key}`, 'error'); + } + } + return res; + } + async doInsertKeymap(key) { + let nextKey = this.config.nextKey; + let previousKey = this.config.previousKey; + if (key == nextKey) { + await this.manager.normal('j'); + return true; + } + if (key == previousKey) { + await this.manager.normal('k'); + return true; + } + let expr = this.userInsertMappings.get(key); + if (expr) { + await this.evalExpression(expr, 'insert'); + return true; + } + if (this.insertMappings.has(key)) { + let fn = this.insertMappings.get(key); + await Promise.resolve(fn()); + return true; + } + return false; + } + async doNormalKeymap(key) { + let expr = this.userNormalMappings.get(key); + if (expr) { + await this.evalExpression(expr, 'normal'); + return true; + } + if (this.normalMappings.has(key)) { + let fn = this.normalMappings.get(key); + await Promise.resolve(fn()); + return true; + } + return false; + } + add(mode, key, fn) { + let mappings = mode == 'insert' ? this.insertMappings : this.normalMappings; + if (Array.isArray(key)) { + for (let k of key) { + mappings.set(k, fn); + } + } + else { + mappings.set(key, fn); + } + } + async onError(msg) { + let { nvim } = this; + await nvim.call('coc#list#stop_prompt', []); + workspace_1.default.showMessage(msg, 'error'); + this.manager.prompt.start(); + } + async evalExpression(expr, _mode) { + if (typeof expr != 'string' || expr.indexOf(':') == -1) { + await this.onError(`Invalid expression ${expr}`); + return; + } + let { manager } = this; + let { prompt } = manager; + let [key, action] = expr.split(':', 2); + if (key == 'do') { + switch (action) { + case 'switch': + await manager.switchMatcher(); + return; + case 'selectall': + await manager.ui.selectAll(); + return; + case 'help': + await manager.showHelp(); + return; + case 'refresh': + await manager.worker.loadItems(); + return; + case 'exit': + await manager.cancel(true); + return; + case 'stop': + manager.stop(); + return; + case 'cancel': + await manager.cancel(false); + return; + case 'toggle': + await manager.ui.toggleSelection(); + return; + case 'previous': + await manager.normal('k'); + return; + case 'next': + await manager.normal('j'); + return; + case 'defaultaction': + await manager.doAction(); + return; + default: + await this.onError(`'${action}' not supported`); + } + } + else if (key == 'prompt') { + switch (action) { + case 'previous': + manager.history.previous(); + return; + case 'next': + manager.history.next(); + return; + case 'start': + return prompt.moveToStart(); + case 'end': + return prompt.moveToEnd(); + case 'left': + return prompt.moveLeft(); + case 'right': + return prompt.moveRight(); + case 'deleteforward': + return prompt.onBackspace(); + case 'deletebackward': + return prompt.removeNext(); + case 'removetail': + return prompt.removeTail(); + case 'removeahead': + return prompt.removeAhead(); + case 'insertregister': + await prompt.insertRegister(); + return; + case 'paste': + await prompt.paste(); + return; + default: + await this.onError(`prompt '${action}' not supported`); + } + } + else if (key == 'eval') { + await prompt.eval(action); + } + else if (key == 'command') { + await manager.command(action); + } + else if (key == 'action') { + await manager.doAction(action); + } + else if (key == 'feedkeys') { + await manager.feedkeys(action); + } + else if (key == 'normal') { + await manager.normal(action, false); + } + else if (key == 'normal!') { + await manager.normal(action, true); + } + else if (key == 'call') { + await manager.call(action); + } + else if (key == 'expr') { + let name = await manager.call(action); + if (name) + await manager.doAction(name); + } + else { + await this.onError(`Invalid expression ${expr}`); + } + } + async doScroll(key) { + await this.manager.feedkeys(key); + } +} +exports.default = Mappings; +//# sourceMappingURL=mappings.js.map + +/***/ }), +/* 369 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('list-prompt'); +class Prompt { + constructor(nvim, config) { + this.nvim = nvim; + this.config = config; + this.cusorIndex = 0; + this._input = ''; + this._mode = 'insert'; + this.interactive = false; + this.requestInput = false; + this._onDidChangeInput = new vscode_languageserver_protocol_1.Emitter(); + this.onDidChangeInput = this._onDidChangeInput.event; + } + get input() { + return this._input; + } + set input(str) { + if (this._input == str) + return; + this.cusorIndex = str.length; + this._input = str; + this.drawPrompt(); + this._onDidChangeInput.fire(this._input); + } + get mode() { + return this._mode; + } + set mode(val) { + if (val == this._mode) + return; + this._mode = val; + this.drawPrompt(); + } + set matcher(val) { + this._matcher = val; + this.drawPrompt(); + } + start(opts) { + if (opts) { + this.interactive = opts.interactive; + this.cusorIndex = opts.input.length; + this._input = opts.input; + this._mode = opts.mode; + this._matcher = opts.interactive ? '' : opts.matcher; + } + let fn = workspace_1.default.isVim ? 'coc#list#prompt_start' : 'coc#list#start_prompt'; + this.nvim.call(fn, [], true); + this.drawPrompt(); + } + cancel() { + let { nvim } = this; + nvim.command('echo ""', true); + nvim.command('redraw', true); + nvim.call('coc#list#stop_prompt', [], true); + } + reset() { + this._input = ''; + this.cusorIndex = 0; + } + drawPrompt() { + let indicator = this.config.get('indicator', '>'); + let { cusorIndex, interactive, input, _matcher } = this; + let cmds = ['echo ""']; + if (this.mode == 'insert') { + if (interactive) { + cmds.push(`echohl MoreMsg | echon 'INTERACTIVE ' | echohl None`); + } + else if (_matcher) { + cmds.push(`echohl MoreMsg | echon '${_matcher.toUpperCase()} ' | echohl None`); + } + cmds.push(`echohl Special | echon '${indicator} ' | echohl None`); + if (cusorIndex == input.length) { + cmds.push(`echon '${input.replace(/'/g, "''")}'`); + cmds.push(`echohl Cursor | echon ' ' | echohl None`); + } + else { + let pre = input.slice(0, cusorIndex); + if (pre) + cmds.push(`echon '${pre.replace(/'/g, "''")}'`); + cmds.push(`echohl Cursor | echon '${input[cusorIndex].replace(/'/, "''")}' | echohl None`); + let post = input.slice(cusorIndex + 1); + cmds.push(`echon '${post.replace(/'/g, "''")}'`); + } + } + else { + cmds.push(`echohl MoreMsg | echo "" | echohl None`); + } + cmds.push('redraw'); + let cmd = cmds.join('|'); + this.nvim.command(cmd, true); + } + moveLeft() { + if (this.cusorIndex == 0) + return; + this.cusorIndex = this.cusorIndex - 1; + this.drawPrompt(); + } + moveRight() { + if (this.cusorIndex == this._input.length) + return; + this.cusorIndex = this.cusorIndex + 1; + this.drawPrompt(); + } + moveToEnd() { + if (this.cusorIndex == this._input.length) + return; + this.cusorIndex = this._input.length; + this.drawPrompt(); + } + moveToStart() { + if (this.cusorIndex == 0) + return; + this.cusorIndex = 0; + this.drawPrompt(); + } + onBackspace() { + let { cusorIndex, input } = this; + if (cusorIndex == 0) + return; + let pre = input.slice(0, cusorIndex); + let post = input.slice(cusorIndex); + this.cusorIndex = cusorIndex - 1; + this._input = `${pre.slice(0, pre.length - 1)}${post}`; + this.drawPrompt(); + this._onDidChangeInput.fire(this._input); + } + removeNext() { + let { cusorIndex, input } = this; + if (cusorIndex == input.length - 1) + return; + let pre = input.slice(0, cusorIndex); + let post = input.slice(cusorIndex + 1); + this._input = `${pre}${post}`; + this.drawPrompt(); + this._onDidChangeInput.fire(this._input); + } + removeWord() { + let { cusorIndex, input } = this; + if (cusorIndex == 0) + return; + let pre = input.slice(0, cusorIndex); + let post = input.slice(cusorIndex); + let remain = pre.replace(/[\w$]+([^\w$]+)?$/, ''); + this.cusorIndex = cusorIndex - (pre.length - remain.length); + this._input = `${remain}${post}`; + this.drawPrompt(); + this._onDidChangeInput.fire(this._input); + } + removeTail() { + let { cusorIndex, input } = this; + if (cusorIndex == input.length) + return; + let pre = input.slice(0, cusorIndex); + this._input = pre; + this.drawPrompt(); + this._onDidChangeInput.fire(this._input); + } + removeAhead() { + let { cusorIndex, input } = this; + if (cusorIndex == 0) + return; + let post = input.slice(cusorIndex); + this.cusorIndex = 0; + this._input = post; + this.drawPrompt(); + this._onDidChangeInput.fire(this._input); + } + async acceptCharacter(ch) { + if (this.requestInput) { + this.requestInput = false; + if (/^[0-9a-z"%#*+/:\-.]$/.test(ch)) { + let text = await this.nvim.call('getreg', ch); + text = text.replace(/\n/g, ' '); + this.addText(text); + } + } + else { + this.addText(ch); + } + } + async insertRegister() { + this.requestInput = true; + } + async paste() { + await this.eval('@*'); + } + async eval(expression) { + let { cusorIndex, input } = this; + let text = await this.nvim.eval(expression); + text = text.replace(/\n/g, ''); + this.addText(text); + } + addText(text) { + let { cusorIndex, input } = this; + this.cusorIndex = cusorIndex + text.length; + let pre = input.slice(0, cusorIndex); + let post = input.slice(cusorIndex); + this._input = `${pre}${text}${post}`; + this.drawPrompt(); + this._onDidChangeInput.fire(this._input); + } +} +exports.default = Prompt; +//# sourceMappingURL=prompt.js.map + +/***/ }), +/* 370 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const commands_1 = tslib_1.__importDefault(__webpack_require__(232)); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const basic_1 = tslib_1.__importDefault(__webpack_require__(371)); +class CommandsList extends basic_1.default { + constructor(nvim) { + super(nvim); + this.defaultAction = 'run'; + this.description = 'registered commands of coc.nvim'; + this.name = 'commands'; + this.mru = workspace_1.default.createMru('commands'); + this.addAction('run', async (item) => { + let { cmd } = item.data; + await events_1.default.fire('Command', [cmd]); + await commands_1.default.executeCommand(cmd); + await commands_1.default.addRecent(cmd); + }); + } + async loadItems(_context) { + let items = []; + let list = commands_1.default.commandList; + let { titles } = commands_1.default; + let mruList = await this.mru.load(); + for (let key of titles.keys()) { + items.push({ + label: `${key}\t${titles.get(key)}`, + filterText: key, + data: { cmd: key, score: score(mruList, key) } + }); + } + for (let o of list) { + let { id } = o; + if (!titles.has(id)) { + items.push({ + label: id, + filterText: id, + data: { cmd: id, score: score(mruList, id) } + }); + } + } + items.sort((a, b) => { + return b.data.score - a.data.score; + }); + return items; + } + doHighlight() { + let { nvim } = this; + nvim.pauseNotification(); + nvim.command('syntax match CocCommandsTitle /\\t.*$/ contained containedin=CocCommandsLine', true); + nvim.command('highlight default link CocCommandsTitle Comment', true); + nvim.resumeNotification().catch(_e => { + // noop + }); + } +} +exports.default = CommandsList; +function score(list, key) { + let idx = list.indexOf(key); + return idx == -1 ? -1 : list.length - idx; +} +//# sourceMappingURL=commands.js.map + +/***/ }), +/* 371 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const readline_1 = tslib_1.__importDefault(__webpack_require__(60)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const vscode_uri_1 = __webpack_require__(180); +const util_1 = __webpack_require__(174); +const position_1 = __webpack_require__(213); +const string_1 = __webpack_require__(210); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const configuration_1 = tslib_1.__importDefault(__webpack_require__(365)); +const logger = __webpack_require__(186)('list-basic'); +class BasicList { + constructor(nvim) { + this.nvim = nvim; + this.defaultAction = 'open'; + this.actions = []; + this.options = []; + this.disposables = []; + this.config = new configuration_1.default(); + } + get hlGroup() { + return this.config.get('previewHighlightGroup', 'Search'); + } + get previewHeight() { + return this.config.get('maxPreviewHeight', 12); + } + get splitRight() { + return this.config.get('previewSplitRight', false); + } + parseArguments(args) { + if (!this.optionMap) { + this.optionMap = new Map(); + for (let opt of this.options) { + let parts = opt.name.split(/,\s*/g).map(s => s.replace(/\s+.*/g, '')); + let name = opt.key ? opt.key : parts[parts.length - 1].replace(/^-/, ''); + for (let p of parts) { + this.optionMap.set(p, { name, hasValue: opt.hasValue }); + } + } + } + let res = {}; + for (let i = 0; i < args.length; i++) { + let arg = args[i]; + let def = this.optionMap.get(arg); + if (!def) { + logger.error(`Option "${arg}" of "${this.name}" not found`); + continue; + } + let value = true; + if (def.hasValue) { + value = args[i + 1] || ''; + i = i + 1; + } + res[def.name] = value; + } + return res; + } + getConfig() { + return workspace_1.default.getConfiguration(`list.source.${this.name}`); + } + addAction(name, fn, options) { + this.createAction(Object.assign({ + name, + execute: fn + }, options || {})); + } + addMultipleAction(name, fn, options) { + this.createAction(Object.assign({ + name, + multiple: true, + execute: fn + }, options || {})); + } + addLocationActions() { + this.createAction({ + name: 'preview', + execute: async (item, context) => { + let loc = await this.convertLocation(item.location); + await this.previewLocation(loc, context); + } + }); + let { nvim } = this; + this.createAction({ + name: 'quickfix', + multiple: true, + execute: async (items) => { + let quickfixItems = await Promise.all(items.map(item => { + return this.convertLocation(item.location).then(loc => { + return workspace_1.default.getQuickfixItem(loc); + }); + })); + await nvim.call('setqflist', [quickfixItems]); + let openCommand = await nvim.getVar('coc_quickfix_open_command'); + nvim.command(typeof openCommand === 'string' ? openCommand : 'copen', true); + } + }); + for (let name of ['open', 'tabe', 'drop', 'vsplit', 'split']) { + this.createAction({ + name, + execute: async (item) => { + await this.jumpTo(item.location, name == 'open' ? null : name); + } + }); + } + } + async convertLocation(location) { + if (typeof location == 'string') + return vscode_languageserver_protocol_1.Location.create(location, vscode_languageserver_protocol_1.Range.create(0, 0, 0, 0)); + if (vscode_languageserver_protocol_1.Location.is(location)) + return location; + let u = vscode_uri_1.URI.parse(location.uri); + if (u.scheme != 'file') + return vscode_languageserver_protocol_1.Location.create(location.uri, vscode_languageserver_protocol_1.Range.create(0, 0, 0, 0)); + const rl = readline_1.default.createInterface({ + input: fs_1.default.createReadStream(u.fsPath, { encoding: 'utf8' }), + }); + let match = location.line; + let n = 0; + let resolved = false; + let line = await new Promise(resolve => { + rl.on('line', line => { + if (resolved) + return; + if (line.indexOf(match) !== -1) { + rl.removeAllListeners(); + rl.close(); + resolved = true; + resolve(line); + return; + } + n = n + 1; + }); + rl.on('error', e => { + this.nvim.errWriteLine(`Read ${u.fsPath} error: ${e.message}`); + resolve(null); + }); + }); + if (line != null) { + let character = location.text ? line.indexOf(location.text) : 0; + if (character == 0) + character = line.match(/^\s*/)[0].length; + let end = vscode_languageserver_protocol_1.Position.create(n, character + (location.text ? location.text.length : 0)); + return vscode_languageserver_protocol_1.Location.create(location.uri, vscode_languageserver_protocol_1.Range.create(vscode_languageserver_protocol_1.Position.create(n, character), end)); + } + return vscode_languageserver_protocol_1.Location.create(location.uri, vscode_languageserver_protocol_1.Range.create(0, 0, 0, 0)); + } + async jumpTo(location, command) { + if (typeof location == 'string') { + await workspace_1.default.jumpTo(location, null, command); + return; + } + let { range, uri } = await this.convertLocation(location); + let position = range.start; + if (position.line == 0 && position.character == 0 && position_1.comparePosition(position, range.end) == 0) { + // allow plugin that remember position. + position = null; + } + await workspace_1.default.jumpTo(uri, position, command); + } + createAction(action) { + let { name } = action; + let idx = this.actions.findIndex(o => o.name == name); + // allow override + if (idx !== -1) + this.actions.splice(idx, 1); + this.actions.push(action); + } + async previewLocation(location, context) { + let { nvim } = this; + let { uri, range } = location; + let lineCount = Infinity; + let doc = workspace_1.default.getDocument(location.uri); + if (doc) + lineCount = doc.lineCount; + let height = Math.min(this.previewHeight, lineCount); + let u = vscode_uri_1.URI.parse(uri); + // handle different scheme + if (u.scheme == 'untitled' || u.scheme == 'unknown') { + let bufnr = parseInt(u.path, 10); + let valid = await nvim.call('bufloaded', [bufnr]); + let lnum = location.range.start.line + 1; + if (valid) { + let name = await nvim.call('bufname', [bufnr]); + name = name || '[No Name]'; + let filetype = await nvim.call('getbufvar', [bufnr, '&filetype']); + let lines = await nvim.call('getbufline', [bufnr, 1, '$']); + await this.preview({ bufname: name, sketch: true, filetype: filetype || 'txt', lnum, lines }, context); + } + else { + await this.preview({ sketch: true, filetype: 'txt', lines: [] }, context); + } + return; + } + // check + let filepath = u.scheme == 'file' ? u.fsPath : u.toString(); + nvim.pauseNotification(); + nvim.call('fnameescape', filepath, true); + nvim.call('buflisted', filepath, true); + nvim.call('eval', `!empty(getwininfo(${context.window.id}))`, true); + let [res, error] = await nvim.resumeNotification(); + if (error) { + logger.error(error); + return; + } + // open previewwindow + let { position } = context.options; + let [escaped, exists, valid] = res; + let lnum = range.start.line + 1; + let winid = context.listWindow.id; + nvim.pauseNotification(); + nvim.command('pclose', true); + if (this.splitRight || position == 'tab') { + if (valid && this.splitRight) + nvim.call('win_gotoid', [context.window.id], true); + nvim.command(`silent belowright vs +setl\\ previewwindow ${escaped}`, true); + } + else { + let mod = context.options.position == 'top' ? 'below' : 'above'; + nvim.command(`silent ${mod} ${height}sp +setl\\ previewwindow ${escaped}`, true); + nvim.command(`exe "normal! z${height}\\"`, true); + } + nvim.command(`exe ${lnum}`, true); + nvim.command('setl winfixheight nofoldenable', true); + // highlight range + if (position_1.comparePosition(range.start, range.end) !== 0) { + let arr = []; + for (let i = range.start.line; i <= range.end.line; i++) { + let curr = await workspace_1.default.getLine(uri, range.start.line); + let sc = i == range.start.line ? range.start.character : 0; + let ec = i == range.end.line ? range.end.character : curr.length; + if (sc == ec) + continue; + arr.push(vscode_languageserver_protocol_1.Range.create(i, sc, i, ec)); + } + for (let r of arr) { + let line = await workspace_1.default.getLine(uri, r.start.line); + let start = string_1.byteIndex(line, r.start.character) + 1; + let end = string_1.byteIndex(line, r.end.character) + 1; + nvim.call('matchaddpos', [this.hlGroup, [[lnum, start, end - start]]], true); + } + } + if (!exists) + nvim.command('setl nobuflisted bufhidden=wipe', true); + nvim.command('normal! zz', true); + nvim.call('win_gotoid', [winid], true); + if (workspace_1.default.isVim) + nvim.command('redraw', true); + let [, err] = await nvim.resumeNotification(); + // tslint:disable-next-line: no-console + if (err) + console.error(`Error on ${err[0]}: ${err[1]} - ${err[2]}`); + } + async preview(options, context) { + let { nvim } = this; + let { bufname, filetype, sketch, lines, lnum } = options; + if (!bufname) + sketch = true; + let mod = context.options.position == 'top' ? 'below' : 'above'; + let height = Math.min(this.previewHeight, lines ? Math.max(lines.length, 1) : Infinity); + let winid = context.listWindow.id; + let valid = await context.window.valid; + nvim.pauseNotification(); + nvim.command('pclose', true); + if (this.splitRight || context.options.position == 'tab') { + if (valid && this.splitRight) + nvim.call('win_gotoid', [context.window.id], true); + if (bufname) { + nvim.command(`silent belowright vs +setl\\ previewwindow ${bufname}`, true); + } + else { + nvim.command(`silent belowright vnew +setl\\ previewwindow`, true); + } + } + else { + if (bufname) { + nvim.command(`silent ${mod} ${height}sp +setl\\ previewwindow ${bufname}`, true); + } + else { + nvim.command(`silent ${mod} ${height}new +setl\\ previewwindow`, true); + } + nvim.command(`exe "normal! z${height}\\"`, true); + } + if (lines && lines.length) { + nvim.call('append', [0, lines], true); + nvim.command('normal! Gdd', true); + } + nvim.command(`exe ${lnum || 1}`, true); + nvim.command('setl winfixheight nomodifiable', true); + if (sketch) + nvim.command('setl buftype=nofile bufhidden=wipe nobuflisted', true); + if (filetype == 'detect') { + nvim.command('filetype detect', true); + } + else if (filetype) { + nvim.command(`setf ${filetype}`, true); + } + if (lnum && lnum != 1) + nvim.command('normal! zz', true); + nvim.call('win_gotoid', [winid], true); + if (workspace_1.default.isVim) + nvim.command('redraw', true); + let [, err] = await nvim.resumeNotification(); + // tslint:disable-next-line: no-console + if (err) + console.error(`Error on ${err[0]}: ${err[1]} - ${err[2]}`); + } + getPreviewCommand(context) { + let { position } = context.options; + if (position == 'tab') + return `belowright vs`; + let mod = position == 'top' ? 'below' : 'above'; + return `${mod} ${this.previewHeight}sp`; + } + doHighlight() { + // noop + } + dispose() { + util_1.disposeAll(this.disposables); + } +} +exports.default = BasicList; +//# sourceMappingURL=basic.js.map + +/***/ }), +/* 372 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const manager_1 = tslib_1.__importDefault(__webpack_require__(316)); +const location_1 = tslib_1.__importDefault(__webpack_require__(373)); +const fs_1 = __webpack_require__(200); +const logger = __webpack_require__(186)('list-symbols'); +class DiagnosticsList extends location_1.default { + constructor() { + super(...arguments); + this.defaultAction = 'open'; + this.description = 'diagnostics of current workspace'; + this.name = 'diagnostics'; + } + async loadItems(context) { + let list = manager_1.default.getDiagnosticList(); + let { cwd } = context; + return list.map(item => { + let file = fs_1.isParentFolder(cwd, item.file) ? path_1.default.relative(cwd, item.file) : item.file; + return { + label: `${file}:${item.lnum}:${item.col}\t${item.severity}\t${item.message.replace(/\n/g, '')}`, + location: item.location + }; + }); + } + doHighlight() { + let { nvim } = this; + nvim.pauseNotification(); + nvim.command('syntax match CocDiagnosticsFile /\\v^\\s*\\S+/ contained containedin=CocDiagnosticsLine', true); + nvim.command('syntax match CocDiagnosticsError /\\tError\\t/ contained containedin=CocDiagnosticsLine', true); + nvim.command('syntax match CocDiagnosticsWarning /\\tWarning\\t/ contained containedin=CocDiagnosticsLine', true); + nvim.command('syntax match CocDiagnosticsInfo /\\tInformation\\t/ contained containedin=CocDiagnosticsLine', true); + nvim.command('syntax match CocDiagnosticsHint /\\tHint\\t/ contained containedin=CocDiagnosticsLine', true); + nvim.command('highlight default link CocDiagnosticsFile Comment', true); + nvim.command('highlight default link CocDiagnosticsError CocErrorSign', true); + nvim.command('highlight default link CocDiagnosticsWarning CocWarningSign', true); + nvim.command('highlight default link CocDiagnosticsInfo CocInfoSign', true); + nvim.command('highlight default link CocDiagnosticsHint CocHintSign', true); + nvim.resumeNotification().catch(_e => { + // noop + }); + } +} +exports.default = DiagnosticsList; +//# sourceMappingURL=diagnostics.js.map + +/***/ }), +/* 373 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_types_1 = __webpack_require__(161); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const basic_1 = tslib_1.__importDefault(__webpack_require__(371)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const vscode_uri_1 = __webpack_require__(180); +const fs_1 = __webpack_require__(200); +const logger = __webpack_require__(186)('list-location'); +class LocationList extends basic_1.default { + constructor(nvim) { + super(nvim); + this.defaultAction = 'open'; + this.description = 'show locations saved by g:coc_jump_locations variable'; + this.name = 'location'; + this.addLocationActions(); + } + async loadItems(context) { + // filename, lnum, col, text, type + let locs = await this.nvim.getVar('coc_jump_locations'); + locs = locs || []; + locs.forEach(loc => { + if (!loc.uri) { + let fullpath = path_1.default.isAbsolute(loc.filename) ? loc.filename : path_1.default.join(context.cwd, loc.filename); + loc.uri = vscode_uri_1.URI.file(fullpath).toString(); + } + if (!loc.bufnr && workspace_1.default.getDocument(loc.uri) != null) { + loc.bufnr = workspace_1.default.getDocument(loc.uri).bufnr; + } + if (!loc.range) { + let { lnum, col } = loc; + loc.range = vscode_languageserver_types_1.Range.create(lnum - 1, col - 1, lnum - 1, col - 1); + } + else { + loc.lnum = loc.lnum || loc.range.start.line + 1; + loc.col = loc.col || loc.range.start.character + 1; + } + }); + let bufnr = await this.nvim.call('bufnr', '%'); + let ignoreFilepath = locs.every(o => o.bufnr && bufnr && o.bufnr == bufnr); + let items = locs.map(loc => { + let filename = ignoreFilepath ? '' : loc.filename; + let filterText = `${filename}${loc.text.trim()}`; + if (path_1.default.isAbsolute(filename)) { + filename = fs_1.isParentFolder(context.cwd, filename) ? path_1.default.relative(context.cwd, filename) : filename; + } + return { + label: `${filename} |${loc.type ? loc.type + ' ' : ''}${loc.lnum} col ${loc.col}| ${loc.text}`, + location: vscode_languageserver_types_1.Location.create(loc.uri, loc.range), + filterText + }; + }); + return items; + } + doHighlight() { + let { nvim } = this; + nvim.pauseNotification(); + nvim.command('syntax match CocLocationName /\\v^[^|]+/ contained containedin=CocLocationLine', true); + nvim.command('syntax match CocLocationPosition /\\v\\|\\w*\\s?\\d+\\scol\\s\\d+\\|/ contained containedin=CocLocationLine', true); + nvim.command('syntax match CocLocationError /Error/ contained containedin=CocLocationPosition', true); + nvim.command('syntax match CocLocationWarning /Warning/ contained containedin=CocLocationPosition', true); + nvim.command('highlight default link CocLocationName Directory', true); + nvim.command('highlight default link CocLocationPosition LineNr', true); + nvim.command('highlight default link CocLocationError Error', true); + nvim.command('highlight default link CocLocationWarning WarningMsg', true); + nvim.resumeNotification().catch(_e => { + // noop + }); + } +} +exports.default = LocationList; +//# sourceMappingURL=location.js.map + +/***/ }), +/* 374 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const os_1 = tslib_1.__importDefault(__webpack_require__(56)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const extensions_1 = tslib_1.__importDefault(__webpack_require__(238)); +const util_1 = __webpack_require__(174); +const fs_1 = __webpack_require__(200); +const basic_1 = tslib_1.__importDefault(__webpack_require__(371)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('list-extensions'); +class ExtensionList extends basic_1.default { + constructor(nvim) { + super(nvim); + this.defaultAction = 'toggle'; + this.description = 'manage coc extensions'; + this.name = 'extensions'; + this.addAction('toggle', async (item) => { + let { id, state } = item.data; + if (state == 'disabled') + return; + if (state == 'activated') { + extensions_1.default.deactivate(id); + } + else { + extensions_1.default.activate(id); + } + await util_1.wait(100); + }, { persist: true, reload: true, parallel: true }); + this.addAction('disable', async (item) => { + let { id, state } = item.data; + if (state !== 'disabled') + await extensions_1.default.toggleExtension(id); + }, { persist: true, reload: true, parallel: true }); + this.addAction('enable', async (item) => { + let { id, state } = item.data; + if (state == 'disabled') + await extensions_1.default.toggleExtension(id); + }, { persist: true, reload: true, parallel: true }); + this.addAction('lock', async (item) => { + let { id } = item.data; + await extensions_1.default.toggleLock(id); + }, { persist: true, reload: true }); + this.addAction('doc', async (item) => { + let { root } = item.data; + let files = await fs_1.readdirAsync(root); + let file = files.find(f => /^readme/i.test(f)); + if (file) { + let escaped = await nvim.call('fnameescape', [path_1.default.join(root, file)]); + await workspace_1.default.callAsync('coc#util#execute', [`edit ${escaped}`]); + } + }); + this.addAction('reload', async (item) => { + let { id, state } = item.data; + if (state == 'disabled') + return; + if (state == 'activated') { + extensions_1.default.deactivate(id); + } + extensions_1.default.activate(id); + await util_1.wait(100); + }, { persist: true, reload: true }); + this.addMultipleAction('uninstall', async (items) => { + let ids = []; + for (let item of items) { + if (item.data.isLocal) + continue; + ids.push(item.data.id); + } + extensions_1.default.uninstallExtension(ids).catch(e => { + logger.error(e); + }); + }); + } + async loadItems(_context) { + let items = []; + let list = await extensions_1.default.getExtensionStates(); + let lockedList = await extensions_1.default.getLockedList(); + for (let stat of list) { + let prefix = '+'; + if (stat.state == 'disabled') { + prefix = '-'; + } + else if (stat.state == 'activated') { + prefix = '*'; + } + else if (stat.state == 'unknown') { + prefix = '?'; + } + let root = await this.nvim.call('resolve', stat.root); + let locked = lockedList.indexOf(stat.id) !== -1; + items.push({ + label: `${prefix} ${stat.id}${locked ? ' ' : ''}\t${stat.isLocal ? '[RTP]\t' : ''}${stat.version}\t${root.replace(os_1.default.homedir(), '~')}`, + filterText: stat.id, + data: { + id: stat.id, + root, + state: stat.state, + isLocal: stat.isLocal, + priority: getPriority(stat.state) + } + }); + } + items.sort((a, b) => { + if (a.data.priority != b.data.priority) { + return b.data.priority - a.data.priority; + } + return b.data.id - a.data.id ? 1 : -1; + }); + return items; + } + doHighlight() { + let { nvim } = this; + nvim.pauseNotification(); + nvim.command('syntax match CocExtensionsActivited /\\v^\\*/ contained containedin=CocExtensionsLine', true); + nvim.command('syntax match CocExtensionsLoaded /\\v^\\+/ contained containedin=CocExtensionsLine', true); + nvim.command('syntax match CocExtensionsDisabled /\\v^-/ contained containedin=CocExtensionsLine', true); + nvim.command('syntax match CocExtensionsName /\\v%3c\\S+/ contained containedin=CocExtensionsLine', true); + nvim.command('syntax match CocExtensionsRoot /\\v\\t[^\\t]*$/ contained containedin=CocExtensionsLine', true); + nvim.command('syntax match CocExtensionsLocal /\\v\\[RTP\\]/ contained containedin=CocExtensionsLine', true); + nvim.command('highlight default link CocExtensionsActivited Special', true); + nvim.command('highlight default link CocExtensionsLoaded Normal', true); + nvim.command('highlight default link CocExtensionsDisabled Comment', true); + nvim.command('highlight default link CocExtensionsName String', true); + nvim.command('highlight default link CocExtensionsLocal MoreMsg', true); + nvim.command('highlight default link CocExtensionsRoot Comment', true); + nvim.resumeNotification().catch(_e => { + // noop + }); + } +} +exports.default = ExtensionList; +function getPriority(stat) { + switch (stat) { + case 'unknown': + return 2; + case 'activated': + return 1; + case 'disabled': + return -1; + default: + return 0; + } +} +//# sourceMappingURL=extensions.js.map + +/***/ }), +/* 375 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fs_1 = __webpack_require__(200); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const basic_1 = tslib_1.__importDefault(__webpack_require__(371)); +const vscode_uri_1 = __webpack_require__(180); +const util_1 = __webpack_require__(174); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +class FoldList extends basic_1.default { + constructor(nvim) { + super(nvim); + this.defaultAction = 'edit'; + this.description = 'list of current workspace folders'; + this.name = 'folders'; + this.addAction('edit', async (item) => { + let newPath = await nvim.call('input', ['Folder: ', item.label, 'file']); + let stat = await fs_1.statAsync(newPath); + if (!stat || !stat.isDirectory()) { + await nvim.command(`echoerr "invalid path: ${newPath}"`); + return; + } + workspace_1.default.renameWorkspaceFolder(item.label, newPath); + }, { reload: true, persist: true }); + this.addAction('delete', async (item) => { + workspace_1.default.removeWorkspaceFolder(item.label); + }, { reload: true, persist: true }); + this.addAction('newfile', async (item) => { + let file = await workspace_1.default.requestInput('File name', item.label + '/'); + let dir = path_1.default.dirname(file); + let stat = await fs_1.statAsync(dir); + if (!stat || !stat.isDirectory()) { + let success = await util_1.mkdirp(dir); + if (!success) { + util_1.echoErr(nvim, `Error creating new directory ${dir}`); + return; + } + } + await workspace_1.default.createFile(file, { overwrite: false, ignoreIfExists: true }); + await this.jumpTo(vscode_uri_1.URI.file(file).toString()); + }); + } + async loadItems(_context) { + return workspace_1.default.folderPaths.map(p => { + return { label: p }; + }); + } +} +exports.default = FoldList; +//# sourceMappingURL=folders.js.map + +/***/ }), +/* 376 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const basic_1 = tslib_1.__importDefault(__webpack_require__(371)); +const vscode_languageserver_types_1 = __webpack_require__(161); +const vscode_uri_1 = __webpack_require__(180); +const fs_1 = __webpack_require__(200); +class LinksList extends basic_1.default { + constructor(nvim) { + super(nvim); + this.defaultAction = 'open'; + this.description = 'links of current buffer'; + this.name = 'links'; + this.addAction('open', async (item) => { + let { target } = item.data; + let uri = vscode_uri_1.URI.parse(target); + if (uri.scheme.startsWith('http')) { + await nvim.call('coc#util#open_url', target); + } + else { + await workspace_1.default.jumpTo(target); + } + }); + this.addAction('jump', async (item) => { + let { location } = item.data; + await workspace_1.default.jumpTo(location.uri, location.range.start); + }); + } + async loadItems(context) { + let buf = await context.window.buffer; + let doc = workspace_1.default.getDocument(buf.id); + if (!doc) + return null; + let items = []; + let links = await languages_1.default.getDocumentLinks(doc.textDocument); + if (links == null) { + throw new Error('Links provider not found.'); + } + let res = []; + for (let link of links) { + if (link.target) { + items.push({ + label: formatUri(link.target), + data: { + target: link.target, + location: vscode_languageserver_types_1.Location.create(doc.uri, link.range) + } + }); + } + else { + link = await languages_1.default.resolveDocumentLink(link); + if (link.target) { + items.push({ + label: formatUri(link.target), + data: { + target: link.target, + location: vscode_languageserver_types_1.Location.create(doc.uri, link.range) + } + }); + } + res.push(link); + } + } + return items; + } +} +exports.default = LinksList; +function formatUri(uri) { + if (!uri.startsWith('file:')) + return uri; + let filepath = vscode_uri_1.URI.parse(uri).fsPath; + return fs_1.isParentFolder(workspace_1.default.cwd, filepath) ? path_1.default.relative(workspace_1.default.cwd, filepath) : filepath; +} +//# sourceMappingURL=links.js.map + +/***/ }), +/* 377 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const basic_1 = tslib_1.__importDefault(__webpack_require__(371)); +const mru_1 = tslib_1.__importDefault(__webpack_require__(215)); +class LinksList extends basic_1.default { + constructor(nvim, listMap) { + super(nvim); + this.listMap = listMap; + this.name = 'lists'; + this.defaultAction = 'open'; + this.description = 'registered lists of coc.nvim'; + this.mru = new mru_1.default('lists'); + this.addAction('open', async (item) => { + let { name } = item.data; + await this.mru.add(name); + await nvim.command(`CocList ${name}`); + }); + } + async loadItems(_context) { + let items = []; + let mruList = await this.mru.load(); + for (let list of this.listMap.values()) { + if (list.name == 'lists') + continue; + items.push({ + label: `${list.name}\t${list.description || ''}`, + data: { + name: list.name, + interactive: list.interactive, + score: score(mruList, list.name) + } + }); + } + items.sort((a, b) => { + return b.data.score - a.data.score; + }); + return items; + } + doHighlight() { + let { nvim } = this; + nvim.pauseNotification(); + nvim.command('syntax match CocListsDesc /\\t.*$/ contained containedin=CocListsLine', true); + nvim.command('highlight default link CocListsDesc Comment', true); + nvim.resumeNotification().catch(_e => { + // noop + }); + } +} +exports.default = LinksList; +function score(list, key) { + let idx = list.indexOf(key); + return idx == -1 ? -1 : list.length - idx; +} +//# sourceMappingURL=lists.js.map + +/***/ }), +/* 378 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const vscode_languageserver_types_1 = __webpack_require__(161); +const vscode_uri_1 = __webpack_require__(180); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const util_1 = __webpack_require__(174); +const fs_1 = __webpack_require__(200); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const location_1 = tslib_1.__importDefault(__webpack_require__(373)); +const convert_1 = __webpack_require__(379); +const logger = __webpack_require__(186)('list-symbols'); +class Outline extends location_1.default { + constructor() { + super(...arguments); + this.description = 'symbols of current document'; + this.name = 'outline'; + } + async loadItems(context) { + let buf = await context.window.buffer; + let document = workspace_1.default.getDocument(buf.id); + if (!document) + return null; + let config = this.getConfig(); + let ctagsFilestypes = config.get('ctagsFilestypes', []); + let symbols; + if (ctagsFilestypes.indexOf(document.filetype) == -1) { + symbols = await languages_1.default.getDocumentSymbol(document.textDocument); + } + if (!symbols) + return await this.loadCtagsSymbols(document); + if (symbols.length == 0) + return []; + let items = []; + let isSymbols = !symbols[0].hasOwnProperty('location'); + if (isSymbols) { + function addSymbols(symbols, level = 0) { + symbols.sort(sortSymbols); + for (let s of symbols) { + let kind = convert_1.getSymbolKind(s.kind); + let location = vscode_languageserver_types_1.Location.create(document.uri, s.selectionRange); + items.push({ + label: `${' '.repeat(level * 2)}${s.name}\t[${kind}]\t${s.range.start.line + 1}`, + filterText: s.name, + location + }); + if (s.children && s.children.length) { + addSymbols(s.children, level + 1); + } + } + } + addSymbols(symbols); + } + else { + symbols.sort((a, b) => { + let sa = a.location.range.start; + let sb = b.location.range.start; + let d = sa.line - sb.line; + return d == 0 ? sa.character - sb.character : d; + }); + for (let s of symbols) { + let kind = convert_1.getSymbolKind(s.kind); + if (s.name.endsWith(') callback')) + continue; + if (s.location.uri === undefined) { + s.location.uri = document.uri; + } + items.push({ + label: `${s.name} [${kind}] ${s.location.range.start.line + 1}`, + filterText: `${s.name}`, + location: s.location + }); + } + } + return items; + } + doHighlight() { + let { nvim } = this; + nvim.pauseNotification(); + nvim.command('syntax match CocOutlineName /\\v^\\s*[^\t]+/ contained containedin=CocOutlineLine', true); + nvim.command('syntax match CocOutlineKind /\\[\\w\\+\\]/ contained containedin=CocOutlineLine', true); + nvim.command('syntax match CocOutlineLine /\\d\\+$/ contained containedin=CocOutlineLine', true); + nvim.command('highlight default link CocOutlineName Normal', true); + nvim.command('highlight default link CocOutlineKind Typedef', true); + nvim.command('highlight default link CocOutlineLine Comment', true); + nvim.resumeNotification().catch(_e => { + // noop + }); + } + async loadCtagsSymbols(document) { + let uri = vscode_uri_1.URI.parse(document.uri); + let extname = path_1.default.extname(uri.fsPath); + let content = ''; + let tempname = await this.nvim.call('tempname'); + let filepath = `${tempname}.${extname}`; + let escaped = await this.nvim.call('fnameescape', filepath); + await fs_1.writeFile(escaped, document.getDocumentContent()); + try { + content = await util_1.runCommand(`ctags -f - --excmd=number --language-force=${document.filetype} ${escaped}`); + } + catch (e) { + // noop + } + if (!content.trim().length) { + content = await util_1.runCommand(`ctags -f - --excmd=number ${escaped}`); + } + content = content.trim(); + if (!content) + return []; + let lines = content.split('\n'); + let items = []; + for (let line of lines) { + let parts = line.split('\t'); + if (parts.length < 4) + continue; + let lnum = Number(parts[2].replace(/;"$/, '')); + let text = document.getline(lnum - 1); + if (!text) + continue; + let idx = text.indexOf(parts[0]); + let start = idx == -1 ? 0 : idx; + let range = vscode_languageserver_types_1.Range.create(lnum - 1, start, lnum - 1, start + parts[0].length); + items.push({ + label: `${parts[0]} [${parts[3]}] ${lnum}`, + filterText: parts[0], + location: vscode_languageserver_types_1.Location.create(document.uri, range), + data: { line: lnum } + }); + } + items.sort((a, b) => { + return a.data.line - b.data.line; + }); + return items; + } +} +exports.default = Outline; +function sortSymbols(a, b) { + let ra = a.selectionRange; + let rb = b.selectionRange; + if (ra.start.line != rb.start.line) { + return ra.start.line - rb.start.line; + } + return ra.start.character - rb.start.character; +} +//# sourceMappingURL=outline.js.map + +/***/ }), +/* 379 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +function getSymbolKind(kind) { + switch (kind) { + case vscode_languageserver_protocol_1.SymbolKind.File: + return 'File'; + case vscode_languageserver_protocol_1.SymbolKind.Module: + return 'Module'; + case vscode_languageserver_protocol_1.SymbolKind.Namespace: + return 'Namespace'; + case vscode_languageserver_protocol_1.SymbolKind.Package: + return 'Package'; + case vscode_languageserver_protocol_1.SymbolKind.Class: + return 'Class'; + case vscode_languageserver_protocol_1.SymbolKind.Method: + return 'Method'; + case vscode_languageserver_protocol_1.SymbolKind.Property: + return 'Property'; + case vscode_languageserver_protocol_1.SymbolKind.Field: + return 'Field'; + case vscode_languageserver_protocol_1.SymbolKind.Constructor: + return 'Constructor'; + case vscode_languageserver_protocol_1.SymbolKind.Enum: + return 'Enum'; + case vscode_languageserver_protocol_1.SymbolKind.Interface: + return 'Interface'; + case vscode_languageserver_protocol_1.SymbolKind.Function: + return 'Function'; + case vscode_languageserver_protocol_1.SymbolKind.Variable: + return 'Variable'; + case vscode_languageserver_protocol_1.SymbolKind.Constant: + return 'Constant'; + case vscode_languageserver_protocol_1.SymbolKind.String: + return 'String'; + case vscode_languageserver_protocol_1.SymbolKind.Number: + return 'Number'; + case vscode_languageserver_protocol_1.SymbolKind.Boolean: + return 'Boolean'; + case vscode_languageserver_protocol_1.SymbolKind.Array: + return 'Array'; + case vscode_languageserver_protocol_1.SymbolKind.Object: + return 'Object'; + case vscode_languageserver_protocol_1.SymbolKind.Key: + return 'Key'; + case vscode_languageserver_protocol_1.SymbolKind.Null: + return 'Null'; + case vscode_languageserver_protocol_1.SymbolKind.EnumMember: + return 'EnumMember'; + case vscode_languageserver_protocol_1.SymbolKind.Struct: + return 'Struct'; + case vscode_languageserver_protocol_1.SymbolKind.Event: + return 'Event'; + case vscode_languageserver_protocol_1.SymbolKind.Operator: + return 'Operator'; + case vscode_languageserver_protocol_1.SymbolKind.TypeParameter: + return 'TypeParameter'; + default: + return 'Unknown'; + } +} +exports.getSymbolKind = getSymbolKind; +//# sourceMappingURL=convert.js.map + +/***/ }), +/* 380 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const basic_1 = tslib_1.__importDefault(__webpack_require__(371)); +class OutputList extends basic_1.default { + constructor(nvim) { + super(nvim); + this.defaultAction = 'open'; + this.name = 'output'; + this.description = 'output channels of coc.nvim'; + this.addAction('open', async (item) => { + workspace_1.default.showOutputChannel(item.label); + }); + } + async loadItems(_context) { + let names = workspace_1.default.channelNames; + return names.map(n => { + return { label: n }; + }); + } +} +exports.default = OutputList; +//# sourceMappingURL=output.js.map + +/***/ }), +/* 381 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const services_1 = tslib_1.__importDefault(__webpack_require__(351)); +const basic_1 = tslib_1.__importDefault(__webpack_require__(371)); +const util_1 = __webpack_require__(174); +class ServicesList extends basic_1.default { + constructor(nvim) { + super(nvim); + this.defaultAction = 'toggle'; + this.description = 'registered services of coc.nvim'; + this.name = 'services'; + this.addAction('toggle', async (item) => { + let { id } = item.data; + await services_1.default.toggle(id); + await util_1.wait(100); + }, { persist: true, reload: true }); + } + async loadItems(_context) { + let stats = services_1.default.getServiceStats(); + stats.sort((a, b) => { + return a.id > b.id ? -1 : 1; + }); + return stats.map(stat => { + let prefix = stat.state == 'running' ? '*' : ' '; + return { + label: `${prefix}\t${stat.id}\t[${stat.state}]\t${stat.languageIds.join(', ')}`, + data: { id: stat.id } + }; + }); + } + doHighlight() { + let { nvim } = this; + nvim.pauseNotification(); + nvim.command('syntax match CocServicesPrefix /\\v^./ contained containedin=CocServicesLine', true); + nvim.command('syntax match CocServicesName /\\v%3c\\S+/ contained containedin=CocServicesLine', true); + nvim.command('syntax match CocServicesStat /\\v\\t\\[\\w+\\]/ contained containedin=CocServicesLine', true); + nvim.command('syntax match CocServicesLanguages /\\v(\\])@<=.*$/ contained containedin=CocServicesLine', true); + nvim.command('highlight default link CocServicesPrefix Special', true); + nvim.command('highlight default link CocServicesName Type', true); + nvim.command('highlight default link CocServicesStat Statement', true); + nvim.command('highlight default link CocServicesLanguages Comment', true); + nvim.resumeNotification().catch(_e => { + // noop + }); + } +} +exports.default = ServicesList; +//# sourceMappingURL=services.js.map + +/***/ }), +/* 382 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_types_1 = __webpack_require__(161); +const vscode_uri_1 = __webpack_require__(180); +const sources_1 = tslib_1.__importDefault(__webpack_require__(237)); +const basic_1 = tslib_1.__importDefault(__webpack_require__(371)); +class SourcesList extends basic_1.default { + constructor(nvim) { + super(nvim); + this.defaultAction = 'toggle'; + this.description = 'registered completion sources'; + this.name = 'sources'; + this.addAction('toggle', async (item) => { + let { name } = item.data; + sources_1.default.toggleSource(name); + }, { persist: true, reload: true }); + this.addAction('refresh', async (item) => { + let { name } = item.data; + await sources_1.default.refresh(name); + }, { persist: true, reload: true }); + this.addAction('open', async (item) => { + let { location } = item; + if (location) + await this.jumpTo(location); + }); + } + async loadItems(_context) { + let stats = sources_1.default.sourceStats(); + stats.sort((a, b) => { + if (a.type != b.type) + return a.type < b.type ? 1 : -1; + return a.name > b.name ? -1 : 1; + }); + return stats.map(stat => { + let prefix = stat.disabled ? ' ' : '*'; + let location; + if (stat.filepath) { + location = vscode_languageserver_types_1.Location.create(vscode_uri_1.URI.file(stat.filepath).toString(), vscode_languageserver_types_1.Range.create(0, 0, 0, 0)); + } + return { + label: `${prefix}\t${stat.name}\t[${stat.shortcut}]\t${stat.priority}\t${stat.filetypes.join(',')}`, + location, + data: { name: stat.name } + }; + }); + } + doHighlight() { + let { nvim } = this; + nvim.pauseNotification(); + nvim.command('syntax match CocSourcesPrefix /\\v^./ contained containedin=CocSourcesLine', true); + nvim.command('syntax match CocSourcesName /\\v%3c\\S+/ contained containedin=CocSourcesLine', true); + nvim.command('syntax match CocSourcesType /\\v\\t\\[\\w+\\]/ contained containedin=CocSourcesLine', true); + nvim.command('syntax match CocSourcesFileTypes /\\v\\S+$/ contained containedin=CocSourcesLine', true); + nvim.command('highlight default link CocSourcesPrefix Special', true); + nvim.command('highlight default link CocSourcesName Type', true); + nvim.command('highlight default link CocSourcesFileTypes Comment', true); + nvim.command('highlight default link CocSourcesType Statement', true); + nvim.resumeNotification().catch(_e => { + // noop + }); + } +} +exports.default = SourcesList; +//# sourceMappingURL=sources.js.map + +/***/ }), +/* 383 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const vscode_uri_1 = __webpack_require__(180); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const location_1 = tslib_1.__importDefault(__webpack_require__(373)); +const convert_1 = __webpack_require__(379); +const fs_1 = __webpack_require__(200); +const fzy_1 = __webpack_require__(384); +const logger = __webpack_require__(186)('list-symbols'); +class Symbols extends location_1.default { + constructor() { + super(...arguments); + this.interactive = true; + this.description = 'search workspace symbols'; + this.detail = 'Symbols list is provided by server, it works on interactive mode only.'; + this.name = 'symbols'; + } + async loadItems(context) { + let buf = await context.window.buffer; + let document = workspace_1.default.getDocument(buf.id); + if (!document) + return null; + let { input } = context; + if (!context.options.interactive) { + throw new Error('Symbols only works on interactive mode'); + } + let symbols = await languages_1.default.getWorkspaceSymbols(document.textDocument, input); + if (!symbols) { + throw new Error('Workspace symbols provider not found for current document'); + } + let items = []; + for (let s of symbols) { + let kind = convert_1.getSymbolKind(s.kind); + let file = vscode_uri_1.URI.parse(s.location.uri).fsPath; + if (fs_1.isParentFolder(workspace_1.default.cwd, file)) { + file = path_1.default.relative(workspace_1.default.cwd, file); + } + items.push({ + label: `${s.name} [${kind}]\t${file}`, + filterText: `${s.name}`, + location: s.location, + data: { original: s, kind: s.kind, file, score: fzy_1.score(input, s.name) } + }); + } + items.sort((a, b) => { + if (a.data.score != b.data.score) { + return b.data.score - a.data.score; + } + if (a.data.kind != b.data.kind) { + return a.data.kind - b.data.kind; + } + return a.data.file.length - b.data.file.length; + }); + return items; + } + async resolveItem(item) { + let s = item.data.original; + if (!s) + return null; + let resolved = await languages_1.default.resolveWorkspaceSymbol(s); + if (!resolved) + return null; + let kind = convert_1.getSymbolKind(resolved.kind); + let file = vscode_uri_1.URI.parse(resolved.location.uri).fsPath; + if (fs_1.isParentFolder(workspace_1.default.cwd, file)) { + file = path_1.default.relative(workspace_1.default.cwd, file); + } + return { + label: `${s.name} [${kind}]\t${file}`, + filterText: `${s.name}`, + location: s.location + }; + } + doHighlight() { + let { nvim } = this; + nvim.pauseNotification(); + nvim.command('syntax match CocSymbolsName /\\v^\\s*\\S+/ contained containedin=CocSymbolsLine', true); + nvim.command('syntax match CocSymbolsKind /\\[\\w\\+\\]\\t/ contained containedin=CocSymbolsLine', true); + nvim.command('syntax match CocSymbolsFile /\\S\\+$/ contained containedin=CocSymbolsLine', true); + nvim.command('highlight default link CocSymbolsName Normal', true); + nvim.command('highlight default link CocSymbolsKind Typedef', true); + nvim.command('highlight default link CocSymbolsFile Comment', true); + nvim.resumeNotification().catch(_e => { + // noop + }); + } +} +exports.default = Symbols; +//# sourceMappingURL=symbols.js.map + +/***/ }), +/* 384 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +let SCORE_MIN = -Infinity; +let SCORE_MAX = Infinity; +let SCORE_GAP_LEADING = -0.005; +let SCORE_GAP_TRAILING = -0.005; +let SCORE_GAP_INNER = -0.01; +let SCORE_MATCH_CONSECUTIVE = 1; +let SCORE_MATCH_SLASH = 0.9; +let SCORE_MATCH_WORD = 0.8; +let SCORE_MATCH_CAPITAL = 0.7; +let SCORE_MATCH_DOT = 0.6; +function islower(s) { + return s.toLowerCase() === s; +} +function isupper(s) { + return s.toUpperCase() === s; +} +function precompute_bonus(haystack) { + /* Which positions are beginning of words */ + let m = haystack.length; + let match_bonus = new Array(m); + let last_ch = '/'; + for (let i = 0; i < m; i++) { + let ch = haystack[i]; + if (last_ch === '/') { + match_bonus[i] = SCORE_MATCH_SLASH; + } + else if (last_ch === '-' || last_ch === '_' || last_ch === ' ') { + match_bonus[i] = SCORE_MATCH_WORD; + } + else if (last_ch === '.') { + match_bonus[i] = SCORE_MATCH_DOT; + } + else if (islower(last_ch) && isupper(ch)) { + match_bonus[i] = SCORE_MATCH_CAPITAL; + } + else { + match_bonus[i] = 0; + } + last_ch = ch; + } + return match_bonus; +} +function compute(needle, haystack, D, M) { + let n = needle.length; + let m = haystack.length; + let lower_needle = needle.toLowerCase(); + let lower_haystack = haystack.toLowerCase(); + let match_bonus = precompute_bonus(haystack); + /* + * D[][] Stores the best score for this position ending with a match. + * M[][] Stores the best possible score at this position. + */ + for (let i = 0; i < n; i++) { + D[i] = new Array(m); + M[i] = new Array(m); + let prev_score = SCORE_MIN; + let gap_score = i === n - 1 ? SCORE_GAP_TRAILING : SCORE_GAP_INNER; + for (let j = 0; j < m; j++) { + if (lower_needle[i] === lower_haystack[j]) { + let score = SCORE_MIN; + if (!i) { + score = (j * SCORE_GAP_LEADING) + match_bonus[j]; + } + else if (j) { /* i > 0 && j > 0*/ + score = Math.max(M[i - 1][j - 1] + match_bonus[j], + /* consecutive match, doesn't stack with match_bonus */ + D[i - 1][j - 1] + SCORE_MATCH_CONSECUTIVE); + } + D[i][j] = score; + M[i][j] = prev_score = Math.max(score, prev_score + gap_score); + } + else { + D[i][j] = SCORE_MIN; + M[i][j] = prev_score = prev_score + gap_score; + } + } + } +} +function score(needle, haystack) { + let n = needle.length; + let m = haystack.length; + if (!n || !m) + return SCORE_MIN; + if (n === m) { + /* Since this method can only be called with a haystack which + * matches needle. If the lengths of the strings are equal the + * strings themselves must also be equal (ignoring case). + */ + return SCORE_MAX; + } + if (m > 1024) { + /* + * Unreasonably large candidate: return no score + * If it is a valid match it will still be returned, it will + * just be ranked below any reasonably sized candidates + */ + return SCORE_MIN; + } + let D = new Array(n); + let M = new Array(n); + compute(needle, haystack, D, M); + return M[n - 1][m - 1]; +} +exports.score = score; +function positions(needle, haystack) { + let n = needle.length; + let m = haystack.length; + let positions = new Array(n); + if (!n || !m) + return positions; + if (n === m) { + for (let i = 0; i < n; i++) + positions[i] = i; + return positions; + } + if (m > 1024) { + return positions; + } + let D = new Array(n); + let M = new Array(n); + compute(needle, haystack, D, M); + /* backtrack to find the positions of optimal matching */ + let match_required = false; + for (let i = n - 1, j = m - 1; i >= 0; i--) { + for (; j >= 0; j--) { + /* + * There may be multiple paths which result in + * the optimal weight. + * + * For simplicity, we will pick the first one + * we encounter, the latest in the candidate + * string. + */ + if (D[i][j] !== SCORE_MIN && + (match_required || D[i][j] === M[i][j])) { + /* If this score was determined using + * SCORE_MATCH_CONSECUTIVE, the + * previous character MUST be a match + */ + match_required = + i && j && + M[i][j] === D[i - 1][j - 1] + SCORE_MATCH_CONSECUTIVE; + positions[i] = j--; + break; + } + } + } + return positions; +} +exports.positions = positions; +function hasMatch(needle, haystack) { + needle = needle.toLowerCase(); + haystack = haystack.toLowerCase(); + let l = needle.length; + for (let i = 0, j = 0; i < l; i += 1) { + j = haystack.indexOf(needle[i], j) + 1; + if (j === 0) + return false; + } + return true; +} +exports.hasMatch = hasMatch; +//# sourceMappingURL=fzy.js.map + +/***/ }), +/* 385 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const commands_1 = tslib_1.__importDefault(__webpack_require__(232)); +const manager_1 = tslib_1.__importDefault(__webpack_require__(316)); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const services_1 = tslib_1.__importDefault(__webpack_require__(351)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const basic_1 = tslib_1.__importDefault(__webpack_require__(371)); +const logger = __webpack_require__(186)('list-actions'); +class ActionsList extends basic_1.default { + constructor(nvim) { + super(nvim); + this.defaultAction = 'do'; + this.description = 'code actions of selected range.'; + this.name = 'actions'; + this.options = [{ + name: '-start', + description: 'start of line', + hasValue: true + }, { + name: '-end', + description: 'end of line', + hasValue: true + }, { + name: '-quickfix', + description: 'quickfix only', + }, { + name: '-source', + description: 'source action only' + }]; + this.addAction('do', async (item) => { + let action = item.data.action; + let { command, edit } = action; + if (edit) + await workspace_1.default.applyEdit(edit); + if (command) { + if (commands_1.default.has(command.command)) { + commands_1.default.execute(command); + } + else { + let clientId = action.clientId; + let service = services_1.default.getService(clientId); + let params = { + command: command.command, + arguments: command.arguments + }; + if (service.client) { + let { client } = service; + client + .sendRequest(vscode_languageserver_protocol_1.ExecuteCommandRequest.type, params) + .then(undefined, error => { + workspace_1.default.showMessage(`Execute '${command.command} error: ${error}'`, 'error'); + }); + } + } + } + }); + } + async loadItems(context) { + let buf = await context.window.buffer; + let doc = workspace_1.default.getDocument(buf.id); + if (!doc) + return null; + let args = this.parseArguments(context.args); + let range; + if (args.start && args.end) { + range = vscode_languageserver_protocol_1.Range.create(parseInt(args.start, 10) - 1, 0, parseInt(args.end, 10), 0); + } + else { + range = vscode_languageserver_protocol_1.Range.create(0, 0, doc.lineCount, 0); + } + let diagnostics = manager_1.default.getDiagnosticsInRange(doc.textDocument, range); + let actionContext = { diagnostics }; + if (args.quickfix) { + actionContext.only = [vscode_languageserver_protocol_1.CodeActionKind.QuickFix]; + } + else if (args.source) { + actionContext.only = [vscode_languageserver_protocol_1.CodeActionKind.Source]; + } + let codeActionsMap = await languages_1.default.getCodeActions(doc.textDocument, range, actionContext); + if (!codeActionsMap) + return []; + let codeActions = []; + for (let clientId of codeActionsMap.keys()) { + let actions = codeActionsMap.get(clientId); + for (let action of actions) { + codeActions.push(Object.assign({ clientId }, action)); + } + } + codeActions.sort((a, b) => { + if (a.isPrefered && !b.isPrefered) { + return -1; + } + if (b.isPrefered && !a.isPrefered) { + return 1; + } + return 0; + }); + let items = codeActions.map(action => { + return { + label: `${action.title} ${action.clientId ? `[${action.clientId}]` : ''} ${action.kind ? `(${action.kind})` : ''}`, + data: { action } + }; + }); + return items; + } + doHighlight() { + let { nvim } = this; + nvim.pauseNotification(); + nvim.command('syntax match CocActionsTitle /\\v^[^[]+/ contained containedin=CocActionsLine', true); + nvim.command('syntax match CocActionsClient /\\[\\w\\+\\]/ contained containedin=CocActionsLine', true); + nvim.command('syntax match CocActionsKind /\\v\\(.*\\)$/ contained containedin=CocActionsLine', true); + nvim.command('highlight default link CocActionsTitle Normal', true); + nvim.command('highlight default link CocActionsClient Typedef', true); + nvim.command('highlight default link CocActionsKind Comment', true); + nvim.resumeNotification().catch(_e => { + // noop + }); + } +} +exports.default = ActionsList; +//# sourceMappingURL=actions.js.map + +/***/ }), +/* 386 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const util_1 = __webpack_require__(174); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const debounce = __webpack_require__(176); +const logger = __webpack_require__(186)('list-ui'); +class ListUI { + constructor(nvim, config) { + this.nvim = nvim; + this.config = config; + this.newTab = false; + this._bufnr = 0; + this.currIndex = 0; + this.highlights = []; + this.items = []; + this.disposables = []; + this.selected = new Set(); + this.creating = false; + this._onDidChangeLine = new vscode_languageserver_protocol_1.Emitter(); + this._onDidOpen = new vscode_languageserver_protocol_1.Emitter(); + this._onDidClose = new vscode_languageserver_protocol_1.Emitter(); + this._onDidChange = new vscode_languageserver_protocol_1.Emitter(); + this._onDidLineChange = new vscode_languageserver_protocol_1.Emitter(); + this._onDoubleClick = new vscode_languageserver_protocol_1.Emitter(); + this.onDidChangeLine = this._onDidChangeLine.event; + this.onDidLineChange = this._onDidLineChange.event; + this.onDidOpen = this._onDidOpen.event; + this.onDidClose = this._onDidClose.event; + this.onDidChange = this._onDidChange.event; + this.onDidDoubleClick = this._onDoubleClick.event; + let signText = config.get('selectedSignText', '*'); + nvim.command(`sign define CocSelected text=${signText} texthl=CocSelectedText linehl=CocSelectedLine`, true); + this.signOffset = config.get('signOffset'); + events_1.default.on('BufUnload', async (bufnr) => { + if (bufnr == this.bufnr) { + this._bufnr = 0; + this.window = null; + this._onDidClose.fire(bufnr); + } + }, null, this.disposables); + let timer; + events_1.default.on('CursorMoved', async (bufnr, cursor) => { + if (timer) + clearTimeout(timer); + if (bufnr != this.bufnr) + return; + let lnum = cursor[0]; + if (this.currIndex + 1 != lnum) { + this.currIndex = lnum - 1; + this._onDidChangeLine.fire(lnum); + } + }, null, this.disposables); + events_1.default.on('CursorMoved', debounce(async (bufnr) => { + if (bufnr != this.bufnr) + return; + let [start, end] = await nvim.eval('[line("w0"),line("w$")]'); + if (end < 500) + return; + nvim.pauseNotification(); + this.doHighlight(start - 1, end); + nvim.command('redraw', true); + await nvim.resumeNotification(false, true); + }, 100)); + } + set index(n) { + if (n < 0 || n >= this.items.length) + return; + this.currIndex = n; + if (this.window) { + let { nvim } = this; + nvim.pauseNotification(); + this.setCursor(n + 1, 0); + nvim.command('redraw', true); + nvim.resumeNotification(false, true).logError(); + } + } + get index() { + return this.currIndex; + } + getItem(delta) { + let { currIndex } = this; + return this.items[currIndex + delta]; + } + get item() { + let { window } = this; + if (!window) + return Promise.resolve(null); + return window.cursor.then(cursor => { + this.currIndex = cursor[0] - 1; + return this.items[this.currIndex]; + }, _e => { + return null; + }); + } + async echoMessage(item) { + if (this.bufnr) + return; + let { items } = this; + let idx = items.indexOf(item); + let msg = `[${idx + 1}/${items.length}] ${item.label || ''}`; + this.nvim.callTimer('coc#util#echo_lines', [[msg]], true); + } + async updateItem(item, index) { + if (!this.bufnr || workspace_1.default.bufnr != this.bufnr) + return; + let obj = Object.assign({ resolved: true }, item); + if (index < this.length) { + this.items[index] = obj; + let { nvim } = this; + nvim.pauseNotification(); + nvim.command('setl modifiable', true); + nvim.call('setline', [index + 1, obj.label], true); + nvim.command('setl nomodifiable', true); + await nvim.resumeNotification(); + } + } + async getItems() { + if (this.length == 0) + return []; + let mode = await this.nvim.call('mode'); + if (mode == 'v' || mode == 'V') { + let [start, end] = await this.getSelectedRange(); + let res = []; + for (let i = start; i <= end; i++) { + res.push(this.items[i - 1]); + } + return res; + } + let { selectedItems } = this; + if (selectedItems.length) + return selectedItems; + let item = await this.item; + return item == null ? [] : [item]; + } + async onMouse(event) { + let { nvim, window } = this; + let winid = await nvim.getVvar('mouse_winid'); + if (!window) + return; + let lnum = await nvim.getVvar('mouse_lnum'); + let col = await nvim.getVvar('mouse_col'); + if (event == 'mouseDown') { + this.mouseDown = { winid, lnum, col, current: winid == window.id }; + return; + } + let current = winid == window.id; + if (current && event == 'doubleClick') { + this.setCursor(lnum, 0); + this._onDoubleClick.fire(); + } + if (!this.mouseDown || this.mouseDown.winid != this.mouseDown.winid) + return; + if (current && event == 'mouseDrag') { + await this.selectLines(this.mouseDown.lnum, lnum); + } + else if (current && event == 'mouseUp') { + if (this.mouseDown.lnum == lnum) { + nvim.pauseNotification(); + this.clearSelection(); + this.setCursor(lnum, 0); + nvim.command('redraw', true); + await nvim.resumeNotification(); + } + else { + await this.selectLines(this.mouseDown.lnum, lnum); + } + } + else if (!current && event == 'mouseUp') { + nvim.pauseNotification(); + nvim.call('win_gotoid', winid, true); + nvim.call('cursor', [lnum, col], true); + await nvim.resumeNotification(); + } + } + reset() { + this.items = []; + this.mouseDown = null; + this.selected = new Set(); + this._bufnr = 0; + this.window = null; + } + hide() { + let { bufnr, window, nvim } = this; + if (window) { + nvim.call('coc#util#close', [window.id], true); + } + if (bufnr) { + nvim.command(`silent! bd! ${bufnr}`, true); + } + } + async resume(name, listOptions) { + let { items, selected, nvim, signOffset } = this; + await this.drawItems(items, name, listOptions, true); + if (selected.size > 0 && this.bufnr) { + nvim.pauseNotification(); + for (let lnum of selected) { + nvim.command(`sign place ${signOffset + lnum} line=${lnum} name=CocSelected buffer=${this.bufnr}`, true); + } + await nvim.resumeNotification(); + } + } + async toggleSelection() { + let { nvim, selected, signOffset, bufnr } = this; + if (workspace_1.default.bufnr != bufnr) + return; + let lnum = await nvim.call('line', '.'); + let mode = await nvim.call('mode'); + if (mode == 'v' || mode == 'V') { + let [start, end] = await this.getSelectedRange(); + let exists = selected.has(start); + let reverse = start > end; + if (reverse) + [start, end] = [end, start]; + for (let i = start; i <= end; i++) { + if (!exists) { + selected.add(i); + nvim.command(`sign place ${signOffset + i} line=${i} name=CocSelected buffer=${bufnr}`, true); + } + else { + selected.delete(i); + nvim.command(`sign unplace ${signOffset + i} buffer=${bufnr}`, true); + } + } + this.setCursor(end, 0); + nvim.command('redraw', true); + await nvim.resumeNotification(); + return; + } + let exists = selected.has(lnum); + nvim.pauseNotification(); + if (exists) { + selected.delete(lnum); + nvim.command(`sign unplace ${signOffset + lnum} buffer=${bufnr}`, true); + } + else { + selected.add(lnum); + nvim.command(`sign place ${signOffset + lnum} line=${lnum} name=CocSelected buffer=${bufnr}`, true); + } + this.setCursor(lnum + 1, 0); + nvim.command('redraw', true); + await nvim.resumeNotification(); + } + async selectLines(start, end) { + let { nvim, signOffset, bufnr, length } = this; + this.clearSelection(); + let { selected } = this; + nvim.pauseNotification(); + let reverse = start > end; + if (reverse) + [start, end] = [end, start]; + for (let i = start; i <= end; i++) { + if (i > length) + break; + selected.add(i); + nvim.command(`sign place ${signOffset + i} line=${i} name=CocSelected buffer=${bufnr}`, true); + } + this.setCursor(end, 0); + nvim.command('redraw', true); + await nvim.resumeNotification(); + } + async selectAll() { + let { length } = this; + if (length == 0) + return; + await this.selectLines(1, length); + } + clearSelection() { + let { selected, nvim, signOffset, bufnr } = this; + if (!bufnr) + return; + if (selected.size > 0) { + let signIds = []; + for (let lnum of selected) { + signIds.push(signOffset + lnum); + } + nvim.call('coc#util#unplace_signs', [bufnr, signIds], true); + this.selected = new Set(); + } + } + get shown() { + return this._bufnr != 0; + } + get bufnr() { + return this._bufnr; + } + get ready() { + if (this._bufnr) + return Promise.resolve(); + if (this.creating) { + return new Promise(resolve => { + let disposable = this.onDidOpen(() => { + disposable.dispose(); + resolve(); + }); + }); + } + } + async drawItems(items, name, listOptions, reload = false) { + let { bufnr, config, nvim } = this; + this.newTab = listOptions.position == 'tab'; + let maxHeight = config.get('maxHeight', 12); + let height = Math.max(1, Math.min(items.length, maxHeight)); + let limitLines = config.get('limitLines', 30000); + let curr = this.items[this.index]; + this.items = items.slice(0, limitLines); + if (bufnr == 0 && !this.creating) { + this.creating = true; + let [bufnr, winid] = await nvim.call('coc#list#create', [listOptions.position, height, name, listOptions.numberSelect]); + this._bufnr = bufnr; + this.window = nvim.createWindow(winid); + this.height = height; + this._onDidOpen.fire(this.bufnr); + this.creating = false; + } + else { + await this.ready; + } + let lines = this.items.map(item => item.label); + this.clearSelection(); + await this.setLines(lines, false, reload ? this.currIndex : 0); + let item = this.items[this.index] || { label: '' }; + if (!curr || curr.label != item.label) { + this._onDidLineChange.fire(this.index + 1); + } + } + async appendItems(items) { + let { config } = this; + let limitLines = config.get('limitLines', 1000); + let curr = this.items.length; + if (curr >= limitLines) { + this._onDidChange.fire(); + return; + } + let max = limitLines - curr; + let append = items.slice(0, max); + this.items = this.items.concat(append); + if (this.creating) + return; + await this.setLines(append.map(item => item.label), curr > 0, this.currIndex); + } + async setLines(lines, append = false, index) { + let { nvim, bufnr, window, config } = this; + if (!bufnr || !window) + return; + let resize = !this.newTab && config.get('autoResize', true); + let buf = nvim.createBuffer(bufnr); + nvim.pauseNotification(); + nvim.call('win_gotoid', window.id, true); + if (!append) { + nvim.call('clearmatches', [], true); + } + if (resize) { + let maxHeight = config.get('maxHeight', 12); + let height = Math.max(1, Math.min(this.items.length, maxHeight)); + this.height = height; + nvim.call('coc#list#set_height', [height], true); + } + if (!append) { + if (!lines.length) { + lines = ['Press ? on normal mode to get help.']; + nvim.call('matchaddpos', ['Comment', [[1]], 99], true); + } + } + nvim.command('setl modifiable', true); + if (workspace_1.default.isVim) { + nvim.call('coc#list#setlines', [lines, append], true); + } + else { + buf.setLines(lines, { start: append ? -1 : 0, end: -1, strictIndexing: false }, true); + } + nvim.command('setl nomodifiable', true); + if (!append && index == 0) { + this.doHighlight(0, 300); + } + else { + let height = this.newTab ? workspace_1.default.env.lines : this.height; + this.doHighlight(Math.max(0, index - height), Math.min(index + height + 1, this.length - 1)); + } + if (!append) + window.notify('nvim_win_set_cursor', [[index + 1, 0]]); + this._onDidChange.fire(); + if (workspace_1.default.isVim) + nvim.command('redraw', true); + let [, err] = await nvim.resumeNotification(); + if (err) + logger.error(err); + } + restoreWindow() { + if (this.newTab) + return; + let { window, height } = this; + if (window && height) { + this.nvim.call('coc#list#restore', [window.id, height], true); + } + } + dispose() { + util_1.disposeAll(this.disposables); + } + get length() { + return this.items.length; + } + get selectedItems() { + let { selected, items } = this; + let res = []; + for (let i of selected) { + if (items[i - 1]) + res.push(items[i - 1]); + } + return res; + } + doHighlight(start, end) { + let { nvim } = workspace_1.default; + let { highlights, items } = this; + for (let i = start; i <= Math.min(end, items.length - 1); i++) { + let { ansiHighlights } = items[i]; + let highlight = highlights[i]; + if (ansiHighlights) { + for (let hi of ansiHighlights) { + let { span, hlGroup } = hi; + nvim.call('matchaddpos', [hlGroup, [[i + 1, span[0] + 1, span[1] - span[0]]], 9], true); + } + } + if (highlight) { + let { spans, hlGroup } = highlight; + for (let span of spans) { + nvim.call('matchaddpos', [hlGroup || 'Search', [[i + 1, span[0] + 1, span[1] - span[0]]], 11], true); + } + } + } + } + setCursor(lnum, col) { + let { window, bufnr, items } = this; + let max = items.length == 0 ? 1 : items.length; + if (!bufnr || !window || lnum > max) + return; + window.notify('nvim_win_set_cursor', [[lnum, col]]); + if (this.currIndex + 1 != lnum) { + this.currIndex = lnum - 1; + this._onDidChangeLine.fire(lnum); + } + } + addHighlights(highlights, append = false) { + let limitLines = this.config.get('limitLines', 1000); + if (!append) { + this.highlights = highlights.slice(0, limitLines); + } + else { + if (this.highlights.length < limitLines) { + this.highlights = this.highlights.concat(highlights.slice(0, limitLines - this.highlights.length)); + } + } + } + async getSelectedRange() { + let { nvim } = this; + await nvim.call('coc#list#stop_prompt'); + await nvim.eval('feedkeys("\\", "in")'); + let [, start] = await nvim.call('getpos', "'<"); + let [, end] = await nvim.call('getpos', "'>"); + if (start > end) { + [start, end] = [end, start]; + } + let method = workspace_1.default.isVim ? 'coc#list#prompt_start' : 'coc#list#start_prompt'; + this.nvim.call(method, [], true); + return [start, end]; + } +} +exports.default = ListUI; +//# sourceMappingURL=ui.js.map + +/***/ }), +/* 387 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const vscode_uri_1 = __webpack_require__(180); +const ansiparse_1 = __webpack_require__(350); +const diff_1 = __webpack_require__(208); +const fzy_1 = __webpack_require__(384); +const score_1 = __webpack_require__(388); +const string_1 = __webpack_require__(210); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; +const logger = __webpack_require__(186)('list-worker'); +const controlCode = '\x1b'; +// perform loading task +class Worker { + constructor(nvim, manager) { + this.nvim = nvim; + this.manager = manager; + this.recentFiles = []; + this._loading = false; + this.totalItems = []; + this._onDidChangeItems = new vscode_languageserver_protocol_1.Emitter(); + this.onDidChangeItems = this._onDidChangeItems.event; + let { prompt } = manager; + prompt.onDidChangeInput(async () => { + let { listOptions } = manager; + let { interactive } = listOptions; + let time = manager.getConfig('interactiveDebounceTime', 100); + if (this.timer) + clearTimeout(this.timer); + // reload or filter items + if (interactive) { + this.stop(); + this.timer = setTimeout(async () => { + await this.loadItems(); + }, time); + } + else if (this.length) { + let wait = Math.max(Math.min(Math.floor(this.length / 200), 300), 50); + this.timer = setTimeout(async () => { + await this.drawItems(); + }, wait); + } + }); + } + loadMru() { + let mru = workspace_1.default.createMru('mru'); + mru.load().then(files => { + this.recentFiles = files; + }).logError(); + } + set loading(loading) { + if (this._loading == loading) + return; + this._loading = loading; + let { nvim } = this; + if (loading) { + this.interval = setInterval(async () => { + let idx = Math.floor((new Date()).getMilliseconds() / 100); + nvim.pauseNotification(); + nvim.setVar('coc_list_loading_status', frames[idx], true); + nvim.command('redraws', true); + nvim.resumeNotification(false, true).logError(); + }, 100); + } + else { + if (this.interval) { + clearInterval(this.interval); + nvim.pauseNotification(); + nvim.setVar('coc_list_loading_status', '', true); + nvim.command('redraws', true); + nvim.resumeNotification(false, true).logError(); + } + } + } + get isLoading() { + return this._loading; + } + async loadItems(reload = false) { + let { context, list, listOptions } = this.manager; + if (!list) + return; + this.loadMru(); + if (this.timer) + clearTimeout(this.timer); + this.loading = true; + let { interactive } = listOptions; + let source = this.tokenSource = new vscode_languageserver_protocol_1.CancellationTokenSource(); + let token = source.token; + let items = await list.loadItems(context, token); + if (token.isCancellationRequested) + return; + if (!items || Array.isArray(items)) { + items = (items || []); + this.totalItems = items.map(item => { + item.label = this.fixLabel(item.label); + this.parseListItemAnsi(item); + return item; + }); + this.loading = false; + let highlights = []; + if (!interactive) { + let res = this.filterItems(items); + items = res.items; + highlights = res.highlights; + } + else { + highlights = this.getItemsHighlight(items); + } + this._onDidChangeItems.fire({ + items, + highlights, + reload + }); + } + else { + let task = items; + let totalItems = this.totalItems = []; + let count = 0; + let currInput = context.input; + let timer; + let lastTs; + let _onData = () => { + lastTs = Date.now(); + if (token.isCancellationRequested || !this.manager.isActivated) + return; + if (count >= totalItems.length) + return; + let inputChanged = this.input != currInput; + if (interactive && inputChanged) + return; + if (count == 0 || inputChanged) { + currInput = this.input; + count = totalItems.length; + let items; + let highlights = []; + if (interactive) { + items = totalItems.slice(); + highlights = this.getItemsHighlight(items); + } + else { + let res = this.filterItems(totalItems); + items = res.items; + highlights = res.highlights; + } + this._onDidChangeItems.fire({ items, highlights, reload, append: false }); + } + else { + let remain = totalItems.slice(count); + count = totalItems.length; + let items; + let highlights = []; + if (!interactive) { + let res = this.filterItems(remain); + items = res.items; + highlights = res.highlights; + } + else { + items = remain; + highlights = this.getItemsHighlight(remain); + } + this._onDidChangeItems.fire({ items, highlights, append: true }); + } + }; + task.on('data', async (item) => { + if (timer) + clearTimeout(timer); + if (token.isCancellationRequested) + return; + if (interactive && this.input != currInput) + return; + item.label = this.fixLabel(item.label); + this.parseListItemAnsi(item); + totalItems.push(item); + if (this.input != currInput) + return; + if ((!lastTs && totalItems.length == 500) + || Date.now() - lastTs > 200) { + _onData(); + } + else { + timer = setTimeout(_onData, 50); + } + }); + let disposable = token.onCancellationRequested(() => { + this.loading = false; + disposable.dispose(); + if (timer) + clearTimeout(timer); + if (task) { + task.dispose(); + task = null; + } + }); + task.on('error', async (error) => { + task = null; + this.loading = false; + disposable.dispose(); + if (timer) + clearTimeout(timer); + await this.manager.cancel(); + workspace_1.default.showMessage(`Task error: ${error.toString()}`, 'error'); + logger.error(error); + }); + task.on('end', async () => { + task = null; + this.loading = false; + disposable.dispose(); + if (timer) + clearTimeout(timer); + if (token.isCancellationRequested) + return; + if (totalItems.length == 0) { + this._onDidChangeItems.fire({ items: [], highlights: [] }); + } + else { + _onData(); + } + }); + } + } + // draw all items with filter if necessary + async drawItems() { + let { totalItems } = this; + let { listOptions, isActivated } = this.manager; + if (!isActivated) + return; + let { interactive } = listOptions; + let items = totalItems; + let highlights = []; + if (!interactive) { + let res = this.filterItems(totalItems); + items = res.items; + highlights = res.highlights; + } + else { + highlights = this.getItemsHighlight(items); + } + this._onDidChangeItems.fire({ items, highlights }); + } + stop() { + if (this.tokenSource) { + this.tokenSource.cancel(); + this.tokenSource = null; + } + this.loading = false; + if (this.timer) { + clearTimeout(this.timer); + } + } + get length() { + return this.totalItems.length; + } + get input() { + return this.manager.prompt.input; + } + getItemsHighlight(items) { + let { input } = this; + if (!input) + return []; + return items.map(item => { + let filterLabel = getFilterLabel(item); + if (filterLabel == '') + return null; + let res = score_1.getMatchResult(filterLabel, input); + if (!res || !res.score) + return null; + return this.getHighlights(filterLabel, res.matches); + }); + } + filterItems(items) { + let { input } = this.manager.prompt; + let highlights = []; + let { sort, matcher, ignorecase } = this.manager.listOptions; + if (input.length == 0) { + let filtered = items.slice(); + let sort = filtered.length && typeof filtered[0].recentScore == 'number'; + return { + items: sort ? filtered.sort((a, b) => b.recentScore - a.recentScore) : filtered, + highlights + }; + } + let extended = this.manager.getConfig('extendedSearchMode', true); + let filtered; + if (input.length > 0) { + let inputs = extended ? input.split(/\s+/) : [input]; + if (matcher == 'strict') { + filtered = items.filter(item => { + let spans = []; + let filterLabel = getFilterLabel(item); + for (let input of inputs) { + let idx = ignorecase ? filterLabel.toLowerCase().indexOf(input.toLowerCase()) : filterLabel.indexOf(input); + if (idx == -1) + return false; + spans.push([string_1.byteIndex(filterLabel, idx), string_1.byteIndex(filterLabel, idx + string_1.byteLength(input))]); + } + highlights.push({ spans }); + return true; + }); + } + else if (matcher == 'regex') { + let flags = ignorecase ? 'iu' : 'u'; + let regexes = inputs.reduce((p, c) => { + try { + let regex = new RegExp(c, flags); + p.push(regex); + // tslint:disable-next-line: no-empty + } + catch (e) { } + return p; + }, []); + filtered = items.filter(item => { + let spans = []; + let filterLabel = getFilterLabel(item); + for (let regex of regexes) { + let ms = filterLabel.match(regex); + if (ms == null) + return false; + spans.push([string_1.byteIndex(filterLabel, ms.index), string_1.byteIndex(filterLabel, ms.index + string_1.byteLength(ms[0]))]); + } + highlights.push({ spans }); + return true; + }); + } + else { + filtered = items.filter(item => { + let filterText = item.filterText || item.label; + return inputs.every(s => fzy_1.hasMatch(s, filterText)); + }); + filtered = filtered.map(item => { + let filterLabel = getFilterLabel(item); + let matchScore = 0; + let matches = []; + for (let input of inputs) { + matches.push(...fzy_1.positions(input, filterLabel)); + matchScore += fzy_1.score(input, filterLabel); + } + let { recentScore } = item; + if (!recentScore && item.location) { + let uri = getItemUri(item); + if (uri.startsWith('file')) { + let fsPath = vscode_uri_1.URI.parse(uri).fsPath; + recentScore = -this.recentFiles.indexOf(fsPath); + } + } + return Object.assign({}, item, { + filterLabel, + score: matchScore, + recentScore, + matches + }); + }); + if (sort && items.length) { + filtered.sort((a, b) => { + if (a.score != b.score) + return b.score - a.score; + if (input.length && a.recentScore != b.recentScore) { + return (a.recentScore || -Infinity) - (b.recentScore || -Infinity); + } + if (a.location && b.location) { + let au = getItemUri(a); + let bu = getItemUri(b); + return au > bu ? 1 : -1; + } + return a.label > b.label ? 1 : -1; + }); + } + for (let item of filtered) { + if (!item.matches) + continue; + let hi = this.getHighlights(item.filterLabel, item.matches); + highlights.push(hi); + } + } + } + return { + items: filtered, + highlights + }; + } + getHighlights(text, matches) { + let spans = []; + if (matches.length) { + let start = matches.shift(); + let next = matches.shift(); + let curr = start; + while (next) { + if (next == curr + 1) { + curr = next; + next = matches.shift(); + continue; + } + spans.push([string_1.byteIndex(text, start), string_1.byteIndex(text, curr) + 1]); + start = next; + curr = start; + next = matches.shift(); + } + spans.push([string_1.byteIndex(text, start), string_1.byteIndex(text, curr) + 1]); + } + return { spans }; + } + // set correct label, add ansi highlights + parseListItemAnsi(item) { + let { label } = item; + if (item.ansiHighlights || label.indexOf(controlCode) == -1) + return; + let { line, highlights } = ansiparse_1.parseAnsiHighlights(label); + item.label = line; + item.ansiHighlights = highlights; + } + fixLabel(label) { + let { columns } = workspace_1.default.env; + label = label.split('\n').join(' '); + return label.slice(0, columns * 2); + } +} +exports.default = Worker; +function getFilterLabel(item) { + return item.filterText != null ? diff_1.patchLine(item.filterText, item.label) : item.label; +} +function getItemUri(item) { + let { location } = item; + if (typeof location == 'string') + return location; + return location.uri; +} +//# sourceMappingURL=worker.js.map + +/***/ }), +/* 388 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path_1 = __webpack_require__(57); +const fuzzy_1 = __webpack_require__(367); +// first is start or path start +1, fuzzy +0.5 +// next is followed of path start +1, fuzzy +0.5 +// filename startsWith +1, fuzzy +0.5 +function getMatchResult(text, query, filename = '') { + if (!query) + return { score: 1 }; + let matches = []; + let codes = fuzzy_1.getCharCodes(query); + let filenameIdx = filename ? text.indexOf(filename) : -1; + let matchBase = filenameIdx != -1 && fuzzy_1.fuzzyMatch(codes, filename); + let score = 0; + let c = query[0]; + let idx = 0; + // base => start => pathSeparator => fuzzy + if (matchBase) { + if (filename.startsWith(c)) { + score = score + 2; + idx = filenameIdx + 1; + matches.push(filenameIdx); + } + else if (filename[0].toLowerCase() == c) { + score = score + 1.5; + idx = filenameIdx + 1; + matches.push(filenameIdx); + } + else { + for (let i = 1; i < filename.length; i++) { + if (fuzzy_1.fuzzyChar(c, filename[i])) { + score = score + 1; + idx = filenameIdx + i + 1; + matches.push(filenameIdx + i); + break; + } + } + } + } + else if (text.startsWith(c)) { + score = score + 1; + matches.push(0); + idx = 1; + } + else { + for (let i = 1; i < text.length; i++) { + let pre = text[i - 1]; + if (pre == path_1.sep && text[i] == c) { + score = score + 1; + matches.push(i); + idx = i + 1; + break; + } + } + if (idx == 0) { + for (let i = 0; i < text.length; i++) { + if (fuzzy_1.fuzzyChar(c, text[i])) { + score = score + 0.5; + matches.push(i); + idx = i + 1; + break; + } + } + } + } + if (idx == 0) + return { score: 0 }; + if (codes.length == 1) + return { score, matches }; + return nextResult(codes.slice(1), text, idx, { score, matches }); +} +exports.getMatchResult = getMatchResult; +/** + * + * @public + * @param {number[]} codes - remain codes + * @param {string} text - total text + * @param {number} idx - start index of text + * @param {MatchResult} curr - current result + * @returns {MatchResult | null} + */ +function nextResult(codes, text, idx, curr) { + let { score, matches } = curr; + let results = []; + let c = codes[0]; + let remain = codes.slice(1); + let result; + function getRemianResult(index) { + if (!result) + return; + if (remain.length == 0) { + results.push(result); + } + else if (result) { + let res = nextResult(remain, text, index, result); + if (res) + results.push(res); + } + } + let followed = idx < text.length ? text[idx].charCodeAt(0) : null; + if (!followed) + return null; + if (followed == c) { + result = { score: score + 1, matches: matches.concat([idx]) }; + getRemianResult(idx + 1); + } + else if (fuzzy_1.caseMatch(c, followed)) { + result = { score: score + 0.5, matches: matches.concat([idx]) }; + getRemianResult(idx + 1); + } + if (idx + 1 < text.length) { + // follow path + for (let i = idx + 1; i < text.length; i++) { + let ch = text[i].charCodeAt(0); + if (text[i - 1] == path_1.sep && fuzzy_1.caseMatch(c, ch)) { + let add = c == ch ? 1 : 0.5; + result = { score: score + add, matches: matches.concat([i]) }; + getRemianResult(i + 1); + break; + } + } + // next fuzzy + for (let i = idx + 1; i < text.length; i++) { + let ch = text[i].charCodeAt(0); + if (fuzzy_1.caseMatch(c, ch)) { + let add = c == ch ? 0.5 : 0.2; + result = { score: score + add, matches: matches.concat([i]) }; + getRemianResult(i + 1); + break; + } + } + } + return results.length ? bestResult(results) : null; +} +function bestResult(results) { + let res = results[0]; + for (let i = 1; i < results.length; i++) { + if (results[i].score > res.score) { + res = results[i]; + } + } + return res; +} +//# sourceMappingURL=score.js.map + +/***/ }), +/* 389 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const types_1 = __webpack_require__(189); +const string_1 = __webpack_require__(210); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('model-source'); +class Source { + constructor(option) { + this._disabled = false; + this.nvim = workspace_1.default.nvim; + // readonly properties + this.name = option.name; + this.filepath = option.filepath || ''; + this.sourceType = option.sourceType || types_1.SourceType.Native; + this.isSnippet = !!option.isSnippet; + this.defaults = option; + } + /** + * Priority of source, higher priority makes items lower index. + */ + get priority() { + return this.getConfig('priority', 1); + } + /** + * When triggerOnly is true, not trigger completion on keyword character insert. + */ + get triggerOnly() { + let triggerOnly = this.defaults['triggerOnly']; + if (typeof triggerOnly == 'boolean') + return triggerOnly; + if (!this.triggerCharacters && !this.triggerPatterns) + return false; + return Array.isArray(this.triggerPatterns) && this.triggerPatterns.length != 0; + } + get triggerCharacters() { + return this.getConfig('triggerCharacters', null); + } + // exists opitonnal function names for remote source + get optionalFns() { + return this.defaults['optionalFns'] || []; + } + get triggerPatterns() { + let patterns = this.getConfig('triggerPatterns', null); + if (!patterns || patterns.length == 0) + return null; + return patterns.map(s => { + return (typeof s === 'string') ? new RegExp(s + '$') : s; + }); + } + get shortcut() { + let shortcut = this.getConfig('shortcut', ''); + return shortcut ? shortcut : this.name.slice(0, 3); + } + get enable() { + if (this._disabled) + return false; + return this.getConfig('enable', true); + } + get filetypes() { + return this.getConfig('filetypes', null); + } + get disableSyntaxes() { + return this.getConfig('disableSyntaxes', []); + } + getConfig(key, defaultValue) { + let config = workspace_1.default.getConfiguration(`coc.source.${this.name}`); + defaultValue = this.defaults.hasOwnProperty(key) ? this.defaults[key] : defaultValue; + return config.get(key, defaultValue); + } + toggle() { + this._disabled = !this._disabled; + } + get firstMatch() { + return this.getConfig('firstMatch', true); + } + get menu() { + let { shortcut } = this; + return shortcut ? `[${shortcut}]` : ''; + } + /** + * Filter words that too short or doesn't match input + */ + filterWords(words, opt) { + let { firstMatch } = this; + let res = []; + let { input } = opt; + let cword = opt.word; + if (!input.length) + return []; + let cFirst = input[0]; + for (let word of words) { + if (!word || word.length < 3) + continue; + if (firstMatch && cFirst != word[0]) + continue; + if (!firstMatch && cFirst.toLowerCase() != word[0].toLowerCase()) + continue; + if (word == cword || word == input) + continue; + res.push(word); + } + return res; + } + /** + * fix start column for new valid characters + * + * @protected + * @param {CompleteOption} opt + * @param {string[]} valids - valid charscters + * @returns {number} + */ + fixStartcol(opt, valids) { + let { col, input, line, bufnr } = opt; + let start = string_1.byteSlice(line, 0, col); + let document = workspace_1.default.getDocument(bufnr); + if (!document) + return col; + let { chars } = document; + for (let i = start.length - 1; i >= 0; i--) { + let c = start[i]; + if (!chars.isKeywordChar(c) && valids.indexOf(c) === -1) { + break; + } + input = `${c}${input}`; + col = col - 1; + } + opt.col = col; + opt.input = input; + return col; + } + async shouldComplete(opt) { + let { disableSyntaxes } = this; + let synname = opt.synname.toLowerCase(); + if (disableSyntaxes && disableSyntaxes.length && disableSyntaxes.findIndex(s => synname.indexOf(s.toLowerCase()) != -1) !== -1) { + return false; + } + let fn = this.defaults['shouldComplete']; + if (fn) + return await Promise.resolve(fn.call(this, opt)); + return true; + } + async refresh() { + let fn = this.defaults['refresh']; + if (fn) + await Promise.resolve(fn.call(this)); + } + async onCompleteDone(item, opt) { + let fn = this.defaults['onCompleteDone']; + if (fn) + await Promise.resolve(fn.call(this, item, opt)); + } + async doComplete(opt, token) { + let fn = this.defaults['doComplete']; + if (fn) + return await Promise.resolve(fn.call(this, opt, token)); + return null; + } +} +exports.default = Source; +//# sourceMappingURL=source.js.map + +/***/ }), +/* 390 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fuzzy_1 = __webpack_require__(367); +const string_1 = __webpack_require__(210); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const source_1 = tslib_1.__importDefault(__webpack_require__(389)); +const logger = __webpack_require__(186)('model-source-vim'); +class VimSource extends source_1.default { + async callOptinalFunc(fname, args) { + let exists = this.optionalFns.indexOf(fname) !== -1; + if (!exists) + return null; + let name = `coc#source#${this.name}#${fname}`; + let res; + try { + res = await this.nvim.call(name, args); + } + catch (e) { + workspace_1.default.showMessage(`Vim error from source ${this.name}: ${e.message}`, 'error'); + return null; + } + return res; + } + async shouldComplete(opt) { + let shouldRun = await super.shouldComplete(opt); + if (!shouldRun) + return false; + if (this.optionalFns.indexOf('should_complete') === -1) + return true; + let res = await this.callOptinalFunc('should_complete', [opt]); + return !!res; + } + async refresh() { + await this.callOptinalFunc('refresh', []); + } + async onCompleteDone(item, opt) { + await super.onCompleteDone(item, opt); + if (this.optionalFns.indexOf('on_complete') === -1) + return; + this.callOptinalFunc('on_complete', [item]); // tslint:disable-line + } + onEnter(bufnr) { + if (this.optionalFns.indexOf('on_enter') === -1) + return; + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return; + let { filetypes } = this; + if (filetypes && filetypes.indexOf(doc.filetype) == -1) + return; + this.callOptinalFunc('on_enter', [{ + bufnr, + uri: doc.uri, + languageId: doc.filetype + }]); // tslint:disable-line + } + async doComplete(opt, token) { + let { col, input, line, colnr } = opt; + let startcol = await this.callOptinalFunc('get_startcol', [opt]); + if (token.isCancellationRequested) + return; + if (startcol) { + if (startcol < 0) + return null; + startcol = Number(startcol); + // invalid startcol + if (isNaN(startcol) || startcol < 0) + startcol = col; + if (startcol !== col) { + input = string_1.byteSlice(line, startcol, colnr - 1); + opt = Object.assign({}, opt, { + col: startcol, + changed: col - startcol, + input + }); + } + } + let items = await this.nvim.callAsync('coc#util#do_complete', [this.name, opt]); + if (!items || items.length == 0 || token.isCancellationRequested) + return null; + if (this.firstMatch && input.length) { + let ch = input[0]; + items = items.filter(item => { + let cfirst = item.filterText ? item.filterText[0] : item.word[0]; + return fuzzy_1.fuzzyChar(ch, cfirst); + }); + } + items = items.map(item => { + if (typeof item == 'string') { + return { word: item, menu: this.menu, isSnippet: this.isSnippet }; + } + let menu = item.menu ? item.menu + ' ' : ''; + item.menu = `${menu}${this.menu}`; + item.isSnippet = this.isSnippet; + delete item.user_data; + return item; + }); + let res = { items }; + if (startcol) + res.startcol = startcol; + return res; + } +} +exports.default = VimSource; +//# sourceMappingURL=source-vim.js.map + +/***/ }), +/* 391 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const source_1 = tslib_1.__importDefault(__webpack_require__(389)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('source-around'); +class Around extends source_1.default { + constructor() { + super({ + name: 'around', + filepath: __filename + }); + } + async doComplete(opt) { + let { bufnr, input } = opt; + if (input.length === 0) + return null; + let document = workspace_1.default.getDocument(bufnr); + if (!document) + return null; + let words = document.words; + let moreWords = document.getMoreWords(); + words.push(...moreWords); + words = this.filterWords(words, opt); + return { + items: words.map(word => { + return { + word, + menu: this.menu + }; + }) + }; + } +} +exports.default = Around; +function regist(sourceMap) { + sourceMap.set('around', new Around()); + return vscode_languageserver_protocol_1.Disposable.create(() => { + sourceMap.delete('around'); + }); +} +exports.regist = regist; +//# sourceMappingURL=around.js.map + +/***/ }), +/* 392 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const source_1 = tslib_1.__importDefault(__webpack_require__(389)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('source-buffer'); +class Buffer extends source_1.default { + constructor() { + super({ + name: 'buffer', + filepath: __filename + }); + } + get ignoreGitignore() { + return this.getConfig('ignoreGitignore', true); + } + getWords(bufnr) { + let { ignoreGitignore } = this; + let words = []; + workspace_1.default.documents.forEach(document => { + if (document.bufnr == bufnr) + return; + if (ignoreGitignore && document.isIgnored) + return; + for (let word of document.words) { + if (words.indexOf(word) == -1) { + words.push(word); + } + } + }); + return words; + } + async doComplete(opt) { + let { bufnr, input } = opt; + if (input.length == 0) + return null; + let words = this.getWords(bufnr); + words = this.filterWords(words, opt); + return { + items: words.map(word => { + return { + word, + menu: this.menu + }; + }) + }; + } +} +exports.default = Buffer; +function regist(sourceMap) { + sourceMap.set('buffer', new Buffer()); + return vscode_languageserver_protocol_1.Disposable.create(() => { + sourceMap.delete('buffer'); + }); +} +exports.regist = regist; +//# sourceMappingURL=buffer.js.map + +/***/ }), +/* 393 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const minimatch_1 = tslib_1.__importDefault(__webpack_require__(201)); +const os_1 = tslib_1.__importDefault(__webpack_require__(56)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const util_1 = tslib_1.__importDefault(__webpack_require__(40)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const source_1 = tslib_1.__importDefault(__webpack_require__(389)); +const fs_2 = __webpack_require__(200); +const string_1 = __webpack_require__(210); +const logger = __webpack_require__(186)('source-file'); +const pathRe = /(?:\.{0,2}|~|([\w]+)|)\/(?:[\w.@()-]+\/)*(?:[\w.@()-])*$/; +class File extends source_1.default { + constructor() { + super({ + name: 'file', + filepath: __filename + }); + } + getPathOption(opt) { + let { line, colnr } = opt; + let part = string_1.byteSlice(line, 0, colnr - 1); + if (!part || part.slice(-2) == '//') + return null; + let ms = part.match(pathRe); + if (ms && ms.length) { + let pathstr = ms[0]; + if (pathstr.startsWith('~')) { + pathstr = os_1.default.homedir() + pathstr.slice(1); + } + let input = ms[0].match(/[^/]*$/)[0]; + return { pathstr, part: ms[1], startcol: colnr - input.length - 1, input }; + } + return null; + } + async getFileItem(root, filename) { + let f = path_1.default.join(root, filename); + let stat = await fs_2.statAsync(f); + if (stat) { + let abbr = stat.isDirectory() ? filename + '/' : filename; + let word = filename; + return { word, abbr }; + } + return null; + } + filterFiles(files) { + let ignoreHidden = this.getConfig('ignoreHidden', true); + let ignorePatterns = this.getConfig('ignorePatterns', []); + return files.filter(f => { + if (f == null) + return false; + if (ignoreHidden && /^\./.test(f)) + return false; + for (let p of ignorePatterns) { + if (minimatch_1.default(f, p, { dot: true })) + return false; + } + return true; + }); + } + async getItemsFromRoot(pathstr, root) { + let res = []; + let part = /\/$/.test(pathstr) ? pathstr : path_1.default.dirname(pathstr); + let dir = path_1.default.isAbsolute(pathstr) ? part : path_1.default.join(root, part); + let stat = await fs_2.statAsync(dir); + if (stat && stat.isDirectory()) { + let files = await util_1.default.promisify(fs_1.default.readdir)(dir); + files = this.filterFiles(files); + let items = await Promise.all(files.map(filename => { + return this.getFileItem(dir, filename); + })); + res = res.concat(items); + } + res = res.filter(item => item != null); + return res; + } + get trimSameExts() { + return this.getConfig('trimSameExts', []); + } + async doComplete(opt) { + let { col, filepath } = opt; + let option = this.getPathOption(opt); + if (!option) + return null; + let { pathstr, part, startcol, input } = option; + if (startcol < opt.col) + return null; + let startPart = opt.col == startcol ? '' : string_1.byteSlice(opt.line, opt.col, startcol); + let dirname = path_1.default.dirname(filepath); + let ext = path_1.default.extname(path_1.default.basename(filepath)); + let cwd = await this.nvim.call('getcwd', []); + let root; + if (/^\./.test(pathstr)) { + root = filepath ? path_1.default.dirname(filepath) : cwd; + } + else if (/^\//.test(pathstr)) { + root = /\/$/.test(pathstr) ? pathstr : path_1.default.dirname(pathstr); + } + else if (part) { + if (fs_1.default.existsSync(path_1.default.join(dirname, part))) { + root = dirname; + } + else if (fs_1.default.existsSync(path_1.default.join(cwd, part))) { + root = cwd; + } + } + else { + root = cwd; + } + if (!root) + return null; + let items = await this.getItemsFromRoot(pathstr, root); + let trimExt = this.trimSameExts.indexOf(ext) != -1; + let first = input[0]; + if (first && col == startcol) + items = items.filter(o => o.word[0] === first); + return { + items: items.map(item => { + let ex = path_1.default.extname(item.word); + item.word = trimExt && ex === ext ? item.word.replace(ext, '') : item.word; + return { + word: `${startPart}${item.word}`, + abbr: `${startPart}${item.abbr}`, + menu: this.menu + }; + }) + }; + } +} +exports.default = File; +function regist(sourceMap) { + sourceMap.set('file', new File()); + return vscode_languageserver_protocol_1.Disposable.create(() => { + sourceMap.delete('file'); + }); +} +exports.regist = regist; +//# sourceMappingURL=file.js.map + +/***/ }), +/* 394 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const fuzzy_1 = __webpack_require__(367); +const string_1 = __webpack_require__(210); +const match_1 = __webpack_require__(395); +const logger = __webpack_require__(186)('completion-complete'); +// first time completion +const FIRST_TIMEOUT = 500; +class Complete { + constructor(option, document, recentScores, config, sources, nvim) { + this.option = option; + this.document = document; + this.config = config; + this.sources = sources; + this.nvim = nvim; + // identify this complete + this.results = []; + this.completing = new Set(); + this._canceled = false; + this.tokenSources = new Map(); + this._onDidComplete = new vscode_languageserver_protocol_1.Emitter(); + this.onDidComplete = this._onDidComplete.event; + Object.defineProperty(this, 'recentScores', { + get: () => { + return recentScores || {}; + } + }); + } + get isCompleting() { + return this.completing.size > 0; + } + get isCanceled() { + return this._canceled; + } + get isEmpty() { + return this.results.length == 0; + } + get startcol() { + return this.option.col || 0; + } + get input() { + return this.option.input; + } + get isIncomplete() { + return this.results.findIndex(o => o.isIncomplete == true) !== -1; + } + async completeSource(source) { + let { col } = this.option; + // new option for each source + let opt = Object.assign({}, this.option); + let timeout = this.config.timeout; + timeout = Math.max(Math.min(timeout, 5000), 1000); + try { + if (typeof source.shouldComplete === 'function') { + let shouldRun = await Promise.resolve(source.shouldComplete(opt)); + if (!shouldRun) + return null; + } + let start = Date.now(); + let oldSource = this.tokenSources.get(source.name); + if (oldSource) + oldSource.cancel(); + let tokenSource = new vscode_languageserver_protocol_1.CancellationTokenSource(); + this.tokenSources.set(source.name, tokenSource); + await new Promise((resolve, reject) => { + let { name } = source; + let timer = setTimeout(() => { + this.nvim.command(`echohl WarningMsg| echom 'source ${source.name} timeout after ${timeout}ms'|echohl None`, true); + tokenSource.cancel(); + }, timeout); + let cancelled = false; + let called = false; + let empty = false; + let ft = setTimeout(() => { + if (called) + return; + empty = true; + resolve(); + }, FIRST_TIMEOUT); + let onFinished = () => { + if (called) + return; + called = true; + disposable.dispose(); + clearTimeout(ft); + clearTimeout(timer); + this.tokenSources.delete(name); + }; + let disposable = tokenSource.token.onCancellationRequested(() => { + disposable.dispose(); + this.completing.delete(name); + cancelled = true; + onFinished(); + logger.debug(`Source "${name}" cancelled`); + resolve(); + }); + this.completing.add(name); + Promise.resolve(source.doComplete(opt, tokenSource.token)).then(result => { + this.completing.delete(name); + if (cancelled) + return; + onFinished(); + let dt = Date.now() - start; + logger.debug(`Source "${name}" takes ${dt}ms`); + if (result && result.items && result.items.length) { + result.priority = source.priority; + result.source = name; + // lazy completed items + if (empty && result.startcol && result.startcol != col) { + this.results = [result]; + } + else { + let { results } = this; + let idx = results.findIndex(o => o.source == name); + if (idx != -1) { + results.splice(idx, 1, result); + } + else { + results.push(result); + } + } + if (empty) + this._onDidComplete.fire(); + resolve(); + } + else { + resolve(); + } + }, err => { + this.completing.delete(name); + onFinished(); + reject(err); + }); + }); + } + catch (err) { + this.nvim.command(`echoerr 'Complete ${source.name} error: ${err.message.replace(/'/g, "''")}'`, true); + logger.error('Complete error:', source.name, err); + } + } + async completeInComplete(resumeInput) { + let { results, document } = this; + let remains = results.filter(res => res.isIncomplete != true); + remains.forEach(res => { + res.items.forEach(item => delete item.user_data); + }); + let arr = results.filter(res => res.isIncomplete == true); + let names = arr.map(o => o.source); + let { input, colnr, linenr } = this.option; + Object.assign(this.option, { + input: resumeInput, + line: document.getline(linenr - 1), + colnr: colnr + (resumeInput.length - input.length), + triggerCharacter: null, + triggerForInComplete: true + }); + let sources = this.sources.filter(s => names.indexOf(s.name) !== -1); + await Promise.all(sources.map(s => this.completeSource(s))); + return this.filterResults(resumeInput, Math.floor(Date.now() / 1000)); + } + filterResults(input, cid = 0) { + let { results } = this; + results.sort((a, b) => { + if (a.source == 'tabnine') + return 1; + if (b.source == 'tabnine') + return -1; + return b.priority - a.priority; + }); + let now = Date.now(); + let { bufnr } = this.option; + let { snippetIndicator, removeDuplicateItems, fixInsertedWord } = this.config; + let followPart = (!fixInsertedWord || cid == 0) ? '' : this.getFollowPart(); + if (results.length == 0) + return []; + // max score of high priority source + let maxScore = 0; + let arr = []; + let codes = fuzzy_1.getCharCodes(input); + let words = new Set(); + for (let i = 0, l = results.length; i < l; i++) { + let res = results[i]; + let { items, source, priority } = res; + // tslint:disable-next-line: prefer-for-of + for (let idx = 0; idx < items.length; idx++) { + let item = items[idx]; + let { word } = item; + if ((!item.dup || source == 'tabnine') && words.has(word)) + continue; + if (removeDuplicateItems && !item.isSnippet && words.has(word)) + continue; + let filterText = item.filterText || item.word; + item.filterText = filterText; + if (filterText.length < input.length) + continue; + let score = item.kind && filterText == input ? 64 : match_1.matchScore(filterText, codes); + if (input.length && score == 0) + continue; + if (priority > 90) + maxScore = Math.max(maxScore, score); + if (maxScore > 5 && priority <= 10 && score < maxScore) + continue; + if (followPart.length && !item.isSnippet) { + if (item.word.endsWith(followPart)) { + let { word } = item; + item.word = item.word.slice(0, -followPart.length); + item.abbr = item.abbr || word; + } + } + if (!item.user_data) { + let user_data = { cid, source }; + user_data.index = item.index || idx; + if (item.isSnippet) { + let abbr = item.abbr || item.word; + if (!abbr.endsWith(snippetIndicator)) { + item.abbr = `${item.abbr || item.word}${snippetIndicator}`; + } + } + if (item.signature) + user_data.signature = item.signature; + item.user_data = JSON.stringify(user_data); + item.source = source; + let recentScore = this.recentScores[`${bufnr}|${word}`]; + if (recentScore && now - recentScore < 60 * 1000) { + item.recentScore = recentScore; + } + else { + item.recentScore = 0; + } + } + else { + delete item.sortText; + } + item.priority = priority; + item.abbr = item.abbr || item.word; + item.score = input.length ? score : 0; + item.localBonus = this.localBonus ? this.localBonus.get(filterText) || 0 : 0; + words.add(word); + if (item.isSnippet && item.word == input) { + item.preselect = true; + } + arr.push(item); + } + } + arr.sort((a, b) => { + let sa = a.sortText; + let sb = b.sortText; + let wa = a.filterText; + let wb = b.filterText; + if (a.score != b.score) + return b.score - a.score; + if (a.priority != b.priority) + return b.priority - a.priority; + if (sa && sb && sa != sb) + return sa < sb ? -1 : 1; + if (a.recentScore != b.recentScore) + return b.recentScore - a.recentScore; + if (a.localBonus != b.localBonus) { + if (a.localBonus && b.localBonus && wa != wb) { + if (wa.startsWith(wb)) + return 1; + if (wb.startsWith(wa)) + return -1; + } + return b.localBonus - a.localBonus; + } + // Default sort method + switch (this.config.defaultSortMethod) { + case 'alphabetical': + return a.filterText.localeCompare(b.filterText); + case 'length': + default: // Fallback on length + return a.filterText.length - b.filterText.length; + } + }); + return this.limitCompleteItems(arr.slice(0, this.config.maxItemCount)); + } + limitCompleteItems(items) { + let { highPrioritySourceLimit, lowPrioritySourceLimit } = this.config; + if (!highPrioritySourceLimit && !lowPrioritySourceLimit) + return items; + let counts = new Map(); + return items.filter(item => { + let { priority, source } = item; + let isLow = priority < 90; + let curr = counts.get(source) || 0; + if ((lowPrioritySourceLimit && isLow && curr == lowPrioritySourceLimit) + || (highPrioritySourceLimit && !isLow && curr == highPrioritySourceLimit)) { + return false; + } + counts.set(source, curr + 1); + return true; + }); + } + hasMatch(input) { + let { results } = this; + if (!results) + return false; + let codes = fuzzy_1.getCharCodes(input); + for (let i = 0, l = results.length; i < l; i++) { + let items = results[i].items; + let idx = items.findIndex(item => { + return fuzzy_1.fuzzyMatch(codes, item.filterText || item.word); + }); + if (idx !== -1) + return true; + } + return false; + } + async doComplete() { + let opts = this.option; + let { line, colnr, linenr, col } = this.option; + if (this.config.localityBonus) { + let line = linenr - 1; + this.localBonus = this.document.getLocalifyBonus(vscode_languageserver_protocol_1.Position.create(line, opts.col - 1), vscode_languageserver_protocol_1.Position.create(line, colnr)); + } + else { + this.localBonus = new Map(); + } + await Promise.all(this.sources.map(s => this.completeSource(s))); + let { results } = this; + if (results.length == 0) + return []; + let engrossResult = results.find(r => r.startcol != null && r.startcol != col); + if (engrossResult) { + let { startcol } = engrossResult; + opts.col = startcol; + opts.input = string_1.byteSlice(line, startcol, colnr - 1); + this.results = [engrossResult]; + } + logger.info(`Results from: ${this.results.map(s => s.source).join(',')}`); + return this.filterResults(opts.input, Math.floor(Date.now() / 1000)); + } + resolveCompletionItem(item) { + let { results } = this; + if (!results) + return null; + try { + if (item.user_data) { + let { source } = JSON.parse(item.user_data); + let result = results.find(res => res.source == source); + return result.items.find(o => o.user_data == item.user_data); + } + for (let result of results) { + let res = result.items.find(o => o.abbr == item.abbr && o.info == item.info); + if (res) + return res; + } + return null; + } + catch (e) { + return null; + } + } + getFollowPart() { + let { colnr, line } = this.option; + let idx = string_1.characterIndex(line, colnr - 1); + if (idx == line.length) + return ''; + let part = line.slice(idx - line.length); + return part.match(/^\S?[\w\-]*/)[0]; + } + dispose() { + this._onDidComplete.dispose(); + this._canceled = true; + for (let tokenSource of this.tokenSources.values()) { + tokenSource.cancel(); + } + this.tokenSources.clear(); + this.sources = []; + this.results = []; + } +} +exports.default = Complete; +//# sourceMappingURL=complete.js.map + +/***/ }), +/* 395 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fuzzy_1 = __webpack_require__(367); +function nextWordIndex(start = 0, codes) { + for (let i = start; i < codes.length; i++) { + if (isWordIndex(i, codes)) { + return i; + } + } + return -1; +} +function upperCase(code) { + return code >= 65 && code <= 90; +} +function isWordIndex(index, codes) { + if (index == 0) + return true; + let curr = codes[index]; + if (!fuzzy_1.wordChar(curr)) + return false; + let pre = codes[index - 1]; + if (!fuzzy_1.wordChar(pre)) + return true; + if (upperCase(curr) && !upperCase(pre)) + return true; + return false; +} +/** + * Rules: + * - First strict 5, first case match 2.5 + * - First word character strict 2.5, first word character case 2 + * - First fuzzy match strict 1, first fuzzy case 0.5 + * - Follow strict 1, follow case 0.5 + * - Follow word start 1, follow word case 0.75 + * - First fuzzy strict 0.1, first fuzzy case 0.05 + * + * @public + * @param {string} word + * @param {number[]} input + * @returns {number} + */ +function matchScore(word, input) { + if (input.length == 0 || word.length < input.length) + return 0; + let codes = fuzzy_1.getCharCodes(word); + let curr = codes[0]; + let score = 0; + let first = input[0]; + let idx = 1; + let allowFuzzy = true; + if (!fuzzy_1.wordChar(first)) { + if (first != codes[0]) + return 0; + score = 5; + idx = 1; + } + else { + if (fuzzy_1.caseMatch(first, curr)) { + score = first == curr ? 5 : 2.5; + idx = 1; + } + else { + // first word 2.5/2 + let next = nextWordIndex(1, codes); + if (next != -1) { + if (fuzzy_1.caseMatch(first, codes[next])) { + score = first == codes[next] ? 2.5 : 2; + idx = next + 1; + } + } + if (score == 0) { + // first fuzzy 1/0.5 + for (let i = 1; i < codes.length; i++) { + if (fuzzy_1.caseMatch(first, codes[i])) { + score = first == codes[i] ? 1 : 0.5; + idx = i + 1; + allowFuzzy = false; + } + } + } + } + } + if (input.length == 1 || score == 0) + return score; + let next = nextScore(codes, idx, input.slice(1), allowFuzzy); + return next == 0 ? 0 : score + next; +} +exports.matchScore = matchScore; +function nextScore(codes, index, inputCodes, allowFuzzy = true) { + if (index >= codes.length) + return 0; + let scores = []; + let input = inputCodes[0]; + let len = codes.length; + let isFinal = inputCodes.length == 1; + if (!fuzzy_1.wordChar(input)) { + for (let i = index; i < len; i++) { + if (codes[i] == input) { + if (isFinal) + return 1; + let next = nextScore(codes, i + 1, inputCodes.slice(1), allowFuzzy); + return next == 0 ? 0 : 1 + next; + } + } + return 0; + } + let curr = codes[index]; + let match = fuzzy_1.caseMatch(input, curr); + if (match) { + let score = input == curr ? 1 : 0.5; + if (!isFinal) { + let next = nextScore(codes, index + 1, inputCodes.slice(1), allowFuzzy); + score = next == 0 ? 0 : score + next; + } + scores.push(score); + } + // should not find if current is word index + if (fuzzy_1.wordChar(input) && !isWordIndex(index, codes)) { + let idx = nextWordIndex(index + 1, codes); + if (idx !== -1) { + let next = codes[idx]; + if (fuzzy_1.caseMatch(input, next)) { + let score = input == next ? 1 : 0.75; + if (!isFinal) { + let next = nextScore(codes, idx + 1, inputCodes.slice(1), allowFuzzy); + score = next == 0 ? 0 : score + next; + } + scores.push(score); + } + } + } + // find fuzzy + if (!match && allowFuzzy) { + for (let i = index + 1; i < len; i++) { + let code = codes[i]; + if (fuzzy_1.caseMatch(input, code)) { + let score = input == code ? 0.1 : 0.05; + if (!isFinal) { + let next = nextScore(codes, i + 1, inputCodes.slice(1), false); + score = next == 0 ? 0 : score + next; + } + scores.push(score); + } + } + } + if (!scores.length) + return 0; + return Math.max(...scores); +} +//# sourceMappingURL=match.js.map + +/***/ }), +/* 396 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const floatBuffer_1 = tslib_1.__importDefault(__webpack_require__(318)); +const popup_1 = tslib_1.__importDefault(__webpack_require__(322)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('floating'); +class Floating { + constructor() { + let configuration = workspace_1.default.getConfiguration('suggest'); + let enableFloat = configuration.get('floatEnable', true); + let { env } = workspace_1.default; + if (enableFloat && !env.floating && !env.textprop) { + enableFloat = false; + } + this.config = { + srcId: workspace_1.default.createNameSpace('coc-pum-float'), + maxPreviewWidth: configuration.get('maxPreviewWidth', 80), + enable: enableFloat + }; + } + get buffer() { + let { floatBuffer } = this; + return floatBuffer ? floatBuffer.buffer : null; + } + async showDocumentationFloating(docs, bounding, token) { + let { nvim } = workspace_1.default; + await this.checkBuffer(); + let rect = await this.calculateBounding(docs, bounding); + let config = Object.assign({ relative: 'editor', }, rect); + if (this.window) { + let valid = await this.window.valid; + if (!valid) + this.window = null; + } + if (token.isCancellationRequested) + return; + if (!this.window) { + try { + let win = this.window = await nvim.openFloatWindow(this.buffer, false, config); + if (token.isCancellationRequested) { + this.close(); + return; + } + nvim.pauseNotification(); + win.setVar('float', 1, true); + win.setVar('popup', 1, true); + nvim.command(`noa call win_gotoid(${win.id})`, true); + nvim.command(`setl nospell nolist wrap linebreak foldcolumn=1`, true); + nvim.command(`setl nonumber norelativenumber nocursorline nocursorcolumn colorcolumn=`, true); + nvim.command(`setl signcolumn=no conceallevel=2 concealcursor=n`, true); + nvim.command(`setl winhl=Normal:CocFloating,NormalNC:CocFloating,FoldColumn:CocFloating`, true); + nvim.call('coc#util#do_autocmd', ['CocOpenFloat'], true); + this.floatBuffer.setLines(); + nvim.call('cursor', [1, 1], true); + nvim.command(`noa wincmd p`, true); + let [, err] = await nvim.resumeNotification(); + // tslint:disable-next-line: no-console + if (err) + console.error(`Error on ${err[0]}: ${err[1]} - ${err[2]}`); + } + catch (e) { + logger.error(`Create preview error:`, e.stack); + } + } + else { + nvim.pauseNotification(); + this.window.setConfig(config, true); + nvim.command(`noa call win_gotoid(${this.window.id})`, true); + nvim.call('cursor', [1, 1], true); + this.floatBuffer.setLines(); + nvim.command(`noa wincmd p`, true); + let [, err] = await nvim.resumeNotification(); + // tslint:disable-next-line: no-console + if (err) + console.error(`Error on ${err[0]}: ${err[1]} - ${err[2]}`); + } + } + async showDocumentationVim(docs, bounding, token) { + let { nvim } = workspace_1.default; + await this.checkBuffer(); + let rect = await this.calculateBounding(docs, bounding); + if (token.isCancellationRequested) + return this.close(); + nvim.pauseNotification(); + this.floatBuffer.setLines(); + this.popup.move({ + line: rect.row + 1, + col: rect.col + 1, + minwidth: rect.width, + minheight: rect.height, + maxwidth: rect.width, + maxheight: rect.height + }); + this.popup.show(); + nvim.setVar('coc_popup_id', this.popup.id, true); + nvim.command('redraw', true); + let [, err] = await nvim.resumeNotification(); + // tslint:disable-next-line: no-console + if (err) + console.error(`Error on ${err[0]}: ${err[1]} - ${err[2]}`); + } + async show(docs, bounding, token) { + if (!this.config.enable) + return; + if (workspace_1.default.env.floating) { + await this.showDocumentationFloating(docs, bounding, token); + } + else { + await this.showDocumentationVim(docs, bounding, token); + } + } + async calculateBounding(docs, bounding) { + // drawn lines + let { config, floatBuffer } = this; + let { columns, lines } = workspace_1.default.env; + let { maxPreviewWidth } = config; + let pumWidth = bounding.width + (bounding.scrollbar ? 1 : 0); + let showRight = true; + let paddingRight = columns - bounding.col - pumWidth; + if (bounding.col > paddingRight) + showRight = false; + let maxWidth = showRight ? paddingRight : bounding.col - 1; + maxWidth = Math.min(maxPreviewWidth, maxWidth); + await floatBuffer.setDocuments(docs, maxWidth); + let maxHeight = lines - bounding.row - workspace_1.default.env.cmdheight - 1; + return { + col: showRight ? bounding.col + pumWidth : bounding.col - floatBuffer.width, + row: bounding.row, + height: Math.min(maxHeight, floatBuffer.getHeight(docs, maxWidth)), + width: floatBuffer.width + }; + } + async checkBuffer() { + let { buffer, popup } = this; + let { nvim } = workspace_1.default; + if (workspace_1.default.env.textprop) { + if (popup) { + let visible = await popup.visible(); + if (!visible) { + popup.dispose(); + popup = null; + } + } + if (!popup) { + this.popup = await popup_1.default(nvim, [''], { + padding: [0, 1, 0, 1], + highlight: 'CocFloating', + tab: -1, + }); + let win = nvim.createWindow(this.popup.id); + nvim.pauseNotification(); + win.setVar('float', 1, true); + win.setVar('popup', 1, true); + win.setOption('linebreak', true, true); + win.setOption('showbreak', '', true); + win.setOption('conceallevel', 2, true); + await nvim.resumeNotification(); + } + buffer = nvim.createBuffer(this.popup.bufferId); + this.floatBuffer = new floatBuffer_1.default(nvim, buffer, nvim.createWindow(this.popup.id)); + } + else { + if (buffer) { + let valid = await buffer.valid; + if (valid) + return; + } + buffer = await nvim.createNewBuffer(false, true); + await buffer.setOption('buftype', 'nofile'); + await buffer.setOption('bufhidden', 'hide'); + this.floatBuffer = new floatBuffer_1.default(nvim, buffer); + } + } + close() { + if (workspace_1.default.env.textprop) { + if (this.popup) { + this.popup.dispose(); + } + return; + } + let { window } = this; + if (!window) + return; + this.window.close(true, true); + this.window = null; + } +} +exports.default = Floating; +//# sourceMappingURL=floating.js.map + +/***/ }), +/* 397 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const position_1 = __webpack_require__(213); +const Snippets = tslib_1.__importStar(__webpack_require__(234)); +const string_1 = __webpack_require__(210); +const logger = __webpack_require__(186)('snippets-snipet'); +class CocSnippet { + constructor(_snippetString, position, _variableResolver) { + this._snippetString = _snippetString; + this.position = position; + this._variableResolver = _variableResolver; + this._parser = new Snippets.SnippetParser(); + const snippet = this._parser.parse(this._snippetString, true); + if (_variableResolver) { + snippet.resolveVariables(_variableResolver); + } + this.tmSnippet = snippet; + this.update(); + } + adjustPosition(characterCount, lineCount) { + let { line, character } = this.position; + this.position = { + line: line + lineCount, + character: character + characterCount + }; + this.update(); + } + adjustTextEdit(edit) { + let { range } = edit; + if (position_1.comparePosition(this.range.start, range.end) < 0) + return false; + if (edit.newText.indexOf('\n') == -1 && + this.firstPlaceholder && + position_1.comparePosition(this.firstPlaceholder.range.start, this.range.start) == 0 && + position_1.comparePosition(range.start, range.end) == 0 && + position_1.comparePosition(this.range.start, range.start) == 0) { + return false; + } + let changed = position_1.getChangedPosition(this.range.start, edit); + if (changed.line == 0 && changed.character == 0) + return true; + this.adjustPosition(changed.character, changed.line); + return true; + } + get isPlainText() { + return this._placeholders.every(p => p.isFinalTabstop && p.value == ''); + } + toString() { + return this.tmSnippet.toString(); + } + get range() { + let { position } = this; + const content = this.tmSnippet.toString(); + const doc = vscode_languageserver_protocol_1.TextDocument.create('untitled:/1', 'snippet', 0, content); + const pos = doc.positionAt(content.length); + const end = pos.line == 0 ? position.character + pos.character : pos.character; + return vscode_languageserver_protocol_1.Range.create(position, vscode_languageserver_protocol_1.Position.create(position.line + pos.line, end)); + } + get firstPlaceholder() { + return this.getPlaceholder(this.tmSnippet.minIndexNumber); + } + get lastPlaceholder() { + return this.getPlaceholder(this.tmSnippet.maxIndexNumber); + } + getPlaceholderById(id) { + return this._placeholders.find(o => o.id == id); + } + getPlaceholder(index) { + let placeholders = this._placeholders.filter(o => o.index == index); + let filtered = placeholders.filter(o => !o.transform); + return filtered.length ? filtered[0] : placeholders[0]; + } + getPrevPlaceholder(index) { + if (index == 0) + return this.lastPlaceholder; + let prev = this.getPlaceholder(index - 1); + if (!prev) + return this.getPrevPlaceholder(index - 1); + return prev; + } + getNextPlaceholder(index) { + let max = this.tmSnippet.maxIndexNumber; + if (index == max) + return this.finalPlaceholder; + let next = this.getPlaceholder(index + 1); + if (!next) + return this.getNextPlaceholder(index + 1); + return next; + } + get finalPlaceholder() { + return this._placeholders.find(o => o.isFinalTabstop); + } + getPlaceholderByRange(range) { + return this._placeholders.find(o => { + return position_1.rangeInRange(range, o.range); + }); + } + insertSnippet(placeholder, snippet, range) { + let { start } = placeholder.range; + // let offset = position.character - start.character + let editStart = vscode_languageserver_protocol_1.Position.create(range.start.line - start.line, range.start.line == start.line ? range.start.character - start.character : range.start.character); + let editEnd = vscode_languageserver_protocol_1.Position.create(range.end.line - start.line, range.end.line == start.line ? range.end.character - start.character : range.end.character); + let editRange = vscode_languageserver_protocol_1.Range.create(editStart, editEnd); + let first = this.tmSnippet.insertSnippet(snippet, placeholder.id, editRange); + this.update(); + return first; + } + // update internal positions, no change of buffer + // return TextEdit list when needed + updatePlaceholder(placeholder, edit) { + let { start, end } = edit.range; + let { range } = this; + let { value, id, index } = placeholder; + let newText = position_1.editRange(placeholder.range, value, edit); + let delta = 0; + if (newText.indexOf('\n') == -1) { + for (let p of this._placeholders) { + if (p.index == index && + p.id < id && + p.line == placeholder.range.start.line) { + let text = this.tmSnippet.getPlaceholderText(p.id, newText); + delta = delta + string_1.byteLength(text) - string_1.byteLength(p.value); + } + } + } + this.tmSnippet.updatePlaceholder(id, newText); + let endPosition = position_1.adjustPosition(range.end, edit); + let snippetEdit = { + range: vscode_languageserver_protocol_1.Range.create(range.start, endPosition), + newText: this.tmSnippet.toString() + }; + this.update(); + return { edits: [snippetEdit], delta }; + } + update() { + const snippet = this.tmSnippet; + const placeholders = snippet.placeholders; + const { line, character } = this.position; + const document = vscode_languageserver_protocol_1.TextDocument.create('untitled:/1', 'snippet', 0, snippet.toString()); + this._placeholders = placeholders.map((p, idx) => { + const offset = snippet.offset(p); + const position = document.positionAt(offset); + const start = { + line: line + position.line, + character: position.line == 0 ? character + position.character : position.character + }; + const value = p.toString(); + const lines = value.split('\n'); + let res = { + range: vscode_languageserver_protocol_1.Range.create(start, { + line: start.line + lines.length - 1, + character: lines.length == 1 ? start.character + value.length : lines[lines.length - 1].length + }), + transform: p.transform != null, + line: start.line, + id: idx, + index: p.index, + value, + isFinalTabstop: p.isFinalTabstop, + snippet: this + }; + Object.defineProperty(res, 'snippet', { + enumerable: false + }); + if (p.choice) { + let { options } = p.choice; + if (options && options.length) { + res.choice = options.map(o => o.value); + } + } + return res; + }); + } +} +exports.CocSnippet = CocSnippet; +//# sourceMappingURL=snippet.js.map + +/***/ }), +/* 398 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const path = tslib_1.__importStar(__webpack_require__(57)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const vscode_uri_1 = __webpack_require__(180); +const logger = __webpack_require__(186)('snippets-variable'); +class SnippetVariableResolver { + constructor() { + this._variableToValue = {}; + const currentDate = new Date(); + this._variableToValue = { + CURRENT_YEAR: currentDate.getFullYear().toString(), + CURRENT_YEAR_SHORT: currentDate + .getFullYear() + .toString() + .slice(-2), + CURRENT_MONTH: (currentDate.getMonth() + 1).toString(), + CURRENT_DATE: currentDate.getDate().toString(), + CURRENT_HOUR: currentDate.getHours().toString(), + CURRENT_MINUTE: currentDate.getMinutes().toString(), + CURRENT_SECOND: currentDate.getSeconds().toString(), + CURRENT_DAY_NAME: currentDate.toLocaleString("en-US", { weekday: "long" }), + CURRENT_DAY_NAME_SHORT: currentDate.toLocaleString("en-US", { weekday: "short" }), + CURRENT_MONTH_NAME: currentDate.toLocaleString("en-US", { month: "long" }), + CURRENT_MONTH_NAME_SHORT: currentDate.toLocaleString("en-US", { month: "short" }) + }; + } + get nvim() { + return workspace_1.default.nvim; + } + async init(document) { + let filepath = vscode_uri_1.URI.parse(document.uri).fsPath; + let [lnum, line, cword, selected, clipboard, yank] = await this.nvim.eval(`[line('.'),getline('.'),expand(''),get(g:,'coc_selected_text', ''),getreg('+'),getreg('"')]`); + Object.assign(this._variableToValue, { + YANK: yank || undefined, + CLIPBOARD: clipboard || undefined, + TM_CURRENT_LINE: line, + TM_SELECTED_TEXT: selected || undefined, + TM_CURRENT_WORD: cword, + TM_LINE_INDEX: (lnum - 1).toString(), + TM_LINE_NUMBER: lnum.toString(), + TM_FILENAME: path.basename(filepath), + TM_FILENAME_BASE: path.basename(filepath, path.extname(filepath)), + TM_DIRECTORY: path.dirname(filepath), + TM_FILEPATH: filepath, + }); + } + resolve(variable) { + const variableName = variable.name; + if (this._variableToValue.hasOwnProperty(variableName)) { + return this._variableToValue[variableName] || ''; + } + if (variable.children && variable.children.length) { + return variable.toString(); + } + return variableName; + } +} +exports.SnippetVariableResolver = SnippetVariableResolver; +//# sourceMappingURL=variableResolve.js.map + +/***/ }), +/* 399 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const commands_1 = tslib_1.__importDefault(__webpack_require__(232)); +const manager_1 = tslib_1.__importDefault(__webpack_require__(316)); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const manager_2 = tslib_1.__importDefault(__webpack_require__(364)); +const floatFactory_1 = tslib_1.__importDefault(__webpack_require__(317)); +const services_1 = tslib_1.__importDefault(__webpack_require__(351)); +const manager_3 = tslib_1.__importDefault(__webpack_require__(233)); +const util_1 = __webpack_require__(174); +const convert_1 = __webpack_require__(379); +const object_1 = __webpack_require__(190); +const position_1 = __webpack_require__(213); +const string_1 = __webpack_require__(210); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const codelens_1 = tslib_1.__importDefault(__webpack_require__(400)); +const colors_1 = tslib_1.__importDefault(__webpack_require__(401)); +const documentHighlight_1 = tslib_1.__importDefault(__webpack_require__(403)); +const refactor_1 = tslib_1.__importDefault(__webpack_require__(404)); +const search_1 = tslib_1.__importDefault(__webpack_require__(405)); +const debounce = __webpack_require__(176); +const logger = __webpack_require__(186)('Handler'); +const pairs = new Map([ + ['<', '>'], + ['>', '<'], + ['{', '}'], + ['[', ']'], + ['(', ')'], +]); +class Handler { + constructor(nvim) { + this.nvim = nvim; + this.refactorMap = new Map(); + this.documentLines = []; + this.disposables = []; + this.labels = {}; + this.selectionRange = null; + this.getPreferences(); + workspace_1.default.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('coc.preferences')) { + this.getPreferences(); + } + }); + this.hoverFactory = new floatFactory_1.default(nvim, workspace_1.default.env); + this.disposables.push(this.hoverFactory); + let { signaturePreferAbove, signatureFloatMaxWidth, signatureMaxHeight } = this.preferences; + this.signatureFactory = new floatFactory_1.default(nvim, workspace_1.default.env, signaturePreferAbove, signatureMaxHeight, signatureFloatMaxWidth, false); + this.disposables.push(this.signatureFactory); + events_1.default.on('BufUnload', async (bufnr) => { + let refactor = this.refactorMap.get(bufnr); + if (refactor) { + refactor.dispose(); + this.refactorMap.delete(bufnr); + } + }, null, this.disposables); + events_1.default.on('CursorMovedI', async (bufnr, cursor) => { + if (!this.signaturePosition) + return; + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return; + let { line, character } = this.signaturePosition; + if (cursor[0] - 1 == line) { + let currline = doc.getline(cursor[0] - 1); + let col = string_1.byteLength(currline.slice(0, character)) + 1; + if (cursor[1] > col) + return; + } + this.signatureFactory.close(); + }, null, this.disposables); + events_1.default.on('InsertLeave', () => { + this.signatureFactory.close(); + }, null, this.disposables); + events_1.default.on(['TextChangedI', 'TextChangedP'], async () => { + if (this.preferences.signatureHideOnChange) { + this.signatureFactory.close(); + } + this.hoverFactory.close(); + }, null, this.disposables); + let lastInsert; + events_1.default.on('InsertCharPre', async (character) => { + lastInsert = Date.now(); + if (character == ')') + this.signatureFactory.close(); + }, null, this.disposables); + events_1.default.on('Enter', async (bufnr) => { + let { bracketEnterImprove } = this.preferences; + await this.onCharacterType('\n', bufnr); + if (bracketEnterImprove) { + let line = await nvim.call('line', '.') - 1; + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return; + let pre = doc.getline(line - 1); + let curr = doc.getline(line); + let prevChar = pre[pre.length - 1]; + if (prevChar && pairs.has(prevChar)) { + let nextChar = curr.trim()[0]; + if (nextChar && pairs.get(prevChar) == nextChar) { + let edits = []; + let opts = await workspace_1.default.getFormatOptions(doc.uri); + let space = opts.insertSpaces ? ' '.repeat(opts.tabSize) : '\t'; + let preIndent = pre.match(/^\s*/)[0]; + let currIndent = curr.match(/^\s*/)[0]; + let newText = '\n' + preIndent + space; + let pos = vscode_languageserver_protocol_1.Position.create(line - 1, pre.length); + // make sure indent of current line + if (preIndent != currIndent) { + let newText = doc.filetype == 'vim' ? ' \\ ' + preIndent : preIndent; + edits.push({ range: vscode_languageserver_protocol_1.Range.create(vscode_languageserver_protocol_1.Position.create(line, 0), vscode_languageserver_protocol_1.Position.create(line, currIndent.length)), newText }); + } + else if (doc.filetype == 'vim') { + edits.push({ range: vscode_languageserver_protocol_1.Range.create(line, currIndent.length, line, currIndent.length), newText: ' \\ ' }); + } + if (doc.filetype == 'vim') { + newText = newText + '\\ '; + } + edits.push({ range: vscode_languageserver_protocol_1.Range.create(pos, pos), newText }); + await doc.applyEdits(nvim, edits); + await workspace_1.default.moveTo(vscode_languageserver_protocol_1.Position.create(line, newText.length - 1)); + } + } + } + }, null, this.disposables); + events_1.default.on('TextChangedI', async (bufnr) => { + let curr = Date.now(); + if (!lastInsert || curr - lastInsert > 500) + return; + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return; + let { triggerSignatureHelp, triggerSignatureWait, formatOnType } = this.preferences; + if (!triggerSignatureHelp && !formatOnType) + return; + let [pos, line] = await nvim.eval('[coc#util#cursor(), getline(".")]'); + let pre = pos[1] == 0 ? '' : line.slice(pos[1] - 1, pos[1]); + if (!pre || string_1.isWord(pre)) + return; + if (!doc.paused) + await this.onCharacterType(pre, bufnr); + if (triggerSignatureHelp && languages_1.default.shouldTriggerSignatureHelp(doc.textDocument, pre)) { + doc.forceSync(); + await util_1.wait(Math.min(Math.max(triggerSignatureWait, 50), 300)); + if (!workspace_1.default.insertMode) + return; + try { + let cursor = await nvim.call('coc#util#cursor'); + await this.triggerSignatureHelp(doc, { line: cursor[0], character: cursor[1] }); + } + catch (e) { + logger.error(`Error on signature help:`, e); + } + } + }, null, this.disposables); + events_1.default.on('InsertLeave', async (bufnr) => { + await util_1.wait(30); + if (workspace_1.default.insertMode) + return; + await this.onCharacterType('\n', bufnr, true); + }, null, this.disposables); + events_1.default.on('CursorMoved', debounce((bufnr, cursor) => { + if (!this.preferences.previewAutoClose || !this.hoverPosition) + return; + if (this.preferences.hoverTarget == 'float') + return; + let arr = [bufnr, cursor[0], cursor[1]]; + if (object_1.equals(arr, this.hoverPosition)) + return; + let doc = workspace_1.default.documents.find(doc => doc.uri.startsWith('coc://')); + if (doc && doc.bufnr != bufnr) { + nvim.command('pclose', true); + } + }, 100), null, this.disposables); + if (this.preferences.currentFunctionSymbolAutoUpdate) { + events_1.default.on('CursorHold', async () => { + try { + await this.getCurrentFunctionSymbol(); + } + catch (e) { + logger.error(e); + } + }, null, this.disposables); + } + let provider = { + onDidChange: null, + provideTextDocumentContent: async () => { + nvim.pauseNotification(); + nvim.command('setlocal conceallevel=2 nospell nofoldenable wrap', true); + nvim.command('setlocal bufhidden=wipe nobuflisted', true); + nvim.command('setfiletype markdown', true); + nvim.command(`exe "normal! z${this.documentLines.length}\\"`, true); + await nvim.resumeNotification(); + return this.documentLines.join('\n'); + } + }; + this.disposables.push(workspace_1.default.registerTextDocumentContentProvider('coc', provider)); + this.codeLensManager = new codelens_1.default(nvim); + this.colors = new colors_1.default(nvim); + this.documentHighlighter = new documentHighlight_1.default(nvim, this.colors); + this.disposables.push(commands_1.default.registerCommand('editor.action.organizeImport', async (bufnr) => { + if (!bufnr) + bufnr = await nvim.call('bufnr', '%'); + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return false; + let range = vscode_languageserver_protocol_1.Range.create(0, 0, doc.lineCount, 0); + let actions = await this.getCodeActions(bufnr, range, [vscode_languageserver_protocol_1.CodeActionKind.SourceOrganizeImports]); + if (actions && actions.length) { + await this.applyCodeAction(actions[0]); + return true; + } + workspace_1.default.showMessage(`Orgnize import action not found.`, 'warning'); + return false; + })); + commands_1.default.titles.set('editor.action.organizeImport', 'run organize import code action.'); + } + async getCurrentFunctionSymbol() { + let position = await workspace_1.default.getCursorPosition(); + let buffer = await this.nvim.buffer; + let document = workspace_1.default.getDocument(buffer.id); + if (!document) + return; + let symbols = await this.getDocumentSymbols(document); + if (!symbols || symbols.length === 0) { + buffer.setVar('coc_current_function', '', true); + this.nvim.call('coc#util#do_autocmd', ['CocStatusChange'], true); + return ''; + } + symbols = symbols.filter(s => [ + 'Class', + 'Method', + 'Function', + ].includes(s.kind)); + let functionName = ''; + for (let sym of symbols.reverse()) { + if (sym.range + && position_1.positionInRange(position, sym.range) == 0 + && !sym.text.endsWith(') callback')) { + functionName = sym.text; + let label = this.labels[sym.kind.toLowerCase()]; + if (label) + functionName = `${label} ${functionName}`; + break; + } + } + buffer.setVar('coc_current_function', functionName, true); + this.nvim.call('coc#util#do_autocmd', ['CocStatusChange'], true); + return functionName; + } + async hasProvider(id) { + let bufnr = await this.nvim.call('bufnr', '%'); + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return false; + return languages_1.default.hasProvider(id, doc.textDocument); + } + async onHover() { + let { document, position } = await workspace_1.default.getCurrentState(); + let hovers = await languages_1.default.getHover(document, position); + if (hovers && hovers.length) { + let hover = hovers.find(o => vscode_languageserver_protocol_1.Range.is(o.range)); + if (hover) { + let doc = workspace_1.default.getDocument(document.uri); + if (doc) { + let ids = doc.matchAddRanges([hover.range], 'CocHoverRange', 999); + setTimeout(() => { + this.nvim.call('coc#util#clearmatches', [ids], true); + }, 1000); + } + } + await this.previewHover(hovers); + return true; + } + let target = this.preferences.hoverTarget; + if (target == 'float') { + this.hoverFactory.close(); + } + else if (target == 'preview') { + this.nvim.command('pclose', true); + } + return false; + } + async gotoDefinition(openCommand) { + let { document, position } = await workspace_1.default.getCurrentState(); + let definition = await languages_1.default.getDefinition(document, position); + if (isEmpty(definition)) { + this.onEmptyLocation('Definition', definition); + return false; + } + await this.handleLocations(definition, openCommand); + return true; + } + async gotoDeclaration(openCommand) { + let { document, position } = await workspace_1.default.getCurrentState(); + let definition = await languages_1.default.getDeclaration(document, position); + if (isEmpty(definition)) { + this.onEmptyLocation('Declaration', definition); + return false; + } + await this.handleLocations(definition, openCommand); + return true; + } + async gotoTypeDefinition(openCommand) { + let { document, position } = await workspace_1.default.getCurrentState(); + let definition = await languages_1.default.getTypeDefinition(document, position); + if (isEmpty(definition)) { + this.onEmptyLocation('Type definition', definition); + return false; + } + await this.handleLocations(definition, openCommand); + return true; + } + async gotoImplementation(openCommand) { + let { document, position } = await workspace_1.default.getCurrentState(); + let definition = await languages_1.default.getImplementation(document, position); + if (isEmpty(definition)) { + this.onEmptyLocation('Implementation', definition); + return false; + } + await this.handleLocations(definition, openCommand); + return true; + } + async gotoReferences(openCommand) { + let { document, position } = await workspace_1.default.getCurrentState(); + let locs = await languages_1.default.getReferences(document, { includeDeclaration: false }, position); + if (isEmpty(locs)) { + this.onEmptyLocation('References', locs); + return false; + } + await this.handleLocations(locs, openCommand); + return true; + } + async getDocumentSymbols(document) { + document = document || workspace_1.default.getDocument(workspace_1.default.bufnr); + if (!document) + return []; + let symbols = await languages_1.default.getDocumentSymbol(document.textDocument); + if (!symbols) + return null; + if (symbols.length == 0) + return []; + let level = 0; + let res = []; + let pre = null; + if (isDocumentSymbols(symbols)) { + symbols.sort(sortDocumentSymbols); + symbols.forEach(s => addDoucmentSymbol(res, s, level)); + } + else { + symbols.sort(sortSymbolInformations); + for (let sym of symbols) { + let { name, kind, location, containerName } = sym; + if (!containerName || !pre) { + level = 0; + } + else { + if (pre.containerName == containerName) { + level = pre.level || 0; + } + else { + let container = getPreviousContainer(containerName, res); + level = container ? container.level + 1 : 0; + } + } + let { start } = location.range; + let o = { + col: start.character + 1, + lnum: start.line + 1, + text: name, + level, + kind: convert_1.getSymbolKind(kind), + range: location.range, + containerName + }; + res.push(o); + pre = o; + } + } + return res; + } + async getWordEdit() { + let bufnr = await this.nvim.call('bufnr', '%'); + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return null; + let position = await workspace_1.default.getCursorPosition(); + let range = doc.getWordRangeAtPosition(position); + if (!range || position_1.emptyRange(range)) + return null; + let curname = doc.textDocument.getText(range); + if (languages_1.default.hasProvider('rename', doc.textDocument)) { + if (doc.dirty) { + doc.forceSync(); + await util_1.wait(30); + } + let res = await languages_1.default.prepareRename(doc.textDocument, position); + if (res === false) + return null; + let edit = await languages_1.default.provideRenameEdits(doc.textDocument, position, curname); + if (edit) + return edit; + } + workspace_1.default.showMessage('Rename provider not found, extract word ranges from current buffer', 'more'); + let ranges = doc.getSymbolRanges(curname); + return { + changes: { + [doc.uri]: ranges.map(r => { + return { range: r, newText: curname }; + }) + } + }; + } + async rename(newName) { + let bufnr = await this.nvim.call('bufnr', '%'); + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return false; + let { nvim } = this; + let position = await workspace_1.default.getCursorPosition(); + let range = doc.getWordRangeAtPosition(position); + if (!range || position_1.emptyRange(range)) + return false; + if (!languages_1.default.hasProvider('rename', doc.textDocument)) { + workspace_1.default.showMessage(`Rename provider not found for current document`, 'error'); + return false; + } + if (doc.dirty) { + doc.forceSync(); + await util_1.wait(30); + } + let res = await languages_1.default.prepareRename(doc.textDocument, position); + if (res === false) { + workspace_1.default.showMessage('Invalid position for renmame', 'error'); + return false; + } + if (!newName) { + let curname = await nvim.eval('expand("")'); + newName = await workspace_1.default.callAsync('input', ['New name: ', curname]); + nvim.command('normal! :', true); + if (!newName) { + workspace_1.default.showMessage('Empty name, canceled', 'warning'); + return false; + } + } + let edit = await languages_1.default.provideRenameEdits(doc.textDocument, position, newName); + if (!edit) { + workspace_1.default.showMessage('Invalid position for rename', 'warning'); + return false; + } + await workspace_1.default.applyEdit(edit); + return true; + } + async documentFormatting() { + let bufnr = await this.nvim.eval('bufnr("%")'); + let document = workspace_1.default.getDocument(bufnr); + if (!document) + return false; + let options = await workspace_1.default.getFormatOptions(document.uri); + let textEdits = await languages_1.default.provideDocumentFormattingEdits(document.textDocument, options); + if (!textEdits || textEdits.length == 0) + return false; + await document.applyEdits(this.nvim, textEdits); + return true; + } + async documentRangeFormatting(mode) { + let document = await workspace_1.default.document; + if (!document) + return -1; + let range; + if (mode) { + range = await workspace_1.default.getSelectedRange(mode, document); + if (!range) + return -1; + } + else { + let lnum = await this.nvim.getVvar('lnum'); + let count = await this.nvim.getVvar('count'); + let mode = await this.nvim.call('mode'); + // we can't handle + if (count == 0 || mode == 'i' || mode == 'R') + return -1; + range = vscode_languageserver_protocol_1.Range.create(lnum - 1, 0, lnum - 1 + count, 0); + } + let options = await workspace_1.default.getFormatOptions(document.uri); + let textEdits = await languages_1.default.provideDocumentRangeFormattingEdits(document.textDocument, range, options); + if (!textEdits) + return -1; + await document.applyEdits(this.nvim, textEdits); + return 0; + } + async runCommand(id, ...args) { + if (id) { + await events_1.default.fire('Command', [id]); + let res = await commands_1.default.executeCommand(id, ...args); + if (args.length == 0) { + await commands_1.default.addRecent(id); + } + return res; + } + else { + await manager_2.default.start(['commands']); + } + } + async getCodeActions(bufnr, range, only) { + let document = workspace_1.default.getDocument(bufnr); + if (!document) + return []; + if (!range) { + let lnum = await this.nvim.call('line', ['.']); + range = { + start: { line: lnum - 1, character: 0 }, + end: { line: lnum, character: 0 } + }; + } + let diagnostics = manager_1.default.getDiagnosticsInRange(document.textDocument, range); + let context = { diagnostics }; + if (only && Array.isArray(only)) + context.only = only; + let codeActionsMap = await languages_1.default.getCodeActions(document.textDocument, range, context); + if (!codeActionsMap) + return []; + let codeActions = []; + for (let clientId of codeActionsMap.keys()) { + let actions = codeActionsMap.get(clientId); + for (let action of actions) { + codeActions.push(Object.assign({ clientId }, action)); + } + } + codeActions.sort((a, b) => { + if (a.isPrefered && !b.isPrefered) { + return -1; + } + if (b.isPrefered && !a.isPrefered) { + return 1; + } + return 0; + }); + return codeActions; + } + async doCodeAction(mode, only) { + let bufnr = await this.nvim.call('bufnr', '%'); + let range; + if (mode) + range = await workspace_1.default.getSelectedRange(mode, workspace_1.default.getDocument(bufnr)); + let codeActions = await this.getCodeActions(bufnr, range, Array.isArray(only) ? only : null); + if (!codeActions || codeActions.length == 0) { + workspace_1.default.showMessage('No action available', 'warning'); + return; + } + if (only && typeof only == 'string') { + let action = codeActions.find(o => o.title == only || (o.command && o.command.title == only)); + if (!action) + return workspace_1.default.showMessage(`action "${only}" not found.`, 'warning'); + await this.applyCodeAction(action); + } + else { + let idx = await workspace_1.default.showQuickpick(codeActions.map(o => o.title)); + if (idx == -1) + return; + let action = codeActions[idx]; + if (action) + await this.applyCodeAction(action); + } + } + /** + * Get current codeActions + * + * @public + * @returns {Promise} + */ + async getCurrentCodeActions(mode, only) { + let bufnr = await this.nvim.call('bufnr', '%'); + let document = workspace_1.default.getDocument(bufnr); + if (!document) + return []; + let range; + if (mode) + range = await workspace_1.default.getSelectedRange(mode, workspace_1.default.getDocument(bufnr)); + return await this.getCodeActions(bufnr, range, only); + } + async doQuickfix() { + let actions = await this.getCurrentCodeActions(null, [vscode_languageserver_protocol_1.CodeActionKind.QuickFix]); + if (!actions || actions.length == 0) { + workspace_1.default.showMessage('No quickfix action available', 'warning'); + return false; + } + await this.applyCodeAction(actions[0]); + await this.nvim.command(`silent! call repeat#set("\\(coc-fix-current)", -1)`); + return true; + } + async applyCodeAction(action) { + let { command, edit } = action; + if (edit) + await workspace_1.default.applyEdit(edit); + if (command) { + if (commands_1.default.has(command.command)) { + commands_1.default.execute(command); + } + else { + let clientId = action.clientId; + let service = services_1.default.getService(clientId); + let params = { + command: command.command, + arguments: command.arguments + }; + if (service.client) { + let { client } = service; + client + .sendRequest(vscode_languageserver_protocol_1.ExecuteCommandRequest.type, params) + .then(undefined, error => { + workspace_1.default.showMessage(`Execute '${command.command} error: ${error}'`, 'error'); + }); + } + } + } + } + async doCodeLensAction() { + await this.codeLensManager.doAction(); + } + async fold(kind) { + let document = await workspace_1.default.document; + let win = await this.nvim.window; + let foldmethod = await win.getOption('foldmethod'); + if (foldmethod != 'manual') { + workspace_1.default.showMessage('foldmethod option should be manual!', 'warning'); + return false; + } + let ranges = await languages_1.default.provideFoldingRanges(document.textDocument, {}); + if (ranges == null) { + workspace_1.default.showMessage('no range provider found', 'warning'); + return false; + } + if (!ranges || ranges.length == 0) { + workspace_1.default.showMessage('no range found', 'warning'); + return false; + } + if (kind) { + ranges = ranges.filter(o => o.kind == kind); + } + if (ranges && ranges.length) { + await win.setOption('foldenable', true); + for (let range of ranges.reverse()) { + let { startLine, endLine } = range; + let cmd = `${startLine + 1}, ${endLine + 1}fold`; + this.nvim.command(cmd, true); + } + return true; + } + return false; + } + async pickColor() { + await this.colors.pickColor(); + } + async pickPresentation() { + await this.colors.pickPresentation(); + } + async highlight() { + let bufnr = await this.nvim.call('bufnr', '%'); + await this.documentHighlighter.highlight(bufnr); + } + async getSymbolsRanges() { + let document = await workspace_1.default.document; + let highlights = await this.documentHighlighter.getHighlights(document); + if (!highlights) + return null; + return highlights.map(o => o.range); + } + async links() { + let doc = await workspace_1.default.document; + let links = await languages_1.default.getDocumentLinks(doc.textDocument); + links = links || []; + let res = []; + for (let link of links) { + if (link.target) { + res.push(link); + } + else { + link = await languages_1.default.resolveDocumentLink(link); + res.push(link); + } + } + return links; + } + async openLink() { + let { document, position } = await workspace_1.default.getCurrentState(); + let links = await languages_1.default.getDocumentLinks(document); + if (!links || links.length == 0) + return false; + for (let link of links) { + if (position_1.positionInRange(position, link.range)) { + let { target } = link; + if (!target) { + link = await languages_1.default.resolveDocumentLink(link); + target = link.target; + } + if (target) { + await workspace_1.default.openResource(target); + return true; + } + return false; + } + } + return false; + } + async getCommands() { + let list = commands_1.default.commandList; + let res = []; + let { titles } = commands_1.default; + for (let item of list) { + res.push({ + id: item.id, + title: titles.get(item.id) || '' + }); + } + return res; + } + async selectFunction(inner, visualmode) { + let { nvim } = this; + let bufnr = await nvim.eval('bufnr("%")'); + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return; + let range; + if (visualmode) { + range = await workspace_1.default.getSelectedRange(visualmode, doc); + } + else { + let pos = await workspace_1.default.getCursorPosition(); + range = vscode_languageserver_protocol_1.Range.create(pos, pos); + } + let symbols = await this.getDocumentSymbols(doc); + if (!symbols || symbols.length === 0) { + workspace_1.default.showMessage('No symbols found', 'warning'); + return; + } + let properties = symbols.filter(s => s.kind == 'Property'); + symbols = symbols.filter(s => [ + 'Method', + 'Function', + ].includes(s.kind)); + let selectRange; + for (let sym of symbols.reverse()) { + if (sym.range && !object_1.equals(sym.range, range) && position_1.rangeInRange(range, sym.range)) { + selectRange = sym.range; + break; + } + } + if (!selectRange) { + for (let sym of properties) { + if (sym.range && !object_1.equals(sym.range, range) && position_1.rangeInRange(range, sym.range)) { + selectRange = sym.range; + break; + } + } + } + if (inner && selectRange) { + let { start, end } = selectRange; + let line = doc.getline(start.line + 1); + let endLine = doc.getline(end.line - 1); + selectRange = vscode_languageserver_protocol_1.Range.create(start.line + 1, line.match(/^\s*/)[0].length, end.line - 1, endLine.length); + } + if (selectRange) + await workspace_1.default.selectRange(selectRange); + } + async onCharacterType(ch, bufnr, insertLeave = false) { + if (!ch || string_1.isWord(ch) || !this.preferences.formatOnType) + return; + if (manager_3.default.getSession(bufnr) != null) + return; + let doc = workspace_1.default.getDocument(bufnr); + if (!doc || doc.paused) + return; + if (!languages_1.default.hasOnTypeProvider(ch, doc.textDocument)) + return; + let position = await workspace_1.default.getCursorPosition(); + let origLine = doc.getline(position.line); + let { changedtick, dirty } = doc; + if (dirty) { + doc.forceSync(); + await util_1.wait(50); + } + let pos = insertLeave ? { line: position.line + 1, character: 0 } : position; + try { + let edits = await languages_1.default.provideDocumentOnTypeEdits(ch, doc.textDocument, pos); + // changed by other process + if (doc.changedtick != changedtick) + return; + if (insertLeave) { + edits = edits.filter(edit => { + return edit.range.start.line < position.line + 1; + }); + } + if (edits && edits.length) { + await doc.applyEdits(this.nvim, edits); + let newLine = doc.getline(position.line); + if (newLine.length > origLine.length) { + let character = position.character + (newLine.length - origLine.length); + await workspace_1.default.moveTo(vscode_languageserver_protocol_1.Position.create(position.line, character)); + } + } + } + catch (e) { + if (!/timeout\s/.test(e.message)) { + console.error(`Error on formatOnType: ${e.message}`); // tslint:disable-line + } + } + } + async triggerSignatureHelp(document, position) { + if (this.signatureTokenSource) { + this.signatureTokenSource.cancel(); + this.signatureTokenSource = null; + } + let part = document.getline(position.line).slice(0, position.character); + if (part.endsWith(')')) { + this.signatureFactory.close(); + return; + } + let idx = Math.max(part.lastIndexOf(','), part.lastIndexOf('(')); + if (idx != -1) + position.character = idx + 1; + let tokenSource = this.signatureTokenSource = new vscode_languageserver_protocol_1.CancellationTokenSource(); + let token = tokenSource.token; + let timer = setTimeout(() => { + if (!token.isCancellationRequested) { + tokenSource.cancel(); + } + }, 3000); + let signatureHelp = await languages_1.default.getSignatureHelp(document.textDocument, position, token); + clearTimeout(timer); + if (token.isCancellationRequested || !signatureHelp || signatureHelp.signatures.length == 0) { + this.signatureFactory.close(); + return false; + } + let { activeParameter, activeSignature, signatures } = signatureHelp; + if (activeSignature) { + // make active first + let [active] = signatures.splice(activeSignature, 1); + if (active) + signatures.unshift(active); + } + if (this.preferences.signatureHelpTarget == 'float') { + let paramDoc = null; + let docs = signatures.reduce((p, c, idx) => { + let activeIndexes = null; + let nameIndex = c.label.indexOf('('); + if (idx == 0 && activeParameter != null) { + let active = c.parameters[activeParameter]; + if (active) { + let after = c.label.slice(nameIndex == -1 ? 0 : nameIndex); + paramDoc = active.documentation; + if (typeof active.label === 'string') { + let str = after.slice(0); + let ms = str.match(new RegExp('\\b' + active.label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '\\b')); + let index = ms ? ms.index : str.indexOf(active.label); + if (index != -1) { + activeIndexes = [ + index + nameIndex, + index + active.label.length + nameIndex + ]; + } + } + else { + activeIndexes = active.label; + } + } + } + if (activeIndexes == null) { + activeIndexes = [nameIndex + 1, nameIndex + 1]; + } + p.push({ + content: c.label, + filetype: document.filetype, + active: activeIndexes + }); + if (paramDoc) { + let content = typeof paramDoc === 'string' ? paramDoc : paramDoc.value; + if (content.trim().length) { + p.push({ + content, + filetype: vscode_languageserver_protocol_1.MarkupContent.is(c.documentation) ? 'markdown' : 'txt' + }); + } + } + if (idx == 0 && c.documentation) { + let { documentation } = c; + let content = typeof documentation === 'string' ? documentation : documentation.value; + if (content.trim().length) { + p.push({ + content, + filetype: vscode_languageserver_protocol_1.MarkupContent.is(c.documentation) ? 'markdown' : 'txt' + }); + } + } + return p; + }, []); + let offset = 0; + let session = manager_3.default.getSession(document.bufnr); + if (session && session.isActive) { + let { value } = session.placeholder; + if (value.indexOf('\n') == -1) + offset = value.length; + } + this.signaturePosition = position; + await this.signatureFactory.create(docs, true, offset); + // show float + } + else { + let columns = workspace_1.default.env.columns; + signatures = signatures.slice(0, workspace_1.default.env.cmdheight); + let signatureList = []; + for (let signature of signatures) { + let parts = []; + let { label } = signature; + label = label.replace(/\n/g, ' '); + if (label.length >= columns - 16) { + label = label.slice(0, columns - 16) + '...'; + } + let nameIndex = label.indexOf('('); + if (nameIndex == -1) { + parts = [{ text: label, type: 'Normal' }]; + } + else { + parts.push({ + text: label.slice(0, nameIndex), + type: 'Label' + }); + let after = label.slice(nameIndex); + if (signatureList.length == 0 && activeParameter != null) { + let active = signature.parameters[activeParameter]; + if (active) { + let start; + let end; + if (typeof active.label === 'string') { + let str = after.slice(0); + let ms = str.match(new RegExp('\\b' + active.label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '\\b')); + let idx = ms ? ms.index : str.indexOf(active.label); + if (idx == -1) { + parts.push({ text: after, type: 'Normal' }); + } + else { + start = idx; + end = idx + active.label.length; + } + } + else { + [start, end] = active.label; + start = start - nameIndex; + end = end - nameIndex; + } + if (start != null && end != null) { + parts.push({ text: after.slice(0, start), type: 'Normal' }); + parts.push({ text: after.slice(start, end), type: 'MoreMsg' }); + parts.push({ text: after.slice(end), type: 'Normal' }); + } + } + } + else { + parts.push({ + text: after, + type: 'Normal' + }); + } + } + signatureList.push(parts); + } + this.nvim.callTimer('coc#util#echo_signatures', [signatureList], true); + } + return true; + } + async showSignatureHelp() { + let buffer = await this.nvim.buffer; + let document = workspace_1.default.getDocument(buffer.id); + if (!document) + return false; + let position = await workspace_1.default.getCursorPosition(); + return await this.triggerSignatureHelp(document, position); + } + async handleLocations(definition, openCommand) { + if (!definition) + return; + let locations = Array.isArray(definition) ? definition : [definition]; + let len = locations.length; + if (len == 0) + return; + if (len == 1 && openCommand !== false) { + let location = definition[0]; + if (vscode_languageserver_protocol_1.LocationLink.is(definition[0])) { + let link = definition[0]; + location = vscode_languageserver_protocol_1.Location.create(link.targetUri, link.targetRange); + } + let { uri, range } = location; + await workspace_1.default.jumpTo(uri, range.start, openCommand); + } + else { + await workspace_1.default.showLocations(definition); + } + } + async getSelectionRanges() { + let { document, position } = await workspace_1.default.getCurrentState(); + let selectionRanges = await languages_1.default.getSelectionRanges(document, [position]); + if (selectionRanges && selectionRanges.length) + return selectionRanges; + return null; + } + async selectRange(visualmode, forward) { + let { nvim } = this; + let positions = []; + let bufnr = await nvim.call('bufnr', '%'); + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return; + if (!forward && (!this.selectionRange || !visualmode)) + return; + if (visualmode) { + let range = await workspace_1.default.getSelectedRange(visualmode, doc); + positions.push(range.start, range.end); + } + else { + let position = await workspace_1.default.getCursorPosition(); + positions.push(position); + } + if (!forward) { + let curr = vscode_languageserver_protocol_1.Range.create(positions[0], positions[1]); + let { selectionRange } = this; + while (selectionRange && selectionRange.parent) { + if (object_1.equals(selectionRange.parent.range, curr)) { + break; + } + selectionRange = selectionRange.parent; + } + if (selectionRange && selectionRange.parent) { + await workspace_1.default.selectRange(selectionRange.range); + } + return; + } + let selectionRanges = await languages_1.default.getSelectionRanges(doc.textDocument, positions); + if (selectionRanges == null) { + workspace_1.default.showMessage('Selection range provider not found for current document', 'warning'); + return; + } + if (!selectionRanges || selectionRanges.length == 0) { + workspace_1.default.showMessage('No selection range found', 'warning'); + return; + } + let mode = await nvim.eval('mode()'); + if (mode != 'n') + await nvim.eval(`feedkeys("\\", 'in')`); + let selectionRange; + if (selectionRanges.length == 1) { + selectionRange = selectionRanges[0]; + } + else if (positions.length > 1) { + let r = vscode_languageserver_protocol_1.Range.create(positions[0], positions[1]); + selectionRange = selectionRanges[0]; + while (selectionRange) { + if (object_1.equals(r, selectionRange.range)) { + selectionRange = selectionRange.parent; + continue; + } + if (position_1.positionInRange(positions[1], selectionRange.range) == 0) { + break; + } + selectionRange = selectionRange.parent; + } + } + if (!selectionRange) + return; + this.selectionRange = selectionRanges[0]; + await workspace_1.default.selectRange(selectionRange.range); + } + async codeActionRange(start, end, only) { + let listArgs = ['--normal', '--number-select', 'actions', `-start`, start + '', `-end`, end + '']; + if (only == 'quickfix') { + listArgs.push('-quickfix'); + } + else if (only == 'source') { + listArgs.push('-source'); + } + await manager_2.default.start(listArgs); + } + /** + * Refactor of current symbol + */ + async doRefactor() { + let [bufnr, cursor, filetype] = await this.nvim.eval('[bufnr("%"),coc#util#cursor(),&filetype]'); + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return; + let position = { line: cursor[0], character: cursor[1] }; + let res = await languages_1.default.prepareRename(doc.textDocument, position); + if (res === false) { + workspace_1.default.showMessage('Invalid position for rename', 'error'); + return; + } + let edit = await languages_1.default.provideRenameEdits(doc.textDocument, position, 'newname'); + if (!edit) { + workspace_1.default.showMessage('Empty workspaceEdit from server', 'warning'); + return; + } + let refactor = await refactor_1.default.createFromWorkspaceEdit(edit, filetype); + if (!refactor.buffer) + return; + this.refactorMap.set(refactor.buffer.id, refactor); + } + async saveRefactor(bufnr) { + let refactor = this.refactorMap.get(bufnr); + if (refactor) { + await refactor.saveRefactor(); + } + } + async search(args) { + let cwd = await this.nvim.call('getcwd'); + let refactor = new refactor_1.default(); + await refactor.createRefactorBuffer(); + if (!refactor.buffer) + return; + this.refactorMap.set(refactor.buffer.id, refactor); + let search = new search_1.default(this.nvim); + search.run(args, cwd, refactor).logError(); + } + async previewHover(hovers) { + let lines = []; + let target = this.preferences.hoverTarget; + let i = 0; + let docs = []; + for (let hover of hovers) { + let { contents } = hover; + if (i > 0) + lines.push('---'); + if (Array.isArray(contents)) { + for (let item of contents) { + if (typeof item === 'string') { + if (item.trim().length) { + lines.push(...item.split('\n')); + docs.push({ content: item, filetype: 'markdown' }); + } + } + else { + let content = item.value.trim(); + if (target == 'preview') { + content = '``` ' + item.language + '\n' + content + '\n```'; + } + lines.push(...content.trim().split('\n')); + docs.push({ filetype: item.language, content: item.value }); + } + } + } + else if (typeof contents == 'string') { + lines.push(...contents.split('\n')); + docs.push({ content: contents, filetype: 'markdown' }); + } + else if (vscode_languageserver_protocol_1.MarkedString.is(contents)) { // tslint:disable-line + let content = contents.value.trim(); + if (target == 'preview') { + content = '``` ' + contents.language + '\n' + content + '\n```'; + } + lines.push(...content.split('\n')); + docs.push({ filetype: contents.language, content: contents.value }); + } + else if (vscode_languageserver_protocol_1.MarkupContent.is(contents)) { + lines.push(...contents.value.split('\n')); + docs.push({ filetype: contents.kind == 'markdown' ? 'markdown' : 'txt', content: contents.value }); + } + i++; + } + if (target == 'echo') { + const msg = lines.join('\n').trim(); + if (msg.length) { + await this.nvim.call('coc#util#echo_hover', msg); + } + } + else if (target == 'float') { + manager_1.default.hideFloat(); + await this.hoverFactory.create(docs); + } + else { + this.documentLines = lines; + let arr = await this.nvim.call('getcurpos'); + this.hoverPosition = [workspace_1.default.bufnr, arr[1], arr[2]]; + await this.nvim.command(`pedit coc://document`); + } + } + getPreferences() { + let config = workspace_1.default.getConfiguration('coc.preferences'); + let signatureConfig = workspace_1.default.getConfiguration('signature'); + let hoverTarget = config.get('hoverTarget', 'float'); + if (hoverTarget == 'float' && !workspace_1.default.env.floating && !workspace_1.default.env.textprop) { + hoverTarget = 'preview'; + } + let signatureHelpTarget = signatureConfig.get('target', 'float'); + if (signatureHelpTarget == 'float' && !workspace_1.default.env.floating && !workspace_1.default.env.textprop) { + signatureHelpTarget = 'echo'; + } + this.labels = workspace_1.default.getConfiguration('suggest').get('completionItemKindLabels', {}); + this.preferences = { + hoverTarget, + signatureHelpTarget, + signatureMaxHeight: signatureConfig.get('maxWindowHeight', 8), + triggerSignatureHelp: signatureConfig.get('enable', true), + triggerSignatureWait: signatureConfig.get('triggerSignatureWait', 50), + signaturePreferAbove: signatureConfig.get('preferShownAbove', true), + signatureFloatMaxWidth: signatureConfig.get('floatMaxWidth', 80), + signatureHideOnChange: signatureConfig.get('hideOnTextChange', false), + formatOnType: config.get('formatOnType', false), + bracketEnterImprove: config.get('bracketEnterImprove', true), + previewAutoClose: config.get('previewAutoClose', false), + currentFunctionSymbolAutoUpdate: config.get('currentFunctionSymbolAutoUpdate', false), + }; + } + onEmptyLocation(name, location) { + if (location == null) { + workspace_1.default.showMessage(`${name} provider not found for current document`, 'warning'); + } + else if (location.length == 0) { + workspace_1.default.showMessage(`${name} not found`, 'warning'); + } + } + dispose() { + this.colors.dispose(); + util_1.disposeAll(this.disposables); + } +} +exports.default = Handler; +function getPreviousContainer(containerName, symbols) { + if (!symbols.length) + return null; + let i = symbols.length - 1; + let last = symbols[i]; + if (last.text == containerName) { + return last; + } + while (i >= 0) { + let sym = symbols[i]; + if (sym.text == containerName) { + return sym; + } + i--; + } + return null; +} +function sortDocumentSymbols(a, b) { + let ra = a.selectionRange; + let rb = b.selectionRange; + if (ra.start.line < rb.start.line) { + return -1; + } + if (ra.start.line > rb.start.line) { + return 1; + } + return ra.start.character - rb.start.character; +} +function addDoucmentSymbol(res, sym, level) { + let { name, selectionRange, kind, children, range } = sym; + let { start } = selectionRange; + res.push({ + col: start.character + 1, + lnum: start.line + 1, + text: name, + level, + kind: convert_1.getSymbolKind(kind), + range, + selectionRange + }); + if (children && children.length) { + children.sort(sortDocumentSymbols); + for (let sym of children) { + addDoucmentSymbol(res, sym, level + 1); + } + } +} +function sortSymbolInformations(a, b) { + let sa = a.location.range.start; + let sb = b.location.range.start; + let d = sa.line - sb.line; + return d == 0 ? sa.character - sb.character : d; +} +function isDocumentSymbol(a) { + return a && !a.hasOwnProperty('location'); +} +function isEmpty(location) { + if (!location) + return true; + if (Array.isArray(location) && location.length == 0) + return true; + return false; +} +function isDocumentSymbols(a) { + return isDocumentSymbol(a[0]); +} +//# sourceMappingURL=index.js.map + +/***/ }), +/* 400 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const debounce_1 = tslib_1.__importDefault(__webpack_require__(176)); +const commands_1 = tslib_1.__importDefault(__webpack_require__(232)); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const services_1 = tslib_1.__importDefault(__webpack_require__(351)); +const util_1 = __webpack_require__(174); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('codelens'); +class CodeLensManager { + constructor(nvim) { + this.nvim = nvim; + this.fetching = new Set(); + this.disposables = []; + this.codeLensMap = new Map(); + this.init().catch(e => { + logger.error(e.message); + }); + } + async init() { + this.setConfiguration(); + if (!this.enabled) + return; + this.srcId = workspace_1.default.createNameSpace('coc-codelens') || 1080; + services_1.default.on('ready', async (id) => { + let service = services_1.default.getService(id); + let doc = workspace_1.default.getDocument(workspace_1.default.bufnr); + if (!doc) + return; + if (workspace_1.default.match(service.selector, doc.textDocument)) { + this.resolveCodeLens.clear(); + await util_1.wait(2000); + await this.fetchDocumentCodeLenes(); + } + }); + let timer; + workspace_1.default.onDidChangeTextDocument(async (e) => { + let doc = workspace_1.default.getDocument(e.textDocument.uri); + if (doc && doc.bufnr == workspace_1.default.bufnr) { + if (timer) + clearTimeout(timer); + setTimeout(async () => { + await this.fetchDocumentCodeLenes(); + }, 100); + } + }, null, this.disposables); + workspace_1.default.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('codelens')) { + this.setConfiguration(); + } + }, null, this.disposables); + events_1.default.on(['TextChanged', 'TextChangedI'], async () => { + this.resolveCodeLens.clear(); + }, null, this.disposables); + events_1.default.on('CursorMoved', () => { + this.resolveCodeLens(); + }, null, this.disposables); + events_1.default.on('BufUnload', bufnr => { + let buf = this.nvim.createBuffer(bufnr); + if (this.nvim.hasFunction('nvim_create_namespace')) { + buf.clearNamespace(this.srcId); + } + else { + buf.clearHighlight({ srcId: this.srcId }); + } + }, null, this.disposables); + events_1.default.on('BufEnter', bufnr => { + setTimeout(async () => { + if (workspace_1.default.bufnr == bufnr) { + await this.fetchDocumentCodeLenes(); + } + }, 100); + }, null, this.disposables); + events_1.default.on('InsertLeave', async () => { + let { bufnr } = workspace_1.default; + let info = this.codeLensMap.get(bufnr); + if (info && info.version != this.version) { + this.resolveCodeLens.clear(); + await util_1.wait(50); + await this.fetchDocumentCodeLenes(); + } + }, null, this.disposables); + this.resolveCodeLens = debounce_1.default(() => { + this._resolveCodeLenes().catch(e => { + logger.error(e); + }); + }, 200); + } + setConfiguration() { + let { nvim } = this; + let config = workspace_1.default.getConfiguration('coc.preferences.codeLens'); + if (Object.keys(config).length == 0) { + config = workspace_1.default.getConfiguration('codeLens'); + } + this.separator = config.get('separator', '‣'); + this.enabled = nvim.hasFunction('nvim_buf_set_virtual_text') && config.get('enable', true); + } + async fetchDocumentCodeLenes(retry = 0) { + let doc = workspace_1.default.getDocument(workspace_1.default.bufnr); + if (!doc) + return; + let { uri, version, bufnr } = doc; + let document = workspace_1.default.getDocument(uri); + if (!this.validDocument(document)) + return; + if (this.fetching.has(bufnr)) + return; + this.fetching.add(bufnr); + try { + let codeLenes = await languages_1.default.getCodeLens(document.textDocument); + if (codeLenes && codeLenes.length > 0) { + this.codeLensMap.set(document.bufnr, { codeLenes, version }); + if (workspace_1.default.bufnr == document.bufnr) { + this.resolveCodeLens.clear(); + await this._resolveCodeLenes(true); + } + } + this.fetching.delete(bufnr); + } + catch (e) { + this.fetching.delete(bufnr); + logger.error(e); + if (/timeout/.test(e.message) && retry < 5) { + this.fetchDocumentCodeLenes(retry + 1); // tslint:disable-line + } + } + } + async setVirtualText(buffer, codeLenes) { + let list = new Map(); + for (let codeLens of codeLenes) { + let { range, command } = codeLens; + if (!command) + continue; + let { line } = range.start; + if (list.has(line)) { + list.get(line).push(codeLens); + } + else { + list.set(line, [codeLens]); + } + } + for (let lnum of list.keys()) { + let codeLenes = list.get(lnum); + let commands = codeLenes.map(codeLens => codeLens.command); + commands = commands.filter(c => c && c.title); + let chunks = commands.map(c => [c.title + ' ', 'CocCodeLens']); + chunks.unshift([`${this.separator} `, 'CocCodeLens']); + await buffer.setVirtualText(this.srcId, lnum, chunks); + } + } + async _resolveCodeLenes(clear = false) { + let { nvim } = this; + let { bufnr } = workspace_1.default; + let { codeLenes, version } = this.codeLensMap.get(bufnr) || {}; + if (workspace_1.default.insertMode) + return; + if (codeLenes && codeLenes.length) { + // resolve codeLens of current window + let start = await nvim.call('line', 'w0'); + let end = await nvim.call('line', 'w$'); + if (version && this.version != version) + return; + if (end >= start) { + codeLenes = codeLenes.filter(o => { + let lnum = o.range.start.line + 1; + return lnum >= start && lnum <= end; + }); + if (codeLenes.length) { + await Promise.all(codeLenes.map(codeLens => { + return languages_1.default.resolveCodeLens(codeLens); + })); + } + } + else { + codeLenes = null; + } + } + nvim.pauseNotification(); + let doc = workspace_1.default.getDocument(bufnr); + if (doc && clear) { + doc.clearMatchIds([this.srcId]); + } + if (codeLenes && codeLenes.length) + await this.setVirtualText(doc.buffer, codeLenes); + nvim.resumeNotification().catch(_e => { + // noop + }); + } + async doAction() { + let { nvim } = this; + let bufnr = await nvim.call('bufnr', '%'); + let line = await nvim.call('line', '.') - 1; + let { codeLenes } = this.codeLensMap.get(bufnr); + if (!codeLenes || codeLenes.length == 0) { + workspace_1.default.showMessage('No codeLenes available', 'warning'); + return; + } + let list = new Map(); + for (let codeLens of codeLenes) { + let { range, command } = codeLens; + if (!command) + continue; + let { line } = range.start; + if (list.has(line)) { + list.get(line).push(codeLens); + } + else { + list.set(line, [codeLens]); + } + } + let current = null; + for (let i = line; i >= 0; i--) { + if (list.has(i)) { + current = list.get(i); + break; + } + } + if (!current) { + workspace_1.default.showMessage('No codeLenes available', 'warning'); + return; + } + let commands = current.map(o => o.command); + commands = commands.filter(c => c.command != null && c.command != ''); + if (commands.length == 0) { + workspace_1.default.showMessage('CodeLenes command not found', 'warning'); + } + else if (commands.length == 1) { + commands_1.default.execute(commands[0]); + } + else { + let res = await workspace_1.default.showQuickpick(commands.map(c => c.title)); + if (res == -1) + return; + commands_1.default.execute(commands[res]); + } + } + validDocument(doc) { + if (!doc) + return false; + if (doc.schema != 'file' || doc.buftype != '') + return false; + return true; + } + get version() { + let doc = workspace_1.default.getDocument(workspace_1.default.bufnr); + return doc ? doc.version : 0; + } + dispose() { + if (this.resolveCodeLens) { + this.resolveCodeLens.clear(); + } + util_1.disposeAll(this.disposables); + } +} +exports.default = CodeLensManager; +//# sourceMappingURL=codelens.js.map + +/***/ }), +/* 401 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const debounce_1 = tslib_1.__importDefault(__webpack_require__(176)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const util_1 = __webpack_require__(174); +const object_1 = __webpack_require__(190); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const highlighter_1 = tslib_1.__importStar(__webpack_require__(402)); +const logger = __webpack_require__(186)('colors'); +class Colors { + constructor(nvim) { + this.nvim = nvim; + this._enabled = true; + this.srcId = 1090; + this.disposables = []; + this.highlighters = new Map(); + this.highlightCurrent = debounce_1.default(() => { + this._highlightCurrent().catch(e => { + logger.error('highlight error:', e.stack); + }); + }, 200); + let config = workspace_1.default.getConfiguration('coc.preferences'); + this._enabled = config.get('colorSupport', true); + this.srcId = workspace_1.default.createNameSpace('coc-colors'); + let timer = setTimeout(async () => { + // wait for extensions + await this._highlightCurrent(); + }, 2000); + this.disposables.push(vscode_languageserver_protocol_1.Disposable.create(() => { + clearTimeout(timer); + })); + events_1.default.on('BufEnter', async () => { + if (global.hasOwnProperty('__TEST__')) + return; + this.highlightCurrent(); + }, null, this.disposables); + events_1.default.on('InsertLeave', async () => { + this.highlightCurrent(); + }, null, this.disposables); + events_1.default.on('BufUnload', async (bufnr) => { + let highlighter = this.highlighters.get(bufnr); + if (highlighter) { + highlighter.dispose(); + this.highlighters.delete(bufnr); + } + }, null, this.disposables); + workspace_1.default.onDidChangeTextDocument(async ({ textDocument, contentChanges }) => { + if (workspace_1.default.insertMode) + return; + let doc = workspace_1.default.getDocument(textDocument.uri); + if (doc && doc.bufnr == workspace_1.default.bufnr) { + let { range, text } = contentChanges[0]; + await util_1.wait(50); + await this.highlightColors(doc); + } + }, null, this.disposables); + workspace_1.default.onDidChangeConfiguration(async (e) => { + if (e.affectsConfiguration('coc.preferences.colorSupport')) { + let config = workspace_1.default.getConfiguration('coc.preferences'); + this._enabled = config.get('colorSupport', true); + } + }, null, this.disposables); + } + async _highlightCurrent() { + if (!this.enabled) + return; + let { bufnr } = workspace_1.default; + let doc = workspace_1.default.getDocument(bufnr); + if (doc) + await this.highlightColors(doc); + } + async highlightColors(document, force = false) { + if (!this.enabled) + return; + if (['help', 'terminal', 'quickfix'].indexOf(document.buftype) !== -1) + return; + let { version, changedtick } = document; + let highlighter = this.getHighlighter(document.bufnr); + if (!highlighter || (highlighter.version == version && !force)) + return; + let colors; + try { + colors = await languages_1.default.provideDocumentColors(document.textDocument); + colors = colors || []; + if (changedtick != document.changedtick) + return; + if (!force && object_1.equals(highlighter.colors, colors)) + return; + await highlighter.highlight(colors); + } + catch (e) { + logger.error(e.stack); + } + } + async pickPresentation() { + let info = await this.currentColorInfomation(); + if (!info) + return workspace_1.default.showMessage('Color not found at current position', 'warning'); + let document = await workspace_1.default.document; + let presentations = await languages_1.default.provideColorPresentations(info, document.textDocument); + if (!presentations || presentations.length == 0) + return; + let res = await workspace_1.default.showQuickpick(presentations.map(o => o.label), 'choose a color presentation:'); + if (res == -1) + return; + let presentation = presentations[res]; + let { textEdit, additionalTextEdits, label } = presentation; + if (!textEdit) + textEdit = { range: info.range, newText: label }; + await document.applyEdits(this.nvim, [textEdit]); + if (additionalTextEdits) { + await document.applyEdits(this.nvim, additionalTextEdits); + } + } + async pickColor() { + let info = await this.currentColorInfomation(); + if (!info) + return workspace_1.default.showMessage('Color not found at current position', 'warning'); + let { color } = info; + let colorArr = [(color.red * 255).toFixed(0), (color.green * 255).toFixed(0), (color.blue * 255).toFixed(0)]; + let res = await this.nvim.call('coc#util#pick_color', [colorArr]); + if (res === false) { + // cancel + return; + } + if (!res || res.length != 3) { + workspace_1.default.showMessage('Failed to get color', 'warning'); + return; + } + let hex = highlighter_1.toHexString({ + red: (res[0] / 65535), + green: (res[1] / 65535), + blue: (res[2] / 65535), + alpha: 1 + }); + let document = await workspace_1.default.document; + await document.applyEdits(this.nvim, [{ + range: info.range, + newText: `#${hex}` + }]); + } + get enabled() { + return this._enabled; + } + clearHighlight(bufnr) { + let highlighter = this.highlighters.get(bufnr); + if (!highlighter) + return; + highlighter.clearHighlight(); + } + hasColor(bufnr) { + let highlighter = this.highlighters.get(bufnr); + if (!highlighter) + return false; + return highlighter.hasColor(); + } + hasColorAtPostion(bufnr, position) { + let highlighter = this.highlighters.get(bufnr); + if (!highlighter) + return false; + return highlighter.hasColorAtPostion(position); + } + dispose() { + this.highlightCurrent.clear(); + for (let highlighter of this.highlighters.values()) { + highlighter.dispose(); + } + util_1.disposeAll(this.disposables); + } + getHighlighter(bufnr) { + let obj = this.highlighters.get(bufnr); + if (obj) + return obj; + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return null; + obj = new highlighter_1.default(this.nvim, doc, this.srcId); + this.highlighters.set(bufnr, obj); + return obj; + } + async currentColorInfomation() { + let bufnr = await this.nvim.call('bufnr', '%'); + let highlighter = this.highlighters.get(bufnr); + if (!highlighter) + return; + let position = await workspace_1.default.getCursorPosition(); + for (let info of highlighter.colors) { + let { range } = info; + let { start, end } = range; + if (position.line == start.line + && position.character >= start.character + && position.character <= end.character) { + return info; + } + } + return null; + } +} +exports.default = Colors; +//# sourceMappingURL=colors.js.map + +/***/ }), +/* 402 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const array_1 = __webpack_require__(212); +const object_1 = __webpack_require__(190); +const position_1 = __webpack_require__(213); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('highlighter'); +const usedColors = new Set(); +class Highlighter { + constructor(nvim, document, srcId) { + this.nvim = nvim; + this.document = document; + this.srcId = srcId; + this.matchIds = new Set(); + this._colors = []; + } + get version() { + return this._version; + } + get bufnr() { + return this.document.bufnr; + } + get colors() { + return this._colors; + } + hasColor() { + return this._colors.length > 0; + } + async highlight(colors) { + colors = colors || []; + this._version = this.document.version; + if (workspace_1.default.isVim + && !workspace_1.default.env.textprop + && workspace_1.default.bufnr != this.document.bufnr) + return; + if (colors.length == 0) + return this.clearHighlight(); + this._colors = colors; + let groups = array_1.group(colors, 100); + let cleared = false; + for (let colors of groups) { + this.nvim.pauseNotification(); + if (!cleared) { + cleared = true; + this.document.clearMatchIds(this.matchIds); + this.matchIds.clear(); + } + let colorRanges = this.getColorRanges(colors); + this.addColors(colors.map(o => o.color)); + for (let o of colorRanges) { + this.addHighlight(o.ranges, o.color); + } + this.nvim.command('redraw', true); + await this.nvim.resumeNotification(); + } + } + addHighlight(ranges, color) { + let { red, green, blue } = toHexColor(color); + let hlGroup = `BG${toHexString(color)}`; + let ids = this.document.highlightRanges(ranges, hlGroup, this.srcId); + for (let id of ids) { + this.matchIds.add(id); + } + } + addColors(colors) { + let commands = []; + for (let color of colors) { + let hex = toHexString(color); + if (!usedColors.has(hex)) { + commands.push(`hi BG${hex} guibg=#${hex} guifg=#${isDark(color) ? 'ffffff' : '000000'}`); + usedColors.add(hex); + } + } + this.nvim.command(commands.join('|'), true); + } + clearHighlight() { + let { matchIds } = this; + if (!this.document) + return; + this.matchIds.clear(); + this.document.clearMatchIds(matchIds); + this._colors = []; + } + getColorRanges(infos) { + let res = []; + for (let info of infos) { + let { color, range } = info; + let idx = res.findIndex(o => { + return object_1.equals(toHexColor(o.color), toHexColor(color)); + }); + if (idx == -1) { + res.push({ + color, + ranges: [range] + }); + } + else { + let r = res[idx]; + r.ranges.push(range); + } + } + return res; + } + hasColorAtPostion(position) { + let { colors } = this; + return colors.some(o => position_1.positionInRange(position, o.range) == 0); + } + dispose() { + this.clearHighlight(); + this.document = null; + } +} +exports.default = Highlighter; +function toHexString(color) { + let c = toHexColor(color); + return `${pad(c.red.toString(16))}${pad(c.green.toString(16))}${pad(c.blue.toString(16))}`; +} +exports.toHexString = toHexString; +function pad(str) { + return str.length == 1 ? `0${str}` : str; +} +function toHexColor(color) { + let { red, green, blue } = color; + return { + red: Math.round(red * 255), + green: Math.round(green * 255), + blue: Math.round(blue * 255) + }; +} +function isDark(color) { + // http://www.w3.org/TR/WCAG20/#relativeluminancedef + let rgb = [color.red, color.green, color.blue]; + let lum = []; + for (let i = 0; i < rgb.length; i++) { + let chan = rgb[i]; + lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4); + } + let luma = 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; + return luma <= 0.5; +} +//# sourceMappingURL=highlighter.js.map + +/***/ }), +/* 403 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const languages_1 = tslib_1.__importDefault(__webpack_require__(315)); +const vscode_languageserver_protocol_1 = __webpack_require__(149); +const util_1 = __webpack_require__(174); +const logger = __webpack_require__(186)('documentHighlight'); +class DocumentHighlighter { + constructor(nvim, colors) { + this.nvim = nvim; + this.colors = colors; + this.disposables = []; + this.matchIds = new Set(); + events_1.default.on('BufWinEnter', () => { + this.clearHighlight(); + }, null, this.disposables); + events_1.default.on(['CursorMoved', 'CursorMovedI'], () => { + this.cursorMoveTs = Date.now(); + }, null, this.disposables); + events_1.default.on('InsertEnter', () => { + this.clearHighlight(); + }, null, this.disposables); + } + // clear matchIds of current window + clearHighlight() { + let { matchIds } = this; + let { nvim } = workspace_1.default; + if (matchIds.size == 0) + return; + nvim.pauseNotification(); + nvim.call('coc#util#clearmatches', [Array.from(matchIds)], true); + nvim.command('redraw', true); + nvim.resumeNotification(false, true).catch(_e => { + // noop + }); + this.matchIds.clear(); + } + async highlight(bufnr) { + let { nvim } = this; + let document = workspace_1.default.getDocument(bufnr); + let highlights = await this.getHighlights(document); + if (!highlights || highlights.length == 0) { + this.clearHighlight(); + return; + } + if (workspace_1.default.bufnr != bufnr) + return; + nvim.pauseNotification(); + this.clearHighlight(); + let groups = {}; + for (let hl of highlights) { + let hlGroup = hl.kind == vscode_languageserver_protocol_1.DocumentHighlightKind.Text + ? 'CocHighlightText' + : hl.kind == vscode_languageserver_protocol_1.DocumentHighlightKind.Read ? 'CocHighlightRead' : 'CocHighlightWrite'; + groups[hlGroup] = groups[hlGroup] || []; + groups[hlGroup].push(hl.range); + } + for (let hlGroup of Object.keys(groups)) { + let ids = document.matchAddRanges(groups[hlGroup], hlGroup, -1); + for (let id of ids) { + this.matchIds.add(id); + } + } + this.nvim.command('redraw', true); + await this.nvim.resumeNotification(false, true); + } + async getHighlights(document) { + if (!document) + return null; + let ts = Date.now(); + let { bufnr } = document; + let position = await workspace_1.default.getCursorPosition(); + let line = document.getline(position.line); + let ch = line[position.character]; + if (!ch || !document.isWord(ch) || this.colors.hasColorAtPostion(bufnr, position)) + return null; + try { + let highlights = await languages_1.default.getDocumentHighLight(document.textDocument, position); + if (workspace_1.default.bufnr != document.bufnr || (this.cursorMoveTs && this.cursorMoveTs > ts)) { + return null; + } + return highlights; + } + catch (_e) { + return null; + } + } + dispose() { + util_1.disposeAll(this.disposables); + } +} +exports.default = DocumentHighlighter; +//# sourceMappingURL=documentHighlight.js.map + +/***/ }), +/* 404 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fast_diff_1 = tslib_1.__importDefault(__webpack_require__(209)); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const vscode_languageserver_types_1 = __webpack_require__(161); +const vscode_uri_1 = __webpack_require__(180); +const commands_1 = tslib_1.__importDefault(__webpack_require__(232)); +const highligher_1 = tslib_1.__importDefault(__webpack_require__(349)); +const util_1 = __webpack_require__(174); +const fs_1 = __webpack_require__(200); +const object_1 = __webpack_require__(190); +const string_1 = __webpack_require__(210); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('refactor'); +// cases: buffer change event +const name = '__coc_refactor__'; +const separator = '\u3000'; +let refactorId = 0; +class Refactor { + constructor() { + this.changing = false; + this.matchIds = new Set(); + this.disposables = []; + this.fileItems = []; + this.nvim = workspace_1.default.nvim; + if (workspace_1.default.isNvim && this.nvim.hasFunction('nvim_buf_set_virtual_text')) { + this.srcId = workspace_1.default.createNameSpace('coc-refactor'); + } + let config = workspace_1.default.getConfiguration('refactor'); + this.config = { + afterContext: config.get('afterContext', 3), + beforeContext: config.get('beforeContext', 3), + openCommand: config.get('openCommand', 'edit') + }; + } + get buffer() { + if (!this.bufnr) + return null; + return this.nvim.createBuffer(this.bufnr); + } + get document() { + if (!this.bufnr) + return null; + return workspace_1.default.getDocument(this.bufnr); + } + async valid() { + let { buffer } = this; + if (!buffer) + return false; + return await buffer.valid; + } + /** + * Start refactor from workspaceEdit + */ + async fromWorkspaceEdit(edit, filetype) { + let items = await this.getItemsFromWorkspaceEdit(edit); + await this.createRefactorBuffer(filetype); + await this.addFileItems(items); + } + async fromLines(lines) { + let buf = await this.createRefactorBuffer(); + await buf.setLines(lines, { start: 0, end: -1, strictIndexing: false }); + } + /** + * Create initialized refactor buffer + */ + async createRefactorBuffer(filetype) { + let { nvim } = this; + let [fromWinid, cwd] = await nvim.eval('[win_getid(),getcwd()]'); + let { openCommand } = this.config; + nvim.pauseNotification(); + nvim.command(`${openCommand} ${name}${refactorId++}`, true); + nvim.command(`setl buftype=acwrite nobuflisted bufhidden=wipe nofen wrap conceallevel=2 concealcursor=n`, true); + nvim.command(`setl undolevels=-1 nolist nospell noswapfile foldmethod=expr foldexpr=coc#util#refactor_foldlevel(v:lnum)`, true); + nvim.command(`setl foldtext=coc#util#refactor_fold_text(v:foldstart)`, true); + nvim.call('setline', [1, ['Save current buffer to make changes', separator]], true); + nvim.call('matchadd', ['Comment', '\\%1l'], true); + nvim.call('matchadd', ['Conceal', '^\\%u3000'], true); + nvim.call('matchadd', ['Label', '^\\%u3000\\zs\\S\\+'], true); + nvim.command('setl nomod', true); + if (filetype) + nvim.command(`runtime! syntax/${filetype}.vim`, true); + nvim.call('coc#util#do_autocmd', ['CocRefactorOpen'], true); + workspace_1.default.registerLocalKeymap('n', '', this.splitOpen.bind(this), true); + let [, err] = await nvim.resumeNotification(); + if (err) { + logger.error(err); + workspace_1.default.showMessage(`Error on open refactor window: ${err}`, 'error'); + return; + } + let [bufnr, win] = await nvim.eval('[bufnr("%"),win_getid()]'); + this.fromWinid = fromWinid; + this.winid = win; + this.bufnr = bufnr; + this.cwd = cwd; + await this.ensureDocument(); + workspace_1.default.onDidChangeTextDocument(this.onBufferChange, this, this.disposables); + return nvim.createBuffer(bufnr); + } + /** + * Add FileItem to refactor buffer. + */ + async addFileItems(items) { + let { document } = this; + if (!document) + return; + if (document.dirty) + document.forceSync(); + for (let item of items) { + let fileItem = this.fileItems.find(o => o.filepath == item.filepath); + if (fileItem) { + fileItem.ranges.push(...item.ranges); + } + else { + this.fileItems.push(item); + } + } + let count = document.lineCount; + let highligher = new highligher_1.default(); + let hlRanges = []; + for (let item of items) { + for (let range of item.ranges) { + highligher.addLine(separator); + highligher.addLine(separator); + range.lnum = count + highligher.length; + highligher.addText(`${this.cwd && fs_1.isParentFolder(this.cwd, item.filepath) ? path_1.default.relative(this.cwd, item.filepath) : item.filepath}`); + // white spaces for conceal texts + let n = String(range.start + 1).length + String(range.end).length + 4; + if (!this.srcId) + highligher.addText(' '.repeat(n)); + let base = 0 - highligher.length - count; + if (range.highlights) { + hlRanges.push(...range.highlights.map(r => adjustRange(r, base))); + } + let { lines } = range; + if (!lines) { + lines = await this.getLines(item.filepath, range.start, range.end); + range.lines = lines; + } + highligher.addLines(lines); + } + } + let { nvim, buffer } = this; + this.version = document.version; + nvim.pauseNotification(); + highligher.render(buffer, count); + this.highlightLineNr(); + buffer.setOption('modified', false, true); + buffer.setOption('undolevels', 1000, true); + if (count == 2 && hlRanges.length) { + let pos = hlRanges[0].start; + nvim.call('coc#util#jumpTo', [pos.line, pos.character], true); + } + let [, err] = await nvim.resumeNotification(); + if (err) { + logger.error(err); + return; + } + await document._fetchContent(); + document.forceSync(); + await commands_1.default.executeCommand('editor.action.addRanges', hlRanges); + } + async ensureDocument() { + let { bufnr } = this; + let doc = workspace_1.default.getDocument(bufnr); + if (doc) + return; + return new Promise((resolve, reject) => { + let timer = setTimeout(() => { + reject(new Error('Document create timeout after 2s.')); + }, 2000); + let disposable = workspace_1.default.onDidOpenTextDocument(({ uri }) => { + let doc = workspace_1.default.getDocument(uri); + if (doc.bufnr == bufnr) { + clearTimeout(timer); + disposable.dispose(); + resolve(); + } + }); + }); + } + /** + * Use conceal to add lineNr + */ + highlightLineNr() { + let { fileItems, nvim, winid, srcId, bufnr } = this; + let info = {}; + if (srcId) { + nvim.call('nvim_buf_clear_namespace', [bufnr, srcId, 0, -1], true); + for (let item of fileItems) { + for (let range of item.ranges) { + let text = `${range.start + 1}:${range.end}`; + info[range.lnum] = [range.start + 1, range.end]; + nvim.call('nvim_buf_set_virtual_text', [bufnr, srcId, range.lnum - 1, [[text, 'LineNr']], {}], true); + } + } + } + else { + if (this.matchIds.size) { + nvim.call('coc#util#clearmatches', [Array.from(this.matchIds), this.winid], true); + this.matchIds.clear(); + } + let id = 2000; + for (let item of fileItems) { + let filename = `${this.cwd ? path_1.default.relative(this.cwd, item.filepath) : item.filepath}`; + let col = string_1.byteLength(filename) + 1; + for (let range of item.ranges) { + let text = `:${range.start + 1}:${range.end}`; + for (let i = 0; i < text.length; i++) { + let ch = text[i]; + this.matchIds.add(id); + info[range.lnum] = [range.start + 1, range.end]; + nvim.call('matchaddpos', ['Conceal', [[range.lnum, col + i]], 99, id, { conceal: ch, window: winid }], true); + id++; + } + } + } + } + this.buffer.setVar('line_infos', info, true); + } + /** + * Current changed file ranges + */ + async getFileChanges() { + let changes = []; + let { document } = this; + if (!document) + return; + let lines = await document.buffer.lines; + lines.push(separator); + // current lines + let arr = []; + let fsPath; + let lnum; + for (let i = 0; i < lines.length; i++) { + let line = lines[i]; + if (line.startsWith(separator)) { + if (fsPath) { + changes.push({ + filepath: fsPath, + lines: arr, + lnum + }); + fsPath = undefined; + arr = []; + } + if (line.length > 1) { + let ms = line.match(/^\u3000(.*)/); + if (ms) { + let filepath = ms[1].replace(/\s+$/, ''); + fsPath = !path_1.default.isAbsolute(filepath) && this.cwd ? path_1.default.join(this.cwd, filepath) : filepath; + lnum = i + 1; + arr = []; + } + } + } + else { + arr.push(line); + } + } + return changes; + } + /** + * Save changes to files, return false when no change made. + */ + async saveRefactor() { + let { nvim } = this; + let doc = this.document; + if (!doc) + return; + let { buffer } = doc; + if (workspace_1.default.isVim) { + await doc._fetchContent(); + } + doc.forceSync(); + let changes = await this.getFileChanges(); + if (!changes) + return; + changes.sort((a, b) => a.lnum - b.lnum); + // filter changes that not change + let removeList = []; + let deltaMap = new Map(); + for (let i = 0; i < changes.length; i++) { + let change = changes[i]; + let { filepath, lnum } = change; + let curr = deltaMap.get(filepath) || 0; + let item = this.fileItems.find(o => o.filepath == filepath); + let range = item ? item.ranges.find(o => o.lnum == lnum) : null; + if (!range || object_1.equals(range.lines, change.lines)) { + removeList.push(i); + if (curr) { + range.start = range.start + curr; + range.end = range.end + curr; + } + continue; + } + change.start = range.start; + change.end = range.end; + if (curr != 0) + range.start = range.start + curr; + if (change.lines.length != range.lines.length) { + let delta = change.lines.length - range.lines.length; + let total = delta + curr; + deltaMap.set(filepath, total); + range.end = range.end + total; + } + else { + range.end = range.end + curr; + } + range.lines = change.lines; + } + if (removeList.length) + changes = changes.filter((_, i) => !removeList.includes(i)); + if (changes.length == 0) { + workspace_1.default.showMessage('No change.', 'more'); + await buffer.setOption('modified', false); + return false; + } + let changeMap = {}; + for (let change of changes) { + let uri = vscode_uri_1.URI.file(change.filepath).toString(); + let edits = changeMap[uri] || []; + edits.push({ + range: vscode_languageserver_types_1.Range.create(change.start, 0, change.end, 0), + newText: change.lines.join('\n') + '\n' + }); + changeMap[uri] = edits; + } + this.changing = true; + await workspace_1.default.applyEdit({ changes: changeMap }); + this.changing = false; + nvim.pauseNotification(); + buffer.setOption('modified', false, true); + nvim.command('wa', true); + this.highlightLineNr(); + await nvim.resumeNotification(); + return true; + } + getFileRange(lnum) { + for (let item of this.fileItems) { + for (let r of item.ranges) { + if (r.lnum == lnum) { + return r; + } + } + } + return null; + } + async onBufferChange(e) { + if (e.bufnr == this.bufnr) { + return await this.onRefactorChange(e); + } + if (this.changing) + return; + let { uri } = e.textDocument; + let { range, text } = e.contentChanges[0]; + let filepath = vscode_uri_1.URI.parse(uri).fsPath; + let fileItem = this.fileItems.find(o => o.filepath == filepath); + if (!fileItem) + return; + let lineChange = text.split('\n').length - (range.end.line - range.start.line) - 1; + let edits = []; + // 4 cases: ignore, change lineNr, reload, remove + for (let i = 0; i < fileItem.ranges.length; i++) { + let r = fileItem.ranges[i]; + if (range.start.line >= r.end) { + continue; + } + if (range.end.line < r.start) { + if (lineChange == 0) { + continue; + } + else { + r.start = r.start + lineChange; + r.end = r.end + lineChange; + } + } + else { + let doc = workspace_1.default.getDocument(uri); + let newLines = doc.getLines(r.start, r.end); + if (!newLines.length) { + // remove this range + fileItem.ranges.splice(i, 1); + edits.push({ + range: this.getFileRangeRange(r, false), + newText: '' + }); + } + else { + r.end = r.start + newLines.length; + // reload lines, reset end + edits.push({ + range: this.getFileRangeRange(r, true), + newText: newLines.join('\n') + '\n' + }); + } + } + let buf = this.document.buffer; + let mod = await buf.getOption('modified'); + if (edits.length) { + this.version = this.document.version; + await this.document.applyEdits(edits); + } + this.nvim.pauseNotification(); + this.highlightLineNr(); + if (!mod) + buf.setOption('modified', false, true); + await this.nvim.resumeNotification(); + } + } + /** + * Edit range of FileRange + */ + getFileRangeRange(range, lineOnly = true) { + let { document } = this; + if (!document) + return null; + let { lnum } = range; + let first = document.getline(lnum - 1); + if (!first.startsWith('\u3000')) + return null; + let start = lineOnly ? lnum : lnum - 1; + let end = document.lineCount; + for (let i = lnum; i < document.lineCount; i++) { + let line = document.getline(i); + if (line.startsWith('\u3000')) { + end = lineOnly ? i : i + 1; + break; + } + } + return vscode_languageserver_types_1.Range.create(start, 0, end, 0); + } + /** + * Open line under cursor in split window + */ + async splitOpen() { + let { nvim } = this; + let win = nvim.createWindow(this.fromWinid); + let valid = await win.valid; + let lines = await nvim.eval('getline(1,line("."))'); + let len = lines.length; + for (let i = 0; i < len; i++) { + let line = lines[len - i - 1]; + let ms = line.match(/^\u3000(.+)/); + if (ms) { + let filepath = ms[1].trim(); + let r = this.getLinesRange(len - i); + if (!r) + return; + let lnum = r[0] + i; + let bufname = filepath.startsWith(workspace_1.default.cwd) ? path_1.default.relative(workspace_1.default.cwd, filepath) : filepath; + nvim.pauseNotification(); + if (valid) { + nvim.call('win_gotoid', [this.fromWinid], true); + this.nvim.call('coc#util#jump', ['edit', bufname, [lnum, 1]], true); + } + else { + this.nvim.call('coc#util#jump', ['belowright vs', bufname, [lnum, 1]], true); + } + nvim.command('normal! zz', true); + let [, err] = await nvim.resumeNotification(); + if (err) + workspace_1.default.showMessage(`Error on open ${filepath}: ${err}`, 'error'); + if (!valid) { + this.fromWinid = await nvim.call('win_getid'); + } + break; + } + } + } + async onRefactorChange(e) { + let { nvim } = this; + let doc = this.document; + if (doc.version - this.version == 1) + return; + let { fileItems } = this; + if (!fileItems.length) + return; + let change = e.contentChanges[0]; + let { original } = e; + if (change.range.end.line < 2) + return; + doc.buffer.setOption('modified', true, true); + let { range, text } = change; + let lines = text.split('\n'); + let lineChange = lines.length - (range.end.line - range.start.line) - 1; + if (lineChange == 0) + return; + let lineChanges = []; + if (text.indexOf('\u3000') !== -1) { + let startLine = range.start.line; + let diffs = fast_diff_1.default(original, text); + let offset = 0; + let orig = vscode_languageserver_types_1.TextDocument.create('file:///1', '', 0, original); + for (let i = 0; i < diffs.length; i++) { + let diff = diffs[i]; + let pos = orig.positionAt(offset); + if (diff[0] == fast_diff_1.default.EQUAL) { + offset = offset + diff[1].length; + } + else if (diff[0] == fast_diff_1.default.DELETE) { + let end = orig.positionAt(offset + diff[1].length); + if (diffs[i + 1] && diffs[i + 1][0] == fast_diff_1.default.INSERT) { + let delta = diffs[i + 1][1].split('\n').length - (end.line - pos.line) - 1; + if (delta != 0) + lineChanges.push({ delta, lnum: pos.line + startLine }); + i = i + 1; + } + else { + let delta = -(end.line - pos.line); + if (delta != 0) + lineChanges.push({ delta, lnum: pos.line + startLine }); + } + offset = offset + diff[1].length; + } + else if (diff[0] == fast_diff_1.default.INSERT) { + let delta = diff[1].split('\n').length - 1; + if (delta != 0) + lineChanges.push({ delta, lnum: pos.line + startLine }); + } + } + } + else { + lineChanges = [{ delta: lineChange, lnum: range.start.line }]; + } + let changed = false; + // adjust LineNr highlights + for (let item of fileItems) { + for (let range of item.ranges) { + let arr = lineChanges.filter(o => o.lnum < range.lnum - 1); + if (arr.length) { + let total = arr.reduce((p, c) => p + c.delta, 0); + range.lnum = range.lnum + total; + changed = true; + } + } + } + if (!changed || this.srcId) + return; + let winid = await nvim.call('win_getid'); + if (winid != this.winid) { + await nvim.call('win_gotoid', [winid]); + } + nvim.pauseNotification(); + this.highlightLineNr(); + await nvim.resumeNotification(); + } + async getItemsFromWorkspaceEdit(edit) { + let res = []; + let { beforeContext, afterContext } = this.config; + let { changes, documentChanges } = edit; + if (!changes) { + changes = {}; + for (let change of documentChanges || []) { + if (vscode_languageserver_types_1.TextDocumentEdit.is(change)) { + let { textDocument, edits } = change; + changes[textDocument.uri] = edits; + } + } + } + for (let key of Object.keys(changes)) { + let max = await this.getLineCount(key); + let edits = changes[key]; + let ranges = []; + // start end highlights + let start = null; + let end = null; + let highlights = []; + edits.sort((a, b) => a.range.start.line - b.range.start.line); + for (let edit of edits) { + let { line } = edit.range.start; + let s = Math.max(0, line - beforeContext); + if (start != null && s < end) { + end = Math.min(max, line + afterContext + 1); + highlights.push(adjustRange(edit.range, start)); + } + else { + if (start != null) + ranges.push({ start, end, highlights }); + start = s; + end = Math.min(max, line + afterContext + 1); + highlights = [adjustRange(edit.range, start)]; + } + } + if (start != null) + ranges.push({ start, end, highlights }); + res.push({ + ranges, + filepath: vscode_uri_1.URI.parse(key).fsPath + }); + } + return res; + } + async getLineCount(uri) { + let doc = workspace_1.default.getDocument(uri); + if (doc) + return doc.lineCount; + return await fs_1.getFileLineCount(vscode_uri_1.URI.parse(uri).fsPath); + } + async getLines(fsPath, start, end) { + let uri = vscode_uri_1.URI.file(fsPath).toString(); + let doc = workspace_1.default.getDocument(uri); + if (doc) + return doc.getLines(start, end); + return await fs_1.readFileLines(fsPath, start, end - 1); + } + getLinesRange(lnum) { + for (let item of this.fileItems) { + for (let range of item.ranges) { + if (range.lnum == lnum) { + return [range.start, range.end]; + } + } + } + return null; + } + dispose() { + this.fileItems = []; + util_1.disposeAll(this.disposables); + } + /** + * Refactor from workspaceEdit. + */ + static async createFromWorkspaceEdit(edit, filetype) { + if (!edit || emptyWorkspaceEdit(edit)) + return null; + let refactor = new Refactor(); + await refactor.fromWorkspaceEdit(edit, filetype); + return refactor; + } + /** + * Refactor from locations. + */ + static async createFromLocations(locations, filetype) { + if (!locations || locations.length == 0) + return null; + let changes = {}; + let edit = { changes }; + for (let location of locations) { + let edits = changes[location.uri] || []; + edits.push({ range: location.range, newText: '' }); + changes[location.uri] = edits; + } + let refactor = new Refactor(); + await refactor.fromWorkspaceEdit(edit, filetype); + return refactor; + } + static async createFromLines(lines) { + let refactor = new Refactor(); + await refactor.fromLines(lines); + return refactor; + } +} +exports.default = Refactor; +function adjustRange(range, offset) { + let { start, end } = range; + return vscode_languageserver_types_1.Range.create(start.line - offset, start.character, end.line - offset, end.character); +} +function emptyWorkspaceEdit(edit) { + let { changes, documentChanges } = edit; + if (documentChanges && documentChanges.length) + return false; + if (changes && Object.keys(changes).length) + return false; + return true; +} +//# sourceMappingURL=refactor.js.map + +/***/ }), +/* 405 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const await_semaphore_1 = __webpack_require__(406); +const child_process_1 = __webpack_require__(175); +const events_1 = __webpack_require__(49); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const readline_1 = tslib_1.__importDefault(__webpack_require__(60)); +const vscode_languageserver_types_1 = __webpack_require__(161); +const which_1 = tslib_1.__importDefault(__webpack_require__(181)); +const highligher_1 = tslib_1.__importDefault(__webpack_require__(349)); +const ansiparse_1 = __webpack_require__(350); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const logger = __webpack_require__(186)('handler-search'); +const defaultArgs = ['--color', 'ansi', '--colors', 'path:fg:black', '--colors', 'line:fg:green', '--colors', 'match:fg:red', '--no-messages', '--heading', '-n']; +const controlCode = '\x1b'; +// emit FileItem +class Task extends events_1.EventEmitter { + start(cmd, args, cwd) { + this.process = child_process_1.spawn(cmd, args, { cwd }); + this.process.on('error', e => { + this.emit('error', e.message); + }); + const rl = readline_1.default.createInterface(this.process.stdout); + let start; + let fileItem; + let lines = []; + let highlights = []; + let create = true; + rl.on('line', content => { + if (content.indexOf(controlCode) !== -1) { + let items = ansiparse_1.ansiparse(content); + if (items[0].foreground == 'black') { + fileItem = { filepath: path_1.default.join(cwd, items[0].text), ranges: [] }; + return; + } + let normalLine = items[0].foreground == 'green'; + if (normalLine) { + let lnum = parseInt(items[0].text, 10) - 1; + let padlen = items[0].text.length + 1; + if (create) { + start = lnum; + create = false; + } + let line = ''; + for (let item of items) { + if (item.foreground == 'red') { + let l = lnum - start; + let c = line.length - padlen; + highlights.push(vscode_languageserver_types_1.Range.create(l, c, l, c + item.text.length)); + } + line += item.text; + } + let currline = line.slice(padlen); + lines.push(currline); + } + } + else { + let fileEnd = content.trim().length == 0; + if (fileItem && (fileEnd || content.trim() == '--')) { + let fileRange = { + lines, + highlights, + start, + end: start + lines.length + }; + fileItem.ranges.push(fileRange); + } + if (fileEnd) { + this.emit('item', fileItem); + fileItem = null; + } + lines = []; + highlights = []; + create = true; + } + }); + rl.on('close', () => { + if (fileItem) { + if (lines.length) { + let fileRange = { + lines, + highlights, + start, + end: start + lines.length + }; + fileItem.ranges.push(fileRange); + } + this.emit('item', fileItem); + } + lines = highlights = fileItem = null; + this.emit('end'); + }); + } + dispose() { + if (this.process) { + this.process.kill(); + } + } +} +class Search { + constructor(nvim, cmd = 'rg') { + this.nvim = nvim; + this.cmd = cmd; + } + run(args, cwd, refactor) { + let { nvim, cmd } = this; + let { afterContext, beforeContext } = refactor.config; + let argList = ['-A', afterContext.toString(), '-B', beforeContext.toString()].concat(defaultArgs, args); + argList.push('--', './'); + try { + cmd = which_1.default.sync(cmd); + } + catch (e) { + workspace_1.default.showMessage('Please install ripgrep and make sure rg is in your $PATH', 'error'); + return Promise.reject(e); + } + this.task = new Task(); + this.task.start(cmd, argList, cwd); + let mutex = new await_semaphore_1.Mutex(); + let files = 0; + let matches = 0; + let start = Date.now(); + // remaining items + let fileItems = []; + const addFileItems = async () => { + if (fileItems.length == 0) + return; + let items = fileItems.slice(); + fileItems = []; + const release = await mutex.acquire(); + try { + await refactor.addFileItems(items); + } + catch (e) { + logger.error(e); + } + release(); + }; + return new Promise((resolve, reject) => { + let interval = setInterval(addFileItems, 100); + this.task.on('item', async (fileItem) => { + files++; + matches = matches + fileItem.ranges.reduce((p, r) => p + r.highlights.length, 0); + fileItems.push(fileItem); + }); + this.task.on('error', message => { + clearInterval(interval); + workspace_1.default.showMessage(`Error on command "${cmd}": ${message}`, 'error'); + this.task = null; + reject(new Error(message)); + }); + this.task.on('end', async () => { + clearInterval(interval); + try { + await addFileItems(); + const release = await mutex.acquire(); + release(); + this.task.removeAllListeners(); + this.task = null; + let { document } = refactor; + if (document) { + let buf = document.buffer; + nvim.pauseNotification(); + if (files == 0) { + buf.setLines(['No match found'], { start: 1, end: 2, strictIndexing: false }); + buf.addHighlight({ line: 1, srcId: -1, colEnd: -1, colStart: 0, hlGroup: 'Error' }).logError(); + buf.setOption('modified', false, true); + } + else { + let highligher = new highligher_1.default(); + highligher.addText('Files', 'MoreMsg'); + highligher.addText(': '); + highligher.addText(`${files} `, 'Number'); + highligher.addText('Matches', 'MoreMsg'); + highligher.addText(': '); + highligher.addText(`${matches} `, 'Number'); + highligher.addText('Duration', 'MoreMsg'); + highligher.addText(': '); + highligher.addText(`${Date.now() - start}ms`, 'Number'); + highligher.render(buf, 1, 2); + } + buf.setOption('modified', false, true); + await nvim.resumeNotification(false, true); + } + } + catch (e) { + reject(e); + return; + } + resolve(); + }); + }); + } +} +exports.default = Search; +//# sourceMappingURL=search.js.map + +/***/ }), +/* 406 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +class Semaphore { + constructor(count) { + this.tasks = []; + this.count = count; + } + sched() { + if (this.count > 0 && this.tasks.length > 0) { + this.count--; + let next = this.tasks.shift(); + if (next === undefined) { + throw "Unexpected undefined value in tasks list"; + } + next(); + } + } + acquire() { + return new Promise((res, rej) => { + var task = () => { + var released = false; + res(() => { + if (!released) { + released = true; + this.count++; + this.sched(); + } + }); + }; + this.tasks.push(task); + if (process && process.nextTick) { + process.nextTick(this.sched.bind(this)); + } + else { + setImmediate(this.sched.bind(this)); + } + }); + } + use(f) { + return this.acquire() + .then(release => { + return f() + .then((res) => { + release(); + return res; + }) + .catch((err) => { + release(); + throw err; + }); + }); + } +} +exports.Semaphore = Semaphore; +class Mutex extends Semaphore { + constructor() { + super(1); + } +} +exports.Mutex = Mutex; +//# sourceMappingURL=index.js.map + +/***/ }), +/* 407 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const fast_diff_1 = tslib_1.__importDefault(__webpack_require__(209)); +const debounce_1 = tslib_1.__importDefault(__webpack_require__(176)); +const vscode_languageserver_types_1 = __webpack_require__(161); +const events_1 = tslib_1.__importDefault(__webpack_require__(148)); +const util_1 = __webpack_require__(174); +const array_1 = __webpack_require__(212); +const position_1 = __webpack_require__(213); +const workspace_1 = tslib_1.__importDefault(__webpack_require__(187)); +const range_1 = tslib_1.__importDefault(__webpack_require__(408)); +const logger = __webpack_require__(186)('cursors'); +class Cursors { + constructor(nvim) { + this.nvim = nvim; + this._activated = false; + this._changed = false; + this.ranges = []; + this.disposables = []; + this.matchIds = []; + this.version = -1; + this.loadConfig(); + workspace_1.default.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('cursors')) { + this.loadConfig(); + } + }); + } + loadConfig() { + let config = workspace_1.default.getConfiguration('cursors'); + this.config = { + nextKey: config.get('nextKey', ''), + previousKey: config.get('previousKey', ''), + cancelKey: config.get('cancelKey', '') + }; + } + async select(bufnr, kind, mode) { + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return; + doc.forceSync(); + let { nvim } = this; + if (this._changed || bufnr != this.bufnr) { + this.cancel(); + } + let pos = await workspace_1.default.getCursorPosition(); + let range; + if (kind == 'operator') { + await nvim.command(`normal! ${mode == 'line' ? `'[` : '`['}`); + let start = await workspace_1.default.getCursorPosition(); + await nvim.command(`normal! ${mode == 'line' ? `']` : '`]'}`); + let end = await workspace_1.default.getCursorPosition(); + await workspace_1.default.moveTo(pos); + let relative = position_1.comparePosition(start, end); + // do nothing for empty range + if (relative == 0) + return; + if (relative >= 0) + [start, end] = [end, start]; + // include end character + let line = doc.getline(end.line); + if (end.character < line.length) { + end.character = end.character + 1; + } + let ranges = splitRange(doc, vscode_languageserver_types_1.Range.create(start, end)); + for (let r of ranges) { + let text = doc.textDocument.getText(r); + this.addRange(r, text); + } + } + else if (kind == 'word') { + range = doc.getWordRangeAtPosition(pos); + if (!range) { + let line = doc.getline(pos.line); + if (pos.character == line.length) { + range = vscode_languageserver_types_1.Range.create(pos.line, Math.max(0, line.length - 1), pos.line, line.length); + } + else { + range = vscode_languageserver_types_1.Range.create(pos.line, pos.character, pos.line, pos.character + 1); + } + } + let line = doc.getline(pos.line); + let text = line.slice(range.start.character, range.end.character); + this.addRange(range, text); + } + else if (kind == 'position') { + // make sure range contains character for highlight + let line = doc.getline(pos.line); + if (pos.character >= line.length) { + range = vscode_languageserver_types_1.Range.create(pos.line, line.length - 1, pos.line, line.length); + } + else { + range = vscode_languageserver_types_1.Range.create(pos.line, pos.character, pos.line, pos.character + 1); + } + this.addRange(range, line.slice(range.start.character, range.end.character)); + } + else if (kind == 'range') { + await nvim.call('eval', 'feedkeys("\\", "in")'); + let range = await workspace_1.default.getSelectedRange(mode, doc); + if (!range || position_1.comparePosition(range.start, range.end) == 0) + return; + let ranges = mode == '\x16' ? getVisualRanges(doc, range) : splitRange(doc, range); + for (let r of ranges) { + let text = doc.textDocument.getText(r); + this.addRange(r, text); + } + } + else { + workspace_1.default.showMessage(`${kind} not supported`, 'error'); + return; + } + if (this._activated && !this.ranges.length) { + this.cancel(); + } + else if (this.ranges.length && !this._activated) { + let winid = await nvim.call('win_getid'); + this.activate(doc, winid); + } + if (this._activated) { + nvim.pauseNotification(); + this.doHighlights(); + let [, err] = await nvim.resumeNotification(); + if (err) + logger.error(err); + } + if (kind == 'word' || kind == 'position') { + await nvim.command(`silent! call repeat#set("\\(coc-cursors-${kind})", -1)`); + } + } + activate(doc, winid) { + if (this._activated) + return; + this._activated = true; + this.bufnr = doc.bufnr; + this.winid = winid; + this.nvim.setVar('coc_cursors_activated', 1, true); + doc.forceSync(); + this.textDocument = doc.textDocument; + workspace_1.default.onDidChangeTextDocument(async (e) => { + if (e.textDocument.uri != doc.uri) + return; + if (doc.version - this.version == 1 || !this.ranges.length) + return; + let change = e.contentChanges[0]; + let { original } = e; + let { text, range } = change; + // ignore change after last range + if (position_1.comparePosition(range.start, this.lastPosition) > 0) { + if (this._changed) { + this.cancel(); + } + else { + this.textDocument = doc.textDocument; + } + return; + } + let changeCount = text.split('\n').length - (range.end.line - range.start.line + 1); + // adjust line when change before first position + let d = position_1.comparePosition(range.end, this.firstPosition); + if (d < 0 || d == 0 && (position_1.comparePosition(range.start, range.end) != 0 || text.endsWith('\n'))) { + if (this._changed) { + this.cancel(); + } + else { + if (changeCount != 0) + this.ranges.forEach(r => r.line = r.line + changeCount); + this.textDocument = doc.textDocument; + } + return; + } + // ignore changes when not overlap + if (changeCount == 0) { + let lnums = array_1.distinct(this.ranges.map(r => r.line)); + let startLine = range.start.line; + let endLine = range.end.line; + let overlap = lnums.some(line => line >= startLine && line <= endLine); + if (!overlap) + return; + } + this._changed = true; + // get range from edit + let textRange = this.getTextRange(range, text); + if (textRange) { + await this.applySingleEdit(textRange, { range, newText: text }); + } + else { + await this.applyComposedEdit(original, { range, newText: text }); + } + }, null, this.disposables); + let { cancelKey, nextKey, previousKey } = this.config; + workspace_1.default.registerLocalKeymap('n', cancelKey, () => { + if (!this._activated) + return this.unmap(cancelKey); + this.cancel(); + }, true); + workspace_1.default.registerLocalKeymap('n', nextKey, async () => { + if (!this._activated) + return this.unmap(nextKey); + let ranges = this.ranges.map(o => o.currRange); + let curr = await workspace_1.default.getCursorPosition(); + for (let r of ranges) { + if (position_1.comparePosition(r.start, curr) > 0) { + await workspace_1.default.moveTo(r.start); + return; + } + } + if (ranges.length) + await workspace_1.default.moveTo(ranges[0].start); + }, true); + workspace_1.default.registerLocalKeymap('n', previousKey, async () => { + if (!this._activated) + return this.unmap(previousKey); + let ranges = this.ranges.map(o => o.currRange); + ranges.reverse(); + let curr = await workspace_1.default.getCursorPosition(); + for (let r of ranges) { + if (position_1.comparePosition(r.end, curr) < 0) { + await workspace_1.default.moveTo(r.start); + return; + } + } + if (ranges.length) + await workspace_1.default.moveTo(ranges[0].start); + }, true); + events_1.default.on('CursorMoved', debounce_1.default(async (bufnr) => { + if (bufnr != this.bufnr) + return this.cancel(); + let winid = await this.nvim.call('win_getid'); + if (winid != this.winid) { + this.cancel(); + } + }, 100), null, this.disposables); + } + doHighlights() { + let { matchIds } = this; + let doc = workspace_1.default.getDocument(this.bufnr); + if (!doc || !this.ranges.length) + return; + if (matchIds.length) + this.nvim.call('coc#util#clearmatches', [matchIds, this.winid], true); + let searchRanges = this.ranges.map(o => o.currRange); + this.matchIds = doc.matchAddRanges(searchRanges, 'CocCursorRange', 99); + if (workspace_1.default.isVim) + this.nvim.command('redraw', true); + } + cancel() { + if (!this._activated) + return; + let { matchIds } = this; + this.nvim.setVar('coc_cursors_activated', 0, true); + this.nvim.call('coc#util#clearmatches', [Array.from(matchIds), this.winid], true); + this.matchIds = []; + util_1.disposeAll(this.disposables); + this._changed = false; + this.ranges = []; + this.version = -1; + this._activated = false; + } + unmap(key) { + let { nvim, bufnr } = this; + let { cancelKey, nextKey, previousKey } = this.config; + let escaped = key.startsWith('<') && key.endsWith('>') ? `\\${key}` : key; + nvim.pauseNotification(); + nvim.call('coc#util#unmap', [bufnr, [cancelKey, nextKey, previousKey]], true); + nvim.call('eval', `feedkeys("${escaped}", 't')`, true); + nvim.resumeNotification(false, true).logError(); + } + // Add ranges to current document + async addRanges(ranges) { + let { nvim } = this; + let [bufnr, winid] = await nvim.eval('[bufnr("%"),win_getid()]'); + if (this._activated && (this.bufnr != bufnr || this.winid != winid)) { + this.cancel(); + } + let doc = workspace_1.default.getDocument(bufnr); + if (!doc) + return; + doc.forceSync(); + // filter overlap ranges + if (!this._changed) { + this.ranges = this.ranges.filter(r => { + let { currRange } = r; + return !ranges.some(range => position_1.rangeOverlap(range, currRange)); + }); + } + else { + // use new ranges + this.ranges = []; + } + let { textDocument } = doc; + for (let range of ranges) { + let { line } = range.start; + let textRange = new range_1.default(line, range.start.character, range.end.character, textDocument.getText(range), 0); + this.ranges.push(textRange); + } + this.ranges.sort((a, b) => position_1.comparePosition(a.range.start, b.range.start)); + // fix preCount + let preCount = 0; + let currline = -1; + for (let range of this.ranges) { + let { line } = range; + if (line != currline) { + preCount = 0; + } + range.preCount = preCount; + preCount = preCount + 1; + currline = line; + } + if (!this.ranges.length) + return; + this.activate(doc, winid); + nvim.pauseNotification(); + this.doHighlights(); + let [, err] = await nvim.resumeNotification(); + if (err) + logger.error(err); + } + get activated() { + return this._activated; + } + /** + * Find single range from edit + */ + getTextRange(range, text) { + let { ranges } = this; + // can't support line count change + if (text.indexOf('\n') !== -1 || range.start.line != range.end.line) + return null; + ranges.sort((a, b) => { + if (a.line != b.line) + return a.line - b.line; + return a.currRange.start.character - b.currRange.start.character; + }); + for (let i = 0; i < ranges.length; i++) { + let r = ranges[i]; + if (position_1.rangeInRange(range, r.currRange)) { + return r; + } + if (r.line != range.start.line) { + continue; + } + if (text.length && range.start.character == r.currRange.end.character) { + // end add + let next = ranges[i + 1]; + if (!next) + return r; + return position_1.positionInRange(next.currRange.start, range) ? null : r; + } + } + return null; + } + async applySingleEdit(textRange, edit) { + // single range change, calculate & apply changes for all ranges + let { range, newText } = edit; + let doc = workspace_1.default.getDocument(this.bufnr); + this.adjustChange(textRange, range, newText); + if (this.ranges.length == 1) { + this.doHighlights(); + return; + } + let edits = this.ranges.map(o => o.textEdit); + let content = vscode_languageserver_types_1.TextDocument.applyEdits(this.textDocument, edits); + let newLines = content.split('\n'); + let changedLnum = new Set(); + let arr = []; + for (let r of this.ranges) { + if (!changedLnum.has(r.line)) { + changedLnum.add(r.line); + arr.push([r.line, newLines[r.line]]); + } + } + let { nvim } = this; + this.version = doc.version; + // apply changes + nvim.pauseNotification(); + nvim.command('undojoin', true); + doc.changeLines(arr); + let { cursor } = events_1.default; + if (textRange.preCount > 0 && cursor.bufnr == this.bufnr && textRange.line + 1 == cursor.lnum) { + let changed = textRange.preCount * (newText.length - (range.end.character - range.start.character)); + nvim.call('cursor', [cursor.lnum, cursor.col + changed], true); + } + this.doHighlights(); + let [, err] = await nvim.resumeNotification(); + if (err) + logger.error(err); + } + async applyComposedEdit(original, edit) { + // check complex edit + let { range, newText } = edit; + let { nvim, ranges } = this; + let doc = vscode_languageserver_types_1.TextDocument.create('file:///1', '', 0, original); + let edits = []; + let diffs = fast_diff_1.default(original, newText); + let offset = 0; + for (let i = 0; i < diffs.length; i++) { + let diff = diffs[i]; + let pos = adjustPosition(range.start, doc.positionAt(offset)); + if (diff[0] == fast_diff_1.default.EQUAL) { + offset = offset + diff[1].length; + } + else if (diff[0] == fast_diff_1.default.DELETE) { + let end = adjustPosition(range.start, doc.positionAt(offset + diff[1].length)); + if (diffs[i + 1] && diffs[i + 1][0] == fast_diff_1.default.INSERT) { + // change + edits.push({ range: vscode_languageserver_types_1.Range.create(pos, end), newText: diffs[i + 1][1] }); + i = i + 1; + } + else { + // delete + edits.push({ range: vscode_languageserver_types_1.Range.create(pos, end), newText: '' }); + } + offset = offset + diff[1].length; + } + else if (diff[0] == fast_diff_1.default.INSERT) { + edits.push({ range: vscode_languageserver_types_1.Range.create(pos, pos), newText: diff[1] }); + } + } + if (edits.some(edit => edit.newText.indexOf('\n') != -1 || edit.range.start.line != edit.range.end.line)) { + this.cancel(); + return; + } + if (edits.length == ranges.length) { + let last; + for (let i = 0; i < edits.length; i++) { + let edit = edits[i]; + let textRange = this.ranges[i]; + if (!position_1.rangeIntersect(textRange.currRange, edit.range)) { + this.cancel(); + return; + } + if (last && !equalEdit(edit, last)) { + this.cancel(); + return; + } + textRange.applyEdit(edit); + last = edit; + } + } + else if (edits.length == ranges.length * 2) { + for (let i = 0; i < edits.length - 1; i = i + 2) { + let edit = edits[i]; + let next = edits[i + 1]; + if (edit.newText.length == 0 && next.newText.length == 0) { + // remove begin & end + let textRange = this.ranges[i / 2]; + if (position_1.comparePosition(textRange.currRange.end, next.range.end) != 0) { + this.cancel(); + return; + } + let start = edit.range.start.character - textRange.currRange.start.character; + textRange.replace(start, edit.range.end.character - edit.range.start.character, ''); + let offset = next.range.end.character - next.range.start.character; + let len = textRange.text.length; + textRange.replace(len - offset, len); + } + else if (position_1.emptyRange(edit.range) && position_1.emptyRange(next.range)) { + // add begin & end + let textRange = this.ranges[i / 2]; + if (position_1.comparePosition(textRange.currRange.end, next.range.start) != 0) { + this.cancel(); + return; + } + let start = edit.range.start.character - textRange.currRange.start.character; + textRange.add(start, edit.newText); + let len = textRange.text.length; + textRange.add(len, next.newText); + } + else { + this.cancel(); + } + } + } + else { + this.cancel(); + } + nvim.pauseNotification(); + this.doHighlights(); + await nvim.resumeNotification(false, true); + } + adjustChange(textRange, range, text) { + let { ranges } = this; + if (range.start.character == range.end.character) { + // add + let isEnd = textRange.currRange.end.character == range.start.character; + if (isEnd) { + ranges.forEach(r => { + r.add(r.text.length, text); + }); + } + else { + let d = range.start.character - textRange.currRange.start.character; + ranges.forEach(r => { + r.add(Math.min(r.text.length, d), text); + }); + } + } + else { + // replace + let d = range.end.character - range.start.character; + let isEnd = textRange.currRange.end.character == range.end.character; + if (isEnd) { + if (textRange.currRange.start.character == range.start.character) { + // changed both start and end + if (text.indexOf(textRange.text) !== -1) { + let idx = text.indexOf(textRange.text); + let pre = idx == 0 ? '' : text.slice(0, idx); + let post = text.slice(idx + textRange.text.length); + if (pre) + ranges.forEach(r => r.add(0, pre)); + if (post) + ranges.forEach(r => r.add(r.text.length, post)); + } + else if (textRange.text.indexOf(text) !== -1) { + // delete + let idx = textRange.text.indexOf(text); + let offset = textRange.text.length - (idx + text.length); + if (idx != 0) + ranges.forEach(r => r.replace(0, idx)); + if (offset > 0) + ranges.forEach(r => r.replace(r.text.length - offset, r.text.length)); + } + else { + this.cancel(); + } + } + else { + ranges.forEach(r => { + let l = r.text.length; + r.replace(Math.max(0, l - d), l, text); + }); + } + } + else { + let start = range.start.character - textRange.currRange.start.character; + ranges.forEach(r => { + let l = r.text.length; + r.replace(start, Math.min(start + d, l), text); + }); + } + } + } + addRange(range, text) { + let { ranges } = this; + let idx = ranges.findIndex(o => position_1.rangeIntersect(o.range, range)); + // remove range when intersect + if (idx !== -1) { + ranges.splice(idx, 1); + // adjust preCount after + for (let r of ranges) { + if (r.line == range.start.line && r.start > range.start.character) { + r.preCount = r.preCount - 1; + } + } + } + else { + let preCount = 0; + let idx = 0; + let { line } = range.start; + // idx & preCount + for (let r of ranges) { + if (r.line > line || (r.line == line && r.start > range.end.character)) { + break; + } + if (r.line == line) + preCount++; + idx++; + } + let created = new range_1.default(line, range.start.character, range.end.character, text, preCount); + ranges.splice(idx, 0, created); + // adjust preCount after + for (let r of ranges) { + if (r.line == range.start.line && r.start > range.start.character) { + r.preCount = r.preCount + 1; + } + } + } + } + get lastPosition() { + let { ranges } = this; + let r = ranges[ranges.length - 1]; + return r.currRange.end; + } + get firstPosition() { + let { ranges } = this; + return ranges[0].currRange.start; + } +} +exports.default = Cursors; +function splitRange(doc, range) { + let splited = []; + for (let i = range.start.line; i <= range.end.line; i++) { + let curr = doc.getline(i) || ''; + let sc = i == range.start.line ? range.start.character : 0; + let ec = i == range.end.line ? range.end.character : curr.length; + if (sc == ec) + continue; + splited.push(vscode_languageserver_types_1.Range.create(i, sc, i, ec)); + } + return splited; +} +/** + * Get ranges of visual block + */ +function getVisualRanges(doc, range) { + let { start, end } = range; + if (start.line > end.line) { + [start, end] = [end, start]; + } + let sc = start.character < end.character ? start.character : end.character; + let ec = start.character < end.character ? end.character : start.character; + let ranges = []; + for (let i = start.line; i <= end.line; i++) { + let line = doc.getline(i); + ranges.push(vscode_languageserver_types_1.Range.create(i, sc, i, Math.min(line.length, ec))); + } + return ranges; +} +function adjustPosition(position, delta) { + let { line, character } = delta; + return vscode_languageserver_types_1.Position.create(position.line + line, line == 0 ? position.character + character : character); +} +function equalEdit(one, two) { + if (one.newText.length != two.newText.length) + return false; + let { range } = one; + if (range.end.character - range.start.character != two.range.end.character - two.range.start.character) { + return false; + } + return true; +} +//# sourceMappingURL=index.js.map + +/***/ }), +/* 408 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_languageserver_types_1 = __webpack_require__(161); +const logger = __webpack_require__(186)('cursors-range'); +// edit range +class TextRange { + constructor(line, start, end, text, + // range count at this line before, shuld be updated on range add + preCount) { + this.line = line; + this.start = start; + this.end = end; + this.text = text; + this.preCount = preCount; + this.currStart = start; + this.currEnd = end; + } + add(offset, add) { + let { text, preCount } = this; + let pre = offset == 0 ? '' : text.slice(0, offset); + let post = text.slice(offset); + this.text = `${pre}${add}${post}`; + this.currStart = this.currStart + preCount * add.length; + this.currEnd = this.currEnd + (preCount + 1) * add.length; + } + replace(begin, end, add = '') { + let { text, preCount } = this; + let pre = begin == 0 ? '' : text.slice(0, begin); + let post = text.slice(end); + this.text = pre + add + post; + let l = end - begin - add.length; + this.currStart = this.currStart - preCount * l; + this.currEnd = this.currEnd - (preCount + 1) * l; + } + get range() { + return vscode_languageserver_types_1.Range.create(this.line, this.start, this.line, this.end); + } + get currRange() { + return vscode_languageserver_types_1.Range.create(this.line, this.currStart, this.line, this.currEnd); + } + applyEdit(edit) { + let { range, newText } = edit; + let start = range.start.character; + let end = range.end.character; + let isAdd = start == end; + if (isAdd) { + this.add(start - this.currStart, newText); + } + else { + this.replace(start - this.currStart, end - this.currStart, newText); + } + } + get textEdit() { + return { + range: this.range, + newText: this.text + }; + } +} +exports.default = TextRange; +//# sourceMappingURL=range.js.map + +/***/ }), +/* 409 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(3); +const path_1 = tslib_1.__importDefault(__webpack_require__(57)); +const fs_1 = tslib_1.__importDefault(__webpack_require__(55)); +const glob_1 = tslib_1.__importDefault(__webpack_require__(240)); +const os_1 = __webpack_require__(56); +const util_1 = tslib_1.__importDefault(__webpack_require__(40)); +const fs_2 = __webpack_require__(200); +async function default_1() { + if (global.hasOwnProperty('__TEST__')) + return; + try { + let dir = os_1.tmpdir(); + let files = glob_1.default.sync(path_1.default.join(dir, '/coc-*.sock')); + for (let file of files) { + let valid = await fs_2.validSocket(file); + if (!valid) + await util_1.default.promisify(fs_1.default.unlink)(file); + } + files = glob_1.default.sync(path_1.default.join(dir, '/coc-nvim-tscancellation-*')); + for (let file of files) { + await util_1.default.promisify(fs_1.default.unlink)(file); + } + files = glob_1.default.sync(path_1.default.join(dir, '/ti-*.log')); + for (let file of files) { + await util_1.default.promisify(fs_1.default.unlink)(file); + } + files = glob_1.default.sync(path_1.default.join(dir, '/coc-*.vim')); + for (let file of files) { + if (path_1.default.basename(file) != `coc-${process.pid}.vim`) { + await util_1.default.promisify(fs_1.default.unlink)(file); + } + } + dir = process.env.XDG_RUNTIME_DIR || dir; + files = glob_1.default.sync(path_1.default.join(dir, '/coc-nvim-*.log')); + for (let file of files) { + if (path_1.default.basename(file) != `coc-nvim-${process.pid}.log`) { + await util_1.default.promisify(fs_1.default.unlink)(file); + } + } + } + catch (e) { + // noop + } +} +exports.default = default_1; +//# sourceMappingURL=clean.js.map + +/***/ }), +/* 410 */ +/***/ (function(module) { + +module.exports = JSON.parse("{\"name\":\"coc.nvim\",\"version\":\"0.0.74\",\"description\":\"LSP based intellisense engine for neovim & vim8.\",\"main\":\"./lib/index.js\",\"bin\":\"./bin/server.js\",\"scripts\":{\"clean\":\"rimraf lib build\",\"lint\":\"tslint -c tslint.json -p .\",\"build\":\"tsc -p tsconfig.json\",\"watch\":\"tsc -p tsconfig.json --watch true --sourceMap\",\"test\":\"node --trace-warnings node_modules/.bin/jest --runInBand --detectOpenHandles --forceExit\",\"test-build\":\"node --trace-warnings node_modules/.bin/jest --runInBand --coverage --forceExit\",\"prepare\":\"npm-run-all clean build\"},\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/neoclide/coc.nvim.git\"},\"keywords\":[\"complete\",\"neovim\"],\"author\":\"Qiming Zhao \",\"license\":\"MIT\",\"bugs\":{\"url\":\"https://github.com/neoclide/coc.nvim/issues\"},\"homepage\":\"https://github.com/neoclide/coc.nvim#readme\",\"jest\":{\"globals\":{\"__TEST__\":true},\"watchman\":false,\"clearMocks\":true,\"globalSetup\":\"./jest.js\",\"testEnvironment\":\"node\",\"moduleFileExtensions\":[\"ts\",\"tsx\",\"json\",\"js\"],\"transform\":{\"^.+\\\\.tsx?$\":\"ts-jest\"},\"testRegex\":\"src/__tests__/.*\\\\.(test|spec)\\\\.ts$\",\"coverageDirectory\":\"./coverage/\"},\"devDependencies\":{\"@chemzqm/tslint-config\":\"^1.0.18\",\"@types/debounce\":\"^3.0.0\",\"@types/fb-watchman\":\"^2.0.0\",\"@types/glob\":\"^7.1.1\",\"@types/jest\":\"^24.0.18\",\"@types/minimatch\":\"^3.0.3\",\"@types/mkdirp\":\"^0.5.2\",\"@types/node\":\"^12.7.4\",\"@types/semver\":\"^6.0.2\",\"@types/tar\":\"^4.0.3\",\"@types/tunnel\":\"^0.0.1\",\"@types/uuid\":\"^3.4.5\",\"@types/which\":\"^1.3.1\",\"colors\":\"^1.3.3\",\"jest\":\"24.9.0\",\"npm-run-all\":\"^4.1.5\",\"ts-jest\":\"^24.0.2\",\"tslint\":\"^5.19.0\",\"typescript\":\"3.6.2\",\"vscode-languageserver\":\"5.3.0-next.8\"},\"dependencies\":{\"@chemzqm/neovim\":\"5.1.9\",\"await-semaphore\":\"^0.1.3\",\"bser\":\"^2.1.0\",\"debounce\":\"^1.2.0\",\"fast-diff\":\"^1.2.0\",\"fb-watchman\":\"^2.0.0\",\"follow-redirects\":\"^1.9.0\",\"glob\":\"^7.1.4\",\"isuri\":\"^2.0.3\",\"jsonc-parser\":\"^2.1.1\",\"log4js\":\"^5.1.0\",\"minimatch\":\"^3.0.4\",\"mkdirp\":\"^0.5.1\",\"mv\":\"^2.1.1\",\"rc\":\"^1.2.8\",\"rimraf\":\"^3.0.0\",\"semver\":\"^6.3.0\",\"tar\":\"^4.4.10\",\"tslib\":\"^1.10.0\",\"tunnel\":\"^0.0.6\",\"uuid\":\"^3.3.3\",\"vscode-languageserver-protocol\":\"3.15.0-next.6\",\"vscode-languageserver-types\":\"3.15.0-next.2\",\"vscode-uri\":\"^2.0.3\",\"which\":\"^1.3.1\"}}"); + +/***/ }) +/******/ ]); \ No newline at end of file diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/data/schema.json b/vim/.vim/pack/coc/start/coc.nvim-release/data/schema.json new file mode 100644 index 0000000..cf41afd --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/data/schema.json @@ -0,0 +1,972 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema", + "description": "Configuration file for coc.nvim", + "additionalProperties": false, + "definitions": { + "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." + }, + "disableWorkspaceFolders": { + "type": "boolean", + "default": false, + "description": "Disable workspaceFolders feature for this languageserver." + }, + "disableDiagnostics": { + "type": "boolean", + "default": false, + "description": "Disable handle diagnostics for this languageserver." + }, + "disableCompletion": { + "type": "boolean", + "default": false, + "description": "Disable completion feature for this languageserver." + }, + "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 for reoslve 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, use empty 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"] + }, + "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" + }, + "disableWorkspaceFolders": {}, + "disableDynamicRegister": {}, + "disableDiagnostics": {}, + "disableCompletion": {}, + "enable": {}, + "rootPatterns": {}, + "requireRootPattern": {}, + "ignoredRootPaths": {}, + "filetypes": {}, + "additionalSchemes": {}, + "revealOutputChannelOn": {}, + "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": {}, + "disableWorkspaceFolders": {}, + "disableDiagnostics": {}, + "disableCompletion": {}, + "rootPatterns": {}, + "requireRootPattern": {}, + "ignoredRootPaths": {}, + "filetypes": {}, + "additionalSchemes": {}, + "revealOutputChannelOn": {}, + "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": {}, + "disableWorkspaceFolders": {}, + "disableDiagnostics": {}, + "disableCompletion": {}, + "rootPatterns": {}, + "requireRootPattern": {}, + "ignoredRootPaths": {}, + "filetypes": {}, + "additionalSchemes": {}, + "revealOutputChannelOn": {}, + "initializationOptions": {}, + "stdioEncoding": {}, + "settings": {}, + "trace.server": {} + } + } + }, + "properties": { + "http.proxy": { + "type": "string", + "default": "", + "description": "http proxy uri, used for extensions that send request. Format: proxy-server:1234 or user:password@prox-server:1234 with auth support" + }, + "http.proxyStrictSSL": { + "type": "boolean", + "default": true + }, + "npm.binPath": { + "type": "string", + "default": "npm", + "description": "Command or absolute path to npm or yarn." + }, + "suggest.enablePreselect": { + "type": "boolean", + "description": "Enable preselect feature, only works on neovim", + "default": true + }, + "suggest.maxPreviewWidth": { + "type": "number", + "default": 80, + "description": "Maximum width of floating preview window." + }, + "suggest.enablePreview": { + "type": "boolean", + "description": "Add preview option to completeopt, default: false.", + "default": false + }, + "suggest.floatEnable": { + "type": "boolean", + "description": "Enable floating window for documentation when possible.", + "default": true + }, + "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": "menu", + "description": "Where to add the detail in complete item when it's less than max length.", + "enum": ["abbr", "menu", "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.numberSelect": { + "type": "boolean", + "description": "Input number to select complete item, it could wrong when using and to select complete item", + "default": false + }, + "suggest.disableKind": { + "type": "boolean", + "description": "Remove kind field from vim complete item.", + "default": false + }, + "suggest.disableMenu": { + "type": "boolean", + "description": "Remove menu field from vim complete item.", + "default": false + }, + "suggest.disableMenuShortcut": { + "type": "boolean", + "description": "Disable shortcut of completion source in menu.", + "default": false + }, + "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.timeout": { + "type": "integer", + "default": 5000, + "minimum": 500, + "maximum": 5000, + "description": "Timeout for completion, in miliseconds." + }, + "suggest.minTriggerInputLength": { + "type": "number", + "default": 1, + "description": "Mininal input length for trigger completion, default 1" + }, + "suggest.triggerCompletionWait": { + "type": "integer", + "default": 60, + "minimum": 50, + "maximum": 300, + "description": "Wait time between trigger character type and completion start, for wait server content synchronize." + }, + "suggest.echodocSupport": { + "type": "boolean", + "default": false, + "description": "When enabled, add function signature to user_data.signature to support echodoc.vim" + }, + "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.noselect": { + "type": "boolean", + "description": "Not make vim select first item on completion start", + "default": true + }, + "suggest.keepCompleteopt": { + "type": "boolean", + "description": "When enabled, completeopt is not overriden, auto completion will be disabled if completeopt doesn't have noinsert and noselect.", + "default": false + }, + "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"] + }, + "suggest.completionItemKindLabels": { + "type": "object", + "default": {}, + "description": "Set custom labels to completion items' kinds.", + "properties": { + "text": {"type": "string"}, + "method": {"type": "string"}, + "function": {"type": "string"}, + "constructor": {"type": "string"}, + "field": {"type": "string"}, + "variable": {"type": "string"}, + "class": {"type": "string"}, + "interface": {"type": "string"}, + "module": {"type": "string"}, + "property": {"type": "string"}, + "unit": {"type": "string"}, + "value": {"type": "string"}, + "enum": {"type": "string"}, + "keyword": {"type": "string"}, + "snippet": {"type": "string"}, + "color": {"type": "string"}, + "file": {"type": "string"}, + "reference": {"type": "string"}, + "folder": {"type": "string"}, + "enumMember": {"type": "string"}, + "constant": {"type": "string"}, + "struct": {"type": "string"}, + "event": {"type": "string"}, + "operator": {"type": "string"}, + "typeParameter": {"type": "string"}, + "default": {"type": "string"} + }, + "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"] + }, + "diagnostic.enable": { + "type": "boolean", + "description": "Set to false to disable diagnostic display", + "default": true + }, + "diagnostic.level": { + "type": "string", + "description": "Used for filter diagnostics by diagnostic severity.", + "default": "hint", + "enum": ["hint", "information", "warning", "error"] + }, + "diagnostic.checkCurrentLine": { + "type": "boolean", + "description": "When enabled, show all diagnostics of current line instead of 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": 250 + }, + "diagnostic.joinMessageLines": { + "type": "boolean", + "description": "Join lines messages to reduce lines of floating window.", + "default": false + }, + "diagnostic.refreshOnInsertMode": { + "type": "boolean", + "description": "Enable diagnostic refresh on insert mode, default false.", + "default": false + }, + "diagnostic.refreshAfterSave": { + "type": "boolean", + "description": "Only refresh diagnostics after save, 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.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.enableMessage": { + "type": "string", + "default": "always", + "description": "When to enable echo messages of diagnostics.", + "enum": ["always", "jump", "never"] + }, + "diagnostic.locationlist": { + "type": "boolean", + "description": "Create location list for error & warning", + "default": true + }, + "diagnostic.highlightOffset": { + "type": "number", + "description": "Offset number of buffer.addHighlight, neovim only.", + "default": 1000 + }, + "diagnostic.signOffset": { + "type": "number", + "description": "Offset number of sign", + "default": 1000 + }, + "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.maxWindowHeight": { + "type": "number", + "description": "Maximum height of diagnostics floating window.", + "default": 8 + }, + "diagnostic.maxWindowWidth": { + "type": "number", + "description": "Maximum width of diagnostics floating window.", + "default": 80 + }, + "diagnostic.filetypeMap": { + "type": "object", + "description": "A map between buffer filetype and the filetype assigned to diagnostics. To syntax highlight diagnostics withs their parent buffer type use '\"default\": \"bufferType\"'", + "default": {} + }, + "signature.enable": { + "type": "boolean", + "description": "Enable signature help when trigger character typed, require restart service on change.", + "default": true + }, + "signature.triggerSignatureWait": { + "type": "integer", + "default": 50, + "minimum": 50, + "maximum": 300, + "description": "Timeout for trigger signature help, in miliseconds." + }, + "signature.target": { + "type": "string", + "description": "Target of signature help, use float when possible by default.", + "enum": ["float", "echo"] + }, + "signature.floatMaxWidth": { + "type": "integer", + "default": 60, + "description": "Max width of signature float window." + }, + "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, require restart service on change.", + "default": false + }, + "signature.maxWindowHeight": { + "type": "number", + "description": "Maximum height of floating signature help window.", + "default": 8 + }, + "codeLens.enable": { + "type": "boolean", + "description": "Enable codeLens feature, require neovim with set virtual text feature.", + "default": false + }, + "codeLens.separator": { + "type": "string", + "description": "Separator text for codeLens in virtual text", + "default": "‣" + }, + "refactor.openCommand": { + "type": "string", + "description": "Open command for refactor window.", + "default": "vsplit" + }, + "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." + }, + "workspace.ignoredFiletypes": { + "type": "array", + "default": ["markdown", "log", "txt", "help"], + "description": "Filetypes that should be ignored for resolve workspace folder.", + "items": { + "type": "string" + } + }, + "list.indicator": { + "type": "string", + "default": ">", + "description": "The characer used as first characer in prompt line" + }, + "list.interactiveDebounceTime": { + "type": "number", + "default": 100, + "description": "Debouce time for input change on interactive mode." + }, + "list.maxHeight": { + "type": "number", + "default": 10, + "description": "Maximum height of list window." + }, + "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.autoResize": { + "type": "boolean", + "default": true, + "description": "Enable auto resize feature." + }, + "list.limitLines": { + "type": "number", + "default": 30000, + "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.nextKeymap": { + "type": "string", + "default": "", + "description": "Key used for select next line on insert mode." + }, + "list.previousKeymap": { + "type": "string", + "default": "", + "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.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": "", + "description": "Key used for cancel cursors session." + }, + "cursors.nextKey": { + "type": "string", + "default": "", + "description": "Key used for jump to next cursors position. " + }, + "cursors.previousKey": { + "type": "string", + "default": "", + "description": "Key used for jump to previous cursors position." + }, + "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": "daily", + "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.hoverTarget": { + "type": "string", + "description": "Target to show hover information, default is floating window when possible.", + "enum": ["preview", "echo", "float"] + }, + "coc.preferences.colorSupport": { + "type": "boolean", + "description": "Enable color highlight if language server support it.", + "default": true + }, + "coc.preferences.previewAutoClose": { + "type": "boolean", + "description": "Auto close preview window on cursor move.", + "default": true + }, + "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.enableFloatHighlight": { + "type": "boolean", + "description": "Enable highlight for floating window.", + "default": true + }, + "coc.preferences.rootPatterns": { + "type": "array", + "default": [".vim", ".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": { + "type": "string", + "description": "Command used for location jump, like goto definition, goto references etc.", + "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 format on type", + "default": false + }, + "coc.preferences.snippets.enable": { + "type": "boolean", + "description": "Set to false to disable snippets support.", + "default": true + }, + "coc.source.around.enable": { + "type": "boolean", + "default": true + }, + "coc.source.around.firstMatch": { + "type": "boolean", + "description": "Filter complete items by first letter strict match.", + "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.firstMatch": { + "type": "boolean", + "description": "Filter complete items by first letter strict match.", + "default": true + }, + "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" + } + ] + } + } + } + } +} diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/doc/coc.cnx b/vim/.vim/pack/coc/start/coc.nvim-release/doc/coc.cnx new file mode 100644 index 0000000..ecd2c48 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/doc/coc.cnx @@ -0,0 +1,1697 @@ +*coc-nvim.txt* 基于 LSP 的 vim 智能引擎 + +版本号: 0.0.57 +作者: Qiming Zhao +开源协议: MIT license + +内容 *coc-contents* + +介绍 |coc-introduction| +依赖 |coc-requirement| +安装 |coc-install| +设置 |coc-configuration| +补全 |coc-completion| +语言服务 |coc-languageserver| +接口 |coc-interface| + 快捷键 |coc-key-mappings| + 变量 |coc-variables| + 函数 |coc-functions| + 命令 |coc-commands| + 自动命令 |coc-autocmds| + 高亮 |coc-highlights| +列表 |coc-list| + 列表命令 |coc-list-command| + 列表配置 |coc-list-configuration| + 列表映射 |coc-list-mappings| + 列表源 |coc-list-sources| + 地址列表 |coc-list-location| + 插件列表 |coc-list-extensions| + 错误信息 |coc-list-diagnostics| + 大纲列表 |coc-list-outline| + 项目内符号搜索 |coc-list-symbols| + 服务列表 |coc-list-services| + 命令列表 |coc-list-commands| + 链接列表 |coc-list-links| + 输出列表 |coc-list-output| + 补全源列表 |coc-list-completion-sources| + 已安装列表 |coc-list-lists| +状态栏支持 |coc-status| + 手动 |coc-status-manual| + Airline |coc-status-airline| + Lightline |coc-stauts-lightline| +常见问题 |coc-faq| +更新日志 |coc-changelog| + +============================================================================== + +介绍 *coc-introduction* + +coc.nvim 为您提供全方位的 LSP 特性支持,包含智能补全、错误提示、参数 +提示等功能,关于 LSP 的详细特性请查看官方文档: + +https://microsoft.github.io/language-server-protocol/ + +由于社区提供 language server 能力有限,coc.nvim 同时提供了加载插件的能力, +部分插件由 VSCode 插件改写,提供与 VSCode 一样,甚至更多的功能。例如: + +https://github.com/neoclide/coc-tsserver + +coc.nvim 使用 coc-settings.json 文件进行配置,该文件格式与工作方式与 VSCode +完全相同,你可以安装 coc-json 插件来提供配置的补全、验证等功能。 + +与 VSCode 一样,大部分设置在修改保存后立刻生效,不需要重启操作。 + +============================================================================== + +依赖 *coc-requirement* + +该插件需要 neovim 0.3 版本以上或者 vim 8.0 版本以上 + +首先需要安装 node https://nodejs.org/en/download/ 用于执行 javascript 代码。 + +============================================================================== + +安装 *coc-install* + +推荐使用 https://github.com/junegunn/vim-plug 添加 +> + Plug 'neoclide/coc.nvim', {'branch': 'release'} + +到 `init.vim` 然后执行: > + + :PlugInstall + +如果使用其它插件进行配置,请使用 release 分支代码。 + +============================================================================== + +配置 *coc-configuration* + +可通过 `coc-settings.json` 文件进行配置,该文件为 jconc 格式,就是添加了 +注释格式支持的 json。 + +使用命令 |:CocConfig| 打开用户配置文件,或者在项目根目录下创建 +`.vim/coc-settings.json` 文件,后者优先级更高。 + +执行命令 `:CocInstall coc-json` 安装 json 语言支持,该插件可提供配置补全 +和验证等功能。 + +============================================================================== + +补全 *coc-completion* + + +补全默认是自动触发的,你可以根据自己喜好进行调整。 + +关闭自动补全: > + + "suggest.autoTrigger": "none", +< +进入插入模块即触发自动补全: > + + "suggest.triggerAfterInsertEnter": true, + +调整补全超时时间: > + + "suggest.timeout": 500, +< +补全开启时选中第一项: > + + "suggest.noselect": false, + +保留使用当前的 `completeopt` : +> + + "suggest.keepCompleteopt": true, +< + 注意: 如果你的 completeopt 包含 menu 选项,自动补全将被关闭。 + +让 vim 弹出预览窗口: > + + "suggest.enablePreview": true +< +设置最少补全触发字符数: > + + "suggest.minTriggerInputLength": 2 +< +支持提交字符特性: > + + "suggest.acceptSuggestionOnCommitCharacter": true +< +改变代码片段的提示字符: > + + "suggest.snippetIndicator": "⭐︎" + +------------------------------------------------------------------------------ + +定制补全体验 + +使用 强制触发补全: > + + inoremap coc#refresh() +< +使用 `` 确认补全: > + + inoremap pumvisible() ? "\" : "\" +< +注意: `snippet` 和 `additionalTextEdit` 特性只有在确认补全后才会生效。 + +查看更多补全配置技巧: https://bit.ly/2VaVQ9A + +============================================================================== + +接口 *coc-interface* + +------------------------------------------------------------------------------ + +coc 不会向 vim 添加自己的快捷键,你需要手工配置来满足需要。 + +------------------------------------------------------------------------------ + +快捷键 *coc-key-mappings* + +注意: `i_` 打头的映射仅在插入模式下工作,`n_ `打头的映射仅在正常模式下工作。 + +(coc-diagnostic-info) *n_coc-diagnostic-info* + + 显示当前位置下的错误信息,没有截断。 + +(coc-diagnostic-next) *n_coc-diagnostic-next* + + 跳转到下一个错误处。 + +(coc-diagnostic-prev) *n_coc-diagnostic-prev* + + 跳转到上一个错误处。 + +(coc-definition) *n_coc-definition* + + 跳转到定义位置。 + +(coc-declaration) *n_coc-declaration* + + 跳转到声明位置。 + +(coc-implementation) *n_coc-implementation* + + 跳转到实现位置。 + +(coc-type-definition) *n_coc-type-definition* + + 跳转到类型定义位置。 + +(coc-references) *n_coc-references* + + 跳转到引用位置。 + +(coc-format-selected) *n_coc-format-selected* + *v_coc-format-selected* + + 格式化选中区间,可在正常和可视模式下工作。 + + 正常模式下时作用于 motion 对象。 + + 例如: > + + vmap p (coc-format-selected) + nmap p (coc-format-selected) +< + 表示使用 `p` 格式化选中区间,使用 `pap` 格式化 + 当前段落。 + +(coc-format) *n_coc-format* + + 格式化当前 buffer。 + +(coc-rename) *n_coc-rename* + + 重命名光标所在位置符号。 + +(coc-codeaction) *n_coc-codeaction* + + + 获取并执行 language server 给出的当前缓冲区的 + 可用操作。 + +(coc-codeaction-selected) *n_coc-codeaction-selected* + *v_coc-codeaction-selected* + + 获取并执行 language server 给出的当前选择区间 + 内的可用操作。 + +(coc-openlink) *n_coc-openlink* + + 打开鼠标位置下的链接。 + +(coc-codelens-action) *n_coc-codelens-action* + + 执行 codelens 给出的动作。 + + 需要设置 `"codeLens.enable":true` 开启 codeLens + 支持,该功能需要 neovim 支持 virtual text 特性。 + +(coc-fix-current) *n_coc-fix-current* + + 修复当前行可修复的第一个错误修复操作。 + + +(coc-float-hide) *n_coc-float-hide* + + 隐藏所有浮动窗口。 + +(coc-float-jump) *n_coc-float-jump* + + 跳转到第一个浮动窗口。 + +(coc-refactor) *n_coc-refactor* + + 打开重构窗口,用于重构当前函数或重命名。 + +(coc-range-select) *n_coc-range-select* +(coc-range-select) *v_coc-range-select* + + 选择下一个可选区域。 + + 注意:仅部分语言服务支持。 + +(coc-range-select-backward) *v_coc-range-select-backward* + + 选择上一个可选区域。 + + 注意:仅部分语言服务支持。 + +(coc-funcobj-i) *n_coc-funcobj-i* *v_coc-funcobj-i* + + 选择函数内所有行,默认映射到 `if` 。 + + 例如:使用 `cif` 重写当前函数。 + +(coc-funcobj-a) *n_coc-funcobj-a* *v_coc-funcobj-a* + + 选择当前函数所在区间,默认映射到 `af`。 + +============================================================================== + +变量 *coc-variables* + +b:coc_enabled *b:coc_enabled* + + 为 `0` 时该缓存区将被 coc.nvim 忽略,仅在缓存区创建时设 + 置有效。 + +b:coc_root_patterns *b:coc_root_patterns* + + 当前 buffer 的 workspaceFolder 定位文件列表,用于覆盖 + 全局的 `"coc.preferences.rootPatterns"` 设置。 例如: > + + autocmd FileType python let b:coc_root_patterns = + \ ['.git', '.env'] + +b:coc_suggest_disable *b:coc_suggest_disable* + + 用于针对特定 buffer 禁用补全,例如: > + + " 对 python 文件禁用补全 + autocmd FileType python let b:coc_suggest_disable = 1 + +b:coc_additional_keywords *b:coc_additional_keywords* + + 生成单词列表所用的额外 keyword 字符,例如: > + + " Add keyword characers for css + autocmd FileType css let b:coc_additional_keywords = ["-"] + +b:coc_suggest_blacklist *b:coc_suggest_blacklist* + + 禁用部分单词触发补全,例如: > + + " Disable completion for 'end' in lua file + autocmd FileType lua let b:coc_suggest_blacklist = ["end"] + +b:coc_diagnostic_info *b:coc_diagnostic_info* + + 当前缓冲区的错误信息,格式为: + + `{'error': 0, 'warning': 0, 'information': 0, 'hint':0}` + + 用于自定义状态栏,查看 |coc-status|. + +b:coc_current_function *b:coc_current_function* + + 当前光标所在函数名。 + + 在配置文件中添加: + `"coc.preferences.currentFunctionSymbolAutoUpdate": true` + 启用 CursorHold 时自动更新。 + +g:coc_start_at_startup *g:coc_start_at_startup* + + + 在 vim 启动时启动 coc 服务。如果设置为 0,需要手工 + 执行 |:CocStart| 命令启动服务。 + + 默认: 1 + +g:coc_user_config *g:coc_user_config* + + 配置 coc 的用户配置,推荐使用 coc-settings.json 文件 + 进行配置,而不是该变量。 + + 该设置仅在服务启动前有效。 + +g:coc_extension_root *g:coc_extension_root* + + 自定义插件安装根目录,为空时使用默认地址。 + + Windows 系统: + `~/AppData/Local/coc/extensions` + 其它: + `~/.config/coc/extensions` + + +g:coc_global_extensions *g:coc_global_extensions* + + 用户设置需要安装的插件,coc 会检测其中未安装的插件在 + vim 启动后使用异步方式进行安装,推荐使用 + |coc#add_extension()| 函数进行配置。 + + 该设置仅在服务启动前有效。 + +g:coc_enable_locationlist *g:coc_enable_locationlist* + + 自动打开 CocList 提供地址列表,如果使用其它插件提供 + 地址列表,可设置该数值为 0 + + 默认: 1 + +g:coc_snippet_next *g:coc_snippet_next* + + 跳转到下一个代码片段占位符的快捷键。 + 仅在代码片段生效时有效。 + + 默认: + +g:coc_snippet_prev *g:coc_snippet_prev* + + 跳转到上一个代码片段占位符的快捷键。 + 仅在代码片段生效时有效。 + + 默认: + +g:coc_filetype_map *g:coc_filetype_map* + + 文件类型映射字典,用于让 language server 支持更多 + 的文件类型,例如: > + + let g:coc_filetype_map = { + \ 'html.swig': 'html', + \ 'wxss': 'css', + \ } +< + 默认: {} + + 注意: 为了与 VSCode 一致,coc 总是把 `javascript.jsx` + 映射为 `javascriptreact` , `typescript.tsx` 映射为 + `typescriptreact`. + +g:coc_selectmode_mapping *g:coc_selectmode_mapping* + + 是否启动选择模式映射。 > + + snoremap c + snoremap c + snoremap c + snoremap "_c +< + 默认: 1 + + +g:coc_force_debug *g:coc_force_debug* + + + 强制使用编译后的代码 javascript 代码,默认情况下如果存在 + 已编译版本, coc 将优先使用已编译版本。 + + 默认: 0 + +g:coc_node_path *g:coc_node_path* + + 启动 coc 服务的 node 路径,例如: > + + let g:coc_node_path = '/usr/local/opt/node@10/bin/node' +< + 该配置仅在手工编译代码时生效。 + +g:coc_node_args *g:coc_node_args* + + + 服务启动时 node 命令额外参数。启动 debug 模式可配置: > + + let g:coc_node_args = ['--nolazy', '--inspect-brk=6045'] +< + 默认: [] + + +g:coc_process_pid *g:coc_process_pid* + + coc 服务的进程 id。 + +g:coc_status_error_sign *g:coc_status_error_sign* + + + 状态栏使用的错误提示字符,默认 `E` + +g:coc_status_warning_sign *g:coc_status_warning_sign* + + 状态栏使用的警告提示字符,默认 `W` + +g:coc_status *g:coc_status* + + 插件给出的提示信息,用于状态栏使用。 + +g:WorkspaceFolders *g:WorkspaceFolders* + + 当前的 workspaceFolders,用于 session 使用。 + 需添加 `set sessionoptions+=globals` 让 session 支持 + globals 变量。 + +------------------------------------------------------------------------------ + +函数 *coc-functions* + +coc 在 vim 启动后异步启动服务,多数函数并不能在 vim 启动后立刻使用, +如果你想在服务启动调用函数,需要使用自动命令,例如: > + + autocmd User CocNvimInit call CocAction('runCommand', + \ 'tsserver.watchBuild') +< + *coc#config()* +coc#config({section}, {value}) + + 设置用户配置,该函数不会修改配置文件,该函数可用于动态修改配置。 + + 例如: > + + call coc#config('coc.preferences', { + \ 'timeout': 1000, + \}) + call coc#config('languageserver', { + \ 'ccls': { + \ "command": "ccls", + \ "trace.server": "verbose", + \ "filetypes": ["c", "cpp", "objc", "objcpp"] + \ } + \}) +< + + 注意: 该函数可以多处或者在服务未启动时调用。 + + 注意: 该函数可以同时和配置文件工作,建议主要使用配置文件。 + + *coc#add_extension()* +coc#add_extension({name}, ...) + + + 设置需要安装的插件,如果发现未安装插件,coc 将打开终端缓冲窗口 + 执行安装命令。例如: +> + call coc#add_extension('coc-json', 'coc-tsserver', 'coc-rls') +< + 注意: 该函数可以多处或者在服务未启动时调用。 + + + *coc#add_command()* +coc#add_command({id}, {command}, [{title}]) + + 添加自定义的 vim 命令到 `:CocList commands` 列表中,例如: > + + call coc#add_command('mundoToggle', 'MundoToggle', + \ 'toggle mundo window') +< + *coc#refresh()* +coc#refresh() + + + 开启或者刷新补全,返回 vim 表达式,用于绑定 'imap',例如: > + + inoremap coc#refresh() +< + *coc#expandable()* +coc#expandable() + + 检查当前位置是否可以展开代码块。 + 需要安装 `coc-snippets` 插件。 + + *coc#jumpable()* +coc#jumpable() + + 检查当前位置是否可以跳转到下一个代码块位置。 + + *coc#expandableOrJumpable()* +coc#expandableOrJumpable() + + 检查当前位置是否可以展开代码块或者跳转到下一个代码块位置。 + 需要安装 `coc-snippets` 插件。 + + *coc#on_enter()* +coc#on_enter() + + 通知 coc.nvim 回车事件。 + 目前用于 formatOnType 特性。 > + + inoremap pumvisible() ? coc#_select_confirm() + \: "\u\\=coc#on_enter()\" +< + 注意: 开启 formatOnType 需要设置` "coc.preferences.formatOnType": true` + + *coc#status()* +coc#status() + + + 获取状态字符串,包含了 `b:coc_diagnostic_info` 以及 + `g:coc_status`. + + 详情查看 |coc-status| + + *coc#_select_confirm()* +coc#_select_confirm() + + + 执行确认补全操作,如果没有选中项,选中第一个再确认。 + + 注意: 该函数正确工作需要 |CompleteChanged| 自动命令支持。 + + *health#coc#check()* +health#coc#check() + + 由 neovim 的 |:checkhealth| 触发,检测依赖以及服务状态。 + + *coc#util#job_command()* + +coc#util#job_command() + + 获取服务启动执行的命令。 + + *coc#util#get_config_home()* +coc#util#get_config_home() + + 获取用户配置文件所在目录。 + + *coc#util#install()* +coc#util#install([{config}]) + + 安装打包后的 coc.nvim javascript 部分代码。 + + {config} 可包含: + + - `terminal` 使用 terminal 来异步安装 + - `tag` 安装最新的已发布版本 + + *coc#util#extension_root()* +coc#util#extension_root() + + 获取插件根目录。 + + *coc#util#rebuild()* +coc#util#rebuild() + + 对插件执行 `npm rebuild` 命令。 + + *coc#util#has_float()* + +coc#util#has_float() + + 检测是否存在浮动窗口。 + + *coc#util#float_scrollable()* + +coc#util#float_scrollable() + + 检测是否存在可滚动的浮动窗口。 + + *coc#util#float_scroll()* +coc#util#float_scroll({forward}) + + 用于创建滚动浮动窗口的映射,例如: > + + nnoremap coc#util#has_float() ? coc#util#float_scroll(1) : "\" + nnoremap coc#util#has_float() ? coc#util#float_scroll(0) : "\" +< + *CocRequest()* +CocRequest({id}, {method}, [{params}]) + + 向指定 language server 发送请求。 + + {id} - language server 唯一 id + {method} - 方法名称 + {params} - 可选参数 + > + call CocRequest('tslint', 'textDocument/tslint/allFixes', + \ {'textDocument': {'uri': 'file:///tmp'}}) +< + 发生错误会导致 vim 错误。 + + *CocRequestAsync()* +CocRequestAsync({id}, {method}, [{params}, [{callback}]]) + + 向指定 language server 发送异步请求。 + + {callback} 在请求完成后被调用,第一个参数总是 {error}, + 第二个参数为响应结果。 + + *CocLocations()* +CocLocations({id}, {method}, [{params}, {openCommand}]) + + 从指定 language server 获取地址列表。例如: + > + call CocLocations('ccls', '$ccls/call', {'callee': v:true}) + + call CocLocations('ccls', '$ccls/call', {}, 'vsplit') +< + {openCommand}: 缓冲区打开方法,默认使用 + `coc.preferences.jumpCommand` 打开。 设置为 `v:false` 时总是使用 + locations 列表。 + + *CocLocationsAsync()* +CocLocationsAsync({id}, {method}, [{params}, {openCommand}]) + + 同 |CocLocations()| 一样,只是使用 notification 异步进行。 + + *CocAction()* +CocAction({action}, [...{args}]) + + 执行 CocAction。详见下方列表。 + + *CocActionAsync()* + +CocActionAsync({action}, [...{args}, [{callback}]]) + + 异步执行 CocAction。详见下方列表。 + + {callback} 第一个参数为 {error},第二个为 {response} + +------------------------------------------------------------------------------ + +可用的 Actions 列表 + +"sourceStat" *coc-action-sourceStat* + + 获取已加载补全源列表。 + +"refreshSource" [{source}] *coc-action-refreshSource* + + 刷新指定补全源。 + +"toggleSource" {source} *coc-action-toggleSource* + + 启用/禁用 {source}. + +"diagnosticList" *coc-action-diagnosticList* + + 获取诊断列表。 + +"diagnosticInfo" *coc-action-diagnosticInfo* + + 显示当前位置诊断详情,没有截断。 + +"jumpDefinition" [{openCommand}] *coc-action-jumpDefinition* + + 跳转到定义处。 + + 如有多个定义,使用 |coc-list| 展示。 + + {openCommand}: 可选打开命令,默认为 `coc.preferences.jumpCommand`, + 设置为 `v:false` 时总是使用 locations 列表。 + +"jumpDeclaration" [{openCommand}] *coc-action-jumpDeclaration* + + 跳转到声明处。 + + 行为与 "jumpDefinition" 相同。 + +"jumpImplementation" [{openCommand}] *coc-action-jumpImplementation* + + 跳转到实现处。 + + 行为与 "jumpDefinition" 相同。 + +"jumpTypeDefinition" [{openCommand}] *coc-action-jumpTypeDefinition* + + 跳转到类型定义处。 + + 行为与 "jumpDefinition" 相同。 + +"jumpReferences" [{openCommand}] *coc-action-jumpReferences* + + 跳转到引用处。 + + 行为与 "jumpDefinition" 相同。 + +"doHover" *coc-action-doHover* + + 显示当前位置的悬浮信息。 + + 使用 `coc.preferences.hoverTarget` 改变信息显示方式,默认为预览窗口。 + + 后续将支持浮动窗口。 + +"showSignatureHelp" *coc-action-showSignatureHelp* + + 显示当前函数的函数签名,推荐设置: > + + autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp') +< + 在代码片段跳转后显示函数签名。 + +"getCurrentFunctionSymbol" *coc-action-getCurrentFunctionSymbol* + + 获取当前光标所在的函数名称。 + +"documentSymbols" *coc-action-documentSymbols* + + 获取当前文档的符号列表。 + +"rename" *coc-action-rename* + + 重命名当前光标所在字符。 + +"workspaceSymbols" *coc-action-workspaceSymbols* + + 搜索工作目录下所有符号。 + +"selectionRanges" *coc-action-selectionRanges* + + 获取当前位置的可选区域列表。 + +"services" *coc-action-services* + + 获取所有服务列表。 + +"toggleService" {serviceId} *coc-action-toggleService* + + 开启或停止指定服务。 + +"format" *coc-action-format* + + 格式化当前缓冲区,需要 language server 支持格式化功能。 + +"formatSelected" [{mode}] *coc-action-formatSelected* + + 格式化选中区间,{mode} 可以为 `v` , `V`, `char`, `line` 之一。 + + 如果不提供 {mode}, 该函数必须设置为 |formatexpr| 使用。 + + +"codeAction" [{mode}] [{only}] *coc-action-codeAction* + + 执行 codeAction。 + + {mode} 为 visualmode() 返回结果。 + + {only} 可以是某个 codeAction 的 title,或者是 CodeActionKind 列表 + +"codeLensAction" *coc-action-codeLensAction* + + 执行 codeLens 给出的 codeAction。 + + 存在多个时弹出选择提示。 + +"commands" *coc-action-commands* + + 获取当前缓冲区可用命令列表。 + +"runCommand" [{name}] [...{args}] *coc-action-runCommand* + + 执行 {name} 命令,如果不提供 {name},则提示进行选择。 + + {args} 做为参数传递给对应命令。 + + 对于常用命令,可以设置更方便使用的命令,例如: > + + command! -nargs=0 OR + \ :call CocActionAsync('runCommand', 'tsserver.organizeImports') + +"fold" {{kind}} *coc-action-fold* + + 折叠当前缓冲区,该方法需要 language server 支持。 + + {kind} 可以为'comment', 'imports' and 'region' 之一。 + +"highlight" *coc-action-highlight* + + 高亮鼠标所在的字符。 + + 推荐配置 CursorHold 进行高亮: > + + autocmd CursorHold * silent call CocActionAsync('highlight') +< + 注意: 请确保 'updatetime' 选项不要设置的太高。 + +"openLink" [{command}] *coc-action-openlink* + + 打开光标所在位置的链接。{command} 默认为 + `"coc.preferences.jumpCommand"` + + 支持文件和 url 链接。 + +"extensionStats" *coc-action-extensionStats* + + 获取所有插件的状态列表,包含 `id` `root` 和 `state` + + `state` 可以为 `disabled`, `activated` 和 `loaded`。 + +"toggleExtension" {id} *coc-action-toggleExtension* + + 启用/禁用指定插件。 + +"uninstallExtension" {id} *coc-action-uninstallExtension* + + 卸载指定插件。 + +"reloadExtension" {id} *coc-action-reloadExtension* + + 重加载指定插件。 + +"deactivateExtension" {id} *coc-action-deactivateExtension* + + 停用指定插件。 + +"pickColor" *coc-action-pickColor* + + 改变光标所在的颜色。 + + 需要 language server 支持 document color 功能。 + + 推荐安装 coc-highlight 插件在所有文件中支持该功能。 + + 注意: 仅在 Mac 系统或者 vim 支持 python 且已安装 gtk 模块时可用。 + +"colorPresentation" *coc-action-colorPresentation* + + 改变当前位置颜色显示方式。 + + 需要 language server 支持 color representation 请求。 + + 推荐安装 coc-highlight 插件在所有文件中支持该功能。 + +"codeActions" [{visualmode}] *coc-action-codeActions* + + 获取当前行的所有 codeActions,指定 {visualmode} + 获取上一次选择区间的中的 codeActions. + +"quickfixes" [{visualmode}] *coc-action-quickfixes* + + 获取当前行的 quickfix codeActions,指定 {visualmode} + 获取上一次选择区间的中的 quickfixes. + +"doCodeAction" {codeAction} *coc-action-doCodeAction* + + 执行指定 codeAction。 + +"doQuickfix" *coc-action-doQuickfix* + + 执行当前行第一个 quickfix action,用于快速修复。 + +"addRanges" {ranges} *coc-action-addRanges* + + Ranges 必须为 LSP 定义的 Range 数组: https://git.io/fjiEG + +============================================================================== + +命令 *coc-commands* + +:CocStart *:CocStart* + + 启动 coc 服务,如果已启动则什么都不做。 + +:CocDisable *:CocDisable* + + 停用所有 coc 功能。 + +:CocEnable *:CocEnable* + + 启用搜索 coc 功能。 + +:CocRestart *:CocRestart* + + 重启 coc 服务。 + + 遇到问题,推荐使用该命名而不是重启 vim。 + +:CocConfig *:CocConfig* + + 打开用户的 `coc-settings.json` 文件。 + +:CocInstall [{option}] {name} ... *:CocInstall* + + 安装一个或多个 coc 插件。 + + {option}: 可以使用 `-sync` 用同步方式而不是 terminal + 安装插件。 + + 访问 https://www.npmjs.com/search?q=keywords%3Acoc.nvim + 获取所有 coc 插件。 + +:CocUninstall {name} *:CocUninstall* + + 卸载指定 coc 插件,支持使用 进行补全。 + +:CocUpdate *:CocUpdate* + + 升级所有 coc 插件。 + + 升级前请尽可能确保 coc 为最新版本,否则升级可能失败, + 因为插件可能使用了新版 API 导致不兼容。 + +:CocUpdateSync *:CocUpdateSync* + + 同步方式升级所有插件。 + +:CocRebuild *:CocRebuild* + + 针对插件执行 `npm rebuild` 命令。 + + 升级 nodejs 后可能会需要。 + +:CocCommand {name} [{args}] ... *:CocCommand* + + 执行某个插件提供的命令,支持使用 对 {name} 补全。 + +:{range}CocAction [{only}] *:CocAction* + + 获取当前 buffer 所有的 codeActions 到 actions 列表, + 支持 {range}。 + + {only} 可以为 'quickfix' 或者 'source'。 + +:{range}CocFix *:CocFix* + + 同 `:CocAction quickfix` 一样。 + +:CocOpenLog *:CocOpenLog* + + 打开 coc 的日志文件,默认级别为 info。 + + 设置 `NVIM_COC_LOG_LEVEL` 改变日志级别,例如: > + + export NVIM_COC_LOG_LEVEL=debug +< + 或者添加: > + + let $NVIM_COC_LOG_LEVEL='debug' +< + 到 .vimrc 。 + +:CocInfo *:CocInfo* + + 获取当前系统版本以及日志等信息,bug 报告需提供该命令给出内容。 + +============================================================================== + +自动命令 *coc-autocmds* + + *CocLocationsChange* + + +:autocmd User CocLocationsChange {command} + + 当地址列表变化时触发。 + + 如果你不想用默认 |CocList| 或者想修改默认的选项来展示地址列表, + 可用于自动命令配合其它插件来显示地址列表。 + + 需同时将 |g:coc_enable_locationlist| 设置为 0,例如: +> + let g:coc_enable_locationlist = 0 + autocmd User CocLocationsChange CocList --normal -A location +< + *CocNvimInit* +:autocmd User CocNvimInit {command} + + 服务启动后触发。可用于服务启动后自动执行命令。 + + *CocStatusChange* + +:autocmd User CocStatusChange {command} + + `g:coc_status` 改变时触发,可用于刷新状态栏。 + + *CocDiagnosticChange* + +:autocmd User CocDiagnosticChange {command} + + 错误信息变化时触发,可用于强制更新状态栏。 + + *CocJumpPlaceholder* + +:autocmd User CocJumpPlaceholder {command} + + 跳转占位符时触发。可用于跳转后自动显示函数签名。例如: > + + autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp') + +============================================================================== + +高亮 *coc-highlights* + +使用 |:hi| 命令可以改变 coc 提供的高亮。例如: > + + " 让错误文本显示为红色 + highlight CocErrorHighlight ctermfg=Red guifg=#ff0000 +< +注意: highlight 命令必须在 |:colorscheme| 命令之后使用。 + +注意: 不要使用 `:hi default` + +CocErrorSign *CocErrorSign* + + 默认: `hi CocErrorSign ctermfg=Red guifg=#ff0000` + + 错误标记符使用的高亮。 + +CocWarningSign *CocWarningSign* + + 默认: `hi CocWarningSign ctermfg=Brown guifg=#ff922b` + + 警告标记符使用的高亮。 + +CocInfoSign *CocInfoSign* + + 默认: `hi CocInfoSign ctermfg=Yellow guifg=#fab005` + + 信息标记符使用的高亮。 + +CocHintSign *CocHintSign* + + 默认: `hi CocHintSign ctermfg=Blue guifg=#15aabf` + + 提醒标记符使用的高亮。 + +CocErrorHighlight *CocErrorHighlight* + + 默认: `hi default link CocErrorHighlight CocUnderline` + + 错误文本使用的高亮。 + +CocWarningHighlight *CocWarningHighlight* + + 默认: `hi default link CocWarningHighlight CocUnderline` + + 警告文本使用的高亮。 + +CocInfoHighlight *CocInfoHighlight* + + 默认: `hi default link CocInfoHighlight CocUnderline` + + 信息文本使用的高亮。 + +CocHintHighlight *CocHintHighlight* + + 默认: `hi default link CocHintHighlight CocUnderline` + + 提醒文本使用的高亮。 + +CocHighlightText *CocHighlightText* + + 默认: `hi default link CursorColumn` + + Document highlight 特性使用的高亮。用于高亮显示全部当前缓冲区的相同 + 变量。 + +CocHighlightTextRead *CocHighlightTextRead* + + 默认: `hi default link CocHighlightRead CocHighlightText` + + 用于显示 `Read` 类型的变量。 + +CocHighlightTextWrite *CocHighlightTextWrite* + + 默认: `hi 默认 link CocHighlightWrite CocHighlightText` + + 用于显示 `Write` 类型的变量。 + +CocErrorLine *CocErrorLine* + + 默认: `undefined` + + 错误行的高亮。 + +CocWarningLine *CocWarningLine* + + 默认: `undefined` + + 警告行的高亮。 + +CocInfoLine *CocInfoLine* + + 默认: `undefined` + + 信息行的高亮。 + +CocHintLine *CocHintLine* + + 默认: `undefined` + + 提示行的高亮。 + +CocCodeLens *CocCodeLens* + + 默认:``ctermfg=Gray guifg=#999999` + + 显示 codeLens 信息使用虚拟文本高亮。 + +CocFloating *CocFloating* + + 默认: `Pmenu` + + 悬浮窗口背景高亮。 + +CocErrorFloat *CocErrorFloat* + + 默认: `hi default link CocErrorFloat CocErrorSign` + + 错误浮窗符使用的高亮。 + +CocWarningFloat *CocWarningFloat* + + 默认: `hi default link CocWarningFloat CocWarningSign` + + 警告浮窗符使用的高亮。 + +CocInfoFloat *CocInfoFloat* + + 默认: `hi default link CocInfoFloat CocInfoSign` + + 信息浮窗符使用的高亮。 + +CocHintFloat *CocHintFloat* + + 默认: `hi default link CocHintFloat CocHintSign` + + 提醒浮窗符使用的高亮。 + +CocCursorRange *CocCursorRange* + + Default: `hi default link CocCursorRange Search` + + 鼠标选择区使用的高亮。 + +============================================================================== + +LIST SUPPORT *coc-list* + +自带列表功能可以更轻易与 coc 提供的不同列表进行交互。 + +Coc 列表支持以下特性: + +* 插入和正常模式。 +* 提供默认快捷键。 +* 自定义不同模式下的快捷键。 +* 提供重开之前列表以及操作前/后一个项目的命令。 +* 可设置使用不同的过滤匹配模式。 +* 实时交互模式。 +* 自动预览功能。 +* 数字键选择功能。 +* 支持多种操作。 +* 解析 ansi 高亮。 +* 鼠标支持。 +* 使用 选择操作。 +* 正常模式下使用 进行多选操作。 + +------------------------------------------------------------------------------ + +LIST COMMAND *coc-list-command* + +:CocList [{...options}] [{source}] [{...args}] *CocList* + + 打开名称为 {source} 的列表, 例如: > + + :CocList --normal location +< + 打开当前的跳转列表。 + + 查看 |coc-command-options| 获取可用的 {options}。 + + {args} 为传递给对应源的参数。 + + {source} 为空时,打开列表源的列表。 + +:CocListResume *CocListResume* + + 重新打开上一次的列表,输入字符和鼠标位置等信息将自动 + 复原。 + +:CocPrev *CocPrev* + + 对之前列表的上一个选项执行默认操作。 + + 该操作不会打开之前列表。 + +:CocNext *CocNext* + + 对之前列表的下一个选项执行默认操作。 + + 该操作不会打开之前列表。 + +Command options *coc-list-options* + +--top + 在上方显示列表分割窗口,默认为下方显示。 + +--tab + 使用新标签页打开列表。 + +--normal + 打开后进入正常模式,默认为输入模式。 + +--no-sort + 关闭 coc 提供排序,使用源本身给出的排序。 + +--input={input} + 设置列表的初始输入。 + +--strict +-S + 使用精确匹配,而不是默认的模糊匹配。 + +--regex +-R + 使用正则匹配,而不是默认的模糊匹配。 + +--ignore-case + 匹配时忽略大小写,仅在使用精确或正则匹配时有效。 + +--number-select +-N + 开启数字选择模式,可在正常模式下使用 1-9 选择对应行的项目。 + 使用 0 选择第 10 行。 + +--interactive +-I + 使用实时模式,开启后输入变化时所有选项不由 coc 本身进行过滤 + 排序,而是每次都从后端重新请求结果。 + + 注意:该模式需要列表源支持才可开启,大部分源并不支持该模式。 + + 注意: 开启后过滤和排序完全由列表源进行。 + +--auto-preview +-A + 开启自动预览模式,开启后预览窗口将自动打开。 + +------------------------------------------------------------------------------ + +LIST CONFIGURATION *coc-list-configuration* + +CocList 同样使用 `coc-settings.json` 文件来进行配置。 + +安装 coc-json 插件后可以在 coc-settings.json 文件中输入 `list.` 来获取所有 +list 相关可用配置项。 + +针对特性的 list 源,可使用以 `list.source.{name}` 开头的配置项来设置。 + +修改指定源的默认选项:~ + +使用 `list.source.{name}.defaultOptions` 配置,例如: > + + // 让 symbols 列表启用 interactive 模式,同时支持数字键选中 + "list.source.symbols.defaultOptions": ["--interactive", "--number-select"], +< + 注意: 部分源只能在 interactive 模式下工作,所以推荐使用配置让 + interactive 总是生效。 + +注意: 如果通过命令行传递了参数,默认选项将不会生效。 + +设置指定源默认参数:~ + +使用 `list.source.{name}.defaultArgs` 配置,例如: > + + // 配置 grep 源默认使用正则匹配 + "list.source.grep.defaultArgs": ["-regex"], + +注意: 默认参数仅在命令行调用参数为空时生效。 + +在正常模式键入 `?` 可以查看当前源的详细文档。 + +------------------------------------------------------------------------------ + +LIST MAPPINGS *coc-list-mappings* + +插入模式下的默认快捷键: + + - 退出当前列表。 + - 结束后台任务。 + - 重载当前列表。 + - 切换到正常模式。 + - 选择下一项。 + - 选择上一项。 + - 鼠标左移一格。 + - 鼠标右移一格。 + - 移动鼠标到末尾。 + - 移动鼠标到末尾。 + - 移动鼠标到起始位置。 + - 移动鼠标到起始位置。 + - 向前滚动窗口。 + - 向后滚动窗口。 + - 移除上一个字符。 + - 移除上一个字符。 + - 移除上一个单词。 + - 移除光标之前全部输入。 + - 切换到下一个历史匹配输入。 + - 切换到上一个历史匹配输入。 + - 切换过滤匹配模式。 + - 从 vim 寄存器插入内容。 + - 选择操作项。 + +正常模式下默认快捷键: + + - 退出当前列表。 + - 停止后台任务。 + - 重载当墙列表。 + - 将所有展示项目设置为选中状态。 + - 选择操作项。 + - 切换当前项选中状态。 +i,I,o,O,a,A - 切换到插入模式。 +p - 执行“预览”操作。 +: - 结束列表但不关闭窗口。 +? - 显示帮助文档,暂时仅支持 neovim。 +t - 执行 'tabe' 操作. +d - 执行 'drop' 操作. +s - 执行 'split' 操作. + +使用 |coc-list-mappings-custom| 可覆盖默认提供的映射。 + + *coc-list-mappings-custom* +使用配置项 `"list.normalMappings"` 和 `"list.insertMappings"` 来添加 +自定义配置。例如: > + + "list.insertMappings": { + "": "do:refresh", + "": "feedkeys:\\", + "": "feedkeys:\\", + "": "normal:j", + "": "normal:k", + "": "action:tabe", + "": "call:MyFunc" + "": "eval:@@" + } + "list.normalMappings": { + "c": "expr:MyExprFunc" + "d": "action:delete" + } +< +注意: 针对插入模式的映射,应该只使用 ` 无法被重新映射,因为那样可能导致无法关闭窗口。 + +映射表达式格式为 `command:arguments`,可用命令如下: + +'do' - coc 相关特定操作: + 'refresh' - 刷新列表 + 'exit' - 退出列表 + 'selectall' - 将所有展示项目设置为选中状态 + 'switch' - 切换过滤匹配模式 + 'stop' - 停止加载任务 + 'cancel' - 取消列表同时保留窗口 + 'toggle' - 切换当前项选中状态 + 'previous' - 移动到前一个项目 + 'next' - 移动到后一个项目 + 'defaultaction' - 执行默认操作 + 'help' - 显示帮助 +'prompt' - 提示栏相关操作: + 'previous' - 切换到匹配历史记录的上一个 + 'next' - 切换到匹配历史记录的下一个 + 'start' - 移动光标到开头 + 'end' - 移动光标到结尾 + 'left' - 左移光标 + 'right' - 右移光标 + 'deleteforward' - 删除前一个字符 + 'deletebackward' - 删除后一个字符 + 'removetail' - 删除后面全部字符 + 'removeahead' - 删除前面全部字符 + 'insertregister' - 从 vim 寄存器插入内容 + 'paste' - 插入系统粘贴板内容到当前位置 +'eval' - 执行 viml 表达式并将结果插入到当前位置 +'action' - 执行特定操作,使用 查看当前列表支持操作 +'feedkeys' - 发送按键到列表窗口 +'normal' - 执行 normal 命令 +'normal!' - 执行 normal! 命令 +'command' - 执行 vim 命令 +'call' - 调用 vim 函数,发送 |coc-list-context| 做为唯一参数 +'expr' - 与 'call' 相同,但是函数必须返回的待执行的操作名称 + + *coc-list-context* + +Context 参数包含以下属性: + +'name' - 列表名称,例如: `'location'` +'args' - 传递给列表源使用的参数 +'input' - 当前输入 +'winid' - 列表的 window id +'bufnr' - 列表启动时的缓冲区的 bufnr +'targets' - 当前选中项目列表, 详见: |coc-list-target| + + *coc-list-target* + +Target 包含以下属性: + +'label' - 缓冲区显示的文本,必填属性 +'filtertext' - 可选的过滤用文本 +'location' - 可选的位置信息,详情查看: https://bit.ly/2Rtb6Bo +'data' - 可选的额外信息 + +============================================================================== + +LIST SOURCES *coc-list-sources* + +location *coc-list-location* + + 最近跳转列表。 + + 可用操作: + + - 'open': 使用 `"coc.preferences.jumpCommand"` 配置打开, 默认操作 + - 'preview' : 打开/关闭预览窗口 + - 'tabe': 使用 |:tabe| 命令打开 + - 'drop': 使用 |:drop| 命令打开 + - 'vsplit': 使用 |:vsplit| 命令打开 + - 'split': 使用 |:split| 命令打开 + - 'quickfix': 将选中项添加到 vim 的 quickfix. + +extensions *coc-list-extensions* + + 插件列表。 + + 可用操作: + + - 'toggle' 激活/停用插件, 默认操作 + - 'disable' 禁用插件 + - 'enable' 启动插件 + - 'lock' 锁定/解除插件在当前版本 + - 'doc' 查看插件文档 + - 'reload' 重载插件 + - 'uninstall' 卸载插件 + +diagnostics *coc-list-diagnostics* + + 错误信息列表。 + + 可用操作查看 |coc-list-location| + +outline *coc-list-outline* + + 当前缓冲区大纲,没有对应 language server 提供 symbols 功能时使用 + ctags 命令生成。 + + 可用操作查看 |coc-list-location| + +symbols *coc-list-symbols* + + 项目内搜索符号,必须配合 `--interactive` 参数使用。 + + 可用操作查看 |coc-list-location| + +services *coc-list-services* + + 已注册服务列表。 + + 可用操作: + + - 'toggle': 开启/关闭服务,默认操作。 + +commands *coc-list-commands* + + 已注册命令列表。 + + 可用操作: + + - 'run': 执行命令,默认操作。 + +links *coc-list-links* + + 当前文档链接列表。 + + 可用操作: + + - 'open': 打开链接, 默认操作。 + - 'jump': 跳转到定义处。 + +output *coc-list-output* + + 输出日志列表。 + + 可用操作: + + - 'open': 打开日志, 默认操作。 + +sources *coc-list-completion-sources* + + 可用补全源列表。 + + 可用操作: + + - 'toggle': 激活/停用选中源, 默认操作。 + - 'refresh': 刷新选中源。 + +lists *coc-list-lists* + + 已注册的列表源列表。 + + 可用操作: + + - 'open': 打开选中列表源,默认操作。 + + +============================================================================== + +状态栏支持 *coc-status* + +状态栏包含两个部分: + +- 错误信息提示 +- 插件提供的状态 + +最简单的使用方式是将 `%{coc#status()}` 添加到 vim 的 'statusline' 选项。 + +------------------------------------------------------------------------------ + + *coc-status-manual* + +手工创建函数: +> + 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 +< +添加 `%{StatusDiagnostic()}` 到 'statusline' 选项。 + +------------------------------------------------------------------------------ + + *coc-status-airline* + +vim-airline: https://github.com/vim-airline/vim-airline 支持: + +vim-airline 提供开箱即用的支持。 + +关闭 vim-airline 集成: +> + let g:airline#extensions#coc#enabled = 0 +< +改变错误标签: +> + let airline#extensions#coc#error_symbol = 'Error:' +< +改变警告标签: +> + let airline#extensions#coc#warning_symbol = 'Warning:' +< +改变错误格式: +> + let airline#extensions#coc#stl_format_err = '%E{[%e(#%fe)]}' +< +改变警告格式: +> + let airline#extensions#coc#stl_format_warn = '%W{[%w(#%fw)]}' + +------------------------------------------------------------------------------ + *coc-status-lightline* + +Lightline.vim: https://github.com/itchyny/lightline.vim 支持: +> + let g:lightline = { + \ 'colorscheme': 'wombat', + \ 'active': { + \ 'left': [ [ 'mode', 'paste' ], + \ [ 'cocstatus', 'readonly', 'filename', 'modified' ] ] + \ }, + \ 'component_function': { + \ 'cocstatus': 'coc#status' + \ }, + \ } + + autocmd User CocStatusChange,CocDiagnosticChange call lightline#update() +< +============================================================================== + +常见问题 *coc-faq* + +------------------------------------------------------------------------------ + +Q: 如何显示当前补全项的文档? + +A: vim 自带的 preview 窗口默认是关闭的,可以设置 + `"suggest.enablePreview":true` 来开启。 + + 如果服务端只在补全项变化时返回文档,该方法将无法显示文档,你需要浮动 + 窗口支持来显示文档,参考文档:https://bit.ly/2NCVh5P + +------------------------------------------------------------------------------ + +Q: 鼠标悬停很久才显示错误信息。 + +A: 你需要配置 `set updatetime=100` 来减少 CursorHold 的触发时间。 + +------------------------------------------------------------------------------ + +Q: 我想用 ale 插件显示错误提示。 + +A: 在配置文件中添加: +> + "coc.preferences.diagnostic.displayByAle": true, +< +------------------------------------------------------------------------------ + +Q: 我想使用 codeLens 特性。 + +A: CodeLens 特性需要支持虚拟文本特性的 neovim 版本,默认状态是关闭的。 + 如需启用,需在配置文件中添加: +> + "coc.preferences.codeLens.enable": true, +< +------------------------------------------------------------------------------ + +Q: 我需要高亮 markdown 中的代码。 + +A: 可以使用支持代码高亮的 markdown 插件,例如: + https://github.com/tpope/vim-markdown, 在 vimrc 中添加如下配置: +> + let g:markdown_fenced_languages = ['css', 'js=javascript'] + +============================================================================== + +变更历史 *coc-changelog* + +查看 ../history.md + +============================================================================== + +vim:tw=78:nosta:noet:ts=8:sts=0:ft=help:noet:fen:fdm=marker: diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/doc/coc.txt b/vim/.vim/pack/coc/start/coc.nvim-release/doc/coc.txt new file mode 100644 index 0000000..433e6d2 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/doc/coc.txt @@ -0,0 +1,2424 @@ +*coc-nvim.txt* LSP support for vim & neovim. + +Version: 0.0.57 +Author: Qiming Zhao +License: MIT license + +CONTENTS *coc-contents* + +Introduction |coc-introduction| +Requirement |coc-requirement| +Install |coc-install| +Configuration |coc-configuration| +Completion |coc-completion| +LanguageServer |coc-languageserver| +Interface |coc-interface| + Keymappings |coc-key-mappings| + Variables |coc-variables| + Functions |coc-functions| + Commands |coc-commands| + Autocmds |coc-autocmds| + Highlights |coc-highlights| +List |coc-list| + List command |coc-list-command| + List configuration |coc-list-configuration| + List mappings |coc-list-mappings| + List sources |coc-list-sources| + Location |coc-list-location| + Extensions |coc-list-extensions| + Diagnostics |coc-list-diagnostics| + Outline |coc-list-outline| + Symbols |coc-list-symbols| + Services |coc-list-services| + Commands |coc-list-commands| + Links |coc-list-links| + Output |coc-list-output| + Sources |coc-list-completion-sources| + Lists |coc-list-lists| +Statusline support |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 is created to make your (neo)vim have more intelligence like VSCode. + +It can:~ + +- Provide APIs that work on both vim8 and neovim. +- Load VSCode like extensions. +- Configure coc.nvim and extensions by use jsonc configuration file. +- Configure language servers that implements LSP. + +It's designed to work well with your other vim plugins as much as possible. + +Note: unlike some of IDEs, it doesn't hijack your experience, you can turn +off any feature whenever you want. + +============================================================================== +REQUIREMENT *coc-requirement* + +Note: this plugin requires neovim >= 0.3.0 or vim >= 8.0. + +Node: https://nodejs.org/en/download/ is required to run javascript code. + +If those requirements are not satisfied, the plugin will not be loaded +at all. + +============================================================================== +INSTALL *coc-install* + +To use the [vim-plug](https://github.com/junegunn/vim-plug), add this: > + + Plug 'neoclide/coc.nvim', {'branch': 'release'} + +to your `init.vim` and run: > + + :PlugInstall + +For other plugin managers, use code from release branch. + +Or use vim's buildin package feature 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 - + # 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 - + +============================================================================== +CONFIGURATION *coc-configuration* + +A JSONC formatted file named `coc-settings.json` is used for configuration. + +Use the command |:CocConfig| to open the user configuration file, or create +`.vim/coc-settings.json` in your project root for folder-based configuration. + +To enable completion and validation support of the settings file, install the +`coc-json` extension: `:CocInstall coc-json`. + +Check out https://github.com/neoclide/coc.nvim/wiki/Using-the-configuration-file +for more details. + +Builtin configurations:~ + +"http.proxy":~ + + HTTP proxy URI, used for extensions that send request, default: `""` + +"http.proxyStrictSSL":~ + + default: `true` + +"suggest.enablePreselect":~ + + Enable preselect feature on neovim, default: `true` + +"suggest.maxPreviewWidth":~ + + Maximum width of floating preview window., default: `80` + +"suggest.labelMaxLength":~ + + Maximum length of label shown in pum, default: `200` + +"suggest.enablePreview":~ + + Add preview option to `completeopt`, default: `false` + +"suggest.floatEnable"~ + + Enable floating window for documentation when possible, default: `true` + +"suggest.detailMaxLength":~ + + Max length of detail that should be shown in popup menu., default: + `100` + +"suggest.detailField":~ + + Where to add the detail in complete item when it's less than max + length., default: `"menu"` + + Valid options: ["abbr","menu","preview"] + +"suggest.autoTrigger":~ + + How should completion be triggered, default: `"always"` + + Valid options: ["always","trigger","none"] + +"suggest.languageSourcePriority":~ + + Priority of language sources., default: `99` + +"suggest.numberSelect":~ + + Input number to select complete item, it could be wrong when + using and to select complete item, default: `false` + +"suggest.disableKind":~ + + Remove kind field from vim complete item., default: `false` + +"suggest.disableMenu":~ + + Remove menu field from vim complete item., default: `false` + +"suggest.snippetIndicator":~ + + The character used in abbr of complete item to indicate the item could + be expand as snippet., default: `"~"` + +"suggest.maxCompleteItemCount":~ + + Maximum number of complete items shown in vim, default: `50` + +"suggest.preferCompleteThanJumpPlaceholder":~ + + Confirm completion instead of jump to next placeholder when completion + is activated., default: `false` + +"suggest.fixInsertedWord":~ + + Make inserted word replace word characters after cursor position., + default: `true` + +"suggest.localityBonus":~ + + Boost suggestions that appear closer to the cursor position., + default: `true` + +"suggest.triggerAfterInsertEnter":~ + + Trigger completion after InsertEnter, auto trigger should be 'always' + to enable this option, default: `false` + +"suggest.timeout":~ + + Timeout for completion, in milliseconds., default: `2000` + +"suggest.minTriggerInputLength":~ + + Minimal input length that triggers completion, default 1, default: `1` + +"suggest.triggerCompletionWait":~ + + Wait time between typing the trigger character and starting + completion, to wait for server content synchronization., default: `60` + +"suggest.echodocSupport":~ + + When enabled, add function signature to `user_data.signature` to support + `echodoc.vim`, default: `false` + +"suggest.acceptSuggestionOnCommitCharacter":~ + + 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., default: `false` + +"suggest.noselect":~ + + Prevent vim from selecting the first item on completion start, default: `true` + +"suggest.keepCompleteopt":~ + + When enabled, `completeopt` is not overridden. Autocompletion will be + disabled if `completeopt` doesn't have `noinsert` and `noselect`., default: + `false` + +"suggest.lowPrioritySourceLimit":~ + + Max items count for source priority lower than 90. + +"suggest.highPrioritySourceLimit":~ + + Max items count for source priority bigger than or equal to 90. + +"suggest.completionItemKindLabels":~ + + Set custom labels to completion items' kinds., default: `{}`. + + Example configuration: with https://nerdfonts.com: > + + "suggest.completionItemKindLabels": { + "keyword": "\uf1de", + "variable": "\ue79b", + "value": "\uf89f", + "operator": "\u03a8", + "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" + } +< +"diagnostic.enable":~ + + Set to false to disable diagnostic display, default: `true` + +"diagnostic.level":~ + + Used for filter diagnostics by diagnostic severity., default: + `"hint"` + + Valid options: ["hint","information","warning","error"] + +"diagnostic.checkCurrentLine":~ + + When enabled, show all diagnostics of current line instead of current + position., default: `false` + +"diagnostic.messageTarget":~ + + Diagnostic message target., default: `"float"` + + Valid options: ["echo","float"] + +"diagnostic.joinMessageLines":~ + + Join lines messages to reduce lines of floating window., default: + `false` + +"diagnostic.refreshOnInsertMode":~ + + Enable diagnostic refresh on insert mode, default false., default: + `false` + +"diagnostic.refreshAfterSave":~ + + Only refresh diagnostics after save, default false., default: `false` + +"diagnostic.displayByAle":~ + + Use Ale for displaying diagnostics in vim. This will disable coc for + displaying diagnostics. Restart required on change., default: `false` + +"diagnostic.virtualText":~ + + Use NeoVim virtual text to display diagnostics, default: `false` + +"diagnostic.virtualTextPrefix":~ + + The prefix added virtual text diagnostics, default: `" "` + +"diagnostic.virtualTextLines":~ + + The number of non-empty lines from a diagnostic to display, default: + `3` + +"diagnostic.virtualTextLineSeparator":~ + + The text that will mark a line end from the diagnostic message, + default: `" \\ "` + +"diagnostic.enableSign":~ + + Enable signs for diagnostics., default: `true` + +"diagnostic.enableMessage":~ + + When to enable echo messages of diagnostics., default: `"always"` + + Valid options: ["always","jump","never"] + +"diagnostic.locationlist":~ + + Create location list for error & warning, default: `true` + +"diagnostic.highlightOffset":~ + + Offset number of buffer.addHighlight, neovim only., default: `1000` + +"diagnostic.signOffset":~ + + Offset number of sign, default: `1000` + +"diagnostic.errorSign":~ + + Text of error sign, default: `">>"` + +"diagnostic.warningSign":~ + + Text of warning sign, default: `"⚠"` + +"diagnostic.infoSign":~ + + Text of info sign, default: `">>"` + +"diagnostic.hintSign":~ + + Text of hint sign, default: `">>"` + +"diagnostic.maxWindowHeight":~ + + Maximum height of diagnostics floating window., default: `8` + +"signature.enable":~ + + Enable signature help when trigger character typed, require restart + service on change., default: `true` + +"signature.triggerSignatureWait":~ + + Wait time for trigger signature, default: `50`. + Change to higher value if your language server is slow. + +"signature.target":~ + + Target of signature help, use float when possible by default. + + Valid options: ["float","echo"] + +"signature.preferShownAbove":~ + + Show signature help float window above cursor when possible, require + restart service on change., default: `true` + +"signature.hideOnTextChange":~ + + Hide signature float window when text changed, require restart service + on change., default: `false` + +"signature.maxWindowHeight":~ + + Maximum height of floating signature help window., default: `8` + +"codeLens.enable":~ + + Enable `codeLens` feature, require neovim with set virtual text + feature., default: `false` + +"codeLens.separator":~ + + Separator text for `codeLens` in virtual text, default: `"‣"` + +"workspace.ignoredFiletypes":~ + + Filetypes that should be ignored for resolve workspace folder., + default: `["markdown","log","txt","help"]` + +"list.indicator":~ + + The character used as first character in prompt line, default: `">"` + +"list.maxHeight":~ + + Maximum height of list window., default: `10` + +"list.signOffset":~ + + Sign offset of list, should be different from other plugins., + default: `900` + +"list.selectedSignText":~ + + Sign text for selected lines., default: `"*"` + +"list.autoResize":~ + + Enable auto-resize feature., default: `true` + +"list.limitLines":~ + + Limit lines for list buffer., default: `30000` + +"list.maxPreviewHeight":~ + + Max height for preview window of list., default: `12` + +"list.previewHighlightGroup":~ + + Highlight group used for highlight the range in preview window., + default: `"Search"` + +"list.nextKeymap":~ + + Key used for select next line on insert mode., default: `""` + +"list.previousKeymap":~ + + Key used for select previous line on insert mode., default: `""` + +"list.extendedSearchMode": ~ + + Enable extended search mode which allows multiple search patterns delimited by spaces. + +"list.normalMappings":~ + + Custom keymappings on normal mode., default: `{}` + +"list.insertMappings":~ + + Custom keymappings on insert mode., default: `{}` + +"coc.preferences.useQuickfixForLocations":~ + + Use vim's quickfix list for jump locations, need restart on change., + default: `false` + +"coc.preferences.extensionUpdateCheck":~ + + Interval for check extension update, could be daily, weekly, never, + default: `"daily"` + + Valid options: ["daily","weekly","never"] + +"coc.preferences.snippetStatusText":~ + + Text shown in statusline to indicate snippet session is activated., + default: `"SNIP"` + +"coc.preferences.hoverTarget":~ + + Target to show hover information, default is floating window when + possible. + + Valid options: ["preview","echo","float"] + +"coc.preferences.colorSupport":~ + + Enable color highlight if language server support it., default: + `true` + +"coc.preferences.previewAutoClose":~ + + Auto close preview window on cursor move., default: `true` + +"coc.preferences.currentFunctionSymbolAutoUpdate":~ + + Automatically update the value of `b:coc_current_function` on + `CursorHold` event, default: `false` + +"coc.preferences.formatOnSaveFiletypes":~ + + Filetypes that should run format on save., default: `[]` + +"coc.preferences.enableFloatHighlight":~ + + Enable highlight for floating window., default: `true` + +"coc.preferences.rootPatterns":~ + + Root patterns to resolve workspaceFolder from parent folders of opened + files, resolved from up to down., default: + `[".vim",".git",".hg",".projections.json"]` + +"coc.preferences.watchmanPath":~ + + Executable path for https://facebook.github.io/watchman/, detected + from $PATH by default, default: `null` + +"coc.preferences.jumpCommand":~ + + Command used for location jump, like goto definition, goto references + etc., default: `"edit"` + + Valid options: ["edit","split","vsplit","tabe","drop","tab drop"] + +"coc.preferences.messageLevel":~ + + Message level for filter echoed messages, could be 'more', 'warning' + and 'error', default: `"more"` + + Valid options: ["more","warning","error"] + +"coc.preferences.bracketEnterImprove":~ + + Improve handling of pressing enter inside brackets (`<> {} [] ()`) by + adding a new empty line below and moving the cursor to it. Works with + `coc#on_enter()`, default: `true` + +"coc.preferences.formatOnType":~ + + Set to true to enable format on type, default: `false` + +"coc.preferences.snippets.enable":~ + + Set to false to disable snippets support., default: `true` + +"list.source.outline.ctagsFilestypes":~ + + Filetypes that should use `ctags` for outline instead of language + server., default: `[]` + +"npm.binPath":~ + + Command or full path of npm or yarn executable for install/update + extenextensions, use `npm` by default. + +"languageserver":~ + + Dictionary of languageservers, key is used as id of languageserver., + default: `{}` + +============================================================================== +COMPLETION *coc-completion* + +Completion is triggered automatically by default, you can change completion +behavior in the configuration file. + +Tips:~ + +- 'completeopt' used by coc.nvim default to `noselect,menuone`. + +- Your 'completeopt' option would be changed and restored during completion, + so you can still use `menu,preview` for vim's builtin completion. + +- Snippet expand and additional edit feature of LSP requires confirm + completion to work. + +- Neovim 0.4.0 is required for floating window to work. + +------------------------------------------------------------------------------ + +Example configuration:~ + +Map to trigger completion and navigate to the next item: > + + function! s:check_back_space() abort + let col = col('.') - 1 + return !col || getline('.')[col - 1] =~ '\s' + endfunction + + inoremap + \ pumvisible() ? "\" : + \ check_back_space() ? "\" : + \ coc#refresh() + + +Map to trigger completion: > + + inoremap coc#refresh() +< + to confirm completion, use: > + + inoremap pumvisible() ? "\" : "\" +< +To make auto-select the first completion item and notify coc.nvim to +format on enter, use: > + + inoremap pumvisible() ? coc#_select_confirm() + \: "\u\\=coc#on_enter()\" + +Map for trigger completion, completion confirm, snippet expand and jump +like VSCode. > + + inoremap + \ pumvisible() ? coc#_select_confirm() : + \ coc#expandableOrJumpable() ? "\=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\" : + \ check_back_space() ? "\" : + \ coc#refresh() + + function! s:check_back_space() abort + let col = col('.') - 1 + return !col || getline('.')[col - 1] =~# '\s' + endfunction + + let g:coc_snippet_next = '' +< +Note: the `coc-snippets` extension is required for this to work. + +============================================================================== +INTERFACE *coc-interface* + +------------------------------------------------------------------------------ + +Coc doesn't come with a default global keymap, you need to configure the +mappings yourself. + +Keymappings *coc-key-mappings* + +Note: Mappings that start with `i_` works for insert mode `n_` works for +normal mode, `v_` works for visual mode. + +(coc-diagnostic-info) *n_coc-diagnostic-info* + + Show diagnostic message of current position, no + truncate. + +(coc-diagnostic-next) *n_coc-diagnostic-next* + + Jump to next diagnostic position. + +(coc-diagnostic-prev) *n_coc-diagnostic-prev* + + Jump to previous diagnostic position. + +(coc-diagnostic-next-error) *n_coc-diagnostic-next-error* + + Jump to next diagnostic error position. + +(coc-diagnostic-prev-error) *n_coc-diagnostic-prev-error* + + Jump to previous diagnostic error position. + +(coc-definition) *n_coc-definition* + + Jump to definition(s) of current symbol. + +(coc-declaration) *n_coc-declaration* + + Jump to declaration(s) of current symbol. + +(coc-implementation) *n_coc-implementation* + + Jump to implementation(s) of current symbol. + +(coc-type-definition) *n_coc-type-definition* + + Jump to type definition(s) of current symbol. + +(coc-references) *n_coc-references* + + Jump to references of current symbol. + +(coc-format-selected) *n_coc-format-selected* + *v_coc-format-selected* + + Format selected range, would work in both visual mode + and normal mode, when used in normal mode, the + selection works on the motion object. + + For example: > + + vmap p (coc-format-selected) + nmap p (coc-format-selected) +< + makes `p` format the visually selected range, and you can use + `pap` to format a paragraph. + +(coc-format) *n_coc-format* + + Format the whole buffer, normally you would like to + use a command like: > + + command! -nargs=0 Format :call CocAction('format') +< + to format the current buffer. + +(coc-rename) *n_coc-rename* + + Rename symbol under cursor to a new word. + +(coc-codeaction) *n_coc-codeaction* + + Get and run code action(s) for current line. + +(coc-codeaction-selected) *n_coc-codeaction-selected* + *v_coc-codeaction-selected* + + Get and run code action(s) with the selected region. + Works with both normal and visual mode. + + +(coc-openlink) *n_coc-openlink* + + Open link under cursor. + +(coc-codelens-action) *n_coc-codelens-action* + + Do command from codeLens of current line. + +(coc-fix-current) *n_coc-fix-current* + + Try to run quickfix action for diagnostics on the + current line. + +(coc-float-hide) *n_coc-float-hide* + + Hide all float windows. + +(coc-float-jump) *n_coc-float-jump* + + Jump to first float window. + +(coc-refactor) *n_coc-refactor* + + Open refactor window for refactor of current symbol. + +(coc-range-select) *n_coc-range-select* +(coc-range-select) *v_coc-range-select* + + Select next selection range. + + Note: requires selection ranges feature of language + server, like: coc-tsserver, coc-python + +(coc-range-select-backward) *v_coc-range-select-backward* + + Select previous selection range. + + Note: requires selection ranges feature of language + server, like: coc-tsserver, coc-python + +(coc-funcobj-i) *n_coc-funcobj-i* *v_coc-funcobj-i* + + Select inside function, mapped to `if` by default. + +(coc-funcobj-a) *n_coc-funcobj-a* *v_coc-funcobj-a* + + Select current function, mapped to `af` by default. + +------------------------------------------------------------------------------ +VARIABLES *coc-variables* + +b:coc_enabled *b:coc_enabled* + + Set to `0` on buffer create if you don't want + coc.nvim send buffer events for this buffer, including + buffer create, change and unload. + +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. E.g.: > + + autocmd FileType python let b:coc_root_patterns = + \ ['.git', '.env'] +< + +b:coc_suggest_disable *b:coc_suggest_disable* + + Disable completion support of current buffer. E.g.: > + + " Disable completion for python + autocmd FileType python let b:coc_suggest_disable = 1 + +b:coc_suggest_blacklist *b:coc_suggest_blacklist* + + Words for which completion should be disabled. E.g.: > + + " 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. E.g.: > + + " Add keyword characters for css + autocmd FileType css let b:coc_additional_keywords = ["-"] + +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. + +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`. + +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_user_config *g:coc_user_config* + + + User configuration object, define this variable when + you can't use |coc#config()| + +g:coc_extension_root *g:coc_extension_root* + + Location that coc extensions would be installed to, + empty to use default location: + Windows: + `~/AppData/Local/coc/extensions` + Other: + `~/.config/coc/extensions` + +g:coc_global_extensions *g:coc_global_extensions* + + Global extension names to install when they aren't + installed, define this variable to a list of extension + names when you can't use |coc#add_extension()| + +g:coc_cygqwin_path_prefixes *g:coc_cygqwin_path_prefixes* + + When running under cygwin, the node process will work + with win32 paths, while your vim process will work + with POSIX paths. You can use this map to map between + paths. For example, your root folder might be + `c:/Users/myUser/workspace` mapped in cygwin as + `/home/myUser/workspace`. In this situation, your node + process might send the `c:/Users/myUser/workspace` + path to your vim process. To solve this, you need to + define this map: + + `let g:coc_cygqwin_path_prefixes = ` + ` \{'c:/Users/myUser': '/home/myUser'}` + +g:coc_enable_locationlist *g:coc_enable_locationlist* + + Open location list when location list changes. + + 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: + +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: + +g:coc_filetype_map *g:coc_filetype_map* + + Map for document filetypes so the server could handle + current document as another filetype, ex: > + + let g:coc_filetype_map = { + \ 'html.swig': 'html', + \ 'wxss': 'css', + \ } +< + Default: {} + + Note: coc will always map filetype `javascript.jsx` to + `javascriptreact` and `typescript.tsx` to + `typescriptreact`. + +g:coc_selectmode_mapping *g:coc_selectmode_mapping* + + Add key mappings for making snippet select mode + easier. > + + snoremap c + snoremap c + snoremap c + snoremap "_c +< + Default: 1 + +g:coc_node_path *g:coc_node_path* + + Path to node executable to start coc service. ex: > + + let g:coc_node_path = '/usr/local/opt/node@10/bin/node' +< + Use this when coc has problems with your system node, + + Note: you have to use `$HOME` as home directory. + +g:coc_force_debug *g:coc_force_debug* + + Coc would use the precompiled bundle when the bundle + file exists, set this to 1 to use compiled code instead + of bundle. + + Default: 0 + +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, ex: > + + let g:coc_node_args = ['--nolazy', '--inspect-brk=6045'] +< + + Default: [] + + +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 service. + +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_watch_extensions *g:coc_watch_extensions* + + Extensions to watch for reload, used for developing + extensions only, need watchman installed. + +g:coc_quickfix_open_command *g:coc_quickfix_open_command* + + Open command used for open quickfix. + Used by quickfix action of list sources. + Default: |copen| + +g:WorkspaceFolders *g:WorkspaceFolders* + + Current workspace folders, used for restoring from a + session file, add `set sessionoptions+=globals` to + vimrc for restoring globals. + +g:node_client_debug *g:node_client_debug* + + Enable debug mode of node client on vim8, use command: > + + :call coc#client#open_log() +< + to open the log file. + +g:coc_cursors_activated *g:coc_cursors_activated* + + Use expression `get(g:, 'coc_cursors_activated',0)` to + check if cursors session is activated. + +g:coc_config_home *g:coc_config_home* + + Configure the directory which will be used to look + for coc-settings.json and install extensions. + +------------------------------------------------------------------------------ + +Some variables are provided by coc.nvim so you can use them in your +statusline. See |coc-status| for detail. + +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|. + +g:coc_status *g:coc_status* + + Status string contributed by extensions, used for + status line. + +------------------------------------------------------------------------------ +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#config()* +coc#config({section}, {value}) + + Change user configuration by vim script, no changes would be made to + user configuration file. ex: > + + 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 the service has been + initialized. + + 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()* + + Config extensions to install, a terminal buffer would be opened to + install missing extensions after service started, ex: > + + 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#refresh()* +coc#refresh() + + Start or refresh completion at current cursor position, bind this to + 'imap' to trigger completion, ex: > + + inoremap coc#refresh() +< + *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 `` has been pressed. + Currently used for the formatOnType feature, ex: > + + inoremap pumvisible() ? coc#_select_confirm() + \: "\u\\=coc#on_enter()\" +< + Note:to enable formatOnType, 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#_select_confirm()* +coc#_select_confirm() + + Select first completion item if no completion item is selected, then + confirm the completion. + + Note: for this function to work as expected, either |CompleteChanged| + autocmd should exists or only and should be used to select + a completion item. + + *health#coc#check()* +health#coc#check() + + Neovim only, run health check, triggered by ':checkhealth' + command. + + *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#install()* +coc#util#install([{config}]) + + Install compiled javascript code of coc.nvim. + + {config} could contains: + + - `terminal` use terminal when specified. + - `tag` use latest tag when specified. + + *coc#util#extension_root()* + +coc#util#extension_root() + + Return extensions root of coc.nvim. + + *coc#util#rebuild()* + +coc#util#rebuild() + + Rebuild coc extensions. + + *coc#util#has_float()* + +coc#util#has_float() + + Check if coc float window exists. + + *coc#util#float_scrollable()* + +coc#util#float_scrollable() + + Check if coc float window is scrollable. + + *coc#util#float_scroll()* +coc#util#float_scroll({forward}) + + Return expr for scrolling a floating window forward or backward. ex: > + + nnoremap coc#util#has_float() ? coc#util#float_scroll(1) : "\" + nnoremap coc#util#has_float() ? coc#util#float_scroll(0) : "\" +< + *CocRequest()* +CocRequest({id}, {method}, [{params}]) + + Send a request to language client of {id} with {method} and optional + {params}. eg: > + + 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}]]) + + Async request for remote language client. {callback} is called with + error and response. + + *CocRegistNotification()* + +CocRegistNotification({id}, {method}, {callback}) + + Regist 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()* +CocAction({action}, [...{args}]) + + Run {action} of coc with optional extra {args}. + + *CocActionAsync()* + +CocActionAsync({action}, [...{args}, [{callback}]]) + + Call CocAction without blocking vim UI, the callback is called with + `error` as the first argument and `response` as the second argument. + + *CocHasProvider()* +CocHasProvider({feature}) + + Check if provider exists for specified feature. Supported features: + + `rename` `onTypeEdit` `documentLink` `documentColor` `foldingRange` + `format` `codeAction` `workspaceSymbols` `formatRange` `hover` + `signature` `documentSymbol` `documentHighlight` `definition` + `declaration` `typeDefinition` `reference` `implementation` `codeLens` + `selectionRange` + +------------------------------------------------------------------------------ + +Available Actions ~ + +"sourceStat" *coc-action-sourceStat* + + get the list of completion source stats for the current buffer. + +"refreshSource" [{source}] *coc-action-refreshSource* + + refresh all sources or a source with a name of {source}. + +"toggleSource" {source} *coc-action-toggleSource* + + enable/disable {source}. + +"diagnosticList" *coc-action-diagnosticList* + + Get all diagnostic items of the current neovim session. + +"diagnosticInfo" *coc-action-diagnosticInfo* + + Show diagnostic message at the current position, do not truncate. + +"jumpDefinition" [{openCommand}] *coc-action-jumpDefinition* + + jump to definition position of the current symbol. + Return `v:false` when location not found. + + |coc-list| is used when more than one position is available. + + {openCommand}: optional command to open buffer, default to + `coc.preferences.jumpCommand` in `coc-settings.json` + +"jumpDeclaration" [{openCommand}] *coc-action-jumpDeclaration* + + jump to declaration position 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}] *coc-action-jumpImplementation* + + Jump to implementation position of the current symbol. + Return `v:false` when location not found. + + same behavior as "jumpDefinition" + +"jumpTypeDefinition" [{openCommand}] *coc-action-jumpTypeDefinition* + + Jump to type definition position of the current symbol. + Return `v:false` when location not found. + + same behavior as "jumpDefinition" + +"jumpReferences" [{openCommand}] *coc-action-jumpReferences* + + Jump to references position of the current symbol. + Return `v:false` when location not found. + + same behavior as "jumpDefinition" + +"doHover" *coc-action-doHover* + + Show documentation of the current word in a preview window. + Return `v:false` when hover not found. + + Use `coc.preferences.hoverTarget` to change hover behavior. + + Note: the behavior would change in neovim, where floating windows are + available. + +"showSignatureHelp" *coc-action-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" *coc-action-getCurrentFunctionSymbol* + + Return the function string that current cursor in. + +"documentSymbols" *coc-action-documentSymbols* + + Get a list of symbols in the current document. + +"rename" *coc-action-rename* + + Rename the symbol under the cursor position, user will be prompted for + a new name. + +"workspaceSymbols" *coc-action-workspaceSymbols* + + Search for workspace symbols. + +"selectionRanges" *coc-action-selectionRanges* + + Get selection ranges of current position from language server. + +"services" *coc-action-services* + + Get an information list for all services. + +"toggleService" {serviceId} *coc-action-toggleService* + + Start or stop a service. + +"format" *coc-action-format* + + Format current buffer using the language server. + Return `v:false` when format failed. + +"formatSelected" [{mode}] *coc-action-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|. + + +"codeAction" [{mode}] [{only}] *coc-action-codeAction* + + Prompt for a code action and do it. + + {mode} should be result of visualmode(), when used in visualmode, + could be empty string or v:null for none visualmode. + + {only} can be title of a codeAction or list of CodeActionKind. + + +"codeLensAction" *coc-action-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" *coc-action-commands* + + Get a list of available service commands for the current buffer. + +"runCommand" [{name}] [...{args}] *coc-action-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}} *coc-action-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" *coc-action-highlight* + + Highlight the symbols under the cursor. + Overwrite the highlight groups `CocHighlightText`, `CocHighlightRead` + and `CocHighlightWrite` for customizing the colors. + + To enable highlight on CursorHold, create an autocmd like this: > + + autocmd CursorHold * silent call CocActionAsync('highlight') +< +"openLink" [{command}] *coc-action-openlink* + + Open a link under the cursor with {command}. + {command} default to `edit`. + + File and URL links are supported, return `v:false` when failed. + + Note: it needs language server support documentLink feature to work. + +"extensionStats" *coc-action-extensionStats* + + Get all extension states as a list. Including `id`, `root` and + `state`. + + State could be `disabled`, `activated` and `loaded`. + +"toggleExtension" {id} *coc-action-toggleExtension* + + Enable/disable an extension. + +"uninstallExtension" {id} *coc-action-uninstallExtension* + + Uninstall an extension. + +"reloadExtension" {id} *coc-action-reloadExtension* + + Reload an activated extension. + +"deactivateExtension" {id} *coc-action-deactivateExtension* + + Deactivate an extension of {id}. + +"pickColor" *coc-action-pickColor* + + Change the color at the current cursor position. + + Requires language server support for the document color request. + + Note: only works on mac or when you have python support on vim and + have the gtk module installed. + +"colorPresentation" *coc-action-colorPresentation* + + Change the color presentation at the current color position. + + Requires a language server that supports color representation + requests. + +"codeActions" [{visualmode}] [{only}] *coc-action-codeActions* + + Get codeActions of current range. + + {visualmode} can be result of |visualmode()| for visual selected + range, When it's empty string or not exists use current line. + + {only} can be used to limit codeActionKind, possible values: + 'refactor', 'quickfix' and 'source'. + +"quickfixes" [{visualmode}] *coc-action-quickfixes* + + Get quickfix codeActions of current buffer. + + Add {visualmode} as second argument get quickfix actions with range of + latest |visualmode()| + +"doCodeAction" {codeAction} *coc-action-doCodeAction* + + Do a codeAction. + +"doQuickfix" *coc-action-doQuickfix* + + Do the first quickfix action for the current line. + Return `v:false` when no quickfix action found. + +"addRanges" {ranges} *coc-action-addRanges* + + Ranges must be provided as array of range type: https://git.io/fjiEG + +"getWordEdit" *coc-action-getWordEdit* + + Get workspaceEdit of current word, language server used when possible, + extract word from current buffer as fallback. + +------------------------------------------------------------------------------ +COMMANDS *coc-commands* + +:CocStart *:CocStart* + + Start the coc server, do nothing if it's already started. + +:CocRestart *:CocRestart* + + Restart coc service. + + Use this command when you want coc to start all over again. + +:CocDisable *:CocDisable* + + Disable all events of coc. + +:CocEnable *:CocEnable* + + Enable events of coc. + +:CocConfig *:CocConfig* + + Edit the user config file `coc-settings.json` + +:CocLocalConfig *:CocLocalConfig* + + Edit or create `.vim/coc-settings.json` of the current working + directory. + +: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 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 `` for name + completion. + +:{range}CocAction [{only}] *:CocAction* + + Get codeActions of current document in actions list, + with optional {range}. + + {only} can be 'quickfix' or 'source' as CodeActionKind. + +:{range}CocFix *:CocFix* + + Same as `:CocAction quickfix` for quickfix actions. + +:CocOpenLog *:CocOpenLog* + + Open the log file of coc.nvim. To change the log level + (default `info`), use the environment variable + `NVIM_COC_LOG_LEVEL`. E.g.: > + + export NVIM_COC_LOG_LEVEL=debug +< + or add: > + + let $NVIM_COC_LOG_LEVEL='debug' +< + to the beggining of your `.vimrc` (before the plugin is + loaded). + +:CocInfo *:CocInfo* + + Show version and log information in a split window, useful for + submitting a bug report. + +------------------------------------------------------------------------------ +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 -A 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 so: > + + autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp') +< + *CocOpenFloat* + +:autocmd User CocOpenFloat {command} + + Triggered when a floating window is opened. + *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 of vim in your +vimrc, like: > + + " make error texts have a red color + highlight CocErrorHighlight ctermfg=Red guifg=#ff0000 +< +Note: don't use `:hi default` for overwriting the highlights. + +Note: highlight commands should appear after the |:colorscheme| command or use +|ColorScheme| autocmd to make sure customized highlight works after color +scheme change. + +CocErrorSign *CocErrorSign* + + Default: `hi CocErrorSign ctermfg=Red guifg=#ff0000` + + The highlight used for error signs. + +CocWarningSign *CocWarningSign* + + Default: `hi CocWarningSign ctermfg=Brown guifg=#ff922b` + + The highlight used for warning signs. + +CocInfoSign *CocInfoSign* + + Default: `hi CocInfoSign ctermfg=Yellow guifg=#fab005` + + The highlight used for information signs. + +CocHintSign *CocHintSign* + + Default: `hi CocHintSign ctermfg=Blue guifg=#15aabf` + + The highlight used for hint signs. + +CocErrorVirtualText *CocErrorVirtualText* + + Default: `hi default link CocErrorVirtualText CocErrorSign` + + The highlight used for error signs. + +CocWarningVirtualText *CocWarningVirtualText* + + Default: `hi default link CocWarningVirtualText CocWarningSign` + + The highlight used for warning signs. + +CocInfoVirtualText *CocInfoVirtualText* + + Default: `hi default link CocInfoVirtualText CocInfoSign` + + The highlight used for information signs. + +CocHintVirtualText *CocHintVirtualText* + + Default: `hi default link CocHintVirtualText CocHintSign` + + The highlight used for hint signs. + +CocErrorHighlight *CocErrorHighlight* + + Default: `hi default link CocErrorHighlight CocUnderline` + + The highlight used for error text. + +CocWarningHighlight *CocWarningHighlight* + + Default: `hi default link CocWarningHighlight CocUnderline` + + The highlight used for warning text. + +CocInfoHighlight *CocInfoHighlight* + + Default: `hi default link CocInfoHighlight CocUnderline` + + The highlight used for information text. + +CocHintHighlight *CocHintHighlight* + + Default: `hi default link CocHintHighlight CocUnderline` + + The highlight used for hint text. + +CocHighlightText *CocHighlightText* + + Default `hi default link CursorColumn` + + The highlight used for document highlight feature. Normally used for + highlighting same symbols in the buffer at the current cursor position. + +CocHighlightRead *CocHighlightRead* + + Default `hi default link CocHighlightRead CocHighlightText` + + Highlight for `Read` kind of document symbol. + +CocHighlightWrite *CocHighlightWrite* + + Default `hi default link CocHighlightWrite CocHighlightText` + + Highlight for `Write` kind of document symbol. + +CocErrorLine *CocErrorLine* + + Default `undefined` + + Line highlight of sign for a line that contains error diagnostic. + +CocWarningLine *CocWarningLine* + + Default `undefined` + + Line highlight of sign for a line that contains warning diagnostic. + +CocInfoLine *CocInfoLine* + + Default `undefined` + + Line highlight of sign for a line that contains info diagnostic. + +CocHintLine *CocHintLine* + + Default `undefined` + + Highlight for a line with diagnostic hint. + +CocCodeLens *CocCodeLens* + + Default: `ctermfg=Gray guifg=#999999` + + Highlight group of virtual text for codeLens. + +CocFloating *CocFloating* + + Default: `Pmenu` + + Highlight group of a floating window. + +CocErrorFloat *CocErrorFloat* + + Default: `hi default link CocErrorFloat CocErrorSign` + + The highlight used for a floating window with errors. + +CocWarningFloat *CocWarningFloat* + + Default: `hi default link CocWarningFloat CocWarningSign` + + The highlight used for a floating window with warnings. + +CocInfoFloat *CocInfoFloat* + + Default: `hi default link CocInfoFloat CocInfoSign` + + The highlight used for a floating window with information. + +CocHintFloat *CocHintFloat* + + Default: `hi default link CocHintFloat CocHintSign` + + The highlight used for a floating window with hints. + +CocCursorRange *CocCursorRange* + + Default: `hi default link CocCursorRange Search` + + The highlight used for cursor ranges. + +CocHoverRange *CocHoverRange* + + Default: `hi default link CocHoverRange Search` + + The highlight used for current hover range. + +============================================================================== +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 . +* Multiple selections using in normal mode. +* Select lines by visual selection. + +------------------------------------------------------------------------------ + +LIST COMMAND *coc-list-command* + +:CocList [{...options}] [{source}] [{...args}] *CocList* + + Open coc list of {source}, Ex: > + + :CocList --normal location +< + For current jump locations. + + See |coc-list-options| for available list options, + + {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 *CocListResume* + + Reopen last opened list, input and cursor position will be + preserved. + +:CocPrev *CocPrev* + + Invoke default action for the previous item in the last list. + + Doesn't open the list window if it's closed. + +:CocNext *CocNext* + + Invoke the default action for the next item in the last list. + + Doesn't open the list window if it's closed. + +Command options *coc-list-options* + +--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: it won't work if the list doesn't support interactive mode. + + Note: filtering and sorting would be done by a remote service. + +--auto-preview +-A + Start a preview for the current item on the visible list. + +------------------------------------------------------------------------------ + +LIST CONFIGURATION *coc-list-configuration* + +Use `coc-settings.json` for configuration of lists. + +The general configuration of list starts with `list.` checkout +|coc-configuration| or type `list.` in your settings file to get the list. + +For configuration of a specified list, use section that starts with: +`list.source.{name}`, where `{name}` is the name of list. + +Configure 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` to `defaultOptions`. + +Note: default options will not be used when there're options or arguments +passed with |:CocList| command. + +Config 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. + +Type `?` on normal mode to get supported arguments. + +------------------------------------------------------------------------------ + +LIST MAPPINGS *coc-list-mappings* + +Default mappings in insert mode: + + - cancel list session. + - stop loading task. + - reload list. + - change to normal mode. + - select next line. + - select previous line. + - move cursor left. + - move cursor right. + - move cursor to end of prompt. + - same as . + - move cursor to start of prompt. + - same as . + - scroll window forward. + - scroll window backward. + - remove previous character of cursor. + - remove previous character of cursor. + - remove previous word of cursor. + - remove characters before cursor. + - navigate to next input in history. + - navigate to previous input in history. + - switch matcher for filter items. + - insert content from vim register. + - select action. + +Default mappings in normal mode: + + - cancel list session. + - stop source from fetching more items. + - reload list. + - mark all visible items selected. + - select action. + - 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, ex: > + + "list.insertMappings": { + "": "do:refresh", + "": "feedkeys:\\", + "": "feedkeys:\\", + "": "normal:j", + "": "normal:k", + "": "action:tabe", + "": "call:MyFunc", + // paste yanked text to prompt + "": "eval:@@" + } + "list.normalMappings": { + "c": "expr:MyExprFunc" + "d": "action:delete" + } +< +Note: you should only use mappings that start with ` 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. + 'previous' - move cursor to previous item. + 'next' - move cursor to next item. + 'defaultaction' - execute default action. + '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. + '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 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, ex: `'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 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. + - 'reload' reload extension. + - 'uninstall' uninstall extension. + +diagnostics *coc-list-diagnostics* + + All diagnostics for the workspace. + + Actions: + + - Same as |coc-list-location| + +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. + +output *coc-list-output* + + Current output channels + + Actions: + + - 'open': open output channel in split window, default action. + +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. + +actions *coc-list-actions* + + Get available code actions. + + Actions: + + - 'do': execute selected action. + +============================================================================== + +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. Ex: > + + 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 auocmd 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* + +------------------------------------------------------------------------------ +Q: I need documentation for completion items. + +A: Preview window of vim is disabled by default. You can enable it by + adding `"suggest.enablePreview":true` to your settings file. + + However, it doesn't work when the server only sends documentation on + complete item change, you will need floating window support then, + check out: https://bit.ly/2NCVh5P + +------------------------------------------------------------------------------ +Q: I want to use ale for diagnostics. + +A: Yes, you can make coc send diagnostics to ale, just add > + + "coc.preferences.diagnostic.displayByAle": true, +< + to your coc-settings.json + +------------------------------------------------------------------------------ +Q: I want codeLens feature of LSP. + +A: CodeLens support uses the virtual text feature of neovim, its's not + enabled by default. To enable it, add: > + + "codeLens.enable": true, +< + to your coc-settings.json + +------------------------------------------------------------------------------ +Q: I want to highlight codes in markdown documentation. + +A: Use a markdown plugin which could provide fancy code highlighting, + like https://github.com/tpope/vim-markdown, and use settings like: +> + let g:markdown_fenced_languages = ['css', 'js=javascript'] +< + in your .vimrc. + + +============================================================================== +CHANGELOG *coc-changelog* + +Check out ../history.md + +============================================================================== +vim:tw=78:nosta:noet:ts=8:sts=0:ft=help:noet:fen:fdm=marker: diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/history.md b/vim/.vim/pack/coc/start/coc.nvim-release/history.md new file mode 100644 index 0000000..9a1330d --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/history.md @@ -0,0 +1,1166 @@ +# 2019-08-18 0.0.74 + +- feat(cursors): support multiple cursors. +- feat(extensions): install missing extensions by CocInstall. +- feat(extensions): add command `extensions.forceUpdateAll`. +- feat(completion): rework preselect feature. +- feat(extension): use request for fetch package info. +- feat(language-client): support disableDynamicRegister configuration. +- feat(list): paste from vim register support on insert mode #1088. +- feat(plugin): add CocHasProvider(), close #1087. +- refactor(outline): not exclude variables and callback. +- refactor(diagnostic): remove timeout on InsertLeave. + +# 2019-07-11 0.0.73 + +- fix(completion): fix map of number select +- fix(languages): fix cursor position with snippet +- fix(completion): fix cursor position with additionalTextEdits +- fix(position): fix rangeOverlap check #961 +- fix(list): not change guicursor when it's empty +- fix(list): fix filter not work on loading +- fix(list): fix custom location list command not work +- fix(util): highlight & render on vim8 +- fix(handler): fix getCommands +- fix(handler): not check lastInsert on trigger signatureHelp +- fix(handler): fix check of signature help trigger +- fix(language-client): configuration for configured server, closes #930 +- fix(diagnostic): clear diagnostics on filetype change +- feat(plugin): add download & fetch modules +- feat(plugin): add highligher module +- feat(refactor): add `(coc-refactor)` for refactor window +- feat(extension): use mv module for folder rename +- feat(extension): support install taged extension +- feat(extension): support custom extension root `g:coc_extension_root` +- feat(handler): close signature float window on ')' +- feat(list): support `g:coc_quickfix_open_command` +- feat(list): add eval action +- feat(list): add --tab list option +- feat(list): use highligher module for showHelp +- feat(terminal): add noa on window jump +- feat(terminal): support vim8 +- feat(diagnostic): add diagnosticRelated support +- feat(diagnostic): use text properties on vim8 +- feat(handler): improve signature float window + +# 2019-07-01 + +- feat(plugin): add CocStatusChange autocmd +- feat(extension): support both npm and yarn. +- feat(plugin): work on vim 8.0 +- feat(extensions): add lock & doc actions to extension source +- feat(extension): add proxy auth support (#920) +- feat(source): not change startcol for file source +- feat(completion): no numberSelect for number input +- feat(extensions): Use yarn when npm not found +- feat(completion): no popup for command line buffer +- feat(plugin): support only for codeActions action +- feat(task): debounce stdout +- feat(plugin): add keymaps for selection ranges +- feat(plugin): add function textobj +- feat(list): restore window height, closes #905 +- feat(handler): support signature.floatTimeout +- feat(configuration): support change of workspace configuration +- feat(diagnostic): add keymaps for jump error diagnostics +- feat(plugin): delay start on gvim, fix #659 + +# 2019-06-15 + +- feat(plugin): add popup support of vim +- refactor(completion): improve float support +- refactor(floating): remove unused code +- refactor(workspace): replace find-up +- refactor(handler): improve message for fold method +- fix(virtualtext): invalid highlight tag (#874) +- fix(snippets): fix plaintext check +- fix(highlight): catch error of child_process.spawn +- fix(highlight): use v:progpath, fix #871 +- fix(floatFactory): escape feedkeys +- fix(handler): fix getCurrentFunctionSymbol not work + +# 2019-06-12 + +- feat(document): add getVar method +- fix(util): not break selection on message +- fix(workspace): fix jumpTo not work on vim8 +- fix(completion): trigger completion with word character +- refactor(handler): return boolean result +- perf(workspace): improve jump performance +- fix(util): Escape filename for jump (#862) +- refactor(plugin): not show empty hover +- feat(outline): ignore callback function +- feat(workspace): support list of events with registerAutocmd +- fix(workspace): fix jump with tab drop +- refactor(language-client): change API of selectionRanges + +# 2019-06-09 + +- **Break change** `CocHighlightText` link to `CursorColumn` by default. +- **Break change** logger folder changed to `$XDG_RUNTIME_DIR` when exists. +- Add `` and `` support for list, #825. +- Add function `coc#add_command()`. +- Add `disableDiagnostics` & `disableCompletion` to languageclient configuration. +- Add `signature.triggerSignatureWait` configuration. +- Add vim-repeat support for run command and quickfix. +- Add prefered `codeAction` support. +- Add `prompt.paste` action to list. +- Add title as argument support for `codeAction` action. +- Add `suggest.floatEnable` configuration. +- Add `editor.action.orgnizeImport` command. +- Add `:CocAction` and `:CocFix` commands. +- Add `codeActions` action. +- Fix issues with list. + +# 2019-05-30 + +- **Break change** logger folder changed. +- Add support of vim-repeat for `` keymaps. +- Add `CocRegistNotification()` function. +- Add argument to rename action. +- Add `suggest.disableMenuShortcut` configuration. +- Add glob support for root patterns. +- Add `` keymap to list window. +- Add shortcut in sources list. +- Add `list.previewSplitRight` configuration. +- Add `triggerOnly` property to source. +- Add warning for duplicate extension. +- Bug fixes. + +# 2019-05-07 + +- **New feature** load extensions from coc-extensions folder. +- Add `workspace.renameCurrentFile` command. +- Add `FloatBuffer`, `FloatFactory` and `URI` to exports. +- Add `resolveItem` support to list. +- Fix prompt can't work when execute list action. +- Fix ansiparser for empty color ranges. +- Fix highlight only work with first 8 items. + +# 2019-04-27 + +- **Break change** vim-node-rpc not required on vim. +- **Break change** python not required on vim. +- **Break change** complete items would refreshed after 500ms when not finished. +- Add `additionalSchemes` for configured language server. +- Add support for jumpCommand as false. +- Fix `diagnostic.level` not work. + +# 2019-04-09 + +- **Break change** `--strictMatch` option of list renamed to `--strict` +- **Break change** `suggest.reloadPumOnInsertChar` support removed. +- **Break change** no more binary release. +- **Break change** logic for resolve workspace folder changed. +- Add `Task` module. +- Add `getCurrentFunctionSymbol` action. +- Add `list.source.outline.ctagsFilestypes` setting. +- Add `suggest.disableMenu` and `suggest.disableMenu` settings. +- Add `equal` support for complete items. +- Add support for do action with visual select lines of list. +- Add expand tilder support for language server command. +- Add switch matcher support to list. +- Add select all support to lsit. +- Add quickfix action to list. +- Add `selectionRanges` of LSP. +- Add load extentions for &rtp support. +- Add `coc#on_enter()` for formatOnType and add new lines on enter. +- Improve completion by support trigger completion when pumvisible. +- Remove document check on `BufWritePre`. + +# 2019-03-31 + +- **Break change** not using vim-node-rpc from npm modules any more. +- **Break change** rename `_` to `CocRefresh`. +- Fix wrong format options send to server. +- Fix throw eror when extention root not created. +- Fix MarkedString not considered as markdown. +- Fix echo message on vim exit. +- Fix error throw on file watch. +- Fix unexpected update of user configuration. + +# 2019-03-28 + +- Add `workspace.resolveRootFolder`. +- Add `diagnostic.joinMessageLines` setting. +- Add `suggest.completionItemKindLabels` setting. +- Add `memento` support for extention. +- Add `workspace.getSelectedRange`. +- Add `Terminal` module. +- Add command `workbench.action.reloadWindow`. +- Fix extention not activated by command. +- Fix broken undo with floating window. +- Fix document create possible wrong uri & filetype. +- Improve highlight with floating window. + +# 2019-03-24 + +- **Break change** make number input not trigger completion. +- **Break change** make none keywords character doesn't filter completion. +- Add functions for check snippet state. +- Add setting `diagnostic.checkCurrentLine`. +- Fix `signature.target` not work. +- Fix flick of signature window. +- Fix EPIPE error of node-client. +- Fix wrong root of FileWatchSysmtem. + +# 2019-03-19 + +- **Break change** signature settings now starts `signature`. +- **Break change** default request timeout changed to 5s. +- **Break change** `commands.executeCommand` return promise. +- Add `coc.preferences.signatureHelpTarget`. +- Add `diagnostic.maxWindowHeight` & `signature.maxWindowHeight`. +- Add `diagnostic.enableSign`. +- Add support for `$COC_NO_PLUGINS`. +- Add keymaps: `(coc-float-hide)` and `(coc-float-jump)`. +- Add `coc.preferences.enableFloatHighlight`. +- Fix issues with floating window. +- Fix critical performance issue on diff text. +- Improve color of `CocHighlightText`. +- Improve sort of complete items. +- Improve extention list with version and open action. + +# 2019-03-16 + +- **Break change** change vim config home on windows to '\$HOME/vimfiles'. +- Add highlights to float windows. +- Add CocLocationsAsync(). +- Add support for `b:coc_suggest_disable`. +- Add support for `b:coc_suggest_blacklist`. +- Add setting `diagnostic.messageTarget`. +- Add floating window support for signatures. +- Fix issues with diagnostic float. +- Fix info of completion item not shown. +- Fix CocUpdateSync not work without service start. +- Fix wrong indent spaces of snippets. + +# 2019-03-11 + +- **Break change** change buffers instead of disk file for `workspace.applyEdits`. +- **Break change** add config errors to diagnostic list instead of jump locations. +- **Break change** hack for popup menu flicker is remvoed, use `suggest.reloadPumOnInsertChar` to enable it. +- **Break change** use `nvim_select_popupmenu_item` for number select completion. +- Add floating window for completion items. +- Add floating window support for diagnostics. +- Add floating window support for hover documentation. +- Add `coc#on_enter()` for notify enter pressed. +- Add setting `coc.preferences.useQuickfixForLocations`. +- Add support of `g:coc_watch_extensions` for automatic reload extentions. +- Add command: `editor.action.doCodeAction`. +- Fix service on restarted on windows after rebuild. +- Fix config of airline. +- Fix relative path of watchman. +- Improve Mru model. + +# 2019-03-03 + +- **Break change** signature change of `workspace.registerKeymap`. +- **Break change** `` of CocList can't be remapped any more. +- **Break change** use `yarnpkg` command instead of `yarn` when possible. +- **Break change** `noinsert` is removed from `completeopt` when `noselect` is + enabled, `` would break line by default. +- Add setting `diagnostic.refreshAfterSave`. +- Add chinese documentation. +- Add support of multiple line placeholder. +- Fix edit of nested snippet placeholders. +- Fix possible infinite create of documents. +- Fix check for resume completion. + +# 2019-02-25 + +- **Break change** default of `suggest.detailMaxLength` changed to 100. +- **Break change** option of `workspace.registerKeymap` changed. +- Add settings: `suggest.defailField`. +- Add check for autocmd in health check. +- Add trigger patterns support for complete sources. +- Add support of `coc-snippets-expand-jump` +- Add `source` option for completion start. +- Add `sources.createSource` method. + +# 2019-02-22 + +- **Break change** some configurations have been renamed, checkout #462. +- **Break change** no longer automatic trigger for CursorHoldI #452. +- **Break change** add preview option of `completeopt` according to `suggest.enablePreview`. +- Add statusItem for CocUpdate. +- Add `-sycn` option for `:CocInstall` +- Add support for floating preview window. +- Add more module export. +- Fix check of vim-node-rpc throw error. +- Fix wrong line for TextEdit of complete item. +- Fix diagnostics not cleared on service restart. + +# 2019-02-17 + +- **Break change** completion resolve requires CompleteChanged autocmd. +- **Break change** mapping of space on insert mode of list removed. +- **Break change** kind of completion item use single letter. +- Fix snippet not works on GUI vim. +- Fix cursor vanish on vim by use timer hacks. +- Fix behavior of list preview window. +- Fix python check on vim. +- Fix CocJumpPlaceholder not fired. +- Fix vscode-open command not work. + +# 2019-02-12 + +- **Break change** function `coc#util#clearmatches` signature changed. +- Add check for python gtk module. +- Add check for vim-node-rpc update error. +- Fix source name of diagnostics. +- Fix empty buffers created on preview. +- Fix trigger of `CursorHoldI`. + +# 2019-02-11 + +- **Break change:** internal filetype of settings file changed to jsonc. +- **Break change:** `coc#util#install` changed to synchronize by default. +- **Break change:** no document highlight would be added for colored symbol. +- **Break change:** remove `coc.preferences.openResourceCommand`. +- Add fallback rename implementation which rename symbols on current buffer. +- Add command `:CocUpdateSync`. +- Add `coc.preferences.detailMaxLength` for slice detail on completion menu. +- Add cancel support for completion. +- Add `ctags` as fallback of document symbols list. +- Add default key-mappings for location actions. +- Add python check on vim. +- Add `disableSyntaxes` support for completion sources. +- Add support for change `isProgress` of `StatusBarItem` +- Add check of coc.nvim version for `CocUpdate` +- Add `coc.preferences.previewAutoClose`, default true. +- Add `workspace.add registerAutocmd`. +- Fix highlight not cleared on vim +- Fix health check of service state. +- Fix CursorHoldI not triggered on neovim. +- Fix sort of list not stable. + +# 2019-02-04 + +- **Break change:** no messages when documentSymbol and workspaceSymbol provider + not found. +- Add support for configure sign in statusline. +- Add help action for list. +- Fix parse error on extentions update. +- Fix wrong uri on windows. +- Fix cancel list without close ui. +- Improve startup time by remove jobwait. + +# 2019-02-02 + +- **Break change:** extentions now update automatically, prompt is removed. +- Add check for extention compatibility. +- Add transform support for placeholder. +- Add check for node version. +- Add error check for list. +- Add settings: `coc.preferences.diagnostic.virtualTextLines`. +- Fix preview window not shown. +- Fix highlight not cleared on vim. +- Fix highlight commands of list block vim on start. +- Improve extention load. +- Improve list experience. + +# 2019-01-28 + +- **Break change:** `coc.preferences.diagnostic.echoMessage` changed to enum. +- Add mru support for commands and lists list. +- Add `coc.preferences.diagnostic.refreshOnInsertMode` +- Add `Mru` module. +- Improve highlight for lists, support empty `filterLabel`. +- Fix `findLocations` not work with nest locations. +- Fix cursor position after apply additionalTextEdits. + +# 2019-01-24 + +- **Break change:** python code for denite support moved to seperated repo. +- **Break change:** Quickfix list no longer used. +- Add list support. +- Add configuration: `coc.preferences.diagnostic.virtualText`. +- Add watch for `&rtp` change. +- Add support for configure `g:coc_user_config` and `g:coc_global_extensions` +- Add support for send request to coc on vim start. +- Add `g:coc_start_at_startup` support. +- Add configuration: `coc.preferences.invalidInsertCharacters`. +- Add configuration: `coc.preferences.snippetStatusText`. +- Add `coc#_insert_key()` for insert keymap. +- Add `workspace.registerExprKeymap()`. +- Add detect for `vim-node-rpc` abnormal exist. +- Add `requireRootPattern` to languageserver configuration. +- Fix git check, always generate keywords. +- Fix crash when `righleft` set to 1 on neovim. +- Fix snippet position could be wrong. + +# 2019-01-09 + +- **Break change:** throw error when languageserver id is invalid. +- Add watcher for languageserver configuration change. +- Fix possible invalid package.json. +- Fix applyEdits not work sometimes. +- Fix server still started when command search failed. +- Fix log file not writeable. +- Improve completion performance. + +# 2019-01-03 + +- **Break change:** using of `g:rooter_patterns` is removed. +- **Break change:** diagnostics would be updated in insert mode now. +- Add configuration: `coc.preferences.rootPatterns` +- Add `TM_SELECTED_TEXT` and `CLIPBOARD` support for snippets. +- Fix check of latest insert char failed. +- Fix highlight not cleared sometimes. + +# 2019-01-01 + +- Fix issues with completion. + +# 2018-12-31 + +- **Break change:** created keymaps use rpcrequest instead of rpcnotify. +- **Break change:** snippets provider is removed, use `coc-snippets` for + extention snippets. +- Add command: `coc.action.insertSnippet` +- Fix position of snippets. +- Fix modifier of registed keymaps. +- Fix completion triggered on complete done. +- Fix closure function possible conflict. +- Fix unexpected snippet cancel. +- Fix document applyEdits, always use current lines. +- Fix fail of yarn global command. +- Fix check of changedtick on completion done. +- Fix line used for textEdit of completion. +- Fix snippet canceled by `formatOnType`. +- Fix `CocJumpPlaceholder` not fired +- Optimize content synchronize. + +# 2018-12-27 + +- **Break change:** no more message on service ready. +- **Break change:** vim source now registed as extention. +- **Break change:** complete item sort have reworked. +- **Break change:** request send to coc would throw when service not ready. +- Add support for check current state on diagnostic update. +- Add `env` opinion for registed command languageserver. +- Add outputChannel for watchman. +- Add `coc#_select_confirm()` for trigger select and confirm. +- Add `coc.preferences.numberSelect`. +- Add priority support for format provider. +- Add `workspace.watchGlobal` and `workspace.watchOption` methods. +- Fix cursor disappear on `TextChangedP` with vim. +- Fix coc process not killed when update on windows. +- Fix snippet broken on vim. +- Fix support of startcol of completion result. +- Fix `labelOffsetSupport` wrong position. +- Fix flicking on neovim. +- Fix unicide not considered as iskeyword. +- Fix watchman client not initialized sometimes. +- Improve performance for parse iskeyword. +- Not echo message on vim exit. +- Not send empty configuration change to languageserver. + +# 2018-12-20 + +- **Break change** configuration for module language server, transport now + require specified value. +- **Break change** new algorithm for socre complete items. +- Add command `workspace.clearWatchman`. +- Add `quickfixs`, `doCodeAction` and `doQuickfix` actions. +- Add `g:vim_node_rpc_args` for debug purpose. +- Add `coc#add_extension()` for specify extentions to install. +- Fix clients not restarted on CocRestart. +- Fix `execArgv` and `runtime` not work for node language server. +- Fix detail of complete item not echoed sometimes. +- Fix actions missing when registed with same clientId. +- Fix issues with signature echo. +- Fix uri is wrong with whitespace. +- Improve highlight performance with `nvim_call_atomic`. + +# 2018-12-17 + +- **Break change** `vim-node-rpc` now upgrade in bacground. +- Add `ignoredRootPaths` to `languageserver` option. +- Add detect of vim running state. +- Add `client.vim` for create clients. +- Fix possible wrong current line of `completeResolve`. +- Fix snippet not work with `set virtualedit=all`. +- Fix default timeout to 2000. +- Fix file mode of log file. + +# 2018-12-12 + +- **Break change** `fixInsertedWord` fix inserted word which ends with word + after. +- **Break change** `onCompleteSelect` is removed. +- Add `workspace.registerKeymap` for regist keymap. +- Add match score for sort complete items. +- Fix possible connection lost. +- Fix priority of diagnostic signs. +- Fix possible wrong uri. +- Fix `RevealOutputChannelOn` not default to `never`. +- Fix possible wrong line used for textEdit of complete item. +- Fix possible wrong cursor position of snippet after inserted. + +# 2018-12-08 + +- **Break change** default rootPath would be directory of current file, not cwd. +- **Break change** codeLens feature now disabled by default. +- **Break change** diagnostic prev/next now loop diagnostics. +- Add support of neovim highlight namespace. +- Add support for undo `additionalTextEdits` on neovim +- Fix configuration resolve could be wrong. +- Fix word of completion item could be wrong. +- Fix rootPath could be null. +- Fix highlight not cleared on restart. + +# 2018-12-06 + +- **Break change** `RevealOutputChannelOn` of language client default to + `never`. +- Fix can't install on windows vim. +- Fix `displayByAle` not clearing diagnostics. +- Add check for `vim-node-rpc` udpate on vim. +- Add `Resolver` module. +- Improve apply `WorkspaceEdit`, support `0` as document version and merge + edits for same document. + +# 2018-12-05 + +- Add `CocJumpPlaceholder` autocmd. +- Add `rootPatterns` to `languageserver` config. +- Add setting: `coc.preferences.hoverTarget`, support use echo. +- Add setting `coc.preferences.diagnostic.displayByAle` for use ale to display errors. +- Add setting `coc.preferences.extensionUpdateCheck` for control update check of + extentions. +- Add `coc#config` for set configuration in vim. +- Fix rootPath not resolved on initialize. +- Fix possible wrong `tabSize` by use `shiftwidth` option. +- Fix trigger of `documentColors` request. +- Fix `vim-node-rpc` service not work on windows vim. +- Fix `codeLens` not works. +- Fix highlight of signatureHelp. +- Fix watchman watching same root multiple times. +- Fix completion throw undefined error. +- Fix `open_terminal` not works on vim. +- Fix possible connection lost by use notification when possible. +- Fix process not terminated when connection lost. +- Rework diagnostics with task sequence. +- Rework configuration with more tests. + +# 2018-11-28 + +- _Break change_ signature help reworked, vim API for echo signature changed. +- Add `:CocInfo` command. +- Add trigger for signature help after function expand. +- Add echo message when provider not found for some actions. +- Add support for `formatexpr` +- Add support for locality bonus like VSCode. +- Add support of `applyAdditionaLEdits` on item selected by `` +- Add `coc.preferences.useQuickfixForLocations` +- Add `coc.preferences.messageLevel` +- Add support for trigger command which not registered by server. +- Add `g:coc_denite_quickfix_action` +- Fix insert unwanted word when trigger `commitCharacter`. +- Fix rpc request throw on vim. +- Fix `data` of complete item conflict. +- Fix code action not work sometime. +- Fix `coc.preferences.diagnostic.locationlist` not work. +- Fix `coc.preference.preferCompleteThanJumpPlaceholder`. +- Fix `workspace.jumpTo` not work sometime. +- Fix line indent for snippet. +- Fix trigger of `signatureHelp` and `onTypeFormat`. + +# 2018-11-24 + +- **Break change** sources exluding `around`, `buffer` or `file` are extracted + as extensions. +- **Break change** custom source not exists any more. +- Add `coc.preferences.preferCompleteThanJumpPlaceholder` to make jump + placeholder behavior as confirm completion when possible. +- Add `CocDiagnosticChange` autocmd for force statusline update. +- Add `onDidUnloadExtension` event on extention unload. +- Fix `getDiagnosticsInRange`, consider all interactive ranges. +- Fix completion throw when `data` on complete item is `string`. +- Fix `commitCharacters` not works. +- Fix workspace methods: `renameFile`, `deleteFile` and `resolveRoot`. +- Fix textEdit of builtin sources not works. + +# 2018-11-19 + +- **Break change** snippet support reworked: support nest snippets, independent + session in each buffer and lots of fixes. +- **Break change** diagnostic list now sort by severity first. +- Add commands: `:CocUninstall` and `:CocOpenLog` +- Add cterm color for highlights. +- Add line highlight support for diagnostic. +- Add `coc.preferences.fixInsertedWord` to make complete item replace current word. +- Fix check confirm not works on vim sometimes. +- Fix check of `vim-node-rpc`. +- Fix preselect complete item not first sometimes. +- Improve completion sort result by consider more abort priority and recent + selected. +- Improve colors module, only highlight current buffer and when buffer changed. +- Improve `doc/coc.txt` + +# 2018-11-13 + +- **Break change** default completion timeout changed to 2s. +- **Break change** snippet session not canceled on `InsertLeave`, use + `` in normal mode to cancel. +- Add document color support. +- Add CocAction 'pickColor' and 'colorPresentation'. +- Add prompt for install vim-node-rpc module. +- Add support for `inComplete` completion result. +- Add status item for snippet session. +- Add support for fix inserted text of snippet completion item. +- Fix document highlight not cleared. +- Fix cancel behavior of snippet. +- Fix range check of edit on snippet session. +- Fix check of completion confirm. +- Fix highlight group 'CocHighlightWrite' not work. +- Fix command `editor.action.rename` not works. +- Fix throw error before initialize. +- Fix `g:coc_node_path` not working. +- Fix file source throw undefined error. +- Improve logic of sorting completion items, strict match items comes first. + +# 2018-11-07 + +- **Break change** word source removed from custom sources, enabled for markdown + by default. +- **Break change** ignore sortText when input.length > 3. +- **Break change** show prompt for install `coc-json` when not found. +- Fix document content synchronize could be wrong. +- Fix filetype not converted on completion. +- Fix complete item possible not resolved. +- Improve document highlight, no highlight when cursor moved. +- Improve completion score, use fuzzaldrin-plus replace fuzzaldrin. + +# 2018-11-02 + +- **Break change** no items from snippets source when input is empty. +- **Break change** `javascript.jsx` would changed to `javascriptreact` as languageId. +- **Break change** `typescript.tsx` would changed to `typescriptreact` as languageId. +- Add support for `commitCharacters` and `coc.preferences.acceptSuggestionOnCommitCharacter`. +- Add setting: `coc.preferences.diagnostic.level`. +- Add `g:coc_filetype_map` for customize mapping between filetype and languageId. +- Add `g:coc_node_path` for custom node executable. +- Add `workspaceFolders` feature to language client. +- Add `~` to complete item of snippet source. +- Add `onDidChangeWorkspaceFolder` event +- Fix `eol` issue by check `eol` option. +- Fix `workspace.document` could be null. +- Fix `workspaceFolder` could be null. +- Fix diagnostic for quickfix buffer. +- Fix resolve of `coc.preferences.rootPath` + +# 2018-10-29 + +- **Break change** diagnostic reworked, no refresh on insert mode. +- **Break change** keep `sortText` on filter for better result. +- **Break change** prefer trigger completion than filter, same as VSCode. +- **Break change** filetype of document would be first part of `&filetype` split by `.`. +- **Break change** prefer label as abbr for complete item. +- Fix creating wrong `textEdit` for snippet. +- Fix `startcol` of `CompleteResult` not working. +- Fix `workspaceConfiguration.toJSON` return invalid result. +- Fix `workspace.readFile` not synchronized with buffer. +- Fix `workspace.rootPath` not resolved as expected. +- Fix `CompletionItem` resolved multiple times. +- Fix check of `latestInsert` on completion. +- Fix `formatOnType` possible add unnecessary indent. +- Fix document content synchronized on vim. +- Fix confirm check of completion for all source. +- Fix document possible register multiple times. +- Fix completion always stopped when input is empty. +- Add warning message when definition not found. +- Add `redraw` after `g:coc_status` changed. +- Remove change of `virtualedit` option of snippet. +- Improved performance of filter completion items. + +# 2018-10-25 + +- Fix `implementation` and `typeDefinition` of language client not working. +- Fix `diffLines` return wrong range. +- Fix `setqflist` and `setloclist` not works on vim. +- Fix snippets and `additionalTextEdits` not works on vim. +- Fix append lines not works on vim. +- Fix highlight action not works on vim. +- Fix null version of `TextDocumentIdentifier` not handled. +- Add `workspace.registerTextDocumentContentProvider` for handle custom uri. +- Add `workspace.createStatusBarItem` method. + +# 2018-10-21 + +- **Break change**: `triggerAfterInsertEnter` now respect `minTriggerInputLength`. +- Add `coc.preferences.minTriggerInputLength`. +- Add command: `:CocCommand`. +- Fix `position` of `provideCompletionItems`. +- Fix content change not trigger after completion. +- Fix default sorters & matchers of denite sources. +- Fix `outputChannel` wrong `buftype`. +- Fix completion not works with `textEdit` add new lines. +- Fix first item not resolved when `noselect` is disabled +- Remove using of `diff` module. + +# 2018-10-18 + +- **Break change**: all buffers are created as document. +- **Break change**: retrieve workspace root on document create. +- Fix `uri` for all buffer types. +- Fix bad performance on parse keywords. +- Fix check of language client state. +- Fix register of `renameProvider` +- Fix `CocRequestAsync` not work. +- Fix `workspace.openResource` error with `wildignore` option. +- Fix output channel can't shown if hidden. +- Fix extension activate before document create. +- Add command `vscode.open` and `editor.action.restart`. +- Add `workspace.requestInput` method. +- Add support of `g:rooter_patterns` +- Add `storagePath` to `ExtensionContext` +- Add `workspace.env` property. +- Add support of scoped configuration. +- Disable buffer highlight on vim. + +# 2018-10-14 + +- **Break change** API: `workspace.resoleModule` only does resolve. +- **Break change** extension would still be loaded even if current coc version + miss match. +- **Break change** variables are removed from view of `Denite coc-symbols` +- Fix `workspace.applyEdits` +- Fix `console.log` throws in extension. +- Fix invalid `workspace.root` with custom buffer schema. +- Fix possible crash on neovim 0.3.1 by not attach terminal buffer. +- Fix jump position not stored when jump to current buffer position. +- Fix install function not works on vim. +- Add support for custom uri schema for `workspace.jumpTo` and `workspace.openResource` +- Add `workspace.findUp` for find up file of current buffer. +- Add `env` option for custom language server config. +- Add vim function: `CocRequest` and `CocRequestAsync` for send request to + language server in vim. +- Add `coc.preferences.parseKeywordsLimitLines` and `coc.preferences.hyphenAsKeyword` + for buffer parse. +- Rework completion for performance and accuracy. + +# 2018-10-05 + +- **Break change**, `workspace.onDidChangeConfiguration` emit `ConfigurationChangeEvent` now. +- Add `position` to function `coc#util#open_terminal`. +- Improve performance of completion by use vim's filter when possible. +- Fix service start multiple times. +- Fix parse of `iskeyword` option, consider `@-@`. +- Fix completion of snippet: cancel on line change. + +# 2018-10-01 + +- Improved document `didChange` before trigger completion. +- Add option `coc.preferences.triggerCompletionWait`, default 60. +- Add watch for `iskeyword` change. +- Fix snippet jump not works sometime. +- Fix possible wrong `rootPath` of language server. +- Fix highlight of highlight action not using terminal colors. +- Fix detect for insert new line character. + +# 2018-09-30 + +- Add quickfix source of denite and fzf +- Add option `coc.preferences.rootPath` +- Add option `revealOutputChannelOn` to language server. +- Fix jump of placeholder. +- Fix empty root on language server initialize. + +# 2018-09-28 + +- **Break change**: `coc.preferences.formatOnType` default to `false`. +- **Break change**: snippet completion disabled in `string` and `comment`. +- Add support for register local extension. +- Add title for commands in `Denite coc-command` +- Fix prompt hidden by echo message. +- Fix contribute commands not shown in denite interface. +- Fix parse of `iskeyword`, support character range. +- Fix `triggerKind` of completion. +- Fix install extension from url not reloaded. + +# 2018-09-27 + +- **Break change**: `:CocDisable` disabled all events from vim. +- **Break change**: new snippet implementation. + - Support multiple line snippet. + - Support VSCode snippet extension. + - Support completion of snippets from snippet extension. +- Add highlight groups for different severity. +- Add `coc.preferences.formatOnType` option. +- Add `coc.preferences.snippets.enable` option. +- Fix snippet not works as `insertText`. +- Fix echo message with multiple lines. +- Fix `signatureHelp` with `showcmd` disabled. +- Fix location list cleared on `:lopen`. +- Fix diagnostic info not cleared on `:CocDisable` +- Fix diagnostic info not cleared on buffer unload. +- Fix buffer highlight not cleared on `highlight` action. +- Fix format on type not work as expected. + +# 2018-09-24 + +- **Break change**: use `CursorMove` instead of `CursorHold` for diagnostic + message. +- **Break change**: direct move to diagnostic position would show diagnostic + message without truncate. +- **Break change**: snippet would be canceled when mode changed to normal, no + mapping of `` any more. +- Add format document on `insertLeave` when `onTypeFormat` is supported. +- Add buffer operations on resource edit. +- Add `uninstall` action for `Denite coc-extension`. +- Fix active extension on command not working. +- Fix delete file from resource edit not works. + +# 2018-09-20 + +- Fix diagnostic check next offset for diagnostics. +- Add `(coc-diagnostic-info)` for show diagnostic message without + truncate. + +# 2018-09-15 + +- Fix wrong configuration on update. +- Fix install command with tag version. +- Fix using of unsafe `new Buffer`. +- Add support of trace format & resource operations. +- Add support of json validation for extension. +- Add support of format on save by `coc.preferences.formatOnSaveFiletypes` + +# 2018-09-10 + +- Add `Denite coc-extension` for manage extensions. +- Add actions for manage extension including `toggleExtension` `reloadExtension` + `deactivateExtension` +- Add check for extension update everyday. +- Fix extensions using same process of coc itself. +- Fix `configurationSection` should be null if none was specified. + +# 2018-09-07 + +- **Break change**: all extension all seperated from core, checkout + [Using coc extension](https://github.com/neoclide/coc.nvim/wiki/Using-coc-extensions) +- Fix `textDocumentSync` option not work when received as object. +- Fix wrong diagnostic info when using multiple lint servers. +- Use `CursorHold` for show diagnostic message. +- Add option `coc.preferences.enableMessage` to disable showing of diagnostic + message. +- Add new events module for receive vim events. +- Add support for `prepareRename`. +- Add support for `CodeActionOptions` + +# 2018-08-30 + +- Fix wrong `triggerKind` from VSCode. +- Add `(coc-openlink)` for open link. +- Add `typescript.jsx` as valid typescript type. + +# 2018-08-23 + +- Fix sometimes client status invalid. +- Add multiply provider support for all features. +- Add `documentLink` support +- Add `documentHighlight` support +- Add `foldingRange` support +- Add support of `documentSelector` same as VSCode + +# 2018-08-21 + +- Fix diagnostic and arguments of tsserver. +- Add `keepfocus` option for `open_terminal`. +- Improve error catch of autocmds. +- Add `onTypeFormat` feature for language server +- Add `onTypeFormat` support for tsserver. +- Refactor and more tests of workspace. +- Fix `window/showMessageRequest` request. +- Use `callAsync` for async request to vim. +- Add `CocActionAsync` function send async request to server. + +# 2018-08-17 + +- Fix exists terminal buffer not watched. +- Fix buffer not attached after `edit!`. +- Fix clean diagnostics of `tsserver.watchBuild` command. +- Fix refresh of buffer. +- Fix document not found on `BufEnter`. + + Use `rpcrequest` for `BufCreate` + +- Fix no permission of log file. + + Disable create log file for root user. + +- Add more command for tsserver: + + - `tsserver.reloadProjects` + - `tsserver.openTsServerLog` + - `tsserver.goToProjectConfig` + - `tsserver.restart` + +- Add test for workspace. + +# 2018-08-16 + +- Improved for tsserver: + + - Add `watchBuild` command for build current project with watch in terminal. + - Support of untitled buffer + - Support `projectRootPath` + +- Fix detach error of document. +- Fix trigger characters not works for some source. +- Fix document possible not sync before save. +- Fix denite errors with 0 as result. +- Fix wrong arguments of tsserver refactor command. +- Use `drop` for workspace `openResource`. +- Add clear coc signs on `:CocRestart`. +- **Break change** all buffer types except `nofile` `help` and `quickfix` are + watched for changes. + +# 2018-08-15 + +- Fix filter of completion items on fast input. +- Fix sometimes fails of include & neosnippet source. +- Fix sometimes fails to find global modules. +- Improve complete source initialization. + + - Always respect change of configuration. + +- Add ability to start standalone coc service for debugging. + + - Use `NVIM_LISTEN_ADDRESS=/tmp/nvim nvim` to start + neovim. + - Start coc server by command like `node bin/server.js` + +- Add ability to recover from unload buffer. + + Sometimes `bufReadPost` `BufEnter` could be not be fired on buffer create, + check buffer on `CursorHold` and `TextChanged` to fix this issue. + +- Add tsserver features: `tsserver.formatOnSave` and `tsserver.orgnizeImportOnSave` + + Both default to false. + +- Add tests for completion sources. + +# 2018-08-14 + +- Fix remote source not working. +- Fix sort of completion items. +- Fix EPIPE error from net module. +- Add `tslint.lintProject` command. +- Add config `coc.preferences.maxCompleteItemCount`. +- Add `g:coc_auto_copen`, default to `1`. + +# 2018-08-12 + +- **Break change** `:CocRefresh` replaced with `call CocAction('refreshSource')`. +- Add support filetype change of buffer. +- Add basic test for completion. +- Improve loading speed, use child process to initialize vim sources. +- Improve install.sh, install node when not exists. +- Improve interface of workspace. +- Fix loading of configuration content. + +# 2018-08-11 + +- Fix configuration content not saved on change. +- Fix thrown error on watchman not found. +- Fix incompatible options of `child_process`. +- Fix location list for diagnostics. + + - Reset on `BufWinEnter`. + - Available for all windows of single buffer. + - Use replace on change for coc location list. + - Add debounce. + +- Fix signature help behaviour, truncate messages to not overlap. +- Reworks sources use async import. + +# 2018-08-10 + +- Fix dispose for all modules. +- Add support for multiple `addWillSaveUntilListener`. +- Fix `startcol` for json server. +- Add support filetype `javascriptreact` for tsserver. + +# 2018-08-09 + +- Add `coc#util#install` for installation. +- Add `install.cmd` for windows. + +# 2018-08-08 + +- Improved location list for diagnostics. +- Add `internal` option to command. + + Commands registered by server are internal. + +- Add support for multiple save wait until requests. + +# 2018-08-07 + +- Add `forceFullSync` to language server option. + +# 2018-08-05 + +- Improve eslint extension to use workspaceFolder. +- Fix watchman not works with multiple roots. +- Add feature: dynamic root support for workspace. +- **Break change** output channel of watchman is removed. + +# 2018-08-04 + +- Fix order of document symbols. +- Fix completion snippet with `$variable`. +- Add feature: expand snippet on confirm. +- Add feature: `(coc-complete-custom)` for complete custom sources. + + Default customs sources: `emoji`, `include` and `word` + +- **Break change** `emoji` `include` used for all filetypes by default. + +# 2018-08-03 + +- Add command `:CocErrors` for debug. +- Support `DocumentSymbol` for 'textDocument/documentSymbol' + +# 2018-08-02 + +- Fix error of language client with unsupported schema. + + No document event fired for unsupported schema (eg: fugitive://) + +- Fix update empty configuration not works. + +# 2018-07-31 + +- Improve file source triggered with dirname started path. + +# 2018-07-30 + +- Fix source ultisnip not working. +- Fix custom language client with command not working. +- Fix wrong arguments passed to `runCommand` function. +- Improve module install, add `sudo` for `npm install` on Linux. +- Improve completion on backspace. + - Completion is resumed when search is empty. + - Completion is triggered when user try to fix search. + +# 2018-07-29 + +- **Break change** all servers are decoupled from coc.nvim + + A prompt for download is shown when server not found. + +- **Break change** `vim-node-rpc` decoupled from coc.nvim + + A prompt would be shown to help user install vim-node-rpc in vim. + +- Add command `CocConfig` + +# 2018-07-28 + +- Fix uncaught exception error on windows. +- Use plugin root for assets resolve. +- Fix emoji source not triggered by `:`. +- Improve file source to recognize `~` as user home. + +# 2018-07-27 + +- Prompt user for download server module with big extension like `vetur` and `wxml-langserver` +- **Break change**, section of settings changed: `cssserver.[languageId]` moved to `[languageId]` + + For example: `cssserver.css` section is moved to `css` section. + + This makes coc settings of css languages the same as VSCode. + +- **Break change**, `stylelint` extension is disabled by default, add + + ``` + "stylelint.enable": true, + ``` + + to your `coc-settings.json` to enable it. + + User will be prompted to download server if `stylelint-langserver` is not + installed globally. + +- **Break change**, `triggerAfterInsertEnter` is always `true`, add + + ``` + "coc.preferences.triggerAfterInsertEnter": false, + ``` + + to your `coc-settings.json` to disable it. + +- **Break change**, when `autoTrigger` is `always` completion would be triggered + after completion item select. + +# 2018-07-24 + +- better statusline integration with airline and lightline. + +# 2018-07-23 + +- Coc service start much faster. +- Add vim-node-rpc module. +- **Break change** global function `CocAutocmd` and `CocResult` are removed. +- Support Vue with vetur + +# 2018-07-21 + +- Fix issue with `completeopt`. +- Add source `neosnippet`. +- Add source `gocode`. + +# 2018-07-20 + +- Add documentation for language server debug. +- Rework register of functions, avoid undefined function. + +# 2018-07-19 + +- Fix error of `isFile` check. +- Ignore undefined function on service start. + +# 2018-07-17 + +- Add `coc.preference.jumpCommand` to settings. +- Make coc service standalone. + +# 2018-07-16 + +- Support arguments for `runCommand` action. +- Add coc command `workspace.showOutput`. +- Support output channel for language server. +- Support `[extension].trace.server` setting for trace server communication. + +# 2018-07-15 + +- Support location list for diagnostic. +- Add tsserver project errors command. + +# 2018-07-14 + +- Add support for `preselect` of complete item. +- Add support for socket language server configuration. +- Fix configured language server doesn't work. +- Add `workspace.diffDocument` coc command. +- Fix buffer sometimes not attached. +- Improve completion of JSON extension. + +# 2018-07-13 + +- **Break change:** `diagnostic` in setting.json changed to `diagnostic`. +- Fix clearHighlight arguments. +- Add eslint extension https://github.com/Microsoft/vscode-eslint. +- Fix snippet break with line have \$variable. +- Use jsonc-parser replace json5. +- Add `data/schema.json` for coc-settings.json. + +# 2018-07-12 + +- Fix restart of tsserver not working. +- Fix edit of current buffer change jumplist by using `:keepjumps`. diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/package.json b/vim/.vim/pack/coc/start/coc.nvim-release/package.json new file mode 100644 index 0000000..45d4968 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/package.json @@ -0,0 +1,99 @@ +{ + "name": "coc.nvim", + "version": "0.0.74", + "description": "LSP based intellisense engine for neovim & vim8.", + "main": "./lib/index.js", + "bin": "./bin/server.js", + "scripts": { + "clean": "rimraf lib build", + "lint": "tslint -c tslint.json -p .", + "build": "tsc -p tsconfig.json", + "watch": "tsc -p tsconfig.json --watch true --sourceMap", + "test": "node --trace-warnings node_modules/.bin/jest --runInBand --detectOpenHandles --forceExit", + "test-build": "node --trace-warnings node_modules/.bin/jest --runInBand --coverage --forceExit", + "prepare": "npm-run-all clean build" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/neoclide/coc.nvim.git" + }, + "keywords": [ + "complete", + "neovim" + ], + "author": "Qiming Zhao ", + "license": "MIT", + "bugs": { + "url": "https://github.com/neoclide/coc.nvim/issues" + }, + "homepage": "https://github.com/neoclide/coc.nvim#readme", + "jest": { + "globals": { + "__TEST__": true + }, + "watchman": false, + "clearMocks": true, + "globalSetup": "./jest.js", + "testEnvironment": "node", + "moduleFileExtensions": [ + "ts", + "tsx", + "json", + "js" + ], + "transform": { + "^.+\\.tsx?$": "ts-jest" + }, + "testRegex": "src/__tests__/.*\\.(test|spec)\\.ts$", + "coverageDirectory": "./coverage/" + }, + "devDependencies": { + "@chemzqm/tslint-config": "^1.0.18", + "@types/debounce": "^3.0.0", + "@types/fb-watchman": "^2.0.0", + "@types/glob": "^7.1.1", + "@types/jest": "^24.0.18", + "@types/minimatch": "^3.0.3", + "@types/mkdirp": "^0.5.2", + "@types/node": "^12.7.4", + "@types/semver": "^6.0.2", + "@types/tar": "^4.0.3", + "@types/tunnel": "^0.0.1", + "@types/uuid": "^3.4.5", + "@types/which": "^1.3.1", + "colors": "^1.3.3", + "jest": "24.9.0", + "npm-run-all": "^4.1.5", + "ts-jest": "^24.0.2", + "tslint": "^5.19.0", + "typescript": "3.6.2", + "vscode-languageserver": "5.3.0-next.8" + }, + "dependencies": { + "@chemzqm/neovim": "5.1.9", + "await-semaphore": "^0.1.3", + "bser": "^2.1.0", + "debounce": "^1.2.0", + "fast-diff": "^1.2.0", + "fb-watchman": "^2.0.0", + "follow-redirects": "^1.9.0", + "glob": "^7.1.4", + "isuri": "^2.0.3", + "jsonc-parser": "^2.1.1", + "log4js": "^5.1.0", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "mv": "^2.1.1", + "rc": "^1.2.8", + "rimraf": "^3.0.0", + "semver": "^6.3.0", + "tar": "^4.4.10", + "tslib": "^1.10.0", + "tunnel": "^0.0.6", + "uuid": "^3.3.3", + "vscode-languageserver-protocol": "3.15.0-next.6", + "vscode-languageserver-types": "3.15.0-next.2", + "vscode-uri": "^2.0.3", + "which": "^1.3.1" + } +} diff --git a/vim/.vim/pack/coc/start/coc.nvim-release/plugin/coc.vim b/vim/.vim/pack/coc/start/coc.nvim-release/plugin/coc.vim new file mode 100644 index 0000000..86f6439 --- /dev/null +++ b/vim/.vim/pack/coc/start/coc.nvim-release/plugin/coc.vim @@ -0,0 +1,382 @@ +if exists('g:did_coc_loaded') || v:version < 800 + finish +endif +if has('nvim') && !has('nvim-0.3.0') | finish | endif +let g:did_coc_loaded = 1 +let g:coc_service_initialized = 0 +let s:is_win = has('win32') || has('win64') +let s:root = expand(':h:h') +let s:is_vim = !has('nvim') +let s:is_gvim = get(v:, 'progname', '') ==# 'gvim' + +if get(g:, 'coc_start_at_startup', 1) && !s:is_gvim + call coc#rpc#start_server() +endif + +function! CocAction(...) abort + return coc#rpc#request('CocAction', a:000) +endfunction + +function! CocHasProvider(name) abort + return coc#rpc#request('hasProvider', [a:name]) +endfunction + +function! CocActionAsync(...) abort + return s:AsyncRequest('CocAction', a:000) +endfunction + +function! CocRequest(...) abort + return coc#rpc#request('sendRequest', 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) + call coc#rpc#request('findLocations', args) +endfunction + +function! CocLocationsAsync(id, method, ...) abort + let args = [a:id, a:method] + copy(a:000) + call coc#rpc#notify('findLocations', args) +endfunction + +function! CocRequestAsync(...) + return s:AsyncRequest('sendRequest', a:000) +endfunction + +function! s:AsyncRequest(name, args) abort + let Cb = 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', '-x'] + 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) + call mkdir(home, 'p') + endif + execute 'edit '.home.'/coc-settings.json' +endfunction + +function! s:OpenLocalConfig() + let currentDir = getcwd() + let fsRootDir = fnamemodify($HOME, ":p:h:h:h") + + if currentDir == $HOME + echom "Can't resolve local config from current working directory." + return + endif + + while isdirectory(currentDir) && !(currentDir ==# $HOME) && !(currentDir ==# fsRootDir) + if isdirectory(currentDir.'/.vim') + execute 'edit '.currentDir.'/.vim/coc-settings.json' + return + endif + let currentDir = fnamemodify(currentDir, ':p:h:h') + endwhile + + if coc#util#prompt_confirm("No local config detected, would you like to create .vim/coc-settings.json?") + call mkdir('.vim', 'p') + execute 'edit .vim/coc-settings.json' + endif +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] = get(g:terminal_ansi_colors, i, colors[i]) + else + let color_map[name] = get(g:, 'terminal_color_'.i, colors[i]) + endif + endfor + 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 + exe 'hi default CocListBg'.foreground. ' guibg='.foregroundColor + endfor +endfunction + +function! s:CursorRangeFromSelected(type, ...) abort + " add range by operator + call coc#rpc#request('cursorsSelect', [bufnr('%'), 'operator', a:type]) +endfunction + +function! s:Disable() abort + if get(g:, 'coc_enabled', 0) == 0 + return + endif + augroup coc_nvim + autocmd! + augroup end + echohl MoreMsg + echom '[coc.nvim] 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:SyncAutocmd(...) + if !get(g:,'coc_workspace_initialized', 0) | return | endif + if get(g:, 'coc_service_initialized', 0) + call coc#rpc#request('CocAutocmd', a:000) + else + call coc#rpc#notify('CocAutocmd', a:000) + endif +endfunction + +function! s:Enable() + if get(g:, 'coc_enabled', 0) == 1 + return + endif + let g:coc_enabled = 1 + + augroup coc_nvim + autocmd! + + if exists('##MenuPopupChanged') && exists('*nvim_open_win') + autocmd MenuPopupChanged * call s:Autocmd('MenuPopupChanged', get(v:, 'event', {}), win_screenpos(winnr())[0] + winline() - 2) + endif + if exists('##CompleteChanged') + autocmd CompleteChanged * call s:Autocmd('MenuPopupChanged', get(v:, 'event', {}), win_screenpos(winnr())[0] + winline() - 2) + endif + if exists('##MenuPopupChanged') || exists('##CompleteChanged') + autocmd CompleteDone * call coc#util#close_popup() + endif + + 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', expand('')) + endif + if exists('##TerminalOpen') + autocmd TerminalOpen * call s:Autocmd('TermOpen', +expand('')) + endif + else + autocmd DirChanged * call s:Autocmd('DirChanged', get(v:event, 'cwd', '')) + autocmd TermOpen * call s:Autocmd('TermOpen', +expand('')) + autocmd TermClose * call s:Autocmd('TermClose', +expand('')) + endif + autocmd WinLeave * call coc#util#clearmatches(get(w:, 'coc_matchids', [])) + autocmd BufWinLeave * call s:Autocmd('BufWinLeave', +expand(''), win_getid()) + autocmd BufWinEnter * call s:Autocmd('BufWinEnter', +expand(''), win_getid()) + autocmd FileType * call s:Autocmd('FileType', expand(''), +expand('')) + autocmd CompleteDone * call s:Autocmd('CompleteDone', get(v:, 'completed_item', {})) + autocmd InsertCharPre * call s:Autocmd('InsertCharPre', v:char) + if exists('##TextChangedP') + autocmd TextChangedP * call s:Autocmd('TextChangedP', +expand('')) + endif + autocmd TextChangedI * call s:Autocmd('TextChangedI', +expand('')) + autocmd InsertLeave * call s:Autocmd('InsertLeave', +expand('')) + autocmd InsertEnter * call s:Autocmd('InsertEnter', +expand('')) + autocmd BufHidden * call s:Autocmd('BufHidden', +expand('')) + autocmd BufEnter * call s:Autocmd('BufEnter', +expand('')) + autocmd TextChanged * call s:Autocmd('TextChanged', +expand(''), getbufvar(+expand(''), 'changedtick')) + autocmd BufWritePost * call s:Autocmd('BufWritePost', +expand('')) + autocmd CursorMoved * call s:Autocmd('CursorMoved', +expand(''), [line('.'), col('.')]) + autocmd CursorMovedI * call s:Autocmd('CursorMovedI', +expand(''), [line('.'), col('.')]) + autocmd CursorHold * call s:Autocmd('CursorHold', +expand('')) + autocmd CursorHoldI * call s:Autocmd('CursorHoldI', +expand('')) + autocmd BufNewFile,BufReadPost * call s:Autocmd('BufCreate', +expand('')) + autocmd BufUnload * call s:SyncAutocmd('BufUnload', +expand('')) + autocmd BufWritePre * call s:SyncAutocmd('BufWritePre', +expand('')) + autocmd FocusGained * if mode() !~# '^c' | call s:Autocmd('FocusGained') | endif + autocmd VimResized * call s:Autocmd('VimResized', &columns, &lines) + autocmd VimLeavePre * let g:coc_vim_leaving = 1 + autocmd VimLeave * call coc#rpc#stop() + autocmd BufReadCmd,FileReadCmd,SourceCmd list://* call coc#list#setup(expand('')) + autocmd BufWriteCmd __coc_refactor__* :call coc#rpc#notify('saveRefactor', [+expand('')]) + augroup end +endfunction + +hi default CocUnderline cterm=underline gui=underline +hi default CocErrorSign ctermfg=Red guifg=#ff0000 +hi default CocWarningSign ctermfg=Brown guifg=#ff922b +hi default CocInfoSign ctermfg=Yellow guifg=#fab005 +hi default CocHintSign ctermfg=Blue guifg=#15aabf +hi default CocSelectedText ctermfg=Red guifg=#fb4934 +hi default CocCodeLens ctermfg=Gray guifg=#999999 +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 CocListMode ModeMsg +hi default link CocListPath Comment +hi default link CocHighlightText CursorColumn +if has('nvim') + hi default link CocFloating NormalFloat +else + hi default link CocFloating Pmenu +endif + + +hi default link CocHoverRange Search +hi default link CocCursorRange Search +hi default link CocHighlightRead CocHighlightText +hi default link CocHighlightWrite CocHighlightText + +function! s:FormatFromSelected(type) + call CocAction('formatSelected', a:type) +endfunction + +function! s:CodeActionFromSelected(type) + call CocAction('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', 'node') + 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]) < 8 || (str2nr(ms[1]) == 8 && str2nr(ms[2]) < 10) + call add(lines, 'Error: Node version '.output.' < 8.10.0, please upgrade node.js') + endif + endif + " check bundle + let file = s:root.'/lib/attach.js' + if !filereadable(file) + let file = s:root.'/build/index.js' + if !filereadable(file) + call add(lines, 'Error: javascript bundle not found, run :call coc#util#install() to fix.') + endif + endif + if !empty(lines) + belowright vnew + setl filetype=nofile + call setline(1, lines) + else + if get(g:, 'coc_start_at_startup',1) + echohl MoreMsg | echon 'Start on startup is disabled, try :CocStart' | echohl None + else + echohl MoreMsg | echon 'Service stopped for some unknown reason, try :CocStart' | echohl None + endif + endif + endif +endfunction + +command! -nargs=0 CocInfo :call s:ShowInfo() +command! -nargs=0 CocOpenLog :call coc#rpc#notify('openLog', []) +command! -nargs=0 CocListResume :call coc#rpc#notify('listResume', []) +command! -nargs=0 CocPrev :call coc#rpc#notify('listPrev', []) +command! -nargs=0 CocNext :call coc#rpc#notify('listNext', []) +command! -nargs=0 CocDisable :call s:Disable() +command! -nargs=0 CocEnable :call s:Enable() +command! -nargs=0 CocConfig :call s:OpenConfig() +command! -nargs=0 CocLocalConfig :call s: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=+ -complete=custom,s:SearchOptions CocSearch :call coc#rpc#notify('search', []) +command! -nargs=+ -complete=custom,s:ExtensionList CocUninstall :call coc#rpc#notify('CocAction', ['uninstallExtension', ]) +command! -nargs=* -complete=custom,coc#list#options CocList :call coc#rpc#notify('openList', []) +command! -nargs=* -complete=custom,s:CommandList -range CocCommand :call coc#rpc#notify('runCommand', []) +command! -nargs=* -range CocAction :call coc#rpc#notify('codeActionRange', [, , ]) +command! -nargs=* -range CocFix :call coc#rpc#notify('codeActionRange', [, , 'quickfix']) +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([]) + +call s:Enable() +call s:AddAnsiGroups() + +vnoremap (coc-range-select) :call CocAction('rangeSelect', visualmode(), v:true) +vnoremap (coc-range-select-backword) :call CocAction('rangeSelect', visualmode(), v:false) +nnoremap (coc-range-select) :call CocAction('rangeSelect', '', v:true) +nnoremap (coc-codelens-action) :call CocActionAsync('codeLensAction') +vnoremap (coc-format-selected) :call CocActionAsync('formatSelected', visualmode()) +vnoremap (coc-codeaction-selected) :call CocActionAsync('codeAction', visualmode()) +nnoremap (coc-codeaction-selected) :set operatorfunc=CodeActionFromSelectedg@ +nnoremap (coc-codeaction) :call CocActionAsync('codeAction', '') +nnoremap (coc-rename) :call CocActionAsync('rename') +nnoremap (coc-format-selected) :set operatorfunc=FormatFromSelectedg@ +nnoremap (coc-format) :call CocActionAsync('format') +nnoremap (coc-diagnostic-info) :call CocActionAsync('diagnosticInfo') +nnoremap (coc-diagnostic-next) :call CocActionAsync('diagnosticNext') +nnoremap (coc-diagnostic-prev) :call CocActionAsync('diagnosticPrevious') +nnoremap (coc-diagnostic-next-error) :call CocActionAsync('diagnosticNext', 'error') +nnoremap (coc-diagnostic-prev-error) :call CocActionAsync('diagnosticPrevious', 'error') +nnoremap (coc-definition) :call CocAction('jumpDefinition') +nnoremap (coc-declaration) :call CocAction('jumpDeclaration') +nnoremap (coc-implementation) :call CocAction('jumpImplementation') +nnoremap (coc-type-definition) :call CocAction('jumpTypeDefinition') +nnoremap (coc-references) :call CocAction('jumpReferences') +nnoremap (coc-openlink) :call CocActionAsync('openLink') +nnoremap (coc-fix-current) :call CocActionAsync('doQuickfix') +nnoremap (coc-float-hide) :call coc#util#float_hide() +nnoremap (coc-float-jump) :call coc#util#float_jump() +nnoremap (coc-command-repeat) :call CocAction('repeatCommand') +nnoremap (coc-refactor) :call CocActionAsync('refactor') +inoremap CocRefresh =coc#_complete() + +nnoremap (coc-cursors-operator) :set operatorfunc=CursorRangeFromSelectedg@ +vnoremap (coc-cursors-range) :call coc#rpc#request('cursorsSelect', [bufnr('%'), 'range', visualmode()]) +nnoremap (coc-cursors-word) :call coc#rpc#request('cursorsSelect', [bufnr('%'), 'word', 'n']) +nnoremap (coc-cursors-position) :call coc#rpc#request('cursorsSelect', [bufnr('%'), 'position', 'n']) +vnoremap (coc-funcobj-i) :call coc#rpc#request('selectFunction', [v:true, visualmode()]) +vnoremap (coc-funcobj-a) :call coc#rpc#request('selectFunction', [v:false, visualmode()]) +onoremap (coc-funcobj-i) :call coc#rpc#request('selectFunction', [v:true, '']) +onoremap (coc-funcobj-a) :call coc#rpc#request('selectFunction', [v:false, '']) diff --git a/vim/.vim/plugged/vimtex b/vim/.vim/plugged/vimtex new file mode 160000 index 0000000..0647bb8 --- /dev/null +++ b/vim/.vim/plugged/vimtex @@ -0,0 +1 @@ +Subproject commit 0647bb8991a490f92de173ca67e9b49a3f1fddcd diff --git a/vim/.vim/plugin/plugins.vim b/vim/.vim/plugin/plugins.vim index 2a39d42..7d934fe 100644 --- a/vim/.vim/plugin/plugins.vim +++ b/vim/.vim/plugin/plugins.vim @@ -1,2 +1,6 @@ runtime macros/matchit.vim filetype on + +call plug#begin() +Plug 'lervag/vimtex' +call plug#end()