Commits

sirex  committed 8af2072

Code refactoring and added some new features:

* Python 3 support

* Automatically checks if pathogen is installed, if not installs it
automatically.

* Checks if pathogen is configure correctly.

* Plug-in list now must be listed at the top of ~/.vimrc file and has new
syntax::

" plugin: git git://repo.or.cz/vcscommand.git vcscommand

* README file converted to reStructuredText format.

  • Participants
  • Parent commits 8948d3e

Comments (0)

Files changed (4)

+syntax: glob
+
+*.swp

File README

--*- markdown -*-
-
-Alpha software! Like, alpha alpha, you know ;)
-
-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` 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):
-
-	" Bundle: git://github.com/tpope/vim-pathogen.git
-
-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.
-
-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
-
-    " Bundle: my-strange-url-from-which-no-one-can-tell-the-vcs with git
-
-There, that `with git` in the end is what tells Vimpire what vcs to use. Neat eh?
-
-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,
-
-    " Bundle: git://github.com/tpope/vim-pathogen.git to super-plugin
-
-And this will cause the pathogen plugin to be cloned to `bundle/super-plugin` instead of
-`bundle/vim-pathogen`.
-
-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.
-
-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 ;).
-
-Now, navigate to your vimfiles or dotvim directory and do
-
-	$ wget http://bitbucket.org/sharat87/vimpire/raw/tip/vimpire.py
-	$ python 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 command will be run
-with the plugin's directory as the pwd. For example, to 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.
-
-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.
-
-Report any issues whatsoever :)
+Alpha software! Like, alpha alpha, you know ;)
+
+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`` 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)::
+
+    " Bundle: git://github.com/tpope/vim-pathogen.git
+
+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.
+
+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::
+
+    " Bundle: my-strange-url-from-which-no-one-can-tell-the-vcs with git
+
+There, that ``with git`` in the end is what tells Vimpire what vcs to use. Neat
+eh?
+
+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,::
+
+    " Bundle: git://github.com/tpope/vim-pathogen.git to super-plugin
+
+And this will cause the pathogen plugin to be cloned to ``bundle/super-plugin``
+instead of ``bundle/vim-pathogen``.
+
+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.
+
+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 ;).
+
+Now, navigate to your vimfiles or dotvim directory and do::
+
+    $ wget http://bitbucket.org/sharat87/vimpire/raw/tip/vimpire.py $
+    python 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
+command will be run with the plugin's directory as the pwd. For example, to
+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.
+
+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.
+
+Report any issues whatsoever :)
-#!/usr/bin/python
-#-*- coding:utf-8 -*-
+#!/usr/bin/env python3
 
-import re, os, sys
-import subprocess as sp
-import shutil as sh
+import os
+import re
 
-# The current working directory is assumed to be the dotvim directory, if none
-# is provided on the command line
+from os.path import exists, expanduser, join, basename
+from subprocess import check_call
+from urllib.request import urlretrieve
 
-vimfiles_dir = sys.argv[1] if len(sys.argv) > 1 else (os.getenv('VIMFILES') or os.getenv('DOTVIM'))
-if vimfiles_dir:
-    os.chdir(vimfiles_dir)
+HOME = expanduser('~')
 
-bundles_file = 'vimrc'
-bundle_dir = 'bundle'
+VIMRC = join(HOME, '.vimrc')
+VIMRUNTIME = join(HOME, '.vim')
+AUTOLOAD = join(VIMRUNTIME, 'autoload')
+BUNDLE_DIR = join(VIMRUNTIME, 'bundle')
 
-with open(bundles_file) as f:
-    bundles_file_lines = f.read().splitlines()
+PATHOGEN = 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+)?')
+
+
+def sh(cmd, *args, **kwargs):
+    print('Executing: %s' % ' '.join(cmd))
+    check_call(cmd, *args, **kwargs)
+
+
+def check_env():
+    if not os.path.exists(PATHOGEN):
+        if not os.path.exists(AUTOLOAD):
+            os.makedirs(AUTOLOAD)
+        print('Installing pathogen.vim...')
+        urlretrieve(PATHOGEN_URL, PATHOGEN)
+
+    if not os.path.exists(BUNDLE_DIR):
+        os.makedirs(BUNDLE_DIR)
+
+
+def get_plugins(extra_lines=5):
+    plugins = []
+    read_more = extra_lines
+    pathogen_found = False
+    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
+            elif line.startswith('call pathogen#infect'):
+                pathogen_found = True
+
+            if read_more <= 0:
+                break
+
+            read_more -= 1
+
+    if not pathogen_found:
+        raise Exception('It seems, that pathogen is not configured.\n'
+                        'Make sure, that you have\n'
+                        '\n'
+                        '    call pathogen#infect()\n'
+                        '\n'
+                        'line at the top of your ~/.vimrc file.\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():
-    if not os.path.exists(bundle_dir):
-        os.mkdir(bundle_dir)
-    os.chdir(bundle_dir)
+    plugins = get_plugins()
+    check_env()
 
-    plugin_dirs = []
-    bundles = []
-    in_bundle_context = False
+    handlers = {
+        'git': handle_git,
+    }
 
-    for line in bundles_file_lines:
-        m = re.match(r'^\s*"\s*(\w+)(!?):(!?)\s*(.*)$', line, re.I)
-        if not m: continue
-        tline = TagLine(*m.groups())
-        if tline.name == 'bundle':
-            bundle = Bundle(tline)
-            bundles.append(bundle)
-            in_bundle_context = True
-        elif in_bundle_context:
-            bundle.add_tline(tline)
-        else:
-            in_bundle_context = False
+    os.chdir(BUNDLE_DIR)
 
-    for bundle in bundles:
-        bundle.apply()
-        plugin_dirs.append(bundle.dest_dir)
+    installed_plugins = []
+    for plugin in plugins:
+        args = list(plugin)
+        handler = handlers[args.pop(0)]
+        if handler(*args):
+            installed_plugins.append(args[0])
 
-    print '-' * 35
+    # Update help tags
+    if len(installed_plugins):
+        sh(['vim', '-c', 'Helptags', '-c', 'q'])
 
-    for dirname in (d for d in os.listdir('.') if d not in plugin_dirs):
-        print 'Deleting plugin', dirname
-        sh.rmtree(dirname)
-
-class TagLine(object):
-
-    def __init__(self, name, bang1, bang2, line):
-        self.name = name.lower()
-        self.is_bang = bool(bang1 or bang2)
-        self.line = line
-
-
-class Bundle(object):
-
-    def __init__(self, tline):
-        self.name = tline.name
-        self.is_bang = tline.is_bang
-        self.line = tline.line
-
-        self.cmds = []
-
-    def add_tline(self, tline):
-        if tline.name in 'run command cmd'.split():
-            self.cmds.append(tline.line)
-
-    def apply(self):
-        self.url = url = self.line.split()[0]
-        arg = self.line.lstrip(url)
-
-        # Detect the vcs to use
-        vcs_match = re.search(r'with\s+(\w+)', arg)
-        if vcs_match:
-            vcs = vcs_match.group(1)
-        elif 'bitbucket.org' in url or 'googlecode.com/hg' in url:
-            vcs = 'hg'
-        elif url.startswith('git:') or 'github.com' in url:
-            vcs = 'git'
-        elif url.startswith('svn:'):
-            vcs = 'svn'
-        else:
-            vcs = None
-            print 'Unable to detect vcs for', url
-        self.vcs = vcs
-
-        # Detect the plugin directory to clone/checkout into
-        dest_dir_match = re.search(r'to\s+(\w+)', arg)
-        if dest_dir_match:
-            dest_dir = dest_dir_match.group(1)
-        else:
-            dest_dir = url.split('/')[-1]
-        if dest_dir.endswith('.' + vcs):
-            dest_dir = dest_dir[:-(1 + len(vcs))]
-        self.dest_dir = dest_dir
-
-        # Check if requesting force clone
-        self.force_clone = ' force clone' in arg
-        if self.force_clone:
-            sh.rmtree(self.dest_dir)
-
-        # Detect if any subdirectory contains the vim plugin
-        subdir_match = re.search(r'only\s+"(.+?)"', arg)
-        self.subdir = subdir_match.group(1) if subdir_match else None
-
-        if vcs is not None:
-            print ('!' if self.is_bang else '-') * 20, self.dest_dir
-            getattr(self, '_vcs_' + vcs)()
-
-    def _run_cmds(self):
-        previous_pwd = os.path.abspath('.')
-        in_dest_dir = False
-        if os.path.exists(self.dest_dir):
-            os.chdir(self.dest_dir)
-            in_dest_dir = True
-        for cmd in self.cmds:
-            print cmd
-            if cmd.startswith('cd'):
-                os.chdir(cmd[2:].strip(' "'))
-            else:
-                sp.call(cmd, shell=True)
-            if not in_dest_dir and os.path.exists(self.dest_dir):
-                os.chdir(self.dest_dir)
-                in_dest_dir = True
-        os.chdir(previous_pwd)
-
-    def _vcs_hg(self):
-        self.cmds.insert(0, 'hg ' + ('fetch' if os.path.exists(self.dest_dir) else 'clone ' + self.url))
-        #self.cmds += ['mv "' + self.subdir + '" /tmp/_vimpire_tmp', 'rm ]
-        self._run_cmds()
-
-    def _vcs_git(self):
-        self.cmds.insert(0, 'git ' + ('pull' if os.path.exists(self.dest_dir) else 'clone ' + self.url))
-        self._run_cmds()
 
 if __name__ == '__main__':
     main()