diff --git a/plug.vim b/plug.vim index 1e44c27..e916109 100644 --- a/plug.vim +++ b/plug.vim @@ -80,6 +80,7 @@ let s:TYPE = { \ 'dict': type({}), \ 'funcref': type(function('call')) \ } +let s:loaded = get(s:, 'loaded', {}) function! plug#begin(...) if a:0 > 0 @@ -148,9 +149,8 @@ function! plug#end() " need to loop through the plugins in reverse for name in reverse(copy(g:plugs_order)) let plug = g:plugs[name] - if !has_key(plug, 'on') && !has_key(plug, 'for') - let rtp = s:rtp(plug) - call s:add_rtp(rtp) + if get(s:loaded, plug.dir, 0) || !has_key(plug, 'on') && !has_key(plug, 'for') + let rtp = s:add_rtp(plug) if reload call s:source(rtp, 'plugin/**/*.vim', 'after/plugin/**/*.vim') endif @@ -177,8 +177,11 @@ function! plug#end() endif if has_key(plug, 'for') - call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') - for key in s:to_a(plug.for) + let types = s:to_a(plug.for) + if !empty(types) + call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') + endif + for key in types if !has_key(lod, key) let lod[key] = [] endif @@ -247,12 +250,15 @@ function! s:esc(path) return substitute(a:path, ' ', '\\ ', 'g') endfunction -function! s:add_rtp(rtp) - execute 'set rtp^='.s:esc(a:rtp) - let after = globpath(a:rtp, 'after') +function! s:add_rtp(plug) + let rtp = s:rtp(a:plug) + execute 'set rtp^='.s:esc(rtp) + let after = globpath(rtp, 'after') if isdirectory(after) execute 'set rtp+='.s:esc(after) endif + let s:loaded[a:plug.dir] = 1 + return rtp endfunction function! s:reorg_rtp() @@ -287,8 +293,7 @@ function! plug#load(...) endfunction function! s:lod(plug, types) - let rtp = s:rtp(a:plug) - call s:add_rtp(rtp) + let rtp = s:add_rtp(a:plug) for dir in a:types call s:source(rtp, dir.'/**/*.vim') endfor @@ -339,6 +344,7 @@ function! s:add(repo, ...) \ a:0 == 1 ? s:parse_options(a:1) : s:base_spec) let g:plugs[name] = spec let g:plugs_order += [name] + let s:loaded[spec.dir] = 0 catch return s:err(v:exception) endtry @@ -419,6 +425,7 @@ function! s:syntax() syn match plugCommit /^ [0-9a-z]\{7} .*/ contains=plugRelDate,plugSha syn match plugSha /\(^ \)\@<=[0-9a-z]\{7}/ contained syn match plugRelDate /([^)]*)$/ contained + syn match plugNotLoaded /(not loaded)$/ syn match plugError /^x.*/ syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean hi def link plug1 Title @@ -439,6 +446,8 @@ function! s:syntax() hi def link plugError Error hi def link plugRelDate Comment hi def link plugSha Identifier + + hi def link plugNotLoaded Comment endfunction function! s:lpad(str, len) @@ -473,6 +482,7 @@ function! s:prepare() call s:assign_name() endif silent! unmap + silent! unmap L setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline setf vim-plug call s:syntax() @@ -1072,6 +1082,7 @@ function! s:status() call append(1, '') let ecnt = 0 + let unloaded = 0 let [cnt, total] = [0, len(g:plugs)] for [name, spec] in items(g:plugs) if has_key(spec, 'uri') @@ -1089,6 +1100,11 @@ function! s:status() endif let cnt += 1 let ecnt += !valid + " `s:loaded` entry can be missing if PlugUpgraded + if valid && get(s:loaded, spec.dir, -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, name, msg)) normal! 2G @@ -1096,6 +1112,21 @@ function! s:status() endfor call setline(1, 'Finished. '.ecnt.' error(s).') normal! gg + if unloaded + echo "Press 'L' on each line to load plugin" + nnoremap L :call status_load(line('.')) + xnoremap L :call status_load(line('.')) + end +endfunction + +function! s:status_load(lnum) + let line = getline(a:lnum) + let matches = matchlist(line, '^- \([^:]*\):.*(not loaded)$') + if !empty(matches) + let name = matches[1] + call plug#load(name) + call setline(a:lnum, substitute(line, ' (not loaded)$', '', '')) + endif endfunction function! s:is_preview_window_open() diff --git a/test/run b/test/run index 33f0dea..7ac439e 100755 --- a/test/run +++ b/test/run @@ -21,20 +21,24 @@ make_dirs() { for d in *; do cat > $d/xxx.vim << EOF " echom expand('') - let g:xxx = get(g:, 'xxx', []) - call add(g:xxx, '${1:4}/$d') + let g:$2 = get(g:, '$2', []) + call add(g:$2, '${1:4}/$d') EOF done cd - > /dev/null } -make_dirs xxx/ -make_dirs xxx/after +make_dirs xxx/ xxx +make_dirs xxx/after xxx mkdir xxx/doc cat > xxx/doc/xxx.txt << DOC hello *xxx* DOC +make_dirs yyy/ yyy +make_dirs z1/ z1 +make_dirs z2/ z2 + cat > /tmp/mini-vimrc << VIMRC set rtp+=vader.vim set shell=/bin/bash diff --git a/test/workflow.vader b/test/workflow.vader index 3350618..5c93a89 100644 --- a/test/workflow.vader +++ b/test/workflow.vader @@ -761,6 +761,8 @@ Execute (Filetype-based on-demand loading): setf xxx AssertEqual ['/ftdetect', 'after/ftdetect', '/plugin', 'after/plugin', '/ftplugin', 'after/ftplugin', '/indent', 'after/indent', '/syntax', 'after/syntax'], g:xxx +Before: + ********************************************************************** ~ plug#helptags() ********************************************************************** @@ -772,7 +774,7 @@ Execute (plug#helptags): Assert filereadable(expand('$PWD/xxx/doc/tags')) ********************************************************************** -~ plug#load() +~ Manual loading ********************************************************************** Execute (plug#load - invalid arguments): @@ -783,13 +785,19 @@ Execute (plug#load - invalid arguments): AssertEqual 0, plug#load('xxx', 'non-existent-plugin') AssertEqual 0, plug#load('non-existent-plugin', 'xxx') -Execute (plug#load): +Execute (on: []): call plug#begin() Plug 'junegunn/rust.vim', { 'on': [] } call plug#end() PlugInstall q +Execute (PlugStatus reports (not loaded)): + PlugStatus + AssertExpect 'not loaded', 1 + q + +Execute (plug#load to load it): setf xxx f test.rs Log &filetype @@ -797,7 +805,41 @@ Execute (plug#load): AssertEqual 1, plug#load('rust.vim') AssertEqual 'rust', &filetype -Before: +Execute (PlugStatus should not contain (not loaded)): + PlugStatus + AssertExpect 'not loaded', 0 + q + +Execute (Load plugin from PlugStatus screen with L key in normal mode): + call plug#begin() + Plug '$PWD/yyy', { 'on': [] } + call plug#end() + + PlugStatus + AssertExpect 'not loaded', 1 + Assert !exists('g:yyy'), 'yyy not loaded' + /not loaded + normal L + AssertExpect 'not loaded', 0 + Assert exists('g:yyy'), 'yyy loaded' + q + +Execute (Load plugin from PlugStatus screen with L key in visual mode): + call plug#begin() + Plug '$PWD/z1', { 'on': [] } + Plug '$PWD/z2', { 'for': [] } + call plug#end() + + PlugStatus + AssertExpect 'not loaded', 2 + Assert !exists('g:z1'), 'z1 not loaded' + Assert !exists('g:z2'), 'z2 not loaded' + normal ggVGL + AssertExpect 'not loaded', 0 + Assert exists('g:z1'), 'z1 loaded' + Assert exists('g:z2'), 'z2 loaded' + q + Execute (Cleanup): silent! call system('rm -rf '.temp_plugged) silent! call rename('fzf', 'fzf-staged')