From 3561412b28759d95b4d86c67f2d76855f860bfc0 Mon Sep 17 00:00:00 2001 From: Kristijan Husak Date: Mon, 16 Jul 2018 14:48:41 +0200 Subject: [PATCH 1/5] Add minpac#status() function for showing status of plugins. --- README.md | 11 ++++++ autoload/minpac/impl.vim | 83 ++++++++++++++++++++++++++++++++++++++++ doc/minpac.txt | 9 +++++ plugin/minpac.vim | 5 +++ 4 files changed, 108 insertions(+) diff --git a/README.md b/README.md index 29165d2..a86f4fb 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ endif " information of plugins, then performs the task. command! PackUpdate packadd minpac | source $MYVIMRC | call minpac#update() command! PackClean packadd minpac | source $MYVIMRC | call minpac#clean() +command! PackStatus packadd minpac | source $MYVIMRC | call minpac#status() ``` Note that your .vimrc must be reloadable to use this. E.g.: @@ -179,6 +180,9 @@ call minpac#update() " To uninstall unused plugins: call minpac#clean() + +" To see plugins s tatus: +call minpac#status() ``` @@ -307,6 +311,13 @@ echo minpac#getpackages("minpac", "", "", 1) echo minpac#getpackages("", "NAME", "", 1) ``` +#### minpac#status() + +Print status of plugins in vertical split. + +When ran after `minpac#update()`, shows only installed and updated plugins. + +Otherwise, shows the status of the plugin and commits of last update (if any). ### Hooks diff --git a/autoload/minpac/impl.vim b/autoload/minpac/impl.vim index f946d9b..cd63345 100644 --- a/autoload/minpac/impl.vim +++ b/autoload/minpac/impl.vim @@ -427,4 +427,87 @@ function! minpac#impl#clean(args) abort endif endfunction +function! s:syntax() + syntax clear + syn match minpacDash /^-/ + syn match minpacName /\(^- \)\@<=.*/ contains=minpacStatus + syn match minpacStatus /\(-.*\)\@<=-\s.*$/ contained + syn match minpacStar /^\s\*/ contained + syn match minpacCommit /^\s\*\s[0-9a-f]\{7,9} .*/ contains=minpacRelDate,minpacSha,minpacStar + syn match minpacSha /\(\s\*\s\)\@<=[0-9a-f]\{4,}/ contained + syn match minpacRelDate /([^)]*)$/ contained + + hi def link minpacDash Special + hi def link minpacStar Boolean + hi def link minpacName Function + hi def link minpacSha Identifier + hi def link minpacRelDate Comment + hi def link minpacStatus Constant +endfunction + +function! minpac#impl#status() + let l:result = [] + let l:update_ran = exists('s:installed_plugins') + for l:name in keys(g:minpac#pluglist) + let l:pluginfo = g:minpac#pluglist[l:name] + let l:dir = l:pluginfo.dir + let l:plugin = { 'name': l:name, 'lines': [], 'status': '' } + + if !isdirectory(l:dir) + let l:plugin.status = 'Not installed' + else + let l:commits = systemlist([g:minpac#opt.git, '-C', l:dir, 'log', + \ '--color=never', '--pretty=format:%h %s (%cr)', 'HEAD...HEAD@{1}' + \ ]) + + " Show installed status only when the plugin is installed for the first time + if has_key(l:pluginfo, 'installed') && l:pluginfo.installed ==? 0 + let l:plugin.status = 'Installed' + elseif !l:update_ran + let l:plugin.status = 'OK' + endif + + " Fetching log on non-updated plugin returns fatal error, so make sure + " to handle that case properly + if len(l:commits) > 0 && l:commits[0] !~? 'fatal' + let l:plugin.lines = l:commits + endif + + if get(l:pluginfo, 'revision') !=? '' && l:pluginfo.revision !=# s:get_plugin_revision(l:name) + let l:plugin.status = 'Updated' + endif + endif + + call add(l:result, l:plugin) + endfor + + " Show items with most lines (commits) first. + call sort(l:result, { first, second -> len(second.lines) - len(first.lines) }) + + let l:content = [] + + if l:update_ran + call add(l:content, s:updated_plugins. ' updated. '.s:installed_plugins. ' installed.') + endif + + for l:item in l:result + if l:item.status ==? '' + continue + endif + + call add(l:content, '- '.l:item.name.' - '.l:item.status) + for l:line in l:item.lines + call add(l:content, ' * '.l:line) + endfor + endfor + + let l:content = join(l:content, "\") + silent exe 'vertical topleft new' + setf minpac + silent exe 'put! =l:content' + call s:syntax() + setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline nomodifiable nospell + silent exe 'norm!gg' +endfunction + " vim: set ts=8 sw=2 et: diff --git a/doc/minpac.txt b/doc/minpac.txt index c020da3..7ad7fac 100644 --- a/doc/minpac.txt +++ b/doc/minpac.txt @@ -191,6 +191,9 @@ functions. E.g.: > " To uninstall unused plugins: call minpac#clean() + + " To see plugins status: + call minpac#status() < ------------------------------------------------------------------------------ @@ -343,6 +346,12 @@ minpac#getpackages([{packname}[, {packtype}[, {plugname}[, {nameonly}]]]]) " List package names. echo minpac#getpackages("", "NAME", "", 1) < +minpac#status() *minpac#status()* + Print status of plugins in vertical split. + When ran after `minpac#update()`, shows only installed and updated + plugins. Otherwise, shows the status of the plugin and commits of last + update (if any) + ------------------------------------------------------------------------------ HOOKS *minpac-hooks* diff --git a/plugin/minpac.vim b/plugin/minpac.vim index 2fa2fcf..d119883 100644 --- a/plugin/minpac.vim +++ b/plugin/minpac.vim @@ -109,6 +109,11 @@ function! minpac#clean(...) return minpac#impl#clean(a:000) endfunction +function! minpac#status() + call s:ensure_initialization() + return minpac#impl#status() +endfunction + " Get information of specified plugin. Mainly for debugging. function! minpac#getpluginfo(name) From 0a0d149666a63f92c5e4ecefed974edd1f2b8107 Mon Sep 17 00:00:00 2001 From: Kristijan Husak Date: Wed, 18 Jul 2018 18:43:07 +0200 Subject: [PATCH 2/5] Use s:system function instead of systemlist. --- autoload/minpac/impl.vim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/autoload/minpac/impl.vim b/autoload/minpac/impl.vim index cd63345..01c0b3f 100644 --- a/autoload/minpac/impl.vim +++ b/autoload/minpac/impl.vim @@ -456,10 +456,12 @@ function! minpac#impl#status() if !isdirectory(l:dir) let l:plugin.status = 'Not installed' else - let l:commits = systemlist([g:minpac#opt.git, '-C', l:dir, 'log', + let l:commits = s:system([g:minpac#opt.git, '-C', l:dir, 'log', \ '--color=never', '--pretty=format:%h %s (%cr)', 'HEAD...HEAD@{1}' \ ]) + let l:commits = filter(l:commits[1], {-> v:val !=? '' }) + " Show installed status only when the plugin is installed for the first time if has_key(l:pluginfo, 'installed') && l:pluginfo.installed ==? 0 let l:plugin.status = 'Installed' From cb4f8ffe36d25191c2b7bdb099f0b7ab1c640125 Mon Sep 17 00:00:00 2001 From: Kristijan Husak Date: Fri, 20 Jul 2018 12:31:04 +0200 Subject: [PATCH 3/5] Cleanup commits list code and recommend running status after update. --- README.md | 4 ++-- autoload/minpac/impl.vim | 19 +++++-------------- doc/minpac.txt | 2 +- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index a86f4fb..2a1fe75 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ endif " Define user commands for updating/cleaning the plugins. " Each of them loads minpac, reloads .vimrc to register the " information of plugins, then performs the task. -command! PackUpdate packadd minpac | source $MYVIMRC | call minpac#update() +command! PackUpdate packadd minpac | source $MYVIMRC | call minpac#update() | call minpac#status() command! PackClean packadd minpac | source $MYVIMRC | call minpac#clean() command! PackStatus packadd minpac | source $MYVIMRC | call minpac#status() ``` @@ -181,7 +181,7 @@ call minpac#update() " To uninstall unused plugins: call minpac#clean() -" To see plugins s tatus: +" To see plugins status: call minpac#status() ``` diff --git a/autoload/minpac/impl.vim b/autoload/minpac/impl.vim index 01c0b3f..8699aed 100644 --- a/autoload/minpac/impl.vim +++ b/autoload/minpac/impl.vim @@ -460,23 +460,14 @@ function! minpac#impl#status() \ '--color=never', '--pretty=format:%h %s (%cr)', 'HEAD...HEAD@{1}' \ ]) - let l:commits = filter(l:commits[1], {-> v:val !=? '' }) + let l:plugin.lines = filter(l:commits[1], {-> v:val !=? '' }) - " Show installed status only when the plugin is installed for the first time - if has_key(l:pluginfo, 'installed') && l:pluginfo.installed ==? 0 - let l:plugin.status = 'Installed' - elseif !l:update_ran + if !l:update_ran let l:plugin.status = 'OK' - endif - - " Fetching log on non-updated plugin returns fatal error, so make sure - " to handle that case properly - if len(l:commits) > 0 && l:commits[0] !~? 'fatal' - let l:plugin.lines = l:commits - endif - - if get(l:pluginfo, 'revision') !=? '' && l:pluginfo.revision !=# s:get_plugin_revision(l:name) + elseif len(l:plugin.lines) > 0 let l:plugin.status = 'Updated' + elseif has_key(l:pluginfo, 'installed') && l:pluginfo.installed ==? 0 + let l:plugin.status = 'Installed' endif endif diff --git a/doc/minpac.txt b/doc/minpac.txt index 7ad7fac..80f4602 100644 --- a/doc/minpac.txt +++ b/doc/minpac.txt @@ -166,7 +166,7 @@ Load minpac on demand " Define user commands for updating/cleaning the plugins. " Each of them loads minpac, reloads .vimrc to register the " information of plugins, then performs the task. - command! PackUpdate packadd minpac | source $MYVIMRC | call minpac#update() + command! PackUpdate packadd minpac | source $MYVIMRC | call minpac#update() | call minpac#status() command! PackClean packadd minpac | source $MYVIMRC | call minpac#clean() < Note that your .vimrc must be reloadable to use this. E.g.: From 4f03fcf0bbb8d58f70ce718d252dee5a3ef72466 Mon Sep 17 00:00:00 2001 From: Kristijan Husak Date: Mon, 23 Jul 2018 11:03:11 +0200 Subject: [PATCH 4/5] Remove signature, add commit preview, move status list code to separate file. --- autoload/minpac/impl.vim | 89 +++--------------------- autoload/minpac/status.vim | 134 +++++++++++++++++++++++++++++++++++++ doc/minpac.txt | 18 +++++ plugin/minpac.vim | 2 +- 4 files changed, 164 insertions(+), 79 deletions(-) create mode 100644 autoload/minpac/status.vim diff --git a/autoload/minpac/impl.vim b/autoload/minpac/impl.vim index 8699aed..25bdd86 100644 --- a/autoload/minpac/impl.vim +++ b/autoload/minpac/impl.vim @@ -67,7 +67,7 @@ endfunction " Replacement for system(). " This doesn't open an extra window on MS-Windows. -function! s:system(cmds) abort +function! minpac#impl#system(cmds) abort let l:opt = { \ 'on_stdout': function('s:system_out_cb'), \ 'out': [] @@ -82,10 +82,10 @@ function! s:system(cmds) abort endfunction " Get the revision of the specified plugin. -function! s:get_plugin_revision(name) abort +function! minpac#impl#get_plugin_revision(name) abort let l:pluginfo = g:minpac#pluglist[a:name] let l:dir = l:pluginfo.dir - let l:res = s:system([g:minpac#opt.git, '-C', l:dir, 'rev-parse', 'HEAD']) + let l:res = minpac#impl#system([g:minpac#opt.git, '-C', l:dir, 'rev-parse', 'HEAD']) if l:res[0] == 0 && len(l:res[1]) > 0 return l:res[1][0] else @@ -177,7 +177,7 @@ function! s:job_exit_cb(id, errcode, event) dict abort " Check if it is actually updated (or installed). let l:updated = 1 if l:pluginfo.revision != '' - if l:pluginfo.revision ==# s:get_plugin_revision(self.name) + if l:pluginfo.revision ==# minpac#impl#get_plugin_revision(self.name) let l:updated = 0 endif endif @@ -301,7 +301,7 @@ function! s:update_single_plugin(name, force) abort endif call s:echo_verbose(3, 'Updating ' . a:name) - let l:pluginfo.revision = s:get_plugin_revision(a:name) + let l:pluginfo.revision = minpac#impl#get_plugin_revision(a:name) let l:cmd = [g:minpac#opt.git, '-C', l:dir, 'pull', '--quiet', '--ff-only'] endif return s:start_job(l:cmd, a:name, 0) @@ -427,80 +427,13 @@ function! minpac#impl#clean(args) abort endif endfunction -function! s:syntax() - syntax clear - syn match minpacDash /^-/ - syn match minpacName /\(^- \)\@<=.*/ contains=minpacStatus - syn match minpacStatus /\(-.*\)\@<=-\s.*$/ contained - syn match minpacStar /^\s\*/ contained - syn match minpacCommit /^\s\*\s[0-9a-f]\{7,9} .*/ contains=minpacRelDate,minpacSha,minpacStar - syn match minpacSha /\(\s\*\s\)\@<=[0-9a-f]\{4,}/ contained - syn match minpacRelDate /([^)]*)$/ contained - - hi def link minpacDash Special - hi def link minpacStar Boolean - hi def link minpacName Function - hi def link minpacSha Identifier - hi def link minpacRelDate Comment - hi def link minpacStatus Constant -endfunction - -function! minpac#impl#status() - let l:result = [] +function! minpac#impl#update_information() abort let l:update_ran = exists('s:installed_plugins') - for l:name in keys(g:minpac#pluglist) - let l:pluginfo = g:minpac#pluglist[l:name] - let l:dir = l:pluginfo.dir - let l:plugin = { 'name': l:name, 'lines': [], 'status': '' } - - if !isdirectory(l:dir) - let l:plugin.status = 'Not installed' - else - let l:commits = s:system([g:minpac#opt.git, '-C', l:dir, 'log', - \ '--color=never', '--pretty=format:%h %s (%cr)', 'HEAD...HEAD@{1}' - \ ]) - - let l:plugin.lines = filter(l:commits[1], {-> v:val !=? '' }) - - if !l:update_ran - let l:plugin.status = 'OK' - elseif len(l:plugin.lines) > 0 - let l:plugin.status = 'Updated' - elseif has_key(l:pluginfo, 'installed') && l:pluginfo.installed ==? 0 - let l:plugin.status = 'Installed' - endif - endif - - call add(l:result, l:plugin) - endfor - - " Show items with most lines (commits) first. - call sort(l:result, { first, second -> len(second.lines) - len(first.lines) }) - - let l:content = [] - - if l:update_ran - call add(l:content, s:updated_plugins. ' updated. '.s:installed_plugins. ' installed.') - endif - - for l:item in l:result - if l:item.status ==? '' - continue - endif - - call add(l:content, '- '.l:item.name.' - '.l:item.status) - for l:line in l:item.lines - call add(l:content, ' * '.l:line) - endfor - endfor - - let l:content = join(l:content, "\") - silent exe 'vertical topleft new' - setf minpac - silent exe 'put! =l:content' - call s:syntax() - setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline nomodifiable nospell - silent exe 'norm!gg' + return { + \ 'update_ran': l:update_ran, + \ 'installed': l:update_ran ? s:installed_plugins : 0, + \ 'updated': l:update_ran ? s:updated_plugins : 0, + \ } endfunction " vim: set ts=8 sw=2 et: diff --git a/autoload/minpac/status.vim b/autoload/minpac/status.vim new file mode 100644 index 0000000..6992226 --- /dev/null +++ b/autoload/minpac/status.vim @@ -0,0 +1,134 @@ +let s:results = [] + +function! minpac#status#get() abort + let l:update_info = minpac#impl#update_information() + let l:result = [] + for l:name in keys(g:minpac#pluglist) + let l:pluginfo = g:minpac#pluglist[l:name] + let l:dir = l:pluginfo.dir + let l:plugin = { 'name': l:name, 'lines': [], 'status': '' } + + if !isdirectory(l:dir) + let l:plugin.status = 'Not installed' + else + let l:commits = minpac#impl#system([g:minpac#opt.git, '-C', l:dir, 'log', + \ '--color=never', '--pretty=format:%h %s (%cr)', '--no-show-signature', 'HEAD...HEAD@{1}' + \ ]) + + let l:plugin.lines = filter(l:commits[1], {-> v:val !=? '' }) + + if !l:update_info.update_ran + let l:plugin.status = 'OK' + elseif get(l:pluginfo, 'revision') !=? '' && l:pluginfo.revision !=# minpac#impl#get_plugin_revision(l:name) + let l:plugin.status = 'Updated' + elseif has_key(l:pluginfo, 'installed') && l:pluginfo.installed ==? 0 + let l:plugin.status = 'Installed' + endif + endif + + call add(l:result, l:plugin) + endfor + + " Show items with most lines (commits) first. + call sort(l:result, { first, second -> len(second.lines) - len(first.lines) }) + let s:results = l:result + + let l:content = [] + + if l:update_info.update_ran + call add(l:content, l:update_info.updated. ' updated. '.l:update_info.installed. ' installed.') + endif + + for l:item in l:result + if l:item.status ==? '' + continue + endif + + call add(l:content, '- '.l:item.name.' - '.l:item.status) + for l:line in l:item.lines + call add(l:content, ' * '.l:line) + endfor + endfor + + let l:content = join(l:content, "\") + silent exe 'vertical topleft new' + setf minpac + silent exe 'put! =l:content|norm!gg' + call s:syntax() + call s:mappings() + setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline nomodifiable nospell +endfunction + + +function! s:syntax() abort + syntax clear + syn match minpacDash /^-/ + syn match minpacName /\(^- \)\@<=.*/ contains=minpacStatus + syn match minpacStatus /\(-.*\)\@<=-\s.*$/ contained + syn match minpacStar /^\s\*/ contained + syn match minpacCommit /^\s\*\s[0-9a-f]\{7,9} .*/ contains=minpacRelDate,minpacSha,minpacStar + syn match minpacSha /\(\s\*\s\)\@<=[0-9a-f]\{4,}/ contained + syn match minpacRelDate /([^)]*)$/ contained + + hi def link minpacDash Special + hi def link minpacStar Boolean + hi def link minpacName Function + hi def link minpacSha Identifier + hi def link minpacRelDate Comment + hi def link minpacStatus Constant +endfunction + +function! s:mappings() abort + nnoremap :call openSha() + nnoremap q :q + nnoremap :call nextPackage() + nnoremap :call prevPackage() +endfunction + +function! s:nextPackage() + return search('^-\s.*$') +endfunction + +function! s:prevPackage() + return search('^-\s.*$', 'b') +endfunction + +function s:openSha() abort + let l:sha = matchstr(getline('.'), '^\s\*\s\zs[0-9a-f]\{7,9}') + if empty(l:sha) + return + endif + + let l:name = s:find_name_by_sha(l:sha) + + if empty(l:name) + return + endif + + let l:pluginfo = g:minpac#pluglist[l:name] + exe 'pedit' l:sha + wincmd p + setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable + let l:sha_content = minpac#impl#system([g:minpac#opt.git, '-C', l:pluginfo.dir, 'show', + \ '--no-color', '--pretty=medium', l:sha + \ ]) + let l:sha_content = join(l:sha_content[1], "\") + + silent exe 'put! =l:sha_content|norm!gg' + setlocal nomodifiable + nnoremap q :q +endfunction + +function! s:find_name_by_sha(sha) abort + for l:result in s:results + for l:commit in l:result.lines + if l:commit =~? '^'.a:sha + return l:result.name + endif + endfor + endfor + + return '' +endfunction + +" vim: set ts=8 sw=2 et: diff --git a/doc/minpac.txt b/doc/minpac.txt index 80f4602..2d81c74 100644 --- a/doc/minpac.txt +++ b/doc/minpac.txt @@ -17,6 +17,7 @@ USAGE |minpac-usage| COMMANDS |minpac-commands| FUNCTIONS |minpac-functions| HOOKS |minpac-hooks| + MAPPINGS |minpac-mappings| ============================================================================== @@ -427,5 +428,22 @@ E.g.: > " Quit Vim immediately after all updates are finished. call minpac#update('', {'do': 'quit'}) < +------------------------------------------------------------------------------ +MAPPINGS *minpac-mappings* + +List of mappings available only in status window. + + *minpac-* + Preview the commit under the cursor. + + *minpac-CTRL-j* + Jump to next package in list. + + *minpac-CTRL-k* + Jump to previous package in list. + + *minpac-q* +q Exit the status window. + (Also works for commit preview window) ============================================================================== vim:tw=78:ts=8:ft=help:norl: diff --git a/plugin/minpac.vim b/plugin/minpac.vim index d119883..cad09af 100644 --- a/plugin/minpac.vim +++ b/plugin/minpac.vim @@ -111,7 +111,7 @@ endfunction function! minpac#status() call s:ensure_initialization() - return minpac#impl#status() + return minpac#status#get() endfunction From c45748b9c6449e9331dc889449592e6dd2c5ae65 Mon Sep 17 00:00:00 2001 From: Kristijan Husak Date: Mon, 23 Jul 2018 12:53:19 +0200 Subject: [PATCH 5/5] Use custom counters for status list to get more reliable information. --- autoload/minpac/impl.vim | 9 ++------- autoload/minpac/status.vim | 12 ++++++++---- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/autoload/minpac/impl.vim b/autoload/minpac/impl.vim index 25bdd86..d81f191 100644 --- a/autoload/minpac/impl.vim +++ b/autoload/minpac/impl.vim @@ -427,13 +427,8 @@ function! minpac#impl#clean(args) abort endif endfunction -function! minpac#impl#update_information() abort - let l:update_ran = exists('s:installed_plugins') - return { - \ 'update_ran': l:update_ran, - \ 'installed': l:update_ran ? s:installed_plugins : 0, - \ 'updated': l:update_ran ? s:updated_plugins : 0, - \ } +function! minpac#impl#is_update_ran() abort + return exists('s:installed_plugins') endfunction " vim: set ts=8 sw=2 et: diff --git a/autoload/minpac/status.vim b/autoload/minpac/status.vim index 6992226..1132abb 100644 --- a/autoload/minpac/status.vim +++ b/autoload/minpac/status.vim @@ -1,7 +1,9 @@ let s:results = [] function! minpac#status#get() abort - let l:update_info = minpac#impl#update_information() + let l:is_update_ran = minpac#impl#is_update_ran() + let l:update_count = 0 + let l:install_count = 0 let l:result = [] for l:name in keys(g:minpac#pluglist) let l:pluginfo = g:minpac#pluglist[l:name] @@ -17,11 +19,13 @@ function! minpac#status#get() abort let l:plugin.lines = filter(l:commits[1], {-> v:val !=? '' }) - if !l:update_info.update_ran + if !l:is_update_ran let l:plugin.status = 'OK' elseif get(l:pluginfo, 'revision') !=? '' && l:pluginfo.revision !=# minpac#impl#get_plugin_revision(l:name) + let l:update_count += 1 let l:plugin.status = 'Updated' elseif has_key(l:pluginfo, 'installed') && l:pluginfo.installed ==? 0 + let l:install_count += 1 let l:plugin.status = 'Installed' endif endif @@ -35,8 +39,8 @@ function! minpac#status#get() abort let l:content = [] - if l:update_info.update_ran - call add(l:content, l:update_info.updated. ' updated. '.l:update_info.installed. ' installed.') + if l:is_update_ran + call add(l:content, l:update_count.' updated. '.l:install_count.' installed.') endif for l:item in l:result