From 725a9dd95869231dd3ddb66002a2ee8e9553e3f7 Mon Sep 17 00:00:00 2001 From: Daniel Lundin Date: Wed, 3 Jan 2018 08:47:21 +0100 Subject: [PATCH] Config updates --- .config/alacritty/alacritty.yml | 95 +- .config/nvim/init.vim | 138 +- .config/redshift.conf | 6 +- .gitconfig | 1 + .local/share/nvim/site/autoload/plug.vim | 2504 ++++++++++++++++++++++ .oh-my-zsh | 2 +- .tmux.conf | 6 +- .xinitrc | 2 +- .zshrc | 83 +- bin/dwm | Bin 46920 -> 50992 bytes bin/st | Bin 71616 -> 7 bytes 11 files changed, 2727 insertions(+), 110 deletions(-) create mode 100644 .local/share/nvim/site/autoload/plug.vim mode change 100755 => 120000 bin/st diff --git a/.config/alacritty/alacritty.yml b/.config/alacritty/alacritty.yml index 1594a64..d2ca657 100644 --- a/.config/alacritty/alacritty.yml +++ b/.config/alacritty/alacritty.yml @@ -30,7 +30,7 @@ font: style: Italic # Point size of the font - size: 11.0 + size: 16.0 # Offset is the extra space around each character. offset.y can be thought of # as modifying the linespacing, and offset.x as modifying the letter spacing. offset: @@ -41,61 +41,62 @@ font: render_timer: false # Colors (Tomorrow Night Bright) -colors: - # Default colors - primary: - background: '0xfafafa' - foreground: '0x1d1d1c' - - # Normal colors - normal: - black: '0x212121' - red: '0xb7141e' - green: '0x457b23' - yellow: '0xfc7b08' - blue: '0x134eb2' - magenta: '0x550087' - cyan: '0x0e707c' - white: '0xeeeeee' - - # Bright colors - bright: - black: '0x424242' - red: '0xe83a3f' - green: '0x7aba39' - yellow: '0xfc8e08' - blue: '0x53a4f3' - magenta: '0xa94dbb' - cyan: '0x26bad1' - white: '0xd8d8d8' -# Colors (Solarized Dark) # colors: # # Default colors # primary: -# background: '0x002b36' -# foreground: '0x839496' +# background: '0xfafafa' +# foreground: '0x1d1d1c' # # # Normal colors # normal: -# black: '0x073642' -# red: '0xdc322f' -# green: '0x859900' -# yellow: '0xb58900' -# blue: '0x268bd2' -# magenta: '0xd33682' -# cyan: '0x2aa198' -# white: '0xeee8d5' +# black: '0x212121' +# red: '0xb7141e' +# green: '0x457b23' +# yellow: '0xfc7b08' +# blue: '0x134eb2' +# magenta: '0x550087' +# cyan: '0x0e707c' +# white: '0xeeeeee' # # # Bright colors # bright: -# black: '0x002b36' -# red: '0xcb4b16' -# green: '0x586e75' -# yellow: '0x657b83' -# blue: '0x839496' -# magenta: '0x6c71c4' -# cyan: '0x93a1a1' -# white: '0xfdf6e3' +# black: '0x424242' +# red: '0xe83a3f' +# green: '0x7aba39' +# yellow: '0xfc8e08' +# blue: '0x53a4f3' +# magenta: '0xa94dbb' +# cyan: '0x26bad1' +# white: '0xd8d8d8' + +# Colors (Solarized Dark) +colors: + # Default colors + primary: + background: '0x002b36' + foreground: '0x839496' + + # Normal colors + normal: + black: '0x073642' + red: '0xdc322f' + green: '0x859900' + yellow: '0xb58900' + blue: '0x268bd2' + magenta: '0xd33682' + cyan: '0x2aa198' + white: '0xeee8d5' + + # Bright colors + bright: + black: '0x002b36' + red: '0xcb4b16' + green: '0x586e75' + yellow: '0x657b83' + blue: '0x839496' + magenta: '0x6c71c4' + cyan: '0x93a1a1' + white: '0xfdf6e3' # Key bindings # diff --git a/.config/nvim/init.vim b/.config/nvim/init.vim index 6528cd1..7b361a0 100644 --- a/.config/nvim/init.vim +++ b/.config/nvim/init.vim @@ -1,37 +1,46 @@ "" Vundle -set rtp+=~/.vim/bundle/Vundle.vim -call vundle#begin() +" set rtp+=~/.vim/bundle/Vundle.vim +call plug#begin('~/.local/share/nvim/plugged') " Plugins -Plugin 'VundleVim/Vundle.vim' -Plugin 'airblade/vim-gitgutter' -Plugin 'b4b4r07/vim-hcl' -Plugin 'cespare/vim-toml' -Plugin 'chriskempson/base16-vim' -Plugin 'ervandew/supertab' -Plugin 'fatih/vim-go' -Plugin 'godlygeek/tabular' -Plugin 'hashivim/vim-terraform' -Plugin 'itchyny/lightline.vim' -Plugin 'joshdick/onedark.vim' -Plugin 'junegunn/fzf' -Plugin 'junegunn/fzf.vim' -Plugin 'Matt-Deacalion/vim-systemd-syntax' -Plugin 'nanotech/jellybeans.vim' -Plugin 'NLKNguyen/papercolor-theme' -Plugin 'plasticboy/vim-markdown' -Plugin 'rakr/vim-one' -Plugin 'rust-lang/rust.vim' -Plugin 'tomtom/tcomment_vim' -Plugin 'tpope/vim-fugitive' -Plugin 'tyrannicaltoucan/vim-quantum' -Plugin 'Valloric/YouCompleteMe' -Plugin 'w0rp/ale' +Plug 'VundleVim/Vundle.vim' +Plug 'airblade/vim-gitgutter' +Plug 'b4b4r07/vim-hcl' +Plug 'cespare/vim-toml' +Plug 'djoshea/vim-autoread' +Plug 'ervandew/supertab' +Plug 'fatih/vim-go' +Plug 'godlygeek/tabular' +Plug 'hashivim/vim-terraform' +Plug 'junegunn/vim-easy-align' +Plug 'junegunn/fzf' +Plug 'junegunn/fzf.vim' +Plug 'junegunn/goyo.vim' +Plug 'junegunn/gv.vim' +Plug 'junegunn/vim-peekaboo' +Plug 'Matt-Deacalion/vim-systemd-syntax' +Plug 'NLKNguyen/papercolor-theme' +Plug 'plasticboy/vim-markdown' +Plug 'rakr/vim-one' +Plug 'roxma/nvim-completion-manager' +Plug 'rust-lang/rust.vim' +Plug 'sebdah/vim-delve' +" Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' } +Plug 'Shougo/neosnippet.vim' +Plug 'Shougo/neosnippet-snippets' +Plug 'tomtom/tcomment_vim' +Plug 'tpope/vim-fugitive' +Plug 'tyrannicaltoucan/vim-quantum' +Plug 'vim-airline/vim-airline' +Plug 'vim-airline/vim-airline-themes' +Plug 'w0rp/ale' -call vundle#end() +call plug#end() -set timeoutlen=250 -set ttimeoutlen=200 +set ttimeout +set ttimeoutlen=0 +" set timeoutlen=150 +" set ttimeoutlen=100 filetype on " detect the type of file filetype plugin indent on " load filetype plugins @@ -92,6 +101,9 @@ set wildmenu set wildmode=list:longest set wildignore=*.swp,*.bak,*.pyc,*.class set splitbelow " Preview window +set splitright + +" let mapleader="," "" Session let g:session_autosave = 'no' @@ -165,7 +177,7 @@ map ,; :Commits map ,e :GitFiles map ,d :Files map ,f :History -map ,g :BLines +" map ,g :BLines map ,/ :Ag map ,m :Marks @@ -325,7 +337,7 @@ map ,h :echo "hi<" . synIDattr(synID(line("."),col("."),1),"name") . '> trans<' \ . synIDattr(synID(line("."),col("."),0),"name") . "> lo<" \ . synIDattr(synIDtrans(synID(line("."),col("."),1)),"name") . ">" -set background=light +set background=dark let g:one_allow_italics=1 let g:PaperColor_Light_Override = { 'Background' : '#fefe00' } @@ -406,34 +418,61 @@ function! LightLineReadonly() return &ft !~? 'help' && &readonly ? '' : '' endfunction -set statusline+=%#warningmsg# -set statusline+=%{SyntasticStatuslineFlag()} -set statusline+=%* +" set statusline+=%#warningmsg# +" set statusline+=%{SyntasticStatuslineFlag()} +" set statusline+=%* " Golang -let g:go_highlight_functions = 1 -let g:go_highlight_methods = 1 -let g:go_highlight_structs = 1 -let g:go_highlight_fields = 1 -let g:go_highlight_interfaces = 1 -let g:go_highlight_operators = 1 -let g:go_highlight_types = 1 let g:go_highlight_build_constraints = 1 +let g:go_highlight_extra_types = 1 +let g:go_highlight_fields = 1 +let g:go_highlight_functions = 1 +let g:go_highlight_interfaces = 1 +let g:go_highlight_methods = 1 +let g:go_highlight_operators = 1 +let g:go_highlight_structs = 1 +let g:go_highlight_types = 1 let g:go_auto_sameids = 1 let g:go_auto_type_info = 0 +" let g:go_def_mapping_enabled = 0 let g:go_info_mode = 'guru' -let g:go_updatetime = 500 +let g:go_updatetime = 20 +let g:go_snippet_engine = "neosnippet" + +autocmd FileType go nmap i (go-info) +autocmd FileType go nmap (go-doc) +autocmd FileType go nmap d (go-doc-vertical) + " ALE let g:ale_sign_column_always = 1 " let g:ale_linters = {'go': ['gometalinter', 'gofmt']} -let g:ale_linters = {'go': ['go build', 'gofmt', 'golint', 'gometalinter', 'gosimple', 'go vet', 'staticcheck']} +" let g:ale_linters = {'go': ['go build', 'gofmt', 'golint', 'gometalinter', 'gosimple', 'go vet', 'staticcheck']} +let g:ale_linters = {'go': ['gofmt', 'golint', 'gometalinter', 'gosimple', 'go vet', 'staticcheck']} +let g:ale_sign_error = '⤫' +let g:ale_sign_warning = '⚠' +let g:airline#extensions#ale#enabled = 1 +"" Neosnippet +" imap (neosnippet_expand_or_jump) +" smap (neosnippet_expand_or_jump) +" xmap (neosnippet_expand_target) +" imap (pumvisible() ? "\\(expand_or_nl)" : "\") +" imap (expand_or_nl) (cm#completed_is_snippet() ? "\":"\") +" +imap (neosnippet_expand_or_jump) +vmap (neosnippet_expand_or_jump) +inoremap =cm#sources#neosnippet#trigger_or_popup("\(neosnippet_expand_or_jump)") +vmap (neosnippet_expand_target) +" expand parameters +let g:neosnippet#enable_completed_snippet=1 " Hugo let g:vim_markdown_frontmatter = 1 let g:vim_markdown_toml_frontmatter = 1 + +"" Git let g:gitgutter_override_sign_column_highlight = 0 let g:gitgutter_sign_added = '🞥' let g:gitgutter_sign_modified = '▲' @@ -441,16 +480,19 @@ let g:gitgutter_sign_removed = '🞬' let g:gitgutter_sign_removed_first_line = '🞬' let g:gitgutter_sign_modified_removed = '🞬' +"" Airline +" let g:airline#extensions#tabline#enabled = 1 +let g:airline_theme='distinguished' + +"" Terminal + let $NVIM_TUI_ENABLE_TRUE_COLOR=1 set termguicolors let &t_8f = "[38;2;%lu;%lu;%lum" let &t_8b = "[48;2;%lu;%lu;%lum" -" let base16colorspace=256 " color dln-light -" color jellybeans -" color one -color base16-tomorrow +color dln-dark " highlight LineNr ctermfg=31 ctermbg=234 cterm=italic " highlight CursorLine ctermfg=159 ctermbg=24 @@ -462,5 +504,5 @@ highlight GitGutterChange ctermbg=234 ctermfg=220 highlight GitGutterDelete ctermbg=234 ctermfg=124 highlight GitGutterChangeDelete ctermbg=234 ctermfg=88 -map ,m :color dln +map ,l :color dln-dark diff --git a/.config/redshift.conf b/.config/redshift.conf index d957e48..1fda982 100644 --- a/.config/redshift.conf +++ b/.config/redshift.conf @@ -1,8 +1,8 @@ [redshift] -temp-day=5800 -temp-night=3700 +temp-day=3900 +temp-night=3400 brightness-day=0.99 -brightness-night=0.5 +brightness-night=0.95 location-provider=manual transition=0 diff --git a/.gitconfig b/.gitconfig index d737b69..4cc94be 100644 --- a/.gitconfig +++ b/.gitconfig @@ -135,3 +135,4 @@ diff-chunk = magenta default bold stripLeadingSymbols = true [hub] protocol = git +[http] diff --git a/.local/share/nvim/site/autoload/plug.vim b/.local/share/nvim/site/autoload/plug.vim new file mode 100644 index 0000000..143c377 --- /dev/null +++ b/.local/share/nvim/site/autoload/plug.vim @@ -0,0 +1,2504 @@ +" 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') || has('win64') +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! 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) || !has_key(plug, 'on') && !has_key(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 + +if s:is_win + function! s:rtp(spec) + return s:path(a:spec.dir . get(a:spec, 'rtp', '')) + endfunction + + 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 +else + function! s:rtp(spec) + return s:dirpath(a:spec.dir . get(a:spec, 'rtp', '')) + endfunction + + 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'] + 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 + 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 + set shell=cmd.exe shellcmdflag=/c shellredir=>%s\ 2>&1 + elseif a:swap + set shell=sh shellredir=>%s\ 2>&1 + endif + return prev +endfunction + +function! s:bang(cmd, ...) + try + let [sh, shellcmdflag, shrd] = s:chsh(a:0) + " FIXME: Escaping is incomplete. We could use shellescape with eval, + " but it won't work on Windows. + let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd + if s:is_win + let batchfile = tempname().'.bat' + call writefile(['@echo off', cmd], batchfile) + let cmd = batchfile + endif + let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%') + execute "normal! :execute g:_plug_bang\\" + finally + unlet g:_plug_bang + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win + call delete(batchfile) + endif + endtry + return v:shell_error ? 'Exit status: ' . v:shell_error : '' +endfunction + +function! s:regress_bar() + let bar = substitute(getline(2)[1:-2], '.*\zs=', 'x', '') + call s:progress_bar(2, bar, len(bar)) +endfunction + +function! s:is_updated(dir) + return !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"', a:dir)) +endfunction + +function! s:do(pull, force, todo) + for [name, spec] in items(a:todo) + if !isdirectory(spec.dir) + continue + endif + let installed = has_key(s:update.new, name) + let updated = installed ? 0 : + \ (a:pull && index(s:update.errors, name) < 0 && s:is_updated(spec.dir)) + if a:force || installed || updated + execute 'cd' s:esc(spec.dir) + call append(3, '- Post-update hook for '. name .' ... ') + let error = '' + let type = type(spec.do) + if type == s:TYPE.string + if spec.do[0] == ':' + if !get(s:loaded, name, 0) + let s:loaded[name] = 1 + call s:reorg_rtp() + endif + call s:load_plugin(spec) + try + execute spec.do[1:] + catch + let error = v:exception + endtry + if !s:plug_window_exists() + cd - + throw 'Warning: vim-plug was terminated by the post-update hook of '.name + endif + else + let error = s:bang(spec.do) + endif + elseif type == s:TYPE.funcref + try + let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') + call spec.do({ 'name': name, 'status': status, 'force': a:force }) + catch + let error = v:exception + endtry + else + let error = 'Invalid hook type' + endif + call s:switch_in() + call setline(4, empty(error) ? (getline(4) . 'OK') + \ : ('x' . getline(4)[1:] . error)) + if !empty(error) + call add(s:update.errors, name) + call s:regress_bar() + endif + cd - + endif + endfor +endfunction + +function! s:hash_match(a, b) + return stridx(a:a, a:b) == 0 || stridx(a:b, a:a) == 0 +endfunction + +function! s:checkout(spec) + let sha = a:spec.commit + let output = s:system('git rev-parse HEAD', a:spec.dir) + if !v:shell_error && !s:hash_match(sha, s:lines(output)[0]) + let output = s:system( + \ 'git fetch --depth 999999 && git checkout '.s:esc(sha).' --', a:spec.dir) + endif + return output +endfunction + +function! s:finish(pull) + let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen')) + if new_frozen + let s = new_frozen > 1 ? 's' : '' + call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s)) + endif + call append(3, '- Finishing ... ') | 4 + redraw + call plug#helptags() + call plug#end() + call setline(4, getline(4) . 'Done!') + redraw + let msgs = [] + if !empty(s:update.errors) + call add(msgs, "Press 'R' to retry.") + endif + if a:pull && len(s:update.new) < len(filter(getline(5, '$'), + \ "v:val =~ '^- ' && stridx(v:val, 'Already up-to-date') < 0")) + 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') + let s:clone_opt .= ' -c core.eol=lf -c core.autocrlf=input' + endif + + " 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 '.s:shellesc(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 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 ' . s:shellesc(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': [''], + \ 'batchfile': (s:is_win && (s:nvim || s:vim8)) ? tempname().'.bat' : '', + \ '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) : a:cmd + if !empty(job.batchfile) + call writefile(['@echo off', cmd], job.batchfile) + let cmd = job.batchfile + endif + let argv = add(s:is_win ? ['cmd', '/c'] : ['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() + + if has_key(job, 'batchfile') && !empty(job.batchfile) + call delete(job.batchfile) + endif + 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 = !isdirectory(spec.dir) + + 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, + \ s:shellesc(spec.uri), + \ s:shellesc(s:trim(spec.dir))), { '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) + let escaped = substitute(a:arg, '[&|<>()@^]', '^&', 'g') + let escaped = substitute(escaped, '%', '%%', 'g') + let escaped = substitute(escaped, '"', '\\^&', 'g') + let escaped = substitute(escaped, '\(\\\+\)\(\\^\)', '\1\1\2', 'g') + return '^"'.substitute(escaped, '\(\\\+\)$', '\1\1', '').'^"' +endfunction + +function! s:shellesc(arg) + if &shell =~# 'cmd.exe$' + return s:shellesc_cmd(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) + return printf('cd%s %s && %s', s:is_win ? ' /d' : '', s:shellesc(a:dir), a:cmd) +endfunction + +function! s:system(cmd, ...) + try + let [sh, shellcmdflag, shrd] = s:chsh(1) + let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd + if s:is_win + let batchfile = tempname().'.bat' + call writefile(['@echo off', cmd], batchfile) + let cmd = batchfile + endif + return system(s:is_win ? '('.cmd.')' : cmd) + finally + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win + call delete(batchfile) + endif + endtry +endfunction + +function! s:system_chomp(...) + let ret = call('s:system', a:000) + return v:shell_error ? '' : substitute(ret, '\n$', '', '') +endfunction + +function! s:git_validate(spec, check_branch) + let err = '' + if isdirectory(a:spec.dir) + let result = s:lines(s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url', a:spec.dir)) + let remote = result[-1] + if v:shell_error + let err = join([remote, 'PlugClean required.'], "\n") + elseif !s:compare_git_uri(remote, a:spec.uri) + let err = join(['Invalid URI: '.remote, + \ 'Expected: '.a:spec.uri, + \ 'PlugClean required.'], "\n") + elseif a:check_branch && has_key(a:spec, 'commit') + let result = s:lines(s:system('git rev-parse HEAD 2>&1', a:spec.dir)) + let sha = result[-1] + if v:shell_error + let err = join(add(result, 'PlugClean required.'), "\n") + elseif !s:hash_match(sha, a:spec.commit) + let err = join([printf('Invalid HEAD (expected: %s, actual: %s)', + \ a:spec.commit[:6], sha[:6]), + \ 'PlugUpdate required.'], "\n") + endif + elseif a:check_branch + let branch = result[0] + " Check tag + if has_key(a:spec, 'tag') + let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir) + if a:spec.tag !=# tag && a:spec.tag !~ '\*' + let err = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.', + \ (empty(tag) ? 'N/A' : tag), a:spec.tag) + endif + " Check branch + elseif a:spec.branch !=# branch + let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', + \ branch, a:spec.branch) + endif + if empty(err) + let [ahead, behind] = split(s:lastline(s:system(printf( + \ 'git rev-list --count --left-right HEAD...origin/%s', + \ a:spec.branch), a:spec.dir)), '\t') + if !v:shell_error && ahead + if behind + " Only mention PlugClean if diverged, otherwise it's likely to be + " pushable (and probably not that messed up). + let err = printf( + \ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n" + \ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', a:spec.branch, ahead, behind) + else + let err = printf("Ahead of origin/%s by %d commit(s).\n" + \ .'Cannot update until local changes are pushed.', + \ a:spec.branch, ahead) + endif + endif + endif + endif + else + let err = 'Not found' + endif + return [err, err =~# 'PlugClean'] +endfunction + +function! s:rm_rf(dir) + if isdirectory(a:dir) + call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . s:shellesc(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', s:plug_src, tmp)) + if v:shell_error + return s:err('Error upgrading vim-plug: '. out) + endif + + if readfile(s:me) ==# readfile(new) + echo 'vim-plug is already up-to-date' + return 0 + else + call rename(s:me, s:me . '.old') + call rename(new, s:me) + unlet g:loaded_plug + echo 'vim-plug has been upgraded' + return 1 + endif + finally + silent! call s:rm_rf(tmp) + endtry +endfunction + +function! s:upgrade_specs() + for spec in values(g:plugs) + let spec.frozen = get(spec, 'frozen', 0) + endfor +endfunction + +function! s:status() + call s:prepare() + call append(0, 'Checking plugins') + call append(1, '') + + let ecnt = 0 + let unloaded = 0 + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + let is_dir = isdirectory(spec.dir) + if has_key(spec, 'uri') + if is_dir + let [err, _] = s:git_validate(spec, 1) + let [valid, msg] = [empty(err), empty(err) ? 'OK' : err] + else + let [valid, msg] = [0, 'Not found. Try PlugInstall.'] + endif + else + if is_dir + let [valid, msg] = [1, 'OK'] + else + let [valid, msg] = [0, 'Not found.'] + endif + endif + let cnt += 1 + let ecnt += !valid + " `s:loaded` entry can be missing if PlugUpgraded + if is_dir && get(s:loaded, name, -1) == 0 + let unloaded = 1 + let msg .= ' (not loaded)' + endif + call s:progress_bar(2, repeat('=', cnt), total) + call append(3, s:format_message(valid ? '-' : 'x', name, msg)) + normal! 2G + redraw + endfor + call setline(1, 'Finished. '.ecnt.' error(s).') + normal! gg + setlocal nomodifiable + if unloaded + echo "Press 'L' on each line to load plugin, or 'U' to update" + nnoremap L :call status_load(line('.')) + xnoremap L :call status_load(line('.')) + end +endfunction + +function! s:extract_name(str, prefix, suffix) + return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$') +endfunction + +function! s:status_load(lnum) + let line = getline(a:lnum) + let name = s:extract_name(line, '-', '(not loaded)') + if !empty(name) + call plug#load(name) + setlocal modifiable + call setline(a:lnum, substitute(line, ' (not loaded)$', '', '')) + setlocal nomodifiable + endif +endfunction + +function! s:status_update() range + let lines = getline(a:firstline, a:lastline) + let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)') + if !empty(names) + echo + execute 'PlugUpdate' join(names) + endif +endfunction + +function! s:is_preview_window_open() + silent! wincmd P + if &previewwindow + wincmd p + return 1 + endif +endfunction + +function! s:find_name(lnum) + for lnum in reverse(range(1, a:lnum)) + let line = getline(lnum) + if empty(line) + return '' + endif + let name = s:extract_name(line, '-', '') + if !empty(name) + return name + endif + endfor + return '' +endfunction + +function! s:preview_commit() + if b:plug_preview < 0 + let b:plug_preview = !s:is_preview_window_open() + endif + + let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7,9}') + if empty(sha) + return + endif + + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir) + return + endif + + if exists('g:plug_pwindow') && !s:is_preview_window_open() + execute g:plug_pwindow + execute 'e' sha + else + execute 'pedit' sha + wincmd P + endif + setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable + try + let [sh, shellcmdflag, shrd] = s:chsh(1) + let cmd = 'cd '.s:shellesc(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha + if s:is_win + let batchfile = tempname().'.bat' + call writefile(['@echo off', cmd], batchfile) + let cmd = batchfile + endif + execute 'silent %!' cmd + finally + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win + call delete(batchfile) + endif + endtry + setlocal nomodifiable + nnoremap q :q + wincmd p +endfunction + +function! s:section(flags) + call search('\(^[x-] \)\@<=[^:]\+:', a:flags) +endfunction + +function! s:format_git_log(line) + let indent = ' ' + let tokens = split(a:line, nr2char(1)) + if len(tokens) != 5 + return indent.substitute(a:line, '\s*$', '', '') + endif + let [graph, sha, refs, subject, date] = tokens + let tag = matchstr(refs, 'tag: [^,)]\+') + let tag = empty(tag) ? ' ' : ' ('.tag.') ' + return printf('%s%s%s%s%s (%s)', indent, graph, sha, tag, subject, date) +endfunction + +function! s:append_ul(lnum, text) + call append(a:lnum, ['', a:text, repeat('-', len(a:text))]) +endfunction + +function! s:diff() + call s:prepare() + call append(0, ['Collecting changes ...', '']) + let cnts = [0, 0] + let bar = '' + let total = filter(copy(g:plugs), 's:is_managed(v:key) && isdirectory(v:val.dir)') + call s:progress_bar(2, bar, len(total)) + for origin in [1, 0] + let plugs = reverse(sort(items(filter(copy(total), (origin ? '' : '!').'(has_key(v:val, "commit") || has_key(v:val, "tag"))')))) + if empty(plugs) + continue + endif + call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:') + for [k, v] in plugs + let range = origin ? '..origin/'.v.branch : 'HEAD@{1}..' + let diff = s:system_chomp('git log --graph --color=never '.join(map(['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range], 's:shellesc(v:val)')), 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 :silent! call preview_commit() + nnoremap o :silent! call preview_commit() + 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, '\\\@/dev/null + eval $(tmux switch-client \; show-environment -s 2>/dev/null) +} # User configuration @@ -101,22 +154,34 @@ cd_func () } alias cd=cd_func +## vim +export NVIM_LISTEN_ADDRESS=/tmp/nvimsocket + +e () +{ + tmux select-window -t1 + nvr --remote $(readlink -f "$@") +} ## Powerline -. /usr/lib/python3.6/site-packages/powerline/bindings/zsh/powerline.zsh +# . /usr/lib/python3.6/site-packages/powerline/bindings/zsh/powerline.zsh ## fzf export FZF_TMUX=1 -export FZF_COMPLETION_TRIGGER="." +export FZF_COMPLETION_TRIGGER=";" . /usr/share/fzf/completion.zsh . /usr/share/fzf/key-bindings.zsh # Kubernetes -source <(kubectl completion zsh) -[ -f $HOME/bin/kops ] && source <($HOME/bin/kops completion zsh) +command -v kubectl >/dev/null 2>&1 && source <(kubectl completion zsh) +command -v kops >/dev/null 2>&1 && source <(kops completion zsh) +command -v helm >/dev/null 2>&1 && source <(helm completion zsh) [ -f /opt/google-cloud-sdk/completion.zsh.inc ] && source /opt/google-cloud-sdk/completion.zsh.inc +# Pager +command -v pygmentize >/dev/null 2>&1 && export LESSOPEN="|/usr/bin/pygmentize -f terminal16m -O style=native %s" + ## Aliases alias ag='ag --pager less' alias cdiff='colordiff -u' @@ -131,6 +196,8 @@ alias tree='tree -C' alias upper="tr '[:lower:]' '[:upper:]'" alias vimdiff='vimdiff -R' alias vim=nvim +alias xc='xclip -selection clipboard' +# alias e='nvr --remote' diff --git a/bin/dwm b/bin/dwm index b70545e0236d07c927ef26ebfc9a2cebf07231b0..5553a0e40439c0bb43cbb2f7d67436656ebe4c5a 100755 GIT binary patch literal 50992 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ÿkdaO#{Y@h+ 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 SSa^Q)mJjZ~5ULs-4Q~Lukv0_o diff --git a/bin/st b/bin/st deleted file mode 100755 index a0bb9108f65b191a823b5688287e6e744afb2e2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71616 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