public
Last active

Vim auto-split wrapper

  • Download Gist
vimsp.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
#!/usr/bin/env python
 
"""
Automatically create split windows in vim like so:
vimsp.py col1row1 col2row1 / col1row2 col2row2
"""
 
def neighborhood(iterable):
iterator = iter(iterable)
prev = None
item = iterator.next() # throws StopIteration if empty.
for next in iterator:
yield (prev,item,next)
prev = item
item = next
yield (prev,item,None)
 
HSPLIT,VSPLIT = 'split','vsplit'
def hsplit(file): return HSPLIT+' '+file
def vsplit(file): return VSPLIT+' '+file
 
import sys
files = sys.argv[1:]
 
numlines = files.count('/')
if numlines == 1 and files[0] == '/':
# make all hsplits into vsplits
oldfiles = files[1:]
files = []
for file in oldfiles:
files.append(file)
files.append('/')
files = files[:-1] # remove the last /
numlines = len(oldfiles)
 
args = ['vim'] #,'-c','set splitright']
 
# split top-down first
# each split goes up and opens that file there
for prev, file, next in neighborhood(files):
if next and next=='/': # last file of a line
args.extend(['-c','split %s' % file])
 
# then split left-right for each
# we're starting out in the top split
for prev, file, next in neighborhood(files):
if file=='/': # move down
args.extend(['-c','wincmd j'])
elif next and next!='/': # don't touch the last file
args.extend(['-c','vsplit %s' % file])
 
# move to the top
for i in range(numlines):
args.extend(['-c','wincmd k'])
 
# add last to the end of the args
if files[-1]!='/':
args.append(files[-1])
 
# filter out repeat and useless moves, just for clarity
import re
arg_match = re.compile('wincmd ([jk])')
dir_map = {'j':'k','k':'j'}
removes = []
for i, arg in enumerate(args):
if i in removes: continue
 
count = 1
pos = 1
m = arg_match.match(arg)
if m:
dir = m.groups()[0]
other = dir_map[dir]
while count and len(args)>i+count*2: # we have at least 2 more args left
nm = arg_match.match(args[i+pos*2])
if not nm: break
if nm.groups()[0]==other:
if count == 1:
removes.extend([i-1,i,i+1,i+2]) # remove the -c and the next arg too
break
else:
count -= 1 # this arg just undoes the latest arg
pos += 1
else:
count += 1
pos += 1
# remove the next two, change this one
removes.extend([i+1,i+2])
newarg = re.sub(r'\d*wincmd','%dwincmd' % count,arg)
args[i] = newarg
 
newargs = []
for i, arg in enumerate(args):
if i not in removes:
newargs.append(arg)
 
args = newargs
 
 
import subprocess
print args
subprocess.call(args)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.