Commits

sirex committed 0e07428

Added possibility to install directly from vim.org, added uninstall feature.

Comments (0)

Files changed (2)

-Alpha software! Like, alpha alpha, you know ;)
+This is a script that manages plugins hosted on git, hg or vim.org and make
+them available to pathogen, so it make your vim ever the more awesome!
 
-This is a script that manages plugins hosted on git or hg and make them
-available to pathogen, so it make your vim ever the more awesome!
+First off, this script assumes you have a file called ``~/.vimrc`` file. In
+that file, put lines like the following, (one for each plugin you want)::
 
-First off, this script assumes you have a file called ``vimrc`` in your dotvim
-directory, which might as well be linked to your ``~/.vimrc`` file. In that
-file, put lines like the following, (one for each plugin you want)::
+    " plugin: name type path
 
-    " Bundle: git://github.com/tpope/vim-pathogen.git
+Where:
 
-Note: You'll anyway need the above line at least, you of course need pathogen,
-silly.  Note: You can get github links from http://vim-scripts.org for plugins
-that don't offer sane deployment options.
+name
+    is plugin name.
 
-Add any number such bundle lines with various plugins. Vimpire will try to
-guess the vcs from git or hg, and is correct most of the time, but if you want
-to specify it yourself, do so as::
+type
+    plugin type, supported types are these: hg, git, vim
 
-    " Bundle: my-strange-url-from-which-no-one-can-tell-the-vcs with git
+path
+    this is type dependent path to plugin.
 
-There, that ``with git`` in the end is what tells Vimpire what vcs to use. Neat
-eh?
+Examples::
 
-You can also decide what folder the plugin will be cloned to, by using the
-``to`` option in a similar way to the ``with`` option as described above. For
-example,::
+    " plugin: bufexplorer vim http://www.vim.org/scripts/script.php?script_id=42
+    map     <F3>        :BufExplorer<CR>
 
-    " Bundle: git://github.com/tpope/vim-pathogen.git to super-plugin
+    " plugin: vcscommand git git://repo.or.cz/vcscommand.git
 
-And this will cause the pathogen plugin to be cloned to ``bundle/super-plugin``
-instead of ``bundle/vim-pathogen``.
+    " plugin: pyflakes git git://github.com/kevinw/pyflakes-vim.git
 
-If, for some reason, you don't want to pull/fetch, but clone every time
-instead, you can add ``force clone`` to the end of the bundle line. This is
-useful, if you are messing up the plugin's directory using the commands in
-``Run`` directives, described below.
+Note: You can get github links from http://vim-scripts.org for plugins that
+don't offer sane deployment options.
 
-And of course, you can have a line with both the ``with`` and the ``to``
-options, along with any other that might be added in the future ;).
+Add any number such bundle lines with various plugins.
 
 Now, navigate to your vimfiles or dotvim directory and do::
 
-    $ wget http://bitbucket.org/sharat87/vimpire/raw/tip/vimpire.py $
-    python vimpire.py
+    $ wget http://bitbucket.org/sharat87/vimpire/raw/tip/vimpire.py
+    $ python3 vimpire.py
 
-You may also include a ``Run`` directive below the ``Bundle`` directive to run
-a command after getting/updating the corresponding bundle. Note that this
+You may also include a ``run`` directive below ``plugin`` directive that will
+be executed after getting/updating the corresponding bundle. Note that this
 command will be run with the plugin's directory as the pwd. For example, to
-compile Command-T plugin,::
+compile Command-T plugin::
 
-    " Bundle: git://github.com/tpope/vim-pathogen.git " Run: cd ruby/command-t
-    " Run: ruby extconf.rb && make
-
-Note: If a run directive points to a ``cd`` command, like the 2nd line above,
-it is not sent to the shell. It is natively interpreted by vimpire, and does
-NOT have all the advanced functionality of the ``cd`` command in a shell. So,
-things like ``cd -`` do not work.  This should not affect for most users,
-though.
+    " plugin: command-t git git://git.wincent.com/command-t.git
+    " run: (cd ruby/command-t ; ruby extconf.rb && make)
 
 If a bundle entry is deleted, or a directory exists in the bundle directory,
-without a corresponding entry in the vimrc file, it will be deleted. Deleting
-plugins is still experimental, but if it does not work, you may manually delete
-the plugin directory in the bundle directory.
+without a corresponding entry in the vimrc file, it will be deleted.
 
 Report any issues whatsoever :)
 import os
 import re
 
-from os.path import exists, expanduser, join, basename
+from os.path import exists, expanduser, join, basename, splitext, isdir
 from subprocess import check_call
-from urllib.request import urlretrieve
+from urllib.request import urlretrieve, urlopen
+from zipfile import ZipFile
 
 HOME = expanduser('~')
 
 AUTOLOAD = join(VIMRUNTIME, 'autoload')
 BUNDLE_DIR = join(VIMRUNTIME, 'bundle')
 
-PATHOGEN = join(AUTOLOAD, 'pathogen.vim')
+PATHOGEN_DIR = join(AUTOLOAD, 'pathogen.vim')
 PATHOGEN_URL = ('https://raw.github.com/tpope/vim-pathogen'
                 '/HEAD/autoload/pathogen.vim')
 
