├── LICENSE ├── README.md └── vpm /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Ismail Badawi 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vpm 2 | 3 | This is a tiny script I use to manage vim plugins installed from GitHub to be 4 | managed by [pathogen][]. 5 | 6 | You can use it like this: 7 | 8 | * `vpm ls` prints a list of installed plugins. 9 | * `vpm install url` installs one or more plugins from the given urls. You can 10 | also a pass GitHub user/repos as a shorthand 11 | (e.g. `vpm install tpope/vim-fugitive`). 12 | * `vpm update plugin` downloads any updates to the specified plugins, without 13 | applying them, and outputs the names of any outdated plugins. The incoming 14 | changes can then be inspected with `vpm incoming plugin`, or applied with 15 | `vpm upgrade plugin`. If no plugin is specified, all installed plugins are 16 | updated. 17 | * `vpm incoming plugin` provides a summary of any incoming (downloaded but 18 | unapplied) changes to the specified plugins. In particular, if the plugin 19 | originates from a GitHub repo, a link to the relevant compare view is 20 | provided. If no plugin is specified, incoming changes for all outdated 21 | plugins are summarized. 22 | * `vpm upgrade plugin` applies any incoming changes to the specified plugins. 23 | If no plugin is specified, all outdated plugins are upgraded. 24 | * `vpm uninstall plugin` uninstalls one or more plugins. 25 | * `vpm export` writes a shell script to stdout with vpm commands to install the 26 | currently installed plugins. 27 | 28 | Some example sessions: 29 | 30 | ``` 31 | $ vpm install tpope/vim-fugitive 32 | Installing vim-fugitive... 33 | ``` 34 | 35 | ``` 36 | $ vpm update 37 | vim-fugitive 38 | $ vpm incoming 39 | Can upgrade vim-fugitive from 5d1c219 to 90ee6fb: 40 | 5aaa657 Browse handler API 41 | 24d4098 Change arity of browse API 42 | 7423d72 Ensure clipboard support before using * register 43 | 04fe4bf Set nobuflisted in blame buffers 44 | 90ee6fb Pass line1 and line2 as 0 for :Gbrowse without range 45 | View changes on GitHub: https://github.com/tpope/vim-fugitive/compare/5d1c219...90ee6fb 46 | $ vpm upgrade 47 | Upgraded vim-fugitive to 90ee6fb. 48 | ``` 49 | 50 | ### Installation 51 | 52 | The `vpm` script is relatively standalone (the only dependency is git), so just 53 | stick it somewhere on your `$PATH`. You can download it [from this URL][raw], 54 | or clone this repo and create a symlink. 55 | 56 | ### Why use this as opposed to [Vundle][]? 57 | 58 | Vundle has more features, is integrated with vim, has been around longer, is 59 | actively maintained, etc. By contrast, this is a small shell script I largely 60 | threw together in an afternoon, and I am the only user so far (let me know when 61 | this isn't true anymore!). 62 | 63 | My initial motivation for writing this was that I didn't want to have to 64 | declare anything in my `.vimrc` like Vundle makes you do. I don't really have a 65 | good argument against this practice though. I just don't like the aesthetic. 66 | 67 | ### Dealing with non-git plugins 68 | 69 | This script assumes all the plugins under `$HOME/.vim/bundle` are git repos. 70 | For plugins that aren't, I use a separate bundle directory that I manage 71 | manually. pathogen supports multiple bundle directories; my `.vimrc` starts 72 | with: 73 | 74 | ``` 75 | execute pathogen#infect('bundle/{}', 'bundle-manual/{}') 76 | ``` 77 | 78 | ### License 79 | MIT 80 | 81 | [raw]: https://raw.githubusercontent.com/isbadawi/vpm/master/vpm 82 | [pathogen]: https://github.com/tpope/vim-pathogen 83 | [Vundle]: https://github.com/gmarik/Vundle.vim 84 | -------------------------------------------------------------------------------- /vpm: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | function vpm_plugin_dir { 5 | echo "$HOME/.vim/bundle/$1" 6 | } 7 | 8 | function vpm_plugin_exists { 9 | [ -d "$(vpm_plugin_dir $1)" ] 10 | } 11 | 12 | function vpm_plugin_git { 13 | local plugin_dir=$(vpm_plugin_dir $1) 14 | git --no-pager --git-dir="$plugin_dir/.git" --work-tree="$plugin_dir" "${@:2}" 15 | } 16 | 17 | function vpm_plugin_fetch_update { 18 | vpm_plugin_git $1 fetch --quiet origin master 19 | } 20 | 21 | function vpm_plugin_version { 22 | vpm_plugin_git $1 rev-parse --short HEAD 23 | } 24 | 25 | function vpm_plugin_is_outdated { 26 | [ -n "$(vpm_plugin_git $1 log HEAD..origin/master --oneline)" ] 27 | } 28 | 29 | function vpm_plugin_url { 30 | vpm_plugin_git $1 config --get remote.origin.url 31 | } 32 | 33 | function vpm_plugin_whatchanged { 34 | local old_head=$(vpm_plugin_git $1 rev-parse --short HEAD) 35 | local new_head=$(vpm_plugin_git $1 rev-parse --short origin/master) 36 | echo "Can upgrade $1 from $old_head to $new_head:" 37 | vpm_plugin_git $1 log --reverse --oneline $old_head...$new_head 38 | 39 | local url=$(vpm_plugin_url $1) 40 | if [[ $url == *github.com* ]]; then 41 | local repo=$(echo $url | sed -e 's/^.*github.com.//' | sed -e 's/.git$//') 42 | local compare_url="https://github.com/$repo/compare/$old_head...$new_head" 43 | echo "View changes on GitHub: $compare_url" 44 | fi 45 | } 46 | 47 | function vpm_ls { 48 | ls -G $(vpm_plugin_dir) 49 | } 50 | 51 | function vpm_install { 52 | for spec in "$@"; do 53 | local plugin_name="$(basename $spec | sed -e 's/.git$//')" 54 | if vpm_plugin_exists "$plugin_name"; then 55 | echo 1>&2 "Plugin already installed: $plugin_name" 56 | return 57 | fi 58 | echo "Installing $plugin_name..." 59 | local plugin_url 60 | if [[ "$spec" =~ ^[a-zA-Z0-9_-]+/[a-zA-Z0-9_\.-]+$ ]]; then 61 | plugin_url="https://github.com/$spec" 62 | else 63 | plugin_url=$spec 64 | fi 65 | git clone --quiet $plugin_url $(vpm_plugin_dir $plugin_name) 66 | done 67 | } 68 | 69 | function vpm_existing_plugins { 70 | local plugins="$@" 71 | if [ $# -eq 0 ]; then 72 | plugins="$(vpm ls)" 73 | fi 74 | for plugin in $plugins; do 75 | if vpm_plugin_exists "$plugin"; then 76 | echo $plugin 77 | else 78 | echo 1>&2 "No such plugin: $plugin" 79 | exit 1 80 | fi 81 | done 82 | } 83 | 84 | function vpm_outdated_plugins { 85 | for plugin in $(vpm_existing_plugins "$@"); do 86 | if vpm_plugin_is_outdated "$plugin"; then 87 | echo $plugin 88 | fi 89 | done 90 | } 91 | 92 | function vpm_update { 93 | for plugin in $(vpm_existing_plugins "$@"); do 94 | vpm_plugin_fetch_update "$plugin" 95 | if vpm_plugin_is_outdated "$plugin"; then 96 | echo $plugin 97 | fi 98 | done 99 | } 100 | 101 | function vpm_upgrade { 102 | for plugin in $(vpm_outdated_plugins "$@"); do 103 | vpm_plugin_git $plugin merge --ff-only --quiet origin/master 104 | echo "Upgraded $plugin to $(vpm_plugin_version $plugin)." 105 | done 106 | } 107 | 108 | function vpm_uninstall { 109 | if [ $# -eq 0 ]; then 110 | return 111 | fi 112 | for plugin in $(vpm_existing_plugins "$@"); do 113 | echo "Uninstalling $plugin..." 114 | rm -rf "$(vpm_plugin_dir $plugin)" 115 | done 116 | } 117 | 118 | function vpm_incoming { 119 | for plugin in $(vpm_outdated_plugins "$@"); do 120 | vpm_plugin_whatchanged "$plugin" 121 | done 122 | } 123 | 124 | function vpm_export { 125 | echo "#!/bin/bash" 126 | for plugin in $(vpm_ls); do 127 | echo "vpm install $(vpm_plugin_url $plugin)" 128 | done 129 | } 130 | 131 | function main { 132 | if [[ $1 =~ ^(ls|install|uninstall|update|incoming|upgrade|export)$ ]]; then 133 | eval "vpm_$1 ${@:2}" 134 | else 135 | echo "usage: vpm ls 136 | vpm install user/repo 137 | vpm uninstall plugin 138 | vpm update [plugin] 139 | vpm incoming [plugin] 140 | vpm upgrade [plugin] 141 | vpm export" 142 | fi 143 | } 144 | 145 | main "$@" 146 | --------------------------------------------------------------------------------