From fba69e62f11ea82cccd465897a69717e3233f461 Mon Sep 17 00:00:00 2001 From: Randy West Date: Thu, 3 Oct 2019 20:15:00 -0400 Subject: [PATCH 01/30] Use branch when checking for new commits --- plugin/vim-outdated-plugins.vim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugin/vim-outdated-plugins.vim b/plugin/vim-outdated-plugins.vim index e7f34bd..3ec051f 100644 --- a/plugin/vim-outdated-plugins.vim +++ b/plugin/vim-outdated-plugins.vim @@ -13,7 +13,8 @@ function! s:CalculateUpdates(job_id, data, event) dict let l:command = "" for key in keys(g:plugs) - let l:command .= '(git -C ' . g:plugs[key].dir . ' rev-list HEAD..origin --count)' + let l:command .= '(git -C ' . g:plugs[key].dir . ' rev-list HEAD..' . + \ g:plugs[key].branch . ' --count)' let l:numberOfcheckedPlugins += 1 if l:numberOfcheckedPlugins != len(keys(g:plugs)) From 5037c9754d22f7c52daef2fd0078c657a15c0aed Mon Sep 17 00:00:00 2001 From: Randy West Date: Wed, 9 Oct 2019 22:17:28 -0400 Subject: [PATCH 02/30] - Added origin/[branch] to rev-list call - Check v:vim_did_enter and call for debugging convenience --- plugin/vim-outdated-plugins.vim | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plugin/vim-outdated-plugins.vim b/plugin/vim-outdated-plugins.vim index 3ec051f..7666bef 100644 --- a/plugin/vim-outdated-plugins.vim +++ b/plugin/vim-outdated-plugins.vim @@ -13,7 +13,7 @@ function! s:CalculateUpdates(job_id, data, event) dict let l:command = "" for key in keys(g:plugs) - let l:command .= '(git -C ' . g:plugs[key].dir . ' rev-list HEAD..' . + let l:command .= '(git -C ' . g:plugs[key].dir . ' rev-list HEAD..origin/' . \ g:plugs[key].branch . ' --count)' let l:numberOfcheckedPlugins += 1 @@ -47,7 +47,7 @@ let s:calculateCallbacks = { function! CheckForUpdates() let g:pluginsToUpdate = 0 - let l:command = "" + let l:command = "" " TODO check only activated plugins and not all downloaded let l:numberOfcheckedPlugins = 0 @@ -63,5 +63,9 @@ function! CheckForUpdates() call async#job#start([ 'bash', '-c', l:command], s:remoteUpdateCallbacks) endfunction -au VimEnter * call CheckForUpdates() +if v:vim_did_enter + call CheckForUpdates() +else + au VimEnter * call CheckForUpdates() +endif From 35198304e0b91a2af344f236661f4ede749956e8 Mon Sep 17 00:00:00 2001 From: Randy West Date: Thu, 10 Oct 2019 17:25:31 -0400 Subject: [PATCH 03/30] Added wait to the end of remote update chain --- plugin/vim-outdated-plugins.vim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin/vim-outdated-plugins.vim b/plugin/vim-outdated-plugins.vim index 7666bef..6cf4516 100644 --- a/plugin/vim-outdated-plugins.vim +++ b/plugin/vim-outdated-plugins.vim @@ -52,11 +52,11 @@ function! CheckForUpdates() " TODO check only activated plugins and not all downloaded let l:numberOfcheckedPlugins = 0 for key in keys(g:plugs) - let l:command .= 'git -C ' . g:plugs[key].dir . ' remote update > /dev/null' + let l:command .= 'git -C ' . g:plugs[key].dir . ' remote update > /dev/null & ' let l:numberOfcheckedPlugins += 1 - if l:numberOfcheckedPlugins != len(keys(g:plugs)) - let l:command .= ' &' + if l:numberOfcheckedPlugins == len(keys(g:plugs)) + let l:command .= 'wait' endif endfor From af6c0440129e6a7271738796b7c3f00071d9afb3 Mon Sep 17 00:00:00 2001 From: Randy West Date: Thu, 10 Oct 2019 17:46:56 -0400 Subject: [PATCH 04/30] No need to say len(keys(...)) (this matches other branches better) --- plugin/vim-outdated-plugins.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/vim-outdated-plugins.vim b/plugin/vim-outdated-plugins.vim index 6cf4516..8b4c333 100644 --- a/plugin/vim-outdated-plugins.vim +++ b/plugin/vim-outdated-plugins.vim @@ -55,7 +55,7 @@ function! CheckForUpdates() let l:command .= 'git -C ' . g:plugs[key].dir . ' remote update > /dev/null & ' let l:numberOfcheckedPlugins += 1 - if l:numberOfcheckedPlugins == len(keys(g:plugs)) + if l:numberOfcheckedPlugins == len(g:plugs) let l:command .= 'wait' endif endfor From 72c9dcf54167936b324617fc46cee3bc49721d95 Mon Sep 17 00:00:00 2001 From: Randy West Date: Fri, 11 Oct 2019 00:32:44 -0400 Subject: [PATCH 05/30] Rewrite in python There was a lot of strange behavior in vimscript version of this plugin. The on_stdout callback appeared to be called a variable number of times before the on_exit callback, most likely indicating a race. I tried refactoring to call the rev-list command sequentially for each plugin in an async cascade, but for unknown reasons, stdout was blank for about half of the calls in my setup. In python, we can use a comparatively simple synchronous function wrapped in vim.async_call, so that's what I've done. The plugin now appears to finally work consistently and as expected. Since async/job.vim is no longer needed, I've removed that as well. --- autoload/async/job.vim | 295 -------------------------------- plugin/vim-outdated-plugins.vim | 77 ++------- python/outdatedplugins.py | 38 ++++ 3 files changed, 49 insertions(+), 361 deletions(-) delete mode 100644 autoload/async/job.vim create mode 100644 python/outdatedplugins.py diff --git a/autoload/async/job.vim b/autoload/async/job.vim deleted file mode 100644 index 7b90225..0000000 --- a/autoload/async/job.vim +++ /dev/null @@ -1,295 +0,0 @@ -" Author: Prabir Shrestha -" Website: https://github.com/prabirshrestha/async.vim -" License: The MIT License {{{ -" The MIT License (MIT) -" -" Copyright (c) 2016 Prabir Shrestha -" -" 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. -" }}} - -let s:save_cpo = &cpo -set cpo&vim - -let s:jobidseq = 0 -let s:jobs = {} " { job, opts, type: 'vimjob|nvimjob'} -let s:job_type_nvimjob = 'nvimjob' -let s:job_type_vimjob = 'vimjob' -let s:job_error_unsupported_job_type = -2 " unsupported job type - -function! s:job_supported_types() abort - let l:supported_types = [] - if has('nvim') - let l:supported_types += [s:job_type_nvimjob] - endif - if !has('nvim') && has('job') && has('channel') && has('lambda') - let l:supported_types += [s:job_type_vimjob] - endif - return l:supported_types -endfunction - -function! s:job_supports_type(type) abort - return index(s:job_supported_types(), a:type) >= 0 -endfunction - -function! s:out_cb(jobid, opts, job, data) abort - if has_key(a:opts, 'on_stdout') - call a:opts.on_stdout(a:jobid, split(a:data, "\n", 1), 'stdout') - endif -endfunction - -function! s:err_cb(jobid, opts, job, data) abort - if has_key(a:opts, 'on_stderr') - call a:opts.on_stderr(a:jobid, split(a:data, "\n", 1), 'stderr') - endif -endfunction - -function! s:exit_cb(jobid, opts, job, status) abort - if has_key(a:opts, 'on_exit') - call a:opts.on_exit(a:jobid, a:status, 'exit') - endif - if has_key(s:jobs, a:jobid) - call remove(s:jobs, a:jobid) - endif -endfunction - -function! s:on_stdout(jobid, data, event) abort - if has_key(s:jobs, a:jobid) - let l:jobinfo = s:jobs[a:jobid] - if has_key(l:jobinfo.opts, 'on_stdout') - call l:jobinfo.opts.on_stdout(a:jobid, a:data, a:event) - endif - endif -endfunction - -function! s:on_stderr(jobid, data, event) abort - if has_key(s:jobs, a:jobid) - let l:jobinfo = s:jobs[a:jobid] - if has_key(l:jobinfo.opts, 'on_stderr') - call l:jobinfo.opts.on_stderr(a:jobid, a:data, a:event) - endif - endif -endfunction - -function! s:on_exit(jobid, status, event) abort - if has_key(s:jobs, a:jobid) - let l:jobinfo = s:jobs[a:jobid] - if has_key(l:jobinfo.opts, 'on_exit') - call l:jobinfo.opts.on_exit(a:jobid, a:status, a:event) - endif - endif -endfunction - -function! s:job_start(cmd, opts) abort - let l:jobtypes = s:job_supported_types() - let l:jobtype = '' - - if has_key(a:opts, 'type') - if type(a:opts.type) == type('') - if !s:job_supports_type(a:opts.type) - return s:job_error_unsupported_job_type - endif - let l:jobtype = a:opts.type - else - let l:jobtypes = a:opts.type - endif - endif - - if empty(l:jobtype) - " find the best jobtype - for l:jobtype2 in l:jobtypes - if s:job_supports_type(l:jobtype2) - let l:jobtype = l:jobtype2 - endif - endfor - endif - - if l:jobtype ==? '' - return s:job_error_unsupported_job_type - endif - - if l:jobtype == s:job_type_nvimjob - let l:job = jobstart(a:cmd, { - \ 'on_stdout': function('s:on_stdout'), - \ 'on_stderr': function('s:on_stderr'), - \ 'on_exit': function('s:on_exit'), - \}) - if l:job <= 0 - return l:job - endif - let l:jobid = l:job " nvimjobid and internal jobid is same - let s:jobs[l:jobid] = { - \ 'type': s:job_type_nvimjob, - \ 'opts': a:opts, - \ } - let s:jobs[l:jobid].job = l:job - elseif l:jobtype == s:job_type_vimjob - let s:jobidseq = s:jobidseq + 1 - let l:jobid = s:jobidseq - let l:jobopt = { - \ 'out_cb': function('s:out_cb', [l:jobid, a:opts]), - \ 'err_cb': function('s:err_cb', [l:jobid, a:opts]), - \ 'exit_cb': function('s:exit_cb', [l:jobid, a:opts]), - \ 'mode': 'raw', - \ } - if has('patch-8.1.889') - let l:jobopt['noblock'] = 1 - endif - let l:job = job_start(a:cmd, l:jobopt) - if job_status(l:job) !=? 'run' - return -1 - endif - let s:jobs[l:jobid] = { - \ 'type': s:job_type_vimjob, - \ 'opts': a:opts, - \ 'job': l:job, - \ 'channel': job_getchannel(l:job), - \ 'buffer': '' - \ } - else - return s:job_error_unsupported_job_type - endif - - return l:jobid -endfunction - -function! s:job_stop(jobid) abort - if has_key(s:jobs, a:jobid) - let l:jobinfo = s:jobs[a:jobid] - if l:jobinfo.type == s:job_type_nvimjob - call jobstop(a:jobid) - elseif l:jobinfo.type == s:job_type_vimjob - call job_stop(s:jobs[a:jobid].job) - endif - if has_key(s:jobs, a:jobid) - call remove(s:jobs, a:jobid) - endif - endif -endfunction - -function! s:job_send(jobid, data) abort - let l:jobinfo = s:jobs[a:jobid] - if l:jobinfo.type == s:job_type_nvimjob - call jobsend(a:jobid, a:data) - elseif l:jobinfo.type == s:job_type_vimjob - if has('patch-8.1.0818') - call ch_sendraw(l:jobinfo.channel, a:data) - else - let l:jobinfo.buffer .= a:data - call s:flush_vim_sendraw(a:jobid, v:null) - endif - endif -endfunction - -function! s:flush_vim_sendraw(jobid, timer) abort - " https://github.com/vim/vim/issues/2548 - " https://github.com/natebosch/vim-lsc/issues/67#issuecomment-357469091 - let l:jobinfo = s:jobs[a:jobid] - sleep 1m - if len(l:jobinfo.buffer) <= 4096 - call ch_sendraw(l:jobinfo.channel, l:jobinfo.buffer) - let l:jobinfo.buffer = '' - else - let l:to_send = l:jobinfo.buffer[:4095] - let l:jobinfo.buffer = l:jobinfo.buffer[4096:] - call ch_sendraw(l:jobinfo.channel, l:to_send) - call timer_start(1, function('s:flush_vim_sendraw', [a:jobid])) - endif -endfunction - -function! s:job_wait_single(jobid, timeout, start) abort - if !has_key(s:jobs, a:jobid) - return -3 - endif - - let l:jobinfo = s:jobs[a:jobid] - if l:jobinfo.type == s:job_type_nvimjob - let l:timeout = a:timeout - reltimefloat(reltime(a:start)) * 1000 - return jobwait([a:jobid], float2nr(l:timeout))[0] - elseif l:jobinfo.type == s:job_type_vimjob - let l:timeout = a:timeout / 1000.0 - try - while l:timeout < 0 || reltimefloat(reltime(a:start)) < l:timeout - let l:info = job_info(l:jobinfo.job) - if l:info.status ==# 'dead' - return l:info.exitval - elseif l:info.status ==# 'fail' - return -3 - endif - sleep 1m - endwhile - catch /^Vim:Interrupt$/ - return -2 - endtry - endif - return -1 -endfunction - -function! s:job_wait(jobids, timeout) abort - let l:start = reltime() - let l:exitcode = 0 - let l:ret = [] - for l:jobid in a:jobids - if l:exitcode != -2 " Not interrupted. - let l:exitcode = s:job_wait_single(l:jobid, a:timeout, l:start) - endif - let l:ret += [l:exitcode] - endfor - return l:ret -endfunction - -function! s:job_pid(jobid) abort - if !has_key(s:jobs, a:jobid) - return 0 - endif - - let l:jobinfo = s:jobs[a:jobid] - if l:jobinfo.type == s:job_type_nvimjob - return jobpid(a:jobid) - elseif l:jobinfo.type == s:job_type_vimjob - let l:vimjobinfo = job_info(a:jobid) - if type(l:vimjobinfo) == type({}) && has_key(l:vimjobinfo, 'process') - return l:vimjobinfo['process'] - endif - endif - return 0 -endfunction - -" public apis {{{ -function! async#job#start(cmd, opts) abort - return s:job_start(a:cmd, a:opts) -endfunction - -function! async#job#stop(jobid) abort - call s:job_stop(a:jobid) -endfunction - -function! async#job#send(jobid, data) abort - call s:job_send(a:jobid, a:data) -endfunction - -function! async#job#wait(jobids, ...) abort - let l:timeout = get(a:000, 0, -1) - return s:job_wait(a:jobids, l:timeout) -endfunction - -function! async#job#pid(jobid) abort - return s:job_pid(a:jobid) -endfunction -" }}} diff --git a/plugin/vim-outdated-plugins.vim b/plugin/vim-outdated-plugins.vim index 8b4c333..b6626f7 100644 --- a/plugin/vim-outdated-plugins.vim +++ b/plugin/vim-outdated-plugins.vim @@ -2,70 +2,15 @@ if !exists('g:outdated_plugins_silent_mode') let g:outdated_plugins_silent_mode = 0 endif -function! s:JobHandler(job_id, data, event) dict - if (str2nr(join(a:data)) != 0) - let g:pluginsToUpdate += 1 - endif -endfunction - -function! s:CalculateUpdates(job_id, data, event) dict - let l:numberOfcheckedPlugins = 0 - let l:command = "" - - for key in keys(g:plugs) - let l:command .= '(git -C ' . g:plugs[key].dir . ' rev-list HEAD..origin/' . - \ g:plugs[key].branch . ' --count)' - let l:numberOfcheckedPlugins += 1 - - if l:numberOfcheckedPlugins != len(keys(g:plugs)) - let l:command .= ' &&' - endif - endfor - - call async#job#start([ 'bash', '-c', l:command], s:calculateCallbacks) -endfunction - -function! s:DisplayResults(job_id, data, event) dict - if g:pluginsToUpdate > 0 - echom 'Plugins to update: ' . g:pluginsToUpdate - else - if !g:outdated_plugins_silent_mode - echom 'All plugins up-to-date' - endif - endif -endfunction - - -let s:remoteUpdateCallbacks = { - \ 'on_exit': function('s:CalculateUpdates') - \ } - -let s:calculateCallbacks = { - \ 'on_stdout': function('s:JobHandler'), - \ 'on_exit': function('s:DisplayResults') - \ } - -function! CheckForUpdates() - let g:pluginsToUpdate = 0 - let l:command = "" - - " TODO check only activated plugins and not all downloaded - let l:numberOfcheckedPlugins = 0 - for key in keys(g:plugs) - let l:command .= 'git -C ' . g:plugs[key].dir . ' remote update > /dev/null & ' - let l:numberOfcheckedPlugins += 1 - - if l:numberOfcheckedPlugins == len(g:plugs) - let l:command .= 'wait' - endif - endfor - - call async#job#start([ 'bash', '-c', l:command], s:remoteUpdateCallbacks) -endfunction - -if v:vim_did_enter - call CheckForUpdates() -else - au VimEnter * call CheckForUpdates() -endif +let s:plugin_root_dir = fnamemodify(resolve(expand(':p')), ':h') + +python3 << EOF +import sys +from os.path import normpath, join +import vim +plugin_root_dir = vim.eval('s:plugin_root_dir') +python_root_dir = normpath(join(plugin_root_dir, '..', 'python')) +sys.path.insert(0, python_root_dir) +import outdatedplugins +EOF diff --git a/python/outdatedplugins.py b/python/outdatedplugins.py new file mode 100644 index 0000000..89328e9 --- /dev/null +++ b/python/outdatedplugins.py @@ -0,0 +1,38 @@ +import vim +import subprocess + + +def check_for_updates(): + g_plugs = vim.eval("g:plugs") + + update_commands = [] + calculate_updates_commands = [] + + for plug in g_plugs.values(): + update_commands.append( + "git -C %s remote update > /dev/null" % plug["dir"]) + calculate_updates_commands.append( + "git -C %s rev-list HEAD..origin/%s --count" % (plug["dir"], plug["branch"])) + + update_commands.append("wait") + update_command = " & ".join(update_commands) + calculate_updates_command = " && ".join(calculate_updates_commands) + + updates_process = subprocess.Popen(["bash", "-c", update_command]) + updates_process.communicate() + + calculate_updates_process = subprocess.Popen( + ["bash", "-c", calculate_updates_command], + stdout=subprocess.PIPE, + text=True) + stdout, stderr = calculate_updates_process.communicate() + + plugs_to_update = sum(1 for i in stdout.split() if int(i) > 0) + g_outdated_plugins_silent_mode = vim.eval("g:outdated_plugins_silent_mode") + if plugs_to_update > 0: + print("Plugins to update: %d" % plugs_to_update) + elif not g_outdated_plugins_silent_mode: + print("All plugins up-to-date") + + +vim.async_call(check_for_updates) From bf43e03c2d47495ed5cfc20f812ab107795bb1e4 Mon Sep 17 00:00:00 2001 From: Randy West Date: Fri, 11 Oct 2019 00:48:34 -0400 Subject: [PATCH 06/30] Properly casts result of vim.eval to int vim.eval returns a string, whereas we need an int for boolean testing --- python/outdatedplugins.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/outdatedplugins.py b/python/outdatedplugins.py index 89328e9..eb22d28 100644 --- a/python/outdatedplugins.py +++ b/python/outdatedplugins.py @@ -28,7 +28,8 @@ def check_for_updates(): stdout, stderr = calculate_updates_process.communicate() plugs_to_update = sum(1 for i in stdout.split() if int(i) > 0) - g_outdated_plugins_silent_mode = vim.eval("g:outdated_plugins_silent_mode") + g_outdated_plugins_silent_mode = int( + vim.eval("g:outdated_plugins_silent_mode")) if plugs_to_update > 0: print("Plugins to update: %d" % plugs_to_update) elif not g_outdated_plugins_silent_mode: From 817220d3fe86e0ca080eb6a5ff03f75f4459244e Mon Sep 17 00:00:00 2001 From: Randy West Date: Fri, 11 Oct 2019 00:52:26 -0400 Subject: [PATCH 07/30] Adds g:outdated_plugins_trigger_mode --- README.md | 31 +++++++++++++++++++++---------- plugin/vim-outdated-plugins.vim | 4 ++++ python/outdatedplugins.py | 4 ++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d8abb35..fdc5d9f 100644 --- a/README.md +++ b/README.md @@ -3,43 +3,54 @@ ![GitHub release](https://img.shields.io/github/release/semanser/vim-outdated-plugins.svg?style=flat-square) # vim-outdated-plugins + Async plugin for showing number of your outdated plugins. ## What it does? + This plugin automatically checks if any of your plugins are outdated and display a message about that. To use this plugin make sure you have **git** installed. ## Installation + ```vim Plug 'semanser/vim-outdated-plugins' ``` ## Configuration + ```vim " Do not show any message if all plugins are up to date. 0 by default let g:outdated_plugins_silent_mode = 1 + +" Trigger :PlugUpdate as needed +let g:outdated_plugins_trigger_mode = 1 ``` ## Screenshots + Simple message text message under the status bar. ![alt text](https://raw.githubusercontent.com/semanser/vim-outdated-plugins/master/images/outdated.png) ![alt text](https://raw.githubusercontent.com/semanser/vim-outdated-plugins/master/images/updated.png) ### OS + - [x] macOS - [x] Linux - [ ] Windows ### Plugin Managers: - - [x] vim-plug - - [ ] Vundle - - [ ] Pathogen - - [ ] dein.vim - - [ ] NeoBundle - - [ ] VAM - - ### Notificatation methods - - [x] Basic echo - - [ ] Status line variable + +- [x] vim-plug +- [ ] Vundle +- [ ] Pathogen +- [ ] dein.vim +- [ ] NeoBundle +- [ ] VAM + +### Notificatation methods + +- [x] Basic echo +- [ ] Status line variable diff --git a/plugin/vim-outdated-plugins.vim b/plugin/vim-outdated-plugins.vim index b6626f7..f010ed0 100644 --- a/plugin/vim-outdated-plugins.vim +++ b/plugin/vim-outdated-plugins.vim @@ -2,6 +2,10 @@ if !exists('g:outdated_plugins_silent_mode') let g:outdated_plugins_silent_mode = 0 endif +if !exists('g:outdated_plugins_trigger_mode') + let g:outdated_plugins_trigger_mode = 0 +endif + let s:plugin_root_dir = fnamemodify(resolve(expand(':p')), ':h') python3 << EOF diff --git a/python/outdatedplugins.py b/python/outdatedplugins.py index eb22d28..cdec8d4 100644 --- a/python/outdatedplugins.py +++ b/python/outdatedplugins.py @@ -30,8 +30,12 @@ def check_for_updates(): plugs_to_update = sum(1 for i in stdout.split() if int(i) > 0) g_outdated_plugins_silent_mode = int( vim.eval("g:outdated_plugins_silent_mode")) + g_outdated_plugins_trigger_mode = int(vim.eval( + "g:outdated_plugins_trigger_mode")) if plugs_to_update > 0: print("Plugins to update: %d" % plugs_to_update) + if g_outdated_plugins_trigger_mode: + vim.command("PlugUpdate") elif not g_outdated_plugins_silent_mode: print("All plugins up-to-date") From 1ef52dc8a22bf9cacbd75bbec45444a7dd486f3e Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 13 Oct 2019 22:49:12 -0400 Subject: [PATCH 08/30] Update to for python3 Was using python2 subprocess.Popen, which accepts the text argument. Since python3 is utf8, this arg was removed (always returns utf8). Also got rid of unused stderr var to quiet lint --- python/outdatedplugins.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/python/outdatedplugins.py b/python/outdatedplugins.py index cdec8d4..90f50bb 100644 --- a/python/outdatedplugins.py +++ b/python/outdatedplugins.py @@ -23,9 +23,8 @@ def check_for_updates(): calculate_updates_process = subprocess.Popen( ["bash", "-c", calculate_updates_command], - stdout=subprocess.PIPE, - text=True) - stdout, stderr = calculate_updates_process.communicate() + stdout=subprocess.PIPE) + stdout = calculate_updates_process.communicate()[0] plugs_to_update = sum(1 for i in stdout.split() if int(i) > 0) g_outdated_plugins_silent_mode = int( From 470655bbf86f672428cf25959bc76470d7334664 Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 13 Oct 2019 23:04:48 -0400 Subject: [PATCH 09/30] Decode process output from binary and use run() Got it backwards in the previous commit. subprocess always returns binary output now, so it must be decoded. Also used subprocess.run instead of Popen/communicate for simplicity --- python/outdatedplugins.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/python/outdatedplugins.py b/python/outdatedplugins.py index 90f50bb..6a648ac 100644 --- a/python/outdatedplugins.py +++ b/python/outdatedplugins.py @@ -18,15 +18,12 @@ def check_for_updates(): update_command = " & ".join(update_commands) calculate_updates_command = " && ".join(calculate_updates_commands) - updates_process = subprocess.Popen(["bash", "-c", update_command]) - updates_process.communicate() + subprocess.run(["bash", "-c", update_command]) - calculate_updates_process = subprocess.Popen( - ["bash", "-c", calculate_updates_command], - stdout=subprocess.PIPE) - stdout = calculate_updates_process.communicate()[0] + out = subprocess.run( + ["bash", "-c", calculate_updates_command], stdout=subprocess.PIPE) - plugs_to_update = sum(1 for i in stdout.split() if int(i) > 0) + plugs_to_update = sum(1 for i in out.stdout.decode().split() if int(i) > 0) g_outdated_plugins_silent_mode = int( vim.eval("g:outdated_plugins_silent_mode")) g_outdated_plugins_trigger_mode = int(vim.eval( From 2031956317dc828e866d761ab1033c1d8bdb563d Mon Sep 17 00:00:00 2001 From: Randy West Date: Tue, 29 Oct 2019 14:54:22 -0400 Subject: [PATCH 10/30] Add guard to keep plug.vim from throwing exception --- python/outdatedplugins.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/python/outdatedplugins.py b/python/outdatedplugins.py index 6a648ac..600b6b7 100644 --- a/python/outdatedplugins.py +++ b/python/outdatedplugins.py @@ -1,8 +1,27 @@ import vim import subprocess +import os + + +def plug_can_proceed(): + # plug.vim has these two guards in place. occassionally, if trigger mode is + # enabled, we can get in a situation where we're calling PlugUpdate when it + # will throw, causing a nasty error message. instead, we can just duplicate + # the guards here + if not os.getcwd(): + return False + + for evar in ["GIT_DIR", "GIT_WORK_TREE"]: + if os.environ.get(evar) != None: + return False + + return True def check_for_updates(): + if not plug_can_proceed(): + return + g_plugs = vim.eval("g:plugs") update_commands = [] From a086e7d01fe01226f894ad36d92a8fddc5db1efb Mon Sep 17 00:00:00 2001 From: Randy West Date: Tue, 29 Oct 2019 14:55:37 -0400 Subject: [PATCH 11/30] Add .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57c8144 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +python/__pycache__ From 3fdf2fab1e614cea519f12fdcfbf27b73a932b1b Mon Sep 17 00:00:00 2001 From: Randy West Date: Thu, 4 Mar 2021 14:29:24 -0800 Subject: [PATCH 12/30] Change installation instructions to fork path Note: this commit should be excluded from any pull requests, but it is useful for clarity should anyone want to use the fork directly --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fdc5d9f..e094eea 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ To use this plugin make sure you have **git** installed. ## Installation ```vim -Plug 'semanser/vim-outdated-plugins' +Plug 'thisisrandy/vim-outdated-plugins' ``` ## Configuration From 45bbdb12a0b5b16d0ecd1d796057e56f7a1f4c65 Mon Sep 17 00:00:00 2001 From: Randy West Date: Mon, 19 Apr 2021 13:38:16 -0700 Subject: [PATCH 13/30] Formatting --- python/outdatedplugins.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/python/outdatedplugins.py b/python/outdatedplugins.py index 600b6b7..fbc6f19 100644 --- a/python/outdatedplugins.py +++ b/python/outdatedplugins.py @@ -28,10 +28,10 @@ def check_for_updates(): calculate_updates_commands = [] for plug in g_plugs.values(): - update_commands.append( - "git -C %s remote update > /dev/null" % plug["dir"]) + update_commands.append("git -C %s remote update > /dev/null" % plug["dir"]) calculate_updates_commands.append( - "git -C %s rev-list HEAD..origin/%s --count" % (plug["dir"], plug["branch"])) + "git -C %s rev-list HEAD..origin/%s --count" % (plug["dir"], plug["branch"]) + ) update_commands.append("wait") update_command = " & ".join(update_commands) @@ -40,13 +40,12 @@ def check_for_updates(): subprocess.run(["bash", "-c", update_command]) out = subprocess.run( - ["bash", "-c", calculate_updates_command], stdout=subprocess.PIPE) + ["bash", "-c", calculate_updates_command], stdout=subprocess.PIPE + ) plugs_to_update = sum(1 for i in out.stdout.decode().split() if int(i) > 0) - g_outdated_plugins_silent_mode = int( - vim.eval("g:outdated_plugins_silent_mode")) - g_outdated_plugins_trigger_mode = int(vim.eval( - "g:outdated_plugins_trigger_mode")) + g_outdated_plugins_silent_mode = int(vim.eval("g:outdated_plugins_silent_mode")) + g_outdated_plugins_trigger_mode = int(vim.eval("g:outdated_plugins_trigger_mode")) if plugs_to_update > 0: print("Plugins to update: %d" % plugs_to_update) if g_outdated_plugins_trigger_mode: From f5566755256914c9266e57f6bf275e81a8f35c22 Mon Sep 17 00:00:00 2001 From: Randy West Date: Mon, 19 Apr 2021 13:59:45 -0700 Subject: [PATCH 14/30] Use master if plug["branch"] is empty It's unclear when this broke, but g:plugs[name].branch is apparently now empty when not explicitly specified. Since this plugin never would have worked if it was always that way, presumably the behavior changed at some point --- python/outdatedplugins.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/outdatedplugins.py b/python/outdatedplugins.py index fbc6f19..b27bb66 100644 --- a/python/outdatedplugins.py +++ b/python/outdatedplugins.py @@ -30,7 +30,8 @@ def check_for_updates(): for plug in g_plugs.values(): update_commands.append("git -C %s remote update > /dev/null" % plug["dir"]) calculate_updates_commands.append( - "git -C %s rev-list HEAD..origin/%s --count" % (plug["dir"], plug["branch"]) + "git -C %s rev-list HEAD..origin/%s --count" + % (plug["dir"], plug["branch"] if plug["branch"] else "master") ) update_commands.append("wait") From ae13c8a50c3c06bbd90fef189d330b0d1b7fe644 Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 14:10:44 -0700 Subject: [PATCH 15/30] Add .venv + generalize pycache in gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 57c8144..9f7550b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -python/__pycache__ +__pycache__ +.venv From e63cc257e0fa6e2d65f3b19ae00b765a3c496912 Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 14:10:57 -0700 Subject: [PATCH 16/30] Add poetry --- poetry.lock | 383 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 16 +++ 2 files changed, 399 insertions(+) create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..ca3f769 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,383 @@ +[[package]] +name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "black" +version = "21.7b0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +appdirs = "*" +click = ">=7.1.2" +dataclasses = {version = ">=0.6", markers = "python_version < \"3.7\""} +mypy-extensions = ">=0.4.3" +pathspec = ">=0.8.1,<1" +regex = ">=2020.1.8" +tomli = ">=0.2.6,<2.0.0" +typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.6.0)", "aiohttp-cors (>=0.4.0)"] +python2 = ["typed-ast (>=1.4.2)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "click" +version = "8.0.1" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "dataclasses" +version = "0.8" +description = "A backport of the dataclasses module for Python 3.6" +category = "dev" +optional = false +python-versions = ">=3.6, <3.7" + +[[package]] +name = "greenlet" +version = "1.1.0" +description = "Lightweight in-process concurrent programming" +category = "main" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" + +[package.extras] +docs = ["sphinx"] + +[[package]] +name = "importlib-metadata" +version = "4.6.1" +description = "Read metadata from Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} +zipp = ">=0.5" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +perf = ["ipython"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] + +[[package]] +name = "msgpack" +version = "1.0.2" +description = "MessagePack (de)serializer." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "pathspec" +version = "0.9.0" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[[package]] +name = "pynvim" +version = "0.4.3" +description = "Python client to neovim" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +greenlet = "*" +msgpack = ">=0.5.0" + +[package.extras] +pyuv = ["pyuv (>=1.0.0)"] +test = ["pytest (>=3.4.0)"] + +[[package]] +name = "regex" +version = "2021.7.6" +description = "Alternative regular expression module, to replace re." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "tomli" +version = "1.1.0" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "typed-ast" +version = "1.4.3" +description = "a fork of Python 2 and 3 ast modules with type comment support" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "typing-extensions" +version = "3.10.0.0" +description = "Backported and Experimental Type Hints for Python 3.5+" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "zipp" +version = "3.5.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] + +[metadata] +lock-version = "1.1" +python-versions = "^3.6.2" +content-hash = "e9864707f52b8c78308f756ab02679b968fc2cebb3d4a0ba73983c6b00a0c9a4" + +[metadata.files] +appdirs = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] +black = [ + {file = "black-21.7b0-py3-none-any.whl", hash = "sha256:1c7aa6ada8ee864db745b22790a32f94b2795c253a75d6d9b5e439ff10d23116"}, + {file = "black-21.7b0.tar.gz", hash = "sha256:c8373c6491de9362e39271630b65b964607bc5c79c83783547d76c839b3aa219"}, +] +click = [ + {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"}, + {file = "click-8.0.1.tar.gz", hash = "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] +dataclasses = [ + {file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"}, + {file = "dataclasses-0.8.tar.gz", hash = "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97"}, +] +greenlet = [ + {file = "greenlet-1.1.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:60848099b76467ef09b62b0f4512e7e6f0a2c977357a036de602b653667f5f4c"}, + {file = "greenlet-1.1.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f42ad188466d946f1b3afc0a9e1a266ac8926461ee0786c06baac6bd71f8a6f3"}, + {file = "greenlet-1.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:76ed710b4e953fc31c663b079d317c18f40235ba2e3d55f70ff80794f7b57922"}, + {file = "greenlet-1.1.0-cp27-cp27m-win32.whl", hash = "sha256:b33b51ab057f8a20b497ffafdb1e79256db0c03ef4f5e3d52e7497200e11f821"}, + {file = "greenlet-1.1.0-cp27-cp27m-win_amd64.whl", hash = "sha256:ed1377feed808c9c1139bdb6a61bcbf030c236dd288d6fca71ac26906ab03ba6"}, + {file = "greenlet-1.1.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:da862b8f7de577bc421323714f63276acb2f759ab8c5e33335509f0b89e06b8f"}, + {file = "greenlet-1.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:5f75e7f237428755d00e7460239a2482fa7e3970db56c8935bd60da3f0733e56"}, + {file = "greenlet-1.1.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:258f9612aba0d06785143ee1cbf2d7361801c95489c0bd10c69d163ec5254a16"}, + {file = "greenlet-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d928e2e3c3906e0a29b43dc26d9b3d6e36921eee276786c4e7ad9ff5665c78a"}, + {file = "greenlet-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cc407b68e0a874e7ece60f6639df46309376882152345508be94da608cc0b831"}, + {file = "greenlet-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c557c809eeee215b87e8a7cbfb2d783fb5598a78342c29ade561440abae7d22"}, + {file = "greenlet-1.1.0-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:3d13da093d44dee7535b91049e44dd2b5540c2a0e15df168404d3dd2626e0ec5"}, + {file = "greenlet-1.1.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b3090631fecdf7e983d183d0fad7ea72cfb12fa9212461a9b708ff7907ffff47"}, + {file = "greenlet-1.1.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:06ecb43b04480e6bafc45cb1b4b67c785e183ce12c079473359e04a709333b08"}, + {file = "greenlet-1.1.0-cp35-cp35m-win32.whl", hash = "sha256:944fbdd540712d5377a8795c840a97ff71e7f3221d3fddc98769a15a87b36131"}, + {file = "greenlet-1.1.0-cp35-cp35m-win_amd64.whl", hash = "sha256:c767458511a59f6f597bfb0032a1c82a52c29ae228c2c0a6865cfeaeaac4c5f5"}, + {file = "greenlet-1.1.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:2325123ff3a8ecc10ca76f062445efef13b6cf5a23389e2df3c02a4a527b89bc"}, + {file = "greenlet-1.1.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:598bcfd841e0b1d88e32e6a5ea48348a2c726461b05ff057c1b8692be9443c6e"}, + {file = "greenlet-1.1.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:be9768e56f92d1d7cd94185bab5856f3c5589a50d221c166cc2ad5eb134bd1dc"}, + {file = "greenlet-1.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe7eac0d253915116ed0cd160a15a88981a1d194c1ef151e862a5c7d2f853d3"}, + {file = "greenlet-1.1.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a6b035aa2c5fcf3dbbf0e3a8a5bc75286fc2d4e6f9cfa738788b433ec894919"}, + {file = "greenlet-1.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca1c4a569232c063615f9e70ff9a1e2fee8c66a6fb5caf0f5e8b21a396deec3e"}, + {file = "greenlet-1.1.0-cp36-cp36m-win32.whl", hash = "sha256:3096286a6072553b5dbd5efbefc22297e9d06a05ac14ba017233fedaed7584a8"}, + {file = "greenlet-1.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:c35872b2916ab5a240d52a94314c963476c989814ba9b519bc842e5b61b464bb"}, + {file = "greenlet-1.1.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:b97c9a144bbeec7039cca44df117efcbeed7209543f5695201cacf05ba3b5857"}, + {file = "greenlet-1.1.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:16183fa53bc1a037c38d75fdc59d6208181fa28024a12a7f64bb0884434c91ea"}, + {file = "greenlet-1.1.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6b1d08f2e7f2048d77343279c4d4faa7aef168b3e36039cba1917fffb781a8ed"}, + {file = "greenlet-1.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14927b15c953f8f2d2a8dffa224aa78d7759ef95284d4c39e1745cf36e8cdd2c"}, + {file = "greenlet-1.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bdcff4b9051fb1aa4bba4fceff6a5f770c6be436408efd99b76fc827f2a9319"}, + {file = "greenlet-1.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c70c7dd733a4c56838d1f1781e769081a25fade879510c5b5f0df76956abfa05"}, + {file = "greenlet-1.1.0-cp37-cp37m-win32.whl", hash = "sha256:0de64d419b1cb1bfd4ea544bedea4b535ef3ae1e150b0f2609da14bbf48a4a5f"}, + {file = "greenlet-1.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:8833e27949ea32d27f7e96930fa29404dd4f2feb13cce483daf52e8842ec246a"}, + {file = "greenlet-1.1.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:c1580087ab493c6b43e66f2bdd165d9e3c1e86ef83f6c2c44a29f2869d2c5bd5"}, + {file = "greenlet-1.1.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ad80bb338cf9f8129c049837a42a43451fc7c8b57ad56f8e6d32e7697b115505"}, + {file = "greenlet-1.1.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:a9017ff5fc2522e45562882ff481128631bf35da444775bc2776ac5c61d8bcae"}, + {file = "greenlet-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7920e3eccd26b7f4c661b746002f5ec5f0928076bd738d38d894bb359ce51927"}, + {file = "greenlet-1.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:408071b64e52192869129a205e5b463abda36eff0cebb19d6e63369440e4dc99"}, + {file = "greenlet-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be13a18cec649ebaab835dff269e914679ef329204704869f2f167b2c163a9da"}, + {file = "greenlet-1.1.0-cp38-cp38-win32.whl", hash = "sha256:22002259e5b7828b05600a762579fa2f8b33373ad95a0ee57b4d6109d0e589ad"}, + {file = "greenlet-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:206295d270f702bc27dbdbd7651e8ebe42d319139e0d90217b2074309a200da8"}, + {file = "greenlet-1.1.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:096cb0217d1505826ba3d723e8981096f2622cde1eb91af9ed89a17c10aa1f3e"}, + {file = "greenlet-1.1.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:03f28a5ea20201e70ab70518d151116ce939b412961c33827519ce620957d44c"}, + {file = "greenlet-1.1.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:7db68f15486d412b8e2cfcd584bf3b3a000911d25779d081cbbae76d71bd1a7e"}, + {file = "greenlet-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70bd1bb271e9429e2793902dfd194b653221904a07cbf207c3139e2672d17959"}, + {file = "greenlet-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f92731609d6625e1cc26ff5757db4d32b6b810d2a3363b0ff94ff573e5901f6f"}, + {file = "greenlet-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06d7ac89e6094a0a8f8dc46aa61898e9e1aec79b0f8b47b2400dd51a44dbc832"}, + {file = "greenlet-1.1.0-cp39-cp39-win32.whl", hash = "sha256:adb94a28225005890d4cf73648b5131e885c7b4b17bc762779f061844aabcc11"}, + {file = "greenlet-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:aa4230234d02e6f32f189fd40b59d5a968fe77e80f59c9c933384fe8ba535535"}, + {file = "greenlet-1.1.0.tar.gz", hash = "sha256:c87df8ae3f01ffb4483c796fe1b15232ce2b219f0b18126948616224d3f658ee"}, +] +importlib-metadata = [ + {file = "importlib_metadata-4.6.1-py3-none-any.whl", hash = "sha256:9f55f560e116f8643ecf2922d9cd3e1c7e8d52e683178fecd9d08f6aa357e11e"}, + {file = "importlib_metadata-4.6.1.tar.gz", hash = "sha256:079ada16b7fc30dfbb5d13399a5113110dab1aa7c2bc62f66af75f0b717c8cac"}, +] +msgpack = [ + {file = "msgpack-1.0.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:b6d9e2dae081aa35c44af9c4298de4ee72991305503442a5c74656d82b581fe9"}, + {file = "msgpack-1.0.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:a99b144475230982aee16b3d249170f1cccebf27fb0a08e9f603b69637a62192"}, + {file = "msgpack-1.0.2-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1026dcc10537d27dd2d26c327e552f05ce148977e9d7b9f1718748281b38c841"}, + {file = "msgpack-1.0.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:fe07bc6735d08e492a327f496b7850e98cb4d112c56df69b0c844dbebcbb47f6"}, + {file = "msgpack-1.0.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:9ea52fff0473f9f3000987f313310208c879493491ef3ccf66268eff8d5a0326"}, + {file = "msgpack-1.0.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:26a1759f1a88df5f1d0b393eb582ec022326994e311ba9c5818adc5374736439"}, + {file = "msgpack-1.0.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:497d2c12426adcd27ab83144057a705efb6acc7e85957a51d43cdcf7f258900f"}, + {file = "msgpack-1.0.2-cp36-cp36m-win32.whl", hash = "sha256:e89ec55871ed5473a041c0495b7b4e6099f6263438e0bd04ccd8418f92d5d7f2"}, + {file = "msgpack-1.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a4355d2193106c7aa77c98fc955252a737d8550320ecdb2e9ac701e15e2943bc"}, + {file = "msgpack-1.0.2-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:d6c64601af8f3893d17ec233237030e3110f11b8a962cb66720bf70c0141aa54"}, + {file = "msgpack-1.0.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f484cd2dca68502de3704f056fa9b318c94b1539ed17a4c784266df5d6978c87"}, + {file = "msgpack-1.0.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f3e6aaf217ac1c7ce1563cf52a2f4f5d5b1f64e8729d794165db71da57257f0c"}, + {file = "msgpack-1.0.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:8521e5be9e3b93d4d5e07cb80b7e32353264d143c1f072309e1863174c6aadb1"}, + {file = "msgpack-1.0.2-cp37-cp37m-win32.whl", hash = "sha256:31c17bbf2ae5e29e48d794c693b7ca7a0c73bd4280976d408c53df421e838d2a"}, + {file = "msgpack-1.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:8ffb24a3b7518e843cd83538cf859e026d24ec41ac5721c18ed0c55101f9775b"}, + {file = "msgpack-1.0.2-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:b28c0876cce1466d7c2195d7658cf50e4730667196e2f1355c4209444717ee06"}, + {file = "msgpack-1.0.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:87869ba567fe371c4555d2e11e4948778ab6b59d6cc9d8460d543e4cfbbddd1c"}, + {file = "msgpack-1.0.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:b55f7db883530b74c857e50e149126b91bb75d35c08b28db12dcb0346f15e46e"}, + {file = "msgpack-1.0.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:ac25f3e0513f6673e8b405c3a80500eb7be1cf8f57584be524c4fa78fe8e0c83"}, + {file = "msgpack-1.0.2-cp38-cp38-win32.whl", hash = "sha256:0cb94ee48675a45d3b86e61d13c1e6f1696f0183f0715544976356ff86f741d9"}, + {file = "msgpack-1.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:e36a812ef4705a291cdb4a2fd352f013134f26c6ff63477f20235138d1d21009"}, + {file = "msgpack-1.0.2-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:2a5866bdc88d77f6e1370f82f2371c9bc6fc92fe898fa2dec0c5d4f5435a2694"}, + {file = "msgpack-1.0.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:92be4b12de4806d3c36810b0fe2aeedd8d493db39e2eb90742b9c09299eb5759"}, + {file = "msgpack-1.0.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:de6bd7990a2c2dabe926b7e62a92886ccbf809425c347ae7de277067f97c2887"}, + {file = "msgpack-1.0.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:5a9ee2540c78659a1dd0b110f73773533ee3108d4e1219b5a15a8d635b7aca0e"}, + {file = "msgpack-1.0.2-cp39-cp39-win32.whl", hash = "sha256:c747c0cc08bd6d72a586310bda6ea72eeb28e7505990f342552315b229a19b33"}, + {file = "msgpack-1.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:d8167b84af26654c1124857d71650404336f4eb5cc06900667a493fc619ddd9f"}, + {file = "msgpack-1.0.2.tar.gz", hash = "sha256:fae04496f5bc150eefad4e9571d1a76c55d021325dcd484ce45065ebbdd00984"}, +] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] +pathspec = [ + {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, + {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, +] +pynvim = [ + {file = "pynvim-0.4.3.tar.gz", hash = "sha256:3a795378bde5e8092fbeb3a1a99be9c613d2685542f1db0e5c6fd467eed56dff"}, +] +regex = [ + {file = "regex-2021.7.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e6a1e5ca97d411a461041d057348e578dc344ecd2add3555aedba3b408c9f874"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:6afe6a627888c9a6cfbb603d1d017ce204cebd589d66e0703309b8048c3b0854"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ccb3d2190476d00414aab36cca453e4596e8f70a206e2aa8db3d495a109153d2"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:ed693137a9187052fc46eedfafdcb74e09917166362af4cc4fddc3b31560e93d"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:99d8ab206a5270c1002bfcf25c51bf329ca951e5a169f3b43214fdda1f0b5f0d"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:b85ac458354165405c8a84725de7bbd07b00d9f72c31a60ffbf96bb38d3e25fa"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:3f5716923d3d0bfb27048242a6e0f14eecdb2e2a7fac47eda1d055288595f222"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5983c19d0beb6af88cb4d47afb92d96751fb3fa1784d8785b1cdf14c6519407"}, + {file = "regex-2021.7.6-cp36-cp36m-win32.whl", hash = "sha256:c92831dac113a6e0ab28bc98f33781383fe294df1a2c3dfd1e850114da35fd5b"}, + {file = "regex-2021.7.6-cp36-cp36m-win_amd64.whl", hash = "sha256:791aa1b300e5b6e5d597c37c346fb4d66422178566bbb426dd87eaae475053fb"}, + {file = "regex-2021.7.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:59506c6e8bd9306cd8a41511e32d16d5d1194110b8cfe5a11d102d8b63cf945d"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:564a4c8a29435d1f2256ba247a0315325ea63335508ad8ed938a4f14c4116a5d"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:59c00bb8dd8775473cbfb967925ad2c3ecc8886b3b2d0c90a8e2707e06c743f0"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:9a854b916806c7e3b40e6616ac9e85d3cdb7649d9e6590653deb5b341a736cec"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:db2b7df831c3187a37f3bb80ec095f249fa276dbe09abd3d35297fc250385694"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:173bc44ff95bc1e96398c38f3629d86fa72e539c79900283afa895694229fe6a"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:15dddb19823f5147e7517bb12635b3c82e6f2a3a6b696cc3e321522e8b9308ad"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ddeabc7652024803666ea09f32dd1ed40a0579b6fbb2a213eba590683025895"}, + {file = "regex-2021.7.6-cp37-cp37m-win32.whl", hash = "sha256:f080248b3e029d052bf74a897b9d74cfb7643537fbde97fe8225a6467fb559b5"}, + {file = "regex-2021.7.6-cp37-cp37m-win_amd64.whl", hash = "sha256:d8bbce0c96462dbceaa7ac4a7dfbbee92745b801b24bce10a98d2f2b1ea9432f"}, + {file = "regex-2021.7.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:edd1a68f79b89b0c57339bce297ad5d5ffcc6ae7e1afdb10f1947706ed066c9c"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux1_i686.whl", hash = "sha256:422dec1e7cbb2efbbe50e3f1de36b82906def93ed48da12d1714cabcd993d7f0"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cbe23b323988a04c3e5b0c387fe3f8f363bf06c0680daf775875d979e376bd26"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:0eb2c6e0fcec5e0f1d3bcc1133556563222a2ffd2211945d7b1480c1b1a42a6f"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:1c78780bf46d620ff4fff40728f98b8afd8b8e35c3efd638c7df67be2d5cddbf"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:bc84fb254a875a9f66616ed4538542fb7965db6356f3df571d783f7c8d256edd"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:598c0a79b4b851b922f504f9f39a863d83ebdfff787261a5ed061c21e67dd761"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875c355360d0f8d3d827e462b29ea7682bf52327d500a4f837e934e9e4656068"}, + {file = "regex-2021.7.6-cp38-cp38-win32.whl", hash = "sha256:e586f448df2bbc37dfadccdb7ccd125c62b4348cb90c10840d695592aa1b29e0"}, + {file = "regex-2021.7.6-cp38-cp38-win_amd64.whl", hash = "sha256:2fe5e71e11a54e3355fa272137d521a40aace5d937d08b494bed4529964c19c4"}, + {file = "regex-2021.7.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6110bab7eab6566492618540c70edd4d2a18f40ca1d51d704f1d81c52d245026"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:4f64fc59fd5b10557f6cd0937e1597af022ad9b27d454e182485f1db3008f417"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:89e5528803566af4df368df2d6f503c84fbfb8249e6631c7b025fe23e6bd0cde"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2366fe0479ca0e9afa534174faa2beae87847d208d457d200183f28c74eaea59"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f9392a4555f3e4cb45310a65b403d86b589adc773898c25a39184b1ba4db8985"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2bceeb491b38225b1fee4517107b8491ba54fba77cf22a12e996d96a3c55613d"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:f98dc35ab9a749276f1a4a38ab3e0e2ba1662ce710f6530f5b0a6656f1c32b58"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:319eb2a8d0888fa6f1d9177705f341bc9455a2c8aca130016e52c7fe8d6c37a3"}, + {file = "regex-2021.7.6-cp39-cp39-win32.whl", hash = "sha256:eaf58b9e30e0e546cdc3ac06cf9165a1ca5b3de8221e9df679416ca667972035"}, + {file = "regex-2021.7.6-cp39-cp39-win_amd64.whl", hash = "sha256:4c9c3155fe74269f61e27617529b7f09552fbb12e44b1189cebbdb24294e6e1c"}, + {file = "regex-2021.7.6.tar.gz", hash = "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d"}, +] +tomli = [ + {file = "tomli-1.1.0-py3-none-any.whl", hash = "sha256:f4a182048010e89cbec0ae4686b21f550a7f2903f665e34a6de58ec15424f919"}, + {file = "tomli-1.1.0.tar.gz", hash = "sha256:33d7984738f8bb699c9b0a816eb646a8178a69eaa792d258486776a5d21b8ca5"}, +] +typed-ast = [ + {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, + {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"}, + {file = "typed_ast-1.4.3-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528"}, + {file = "typed_ast-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428"}, + {file = "typed_ast-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3"}, + {file = "typed_ast-1.4.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f"}, + {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341"}, + {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace"}, + {file = "typed_ast-1.4.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f"}, + {file = "typed_ast-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363"}, + {file = "typed_ast-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7"}, + {file = "typed_ast-1.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266"}, + {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e"}, + {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04"}, + {file = "typed_ast-1.4.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899"}, + {file = "typed_ast-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c"}, + {file = "typed_ast-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805"}, + {file = "typed_ast-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a"}, + {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff"}, + {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41"}, + {file = "typed_ast-1.4.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39"}, + {file = "typed_ast-1.4.3-cp38-cp38-win32.whl", hash = "sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927"}, + {file = "typed_ast-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40"}, + {file = "typed_ast-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3"}, + {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4"}, + {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0"}, + {file = "typed_ast-1.4.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3"}, + {file = "typed_ast-1.4.3-cp39-cp39-win32.whl", hash = "sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808"}, + {file = "typed_ast-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c"}, + {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"}, +] +typing-extensions = [ + {file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"}, + {file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"}, + {file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"}, +] +zipp = [ + {file = "zipp-3.5.0-py3-none-any.whl", hash = "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3"}, + {file = "zipp-3.5.0.tar.gz", hash = "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4"}, +] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4470a7a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,16 @@ +[tool.poetry] +name = "vim-outdated-plugins" +version = "0.1.0" +description = "" +authors = ["Randy West "] + +[tool.poetry.dependencies] +python = "^3.6.2" +pynvim = "^0.4.3" + +[tool.poetry.dev-dependencies] +black = "^21.7b0" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" From 0f0b4685615b96e0049b25b1f1bc0095c9a6acce Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 14:27:54 -0700 Subject: [PATCH 17/30] Rewrite as remote plugin to avoid blocking --- plugin/vim-outdated-plugins.vim | 20 -------- python/outdatedplugins.py | 58 ---------------------- rplugin/python3/outdatedplugins.py | 78 ++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 78 deletions(-) delete mode 100644 plugin/vim-outdated-plugins.vim delete mode 100644 python/outdatedplugins.py create mode 100644 rplugin/python3/outdatedplugins.py diff --git a/plugin/vim-outdated-plugins.vim b/plugin/vim-outdated-plugins.vim deleted file mode 100644 index f010ed0..0000000 --- a/plugin/vim-outdated-plugins.vim +++ /dev/null @@ -1,20 +0,0 @@ -if !exists('g:outdated_plugins_silent_mode') - let g:outdated_plugins_silent_mode = 0 -endif - -if !exists('g:outdated_plugins_trigger_mode') - let g:outdated_plugins_trigger_mode = 0 -endif - -let s:plugin_root_dir = fnamemodify(resolve(expand(':p')), ':h') - -python3 << EOF -import sys -from os.path import normpath, join -import vim -plugin_root_dir = vim.eval('s:plugin_root_dir') -python_root_dir = normpath(join(plugin_root_dir, '..', 'python')) -sys.path.insert(0, python_root_dir) -import outdatedplugins -EOF - diff --git a/python/outdatedplugins.py b/python/outdatedplugins.py deleted file mode 100644 index b27bb66..0000000 --- a/python/outdatedplugins.py +++ /dev/null @@ -1,58 +0,0 @@ -import vim -import subprocess -import os - - -def plug_can_proceed(): - # plug.vim has these two guards in place. occassionally, if trigger mode is - # enabled, we can get in a situation where we're calling PlugUpdate when it - # will throw, causing a nasty error message. instead, we can just duplicate - # the guards here - if not os.getcwd(): - return False - - for evar in ["GIT_DIR", "GIT_WORK_TREE"]: - if os.environ.get(evar) != None: - return False - - return True - - -def check_for_updates(): - if not plug_can_proceed(): - return - - g_plugs = vim.eval("g:plugs") - - update_commands = [] - calculate_updates_commands = [] - - for plug in g_plugs.values(): - update_commands.append("git -C %s remote update > /dev/null" % plug["dir"]) - calculate_updates_commands.append( - "git -C %s rev-list HEAD..origin/%s --count" - % (plug["dir"], plug["branch"] if plug["branch"] else "master") - ) - - update_commands.append("wait") - update_command = " & ".join(update_commands) - calculate_updates_command = " && ".join(calculate_updates_commands) - - subprocess.run(["bash", "-c", update_command]) - - out = subprocess.run( - ["bash", "-c", calculate_updates_command], stdout=subprocess.PIPE - ) - - plugs_to_update = sum(1 for i in out.stdout.decode().split() if int(i) > 0) - g_outdated_plugins_silent_mode = int(vim.eval("g:outdated_plugins_silent_mode")) - g_outdated_plugins_trigger_mode = int(vim.eval("g:outdated_plugins_trigger_mode")) - if plugs_to_update > 0: - print("Plugins to update: %d" % plugs_to_update) - if g_outdated_plugins_trigger_mode: - vim.command("PlugUpdate") - elif not g_outdated_plugins_silent_mode: - print("All plugins up-to-date") - - -vim.async_call(check_for_updates) diff --git a/rplugin/python3/outdatedplugins.py b/rplugin/python3/outdatedplugins.py new file mode 100644 index 0000000..48d91bd --- /dev/null +++ b/rplugin/python3/outdatedplugins.py @@ -0,0 +1,78 @@ +from typing import Any, List +import pynvim +import subprocess +import os +from pynvim.api.nvim import Nvim + + +def plug_can_proceed(): + # plug.vim has these two guards in place. occassionally, if trigger mode is + # enabled, we can get in a situation where we're calling PlugUpdate when it + # will throw, causing a nasty error message. instead, we can just duplicate + # the guards here + if not os.getcwd(): + return False + + for evar in ["GIT_DIR", "GIT_WORK_TREE"]: + if os.environ.get(evar) != None: + return False + + return True + + +@pynvim.plugin +class OutdatedPlugins: + def __init__(self, vim: Nvim) -> None: + self.vim = vim + + @pynvim.function("CheckOutdatedPlugins") + def check_for_updates(self, args: List): + if not plug_can_proceed(): + return + + g_plugs = self.vim.eval("g:plugs") + + update_commands = [] + calculate_updates_commands = [] + + for plug in g_plugs.values(): + update_commands.append("git -C %s remote update > /dev/null" % plug["dir"]) + calculate_updates_commands.append( + "git -C %s rev-list HEAD..origin/%s --count" + % (plug["dir"], plug["branch"] if plug["branch"] else "master") + ) + + update_commands.append("wait") + update_command = " & ".join(update_commands) + calculate_updates_command = " && ".join(calculate_updates_commands) + + subprocess.run(["bash", "-c", update_command]) + + out = subprocess.run( + ["bash", "-c", calculate_updates_command], stdout=subprocess.PIPE + ) + + plugs_to_update = sum(1 for i in out.stdout.decode().split() if int(i) > 0) + g_outdated_plugins_silent_mode = self.get_default( + "g:outdated_plugins_silent_mode", 0 + ) + g_outdated_plugins_trigger_mode = self.get_default( + "g:outdated_plugins_trigger_mode", 0 + ) + + if plugs_to_update > 0: + self.vim.command(f"echo 'Plugins to update: {plugs_to_update}'") + if g_outdated_plugins_trigger_mode: + self.vim.command("PlugUpdate") + elif not g_outdated_plugins_silent_mode: + self.vim.command("echo 'All plugins up-to-date'") + + def get_default(self, var: str, default: Any) -> Any: + """ + Return the value of the vim variable `var` or `default` if it doesn't exist + """ + + try: + return self.vim.eval(var) + except: + return default From c520cb98dac91bebd0e897a928c07ff3f296af4b Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 14:40:42 -0700 Subject: [PATCH 18/30] Fix grammar --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e094eea..0db1359 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Async plugin for showing number of your outdated plugins. ## What it does? -This plugin automatically checks if any of your plugins are outdated and display a message about that. +This plugin automatically checks if any of your plugins are outdated and displays a message about that. To use this plugin make sure you have **git** installed. From 061169e4d5dc1b096fd5fbc94c6ece58e9be1fac Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 14:41:26 -0700 Subject: [PATCH 19/30] Add autocmd to call plugin fn to config section --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0db1359..2acb59c 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ let g:outdated_plugins_silent_mode = 1 " Trigger :PlugUpdate as needed let g:outdated_plugins_trigger_mode = 1 + +autocmd VimEnter * call CheckOutdatedPlugins() ``` ## Screenshots From 1e9b9b4ba008ecf6b646109899791645b8a3b20c Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 15:15:21 -0700 Subject: [PATCH 20/30] Clarify wording/grammar + addt. info --- README.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2acb59c..c4c669e 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,27 @@ -![Vim support](https://img.shields.io/badge/vim-support-brightgreen.svg?style=flat-square) -![Vim support](https://img.shields.io/badge/neovim-support-brightgreen.svg?style=flat-square) +![Vim support](https://img.shields.io/badge/vim-unsupported-red.svg?style=flat-square) +![Vim support](https://img.shields.io/badge/neovim-supported-green.svg?style=flat-square) ![GitHub release](https://img.shields.io/github/release/semanser/vim-outdated-plugins.svg?style=flat-square) # vim-outdated-plugins -Async plugin for showing number of your outdated plugins. +A remote plugin for showing the number of and automatically updating outdated +plugins managed via [vim-plug](https://github.com/junegunn/vim-plug) -## What it does? +## What does it do? -This plugin automatically checks if any of your plugins are outdated and displays a message about that. +This plugin provides a mechanism for displaying a message indicating whether any +of your plugins are outdated. It can also optionally trigger an update if +needed. -To use this plugin make sure you have **git** installed. +To use this plugin, make sure you are using [neovim](https://neovim.io/), have +[git](https://git-scm.com) installed, and are using +[vim-plug](https://github.com/junegunn/vim-plug) as your plugin manager ## Installation +Add the following line inside of the `call plug#begin()` section of your +`init.vim`: + ```vim Plug 'thisisrandy/vim-outdated-plugins' ``` @@ -27,6 +35,7 @@ let g:outdated_plugins_silent_mode = 1 " Trigger :PlugUpdate as needed let g:outdated_plugins_trigger_mode = 1 +" This line is required to check for outdated plugins on startup autocmd VimEnter * call CheckOutdatedPlugins() ``` From 84804f291a653692722db0db68ecdc79ef2aab5e Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 15:30:24 -0700 Subject: [PATCH 21/30] Add note about trigger mode default value --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c4c669e..581bef6 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Plug 'thisisrandy/vim-outdated-plugins' " Do not show any message if all plugins are up to date. 0 by default let g:outdated_plugins_silent_mode = 1 -" Trigger :PlugUpdate as needed +" Trigger :PlugUpdate as needed. 0 by default let g:outdated_plugins_trigger_mode = 1 " This line is required to check for outdated plugins on startup From cfd1d8b728a39b71625fc9494e5ec4c1e7e4e593 Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 15:44:10 -0700 Subject: [PATCH 22/30] Specify that the plugin is non-blocking --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 581bef6..216ddc5 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,9 @@ # vim-outdated-plugins -A remote plugin for showing the number of and automatically updating outdated -plugins managed via [vim-plug](https://github.com/junegunn/vim-plug) +A [remote](https://pynvim.readthedocs.io/en/latest/usage/remote-plugins.html) +(non-blocking) plugin for showing the number of and automatically updating +outdated plugins managed via [vim-plug](https://github.com/junegunn/vim-plug) ## What does it do? From 2d96d243606af1043d362ced5f03ef44c1ffa8ab Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 15:44:28 -0700 Subject: [PATCH 23/30] Specify why the plugin is needed alongside vim-plug --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 216ddc5..c25eb4c 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,9 @@ outdated plugins managed via [vim-plug](https://github.com/junegunn/vim-plug) This plugin provides a mechanism for displaying a message indicating whether any of your plugins are outdated. It can also optionally trigger an update if -needed. +needed. It fills a gap in [vim-plug](https://github.com/junegunn/vim-plug), +which has no mechanism for fetching updates without also installing them and +cannot function non-disruptively in the background To use this plugin, make sure you are using [neovim](https://neovim.io/), have [git](https://git-scm.com) installed, and are using From c6a45a811b23eb4b9ccce3c12a8e5725e46ccbe6 Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 15:44:45 -0700 Subject: [PATCH 24/30] Add note about trigger mode being disruptive --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c25eb4c..a092647 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,9 @@ Plug 'thisisrandy/vim-outdated-plugins' " Do not show any message if all plugins are up to date. 0 by default let g:outdated_plugins_silent_mode = 1 -" Trigger :PlugUpdate as needed. 0 by default +" Trigger :PlugUpdate as needed. 0 by default. Note that, when triggered, this +" will open and focus a vertical split and do blocking work, which some users may +" find disruptive on startup let g:outdated_plugins_trigger_mode = 1 " This line is required to check for outdated plugins on startup From ddc58197ac00e2aff109cf960b05f422956b412f Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 15:51:00 -0700 Subject: [PATCH 25/30] Move autocmd to install section --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a092647..192ace1 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,13 @@ Add the following line inside of the `call plug#begin()` section of your Plug 'thisisrandy/vim-outdated-plugins' ``` +and anywhere after `call plug#end()`, add + +```vim +" This line is required to check for outdated plugins on startup +autocmd VimEnter * call CheckOutdatedPlugins() +``` + ## Configuration ```vim @@ -39,9 +46,6 @@ let g:outdated_plugins_silent_mode = 1 " will open and focus a vertical split and do blocking work, which some users may " find disruptive on startup let g:outdated_plugins_trigger_mode = 1 - -" This line is required to check for outdated plugins on startup -autocmd VimEnter * call CheckOutdatedPlugins() ``` ## Screenshots From 0f478313b524d446399ab2860d165363ea246e26 Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 15:51:15 -0700 Subject: [PATCH 26/30] Move requirements to their own section --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 192ace1..43c036e 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,6 @@ needed. It fills a gap in [vim-plug](https://github.com/junegunn/vim-plug), which has no mechanism for fetching updates without also installing them and cannot function non-disruptively in the background -To use this plugin, make sure you are using [neovim](https://neovim.io/), have -[git](https://git-scm.com) installed, and are using -[vim-plug](https://github.com/junegunn/vim-plug) as your plugin manager - ## Installation Add the following line inside of the `call plug#begin()` section of your @@ -48,6 +44,13 @@ let g:outdated_plugins_silent_mode = 1 let g:outdated_plugins_trigger_mode = 1 ``` +## Requirements + +- [neovim](https://neovim.io/) +- [git](https://git-scm.com) +- [vim-plug](https://github.com/junegunn/vim-plug) +- [python](https://www.python.org/) >= 3.5 + ## Screenshots Simple message text message under the status bar. From bde2d6d0e184048003e8bf04de87de4c721ab085 Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 16:02:14 -0700 Subject: [PATCH 27/30] Update badges --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 43c036e..2ac977c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ ![Vim support](https://img.shields.io/badge/vim-unsupported-red.svg?style=flat-square) -![Vim support](https://img.shields.io/badge/neovim-supported-green.svg?style=flat-square) -![GitHub release](https://img.shields.io/github/release/semanser/vim-outdated-plugins.svg?style=flat-square) +![Neovim support](https://img.shields.io/badge/neovim-supported-green.svg?style=flat-square) +![Python version](https://img.shields.io/badge/python-%5E3.5-yellow?style=flat-square) +![GitHub release](https://img.shields.io/github/v/release/thisisrandy/vim-outdated-plugins?style=flat-square) # vim-outdated-plugins From 967536ef233248895e5b3fa4e5eeae414c9e15fd Mon Sep 17 00:00:00 2001 From: Randy West Date: Sun, 25 Jul 2021 16:36:30 -0700 Subject: [PATCH 28/30] Add development section --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 2ac977c..5e0218b 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,15 @@ let g:outdated_plugins_trigger_mode = 1 - [vim-plug](https://github.com/junegunn/vim-plug) - [python](https://www.python.org/) >= 3.5 +## Development + +Fork this repository and point the `vim-plug` section of your `init.vim` to it. +After running `:PlugInstall`, you can edit the code directly in the `vim-plug` +directory, which is `~/.config/nvim/plugged` by default. Note that nvim must be +restarted for changes to be reflected. For details and a more general new +development-oriented method, see +[nvim-example-python-plugin](https://github.com/jacobsimpson/nvim-example-python-plugin) + ## Screenshots Simple message text message under the status bar. From a6a3a58bb7a94023ff1608c0a1ad142e32a45ef9 Mon Sep 17 00:00:00 2001 From: Randy West Date: Thu, 15 Sep 2022 19:54:46 -0700 Subject: [PATCH 29/30] Don't guess branch if not specified explicitly --- rplugin/python3/outdatedplugins.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rplugin/python3/outdatedplugins.py b/rplugin/python3/outdatedplugins.py index 48d91bd..924f6ad 100644 --- a/rplugin/python3/outdatedplugins.py +++ b/rplugin/python3/outdatedplugins.py @@ -38,8 +38,8 @@ def check_for_updates(self, args: List): for plug in g_plugs.values(): update_commands.append("git -C %s remote update > /dev/null" % plug["dir"]) calculate_updates_commands.append( - "git -C %s rev-list HEAD..origin/%s --count" - % (plug["dir"], plug["branch"] if plug["branch"] else "master") + "git -C %s rev-list HEAD..origin%s%s --count" + % (plug["dir"], "/" if plug["branch"] else "", plug["branch"]) ) update_commands.append("wait") From 7a740657a81101964e9bc4c0648a768ab2c8c45f Mon Sep 17 00:00:00 2001 From: Randy West Date: Thu, 3 Aug 2023 18:08:56 -0700 Subject: [PATCH 30/30] Use echom instead of echo to print messages --- rplugin/python3/outdatedplugins.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rplugin/python3/outdatedplugins.py b/rplugin/python3/outdatedplugins.py index 924f6ad..6fc828f 100644 --- a/rplugin/python3/outdatedplugins.py +++ b/rplugin/python3/outdatedplugins.py @@ -61,11 +61,11 @@ def check_for_updates(self, args: List): ) if plugs_to_update > 0: - self.vim.command(f"echo 'Plugins to update: {plugs_to_update}'") + self.vim.command(f"echom 'Plugins to update: {plugs_to_update}'") if g_outdated_plugins_trigger_mode: self.vim.command("PlugUpdate") elif not g_outdated_plugins_silent_mode: - self.vim.command("echo 'All plugins up-to-date'") + self.vim.command("echom 'All plugins up-to-date'") def get_default(self, var: str, default: Any) -> Any: """