-PLUGIN_RE = re.compile(r'" plugin: (ht|git|svn|vim) (\S+) ?(\S+)?')
+PLUGIN_RE = re.compile(r'" plugin: (\S+) (ht|git|svn|vim|zip) (\S+)')
 
 
 def sh(cmd, *args, **kwargs):
-    print('Executing: %s' % ' '.join(cmd))
+    if isinstance(cmd, str):
+        print('Executing: %s' % cmd)
+    else:
+        print('Executing: %s' % ' '.join(cmd))
     check_call(cmd, *args, **kwargs)
 
 
 def check_env():
-    if not os.path.exists(PATHOGEN):
+    if not os.path.exists(PATHOGEN_DIR):
         if not os.path.exists(AUTOLOAD):
             os.makedirs(AUTOLOAD)
         print('Installing pathogen.vim...')
-        urlretrieve(PATHOGEN_URL, PATHOGEN)
+        urlretrieve(PATHOGEN_URL, PATHOGEN_DIR)
 
     if not os.path.exists(BUNDLE_DIR):
         os.makedirs(BUNDLE_DIR)
 
 
-def get_plugins(extra_lines=5):
+class Plugin(object):
+    def __init__(self, name, handler, path):
+        self.name = name
+        self.handler = handler
+        self.path = path
+        self.run = []
+
+    def handle_hg(self):
+        sh(['hg', 'clone', self.path, self.name])
+
+    def handle_git(self):
+        sh(['git', 'clone', self.path, self.name])
+
+    def handle_vim(self):
+        with urlopen(self.path) as f:
+            content = f.read().decode('ISO-8859-1')
+        m = re.search(r'download_script\.php\?src_id=\d+', content)
+        if m is None:
+            raise Exception("Can't find vim script to download.")
+        filename, headers = urlretrieve('http://www.vim.org/scripts/' + m.group(0))
+        ext = splitext(headers.get_filename())[1].replace('.', '')
+        with ZipFile(filename) as f:
+            f.extractall(self.name)
+
+    def get_handler(self):
+        return getattr(self, 'handle_%s' % self.handler)
+
+    def install(self):
+        if exists(join(BUNDLE_DIR, self.name)):
+            print('plugin: %s (alreading installed)' % self.name)
+        else:
+            print('plugin: %s installing...' % self.name)
+            handler = self.get_handler()
+            handler()
+
+            if self.run:
+                cwd = os.getcwd()
+                os.chdir(self.name)
+                for cmd in self.run:
+                    sh(cmd, shell=True)
+                os.chdir(cwd)
+
+            print('  ... installed.\n')
+
+
+def get_plugins():
     plugins = []
-    read_more = extra_lines
-    pathogen_found = False
+    pathogen_not_found = True
     with open(VIMRC) as f:
         for line in f:
             if line.startswith('" plugin: '):
                 m = PLUGIN_RE.match(line)
                 if m:
-                    plugins.append(m.groups())
-                    read_more = extra_lines
+                    name, handler, path = m.groups()
+                    plugin = Plugin(name, handler, path)
+                    plugins.append(plugin)
+
+            elif line.startswith('" run: ') and plugin is not None:
+                cmd = line[len('" run: '):]
+                plugin.run.append(cmd)
+
             elif line.startswith('call pathogen#infect'):
-                pathogen_found = True
+                pathogen_not_found = False
+                plugin = None
 
-            if read_more <= 0:
-                break
+            else:
+                plugin = None
 
-            read_more -= 1
-
-    if not pathogen_found:
+    if pathogen_not_found:
         raise Exception('It seems, that pathogen is not configured.\n'
                         'Make sure, that you have\n'
                         '\n'
     return plugins
 
 
-def handle_git(path, name):
-    if name is None:
-        if path.endswith('.git'):
-            name = basename(path)[:-4]
-        else:
-            name = basename(path)
-
-    if not exists(join(BUNDLE_DIR, name)):
-        sh(['git', 'clone', path, name])
-        return True
-
-    return False
-
-        
 def main():
     plugins = get_plugins()
     check_env()
-
-    handlers = {
-        'git': handle_git,
-    }
-
     os.chdir(BUNDLE_DIR)
 
+    update_help_tags = False
     installed_plugins = []
+
+    # Install/update plugins
     for plugin in plugins:
-        args = list(plugin)
-        handler = handlers[args.pop(0)]
-        if handler(*args):
-            installed_plugins.append(args[0])
+        installed_plugins.append(plugin.name)
+        if plugin.install():
+            update_help_tags = True
+
+    # Uninstall removed plugins
+    for name in os.listdir(BUNDLE_DIR):
+        path = join(BUNDLE_DIR, name)
+        if isdir(path) and name not in installed_plugins:
+            print('plugin: %s uninstalling...' % name)
+            sh(['rm', '-rf', path])
+            print('  ... uninstalled.\n')
+            update_help_tags = True
 
     # Update help tags
-    if len(installed_plugins):
+    if update_help_tags:
         sh(['vim', '-c', 'Helptags', '-c', 'q'])