# HG changeset patch # User Steve Losh # Date 1309297737 14400 # Node ID cefc901de8a29a2eeca01bb06a94bdcb81ee3412 # Parent 4995b244e11d5aaa9956bba061c32140e6af8705 Factor out a bunch of stuff into autoload/. diff -r 4995b244e11d -r cefc901de8a2 autoload/threesome.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autoload/threesome.py Tue Jun 28 17:48:57 2011 -0400 @@ -0,0 +1,73 @@ +import vim, os, sys + + +# Add the library to the Python path. +for p in vim.eval("&runtimepath").split(','): + plugin_dir = os.path.join(p, "autoload") + if os.path.exists(os.path.join(plugin_dir, "threesomelib")): + if plugin_dir not in sys.path: + sys.path.append(plugin_dir) + break + + +import threesomelib.init as threesome + +# Wrapper functions ---------------------------------------------------------------- + +def ThreesomeInit(): + threesome.init() + + +def ThreesomeOriginal(): + threesome.modes.current_mode.key_original() + +def ThreesomeOne(): + threesome.modes.current_mode.key_one() + +def ThreesomeTwo(): + threesome.modes.current_mode.key_two() + +def ThreesomeResult(): + threesome.modes.current_mode.key_result() + + +def ThreesomeGrid(): + threesome.modes.key_grid() + +def ThreesomeLoupe(): + threesome.modes.key_loupe() + +def ThreesomeCompare(): + threesome.modes.key_compare() + +def ThreesomePath(): + threesome.modes.key_path() + + +def ThreesomeDiff(): + threesome.modes.current_mode.key_diff() + +def ThreesomeDiffoff(): + threesome.modes.current_mode.key_diffoff() + +def ThreesomeScroll(): + threesome.modes.current_mode.key_scrollbind() + +def ThreesomeLayout(): + threesome.modes.current_mode.key_layout() + +def ThreesomeNext(): + threesome.modes.current_mode.key_next() + +def ThreesomePrev(): + threesome.modes.current_mode.key_prev() + +def ThreesomeUse(): + threesome.modes.current_mode.key_use() + +def ThreesomeUse1(): + threesome.modes.current_mode.key_use1() + +def ThreesomeUse2(): + threesome.modes.current_mode.key_use2() + diff -r 4995b244e11d -r cefc901de8a2 autoload/threesome.vim --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autoload/threesome.vim Tue Jun 28 17:48:57 2011 -0400 @@ -0,0 +1,155 @@ +" ============================================================================ +" File: threesome.vim +" Description: vim global plugin for resolving three-way merge conflicts +" Maintainer: Steve Losh +" License: MIT X11 +" Notes: Alpha. Not ready for real use yet. +" +" ============================================================================ + +"{{{ Init + +" Vim version check {{{ + +if v:version < '703' + function! s:ThreesomeDidNotLoad() + echohl WarningMsg|echomsg "Threesome unavailable: requires Vim 7.3+"|echohl None + endfunction + command! -nargs=0 ThreesomeInit call s:ThreesomeDidNotLoad() + finish +endif + +"}}} +" Python version check {{{ + +if has('python') + let s:has_supported_python = 2 +python << ENDPYTHON +import sys, vim +if sys.version_info[:2] < (2, 5): + vim.command('let s:has_supported_python = 0') +ENDPYTHON +else + let s:has_supported_python = 0 +endif + +if !s:has_supported_python + function! s:ThreesomeDidNotLoad() + echohl WarningMsg|echomsg "Threesome requires Vim to be compiled with Python 2.5+"|echohl None + endfunction + command! -nargs=0 ThreesomeInit call s:ThreesomeDidNotLoad() + finish +endif + +"}}} +" Configuration variables {{{ + +if !exists('g:threesome_disable') " {{{ + let g:threesome_disable = 0 +endif " }}} +if !exists('g:threesome_initial_mode') " {{{ + let g:threesome_initial_mode = 'grid' +endif " }}} +if !exists('g:threesome_initial_layout_grid') " {{{ + let g:threesome_initial_layout_grid = 0 +endif " }}} +if !exists('g:threesome_initial_layout_loupe') " {{{ + let g:threesome_initial_layout_loupe = 0 +endif " }}} +if !exists('g:threesome_initial_layout_compare') " {{{ + let g:threesome_initial_layout_compare = 0 +endif " }}} +if !exists('g:threesome_initial_layout_path') " {{{ + let g:threesome_initial_layout_path = 0 +endif " }}} +if !exists('g:threesome_initial_diff_grid') " {{{ + let g:threesome_initial_diff_grid = 0 +endif " }}} +if !exists('g:threesome_initial_diff_loupe') " {{{ + let g:threesome_initial_diff_loupe = 0 +endif " }}} +if !exists('g:threesome_initial_diff_compare') " {{{ + let g:threesome_initial_diff_compare = 0 +endif " }}} +if !exists('g:threesome_initial_diff_path') " {{{ + let g:threesome_initial_diff_path = 0 +endif " }}} +if !exists('g:threesome_initial_scrollbind_grid') " {{{ + let g:threesome_initial_scrollbind_grid = 0 +endif " }}} +if !exists('g:threesome_initial_scrollbind_loupe') " {{{ + let g:threesome_initial_scrollbind_loupe = 0 +endif " }}} +if !exists('g:threesome_initial_scrollbind_compare') " {{{ + let g:threesome_initial_scrollbind_compare = 0 +endif " }}} +if !exists('g:threesome_initial_scrollbind_path') " {{{ + let g:threesome_initial_scrollbind_path = 0 +endif " }}} + +"}}} + +"}}} +"{{{ Wrappers + +function! threesome#ThreesomeInit()"{{{ + let python_module = fnameescape(globpath(&runtimepath, 'autoload/threesome.py')) + exe 'pyfile ' . python_module + python ThreesomeInit() +endfunction"}}} + +function! threesome#ThreesomeGrid()"{{{ + python ThreesomeGrid() +endfunction"}}} +function! threesome#ThreesomeLoupe()"{{{ + python ThreesomeLoupe() +endfunction"}}} +function! threesome#ThreesomeCompare()"{{{ + python ThreesomeCompare() +endfunction"}}} +function! threesome#ThreesomePath()"{{{ + python ThreesomePath() +endfunction"}}} + +function! threesome#ThreesomeOriginal()"{{{ + python ThreesomeOriginal() +endfunction"}}} +function! threesome#ThreesomeOne()"{{{ + python ThreesomeOne() +endfunction"}}} +function! threesome#ThreesomeTwo()"{{{ + python ThreesomeTwo() +endfunction"}}} +function! threesome#ThreesomeResult()"{{{ + python ThreesomeResult() +endfunction"}}} + +function! threesome#ThreesomeDiff()"{{{ + python ThreesomeDiff() +endfunction"}}} +function! threesome#ThreesomeDiffoff()"{{{ + python ThreesomeDiffoff() +endfunction"}}} +function! threesome#ThreesomeScroll()"{{{ + python ThreesomeScroll() +endfunction"}}} +function! threesome#ThreesomeLayout()"{{{ + python ThreesomeLayout() +endfunction"}}} +function! threesome#ThreesomeNext()"{{{ + python ThreesomeNext() +endfunction"}}} +function! threesome#ThreesomePrev()"{{{ + python ThreesomePrev() +endfunction"}}} +function! threesome#ThreesomeUse()"{{{ + python ThreesomeUse() +endfunction"}}} +function! threesome#ThreesomeUse1()"{{{ + python ThreesomeUse1() +endfunction"}}} +function! threesome#ThreesomeUse2()"{{{ + python ThreesomeUse2() +endfunction"}}} + +"}}} diff -r 4995b244e11d -r cefc901de8a2 autoload/threesomelib/__init__.py diff -r 4995b244e11d -r cefc901de8a2 autoload/threesomelib/init.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autoload/threesomelib/init.py Tue Jun 28 17:48:57 2011 -0400 @@ -0,0 +1,106 @@ +import vim +import modes +from settings import setting +from util import buffers, keys, windows + + +CONFLICT_MARKER_START = '<<<<<<<' +CONFLICT_MARKER_MARK = '=======' +CONFLICT_MARKER_END = '>>>>>>>' + +def process_result(): + windows.close_all() + buffers.result.open() + + lines = [] + in_conflict = False + for line in buffers.result.lines: + if in_conflict: + if CONFLICT_MARKER_MARK in line: + lines.append(line) + if CONFLICT_MARKER_END in line: + in_conflict = False + continue + + if CONFLICT_MARKER_START in line: + in_conflict = True + continue + + lines.append(line) + + buffers.result.set_lines(lines) + +def bind_global_keys(): + keys.bind('g', ':ThreesomeGrid') + keys.bind('l', ':ThreesomeLoupe') + keys.bind('c', ':ThreesomeCompare') + keys.bind('p', ':ThreesomePath') + + keys.bind('o', ':ThreesomeOriginal') + keys.bind('1', ':ThreesomeOne') + keys.bind('2', ':ThreesomeTwo') + keys.bind('r', ':ThreesomeResult') + + keys.bind('d', ':ThreesomeDiff') + keys.bind('D', ':ThreesomeDiffoff') + keys.bind('s', ':ThreesomeScroll') + keys.bind('n', ':ThreesomeNext') + keys.bind('N', ':ThreesomePrev') + keys.bind('', ':ThreesomeLayout') + keys.bind('u', ':ThreesomeUse') + + keys.bind('q', ':wa:qa') + keys.bind('CC', ':cq') + +def setlocal_buffers(): + buffers.original.open() + vim.command('setlocal noswapfile') + vim.command('setlocal nomodifiable') + if setting('wrap'): + vim.command('setlocal ' + setting('wrap')) + + buffers.one.open() + vim.command('setlocal noswapfile') + vim.command('setlocal nomodifiable') + if setting('wrap'): + vim.command('setlocal ' + setting('wrap')) + + buffers.two.open() + vim.command('setlocal noswapfile') + vim.command('setlocal nomodifiable') + if setting('wrap'): + vim.command('setlocal ' + setting('wrap')) + + buffers.result.open() + if setting('wrap'): + vim.command('setlocal ' + setting('wrap')) + + buffers.hud.open() + vim.command('setlocal noswapfile') + vim.command('setlocal nomodifiable') + vim.command('setlocal nobuflisted') + vim.command('setlocal buftype=nofile') + vim.command('setlocal noundofile') + vim.command('setlocal nolist') + vim.command('setlocal ft=threesome') + vim.command('setlocal nowrap') + vim.command('resize ' + setting('hud_size', '3')) + +def create_hud(): + vim.command('new __Threesome_HUD__') + + +def init(): + process_result() + create_hud() + setlocal_buffers() + bind_global_keys() + + initial_mode = setting('initial_mode', 'grid').lower() + if initial_mode not in ['grid', 'loupe', 'compare', 'path']: + initial_mode = 'grid' + + modes.current_mode = getattr(modes, initial_mode) + modes.current_mode.activate() + + diff -r 4995b244e11d -r cefc901de8a2 autoload/threesomelib/modes.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autoload/threesomelib/modes.py Tue Jun 28 17:48:57 2011 -0400 @@ -0,0 +1,904 @@ +from __future__ import with_statement + +import vim +from util import buffers, keys, windows +from settings import boolsetting, setting + + +current_mode = None + +class Mode(object): + def __init__(self): + return super(Mode, self).__init__() + + + def diff(self, diffmode): + with windows.remain(): + getattr(self, '_diff_%d' % diffmode)() + + # Reset the scrollbind to whatever it was before we diffed. + if not diffmode: + self.scrollbind(self._current_scrollbind) + + def key_diff(self, diffmode=None): + next_diff_mode = self._current_diff_mode + 1 + if next_diff_mode >= self._number_of_diff_modes: + next_diff_mode = 0 + self.diff(next_diff_mode) + + + def diffoff(self): + with windows.remain(): + for winnr in range(2, 2 + self._number_of_windows): + windows.focus(winnr) + curbuffer = buffers.current + + for buffer in buffers.all: + buffer.open() + vim.command('diffoff') + if setting('wrap'): + vim.command('setlocal ' + setting('wrap')) + + curbuffer.open() + + + def key_diffoff(self): + self.diff(0) + + + def scrollbind(self, enabled): + if self._current_diff_mode: + return + + with windows.remain(): + self._current_scrollbind = enabled + + for winnr in range(2, 2 + self._number_of_windows): + windows.focus(winnr) + + if enabled: + vim.command('set scrollbind') + else: + vim.command('set noscrollbind') + + if enabled: + vim.command('syncbind') + + def key_scrollbind(self): + self.scrollbind(not self._current_scrollbind) + + + def layout(self, layoutnr): + getattr(self, '_layout_%d' % layoutnr)() + self.diff(self._current_diff_mode) + self.redraw_hud() + + def key_layout(self, diffmode=None): + next_layout = self._current_layout + 1 + if next_layout >= self._number_of_layouts: + next_layout = 0 + self.layout(next_layout) + + + def key_original(self): + pass + + def key_one(self): + pass + + def key_two(self): + pass + + def key_result(self): + pass + + + def key_use(self): + pass + + + def activate(self): + self.layout(self._current_layout) + self.diff(self._current_diff_mode) + self.scrollbind(self._current_scrollbind) + + def deactivate(self): + pass + + + def key_next(self): + self.goto_result() + vim.command(r'exe "normal! /\=\=\=\=\=\=\=\"') + + def key_prev(self): + self.goto_result() + vim.command(r'exe "normal! ?\=\=\=\=\=\=\=\"') + + + def open_hud(self, winnr): + windows.split() + windows.focus(winnr) + buffers.hud.open() + vim.command('wincmd K') + self.redraw_hud() + + def hud_lines(self): + def pad(lines): + l = max([len(line) for line in lines]) + return [line.ljust(l) for line in lines] + + sep = ' | ' + + modes = pad([ + r'Threesome Modes', + r'x[G]rid y[C]ompare'.replace('x', self._id == 'grid' and '*' or ' ') + .replace('y', self._id == 'comp' and '*' or ' '), + r'x[L]oupe y[P]ath'.replace('x', self._id == 'loup' and '*' or ' ') + .replace('y', self._id == 'path' and '*' or ' '), + ]) + diagram = pad(self.hud_diagram()) + commands = pad([ + r'Threesome Commands', + r'd: cycle diffs n: next conflict space: cycle layouts', + r'D: diffs off N: prev conflict s: toggle scrollbind', + ]) + + lines = [] + for line in modes: + lines.append(line + sep) + for i, line in enumerate(diagram): + lines[i] += line + sep + for i, line in enumerate(commands): + lines[i] += line + sep + + for i, line in enumerate(lines): + lines[i] = line.rstrip() + + return lines + + def redraw_hud(self): + with windows.remain(): + windows.focus(1) + + vim.command('setlocal modifiable') + buffers.hud.set_lines(self.hud_lines()) + vim.command('setlocal nomodifiable') + + vim.command('set winfixheight') + vim.command('resize ' + setting('hud_size', '3')) + vim.command('wincmd =') + + +class GridMode(Mode): + """ + Layout 0 Layout 1 Layout 2 + +-------------------+ +--------------------------+ +---------------+ + | Original | | One | Result | Two | | One | + |2 | | | | | |2 | + +-------------------+ | | | | +---------------+ + | One | Two | | | | | | Result | + |3 |4 | | | | | |3 | + +-------------------+ | | | | +---------------+ + | Result | | | | | | Two | + |5 | |2 |3 |4 | |4 | + +-------------------+ +--------------------------+ +---------------+ + """ + + def __init__(self): + self._id = 'grid' + self._current_layout = int(setting('initial_layout_grid', 0)) + self._current_diff_mode = int(setting('initial_diff_grid', 0)) + self._current_scrollbind = boolsetting('initial_scrollbind_grid') + + self._number_of_diff_modes = 2 + self._number_of_layouts = 3 + + return super(GridMode, self).__init__() + + + def _layout_0(self): + self._number_of_windows = 4 + self._current_layout = 0 + + # Open the layout + windows.close_all() + windows.split() + windows.split() + windows.focus(2) + windows.vsplit() + + # Put the buffers in the appropriate windows + windows.focus(1) + buffers.original.open() + + windows.focus(2) + buffers.one.open() + + windows.focus(3) + buffers.two.open() + + windows.focus(4) + buffers.result.open() + + self.open_hud(5) + + windows.focus(5) + + def _layout_1(self): + self._number_of_windows = 3 + self._current_layout = 1 + + # Open the layout + windows.close_all() + windows.vsplit() + windows.vsplit() + + # Put the buffers in the appropriate windows + windows.focus(1) + buffers.one.open() + + windows.focus(2) + buffers.result.open() + + windows.focus(3) + buffers.two.open() + + self.open_hud(4) + + windows.focus(3) + + def _layout_2(self): + self._number_of_windows = 4 + self._current_layout = 2 + + # Open the layout + windows.close_all() + windows.split() + windows.split() + + # Put the buffers in the appropriate windows + windows.focus(1) + buffers.one.open() + + windows.focus(2) + buffers.result.open() + + windows.focus(3) + buffers.two.open() + + self.open_hud(4) + + windows.focus(3) + + + def _diff_0(self): + self.diffoff() + self._current_diff_mode = 0 + + def _diff_1(self): + self.diffoff() + self._current_diff_mode = 1 + + for i in range(2, self._number_of_windows + 2): + windows.focus(i) + vim.command('diffthis') + + + def key_original(self): + if self._current_layout == 0: + windows.focus(2) + elif self._current_layout == 1: + return + elif self._current_layout == 2: + return + + def key_one(self): + if self._current_layout == 0: + windows.focus(3) + elif self._current_layout == 1: + windows.focus(2) + elif self._current_layout == 2: + windows.focus(2) + + def key_two(self): + if self._current_layout == 0: + windows.focus(4) + elif self._current_layout == 1: + windows.focus(4) + elif self._current_layout == 2: + windows.focus(4) + + def key_result(self): + if self._current_layout == 0: + windows.focus(5) + elif self._current_layout == 1: + windows.focus(3) + elif self._current_layout == 2: + windows.focus(3) + + + def _key_use_0(self, target): + targetwin = 3 if target == 1 else 4 + + with windows.remain(): + self.diffoff() + + windows.focus(5) + vim.command('diffthis') + + windows.focus(targetwin) + vim.command('diffthis') + + def _key_use_12(self, target): + targetwin = 2 if target == 1 else 4 + + with windows.remain(): + self.diffoff() + + windows.focus(3) + vim.command('diffthis') + + windows.focus(targetwin) + vim.command('diffthis') + + + def key_use1(self): + current_diff = self._current_diff_mode + + if self._current_layout == 0: + self._key_use_0(1) + elif self._current_layout == 1: + self._key_use_12(1) + elif self._current_layout == 2: + self._key_use_12(1) + + if buffers.current == buffers.result: + vim.command('diffget') + elif buffers.current in (buffers.one, buffers.two): + vim.command('diffput') + + self.diff(current_diff) + + def key_use2(self): + current_diff = self._current_diff_mode + + if self._current_layout == 0: + self._key_use_0(2) + elif self._current_layout == 1: + self._key_use_12(2) + elif self._current_layout == 2: + self._key_use_12(2) + + if buffers.current == buffers.result: + vim.command('diffget') + elif buffers.current in (buffers.one, buffers.two): + vim.command('diffput') + + self.diff(current_diff) + + + def goto_result(self): + if self._current_layout == 0: + windows.focus(5) + elif self._current_layout == 1: + windows.focus(3) + elif self._current_layout == 2: + windows.focus(3) + + + def activate(self): + keys.bind('u1', ':ThreesomeUse1') + keys.bind('u2', ':ThreesomeUse2') + return super(GridMode, self).activate() + + def deactivate(self): + keys.unbind('u1') + keys.unbind('u2') + return super(GridMode, self).deactivate() + + + def hud_diagram(self): + if self._current_layout == 0: + return [ + r' Original', + r'Layout -> One Two', + r' Result', + ] + elif self._current_layout == 1: + return [ + r'', + r'Layout -> One Result Two', + r'', + ] + elif self._current_layout == 2: + return [ + r' One', + r'Layout -> Result', + r' Two', + ] + +class LoupeMode(Mode): + def __init__(self): + self._id = 'loup' + self._current_layout = int(setting('initial_layout_loupe', 0)) + self._current_diff_mode = int(setting('initial_diff_loupe', 0)) + self._current_scrollbind = boolsetting('initial_scrollbind_loupe') + + self._number_of_diff_modes = 1 + self._number_of_layouts = 1 + + self._current_buffer = buffers.result + + return super(LoupeMode, self).__init__() + + + def _diff_0(self): + self.diffoff() + self._current_diff_mode = 0 + + + def _layout_0(self): + self._number_of_windows = 1 + self._current_layout = 0 + + # Open the layout + windows.close_all() + + # Put the buffers in the appropriate windows + windows.focus(1) + self._current_buffer.open() + + self.open_hud(2) + + windows.focus(2) + + + def key_original(self): + windows.focus(2) + buffers.original.open() + self._current_buffer = buffers.original + self.redraw_hud() + + def key_one(self): + windows.focus(2) + buffers.one.open() + self._current_buffer = buffers.one + self.redraw_hud() + + def key_two(self): + windows.focus(2) + buffers.two.open() + self._current_buffer = buffers.two + self.redraw_hud() + + def key_result(self): + windows.focus(2) + buffers.result.open() + self._current_buffer = buffers.result + self.redraw_hud() + + + def key_use(self): + pass + + + def goto_result(self): + self.key_result() + + + def hud_diagram(self): + buf = buffers.labels[self._current_buffer.name] + + if self._current_layout == 0: + return [ + r'', + r'Layout -> %s ' % (buf,), + r'', + ] + +class CompareMode(Mode): + def __init__(self): + self._id = 'comp' + self._current_layout = int(setting('initial_layout_compare', 0)) + self._current_diff_mode = int(setting('initial_diff_compare', 0)) + self._current_scrollbind = boolsetting('initial_scrollbind_compare') + + self._number_of_diff_modes = 2 + self._number_of_layouts = 2 + + self._current_buffer_first = buffers.original + self._current_buffer_second = buffers.result + + return super(CompareMode, self).__init__() + + + def _diff_0(self): + self.diffoff() + self._current_diff_mode = 0 + + def _diff_1(self): + self.diffoff() + self._current_diff_mode = 1 + + windows.focus(2) + vim.command('diffthis') + + windows.focus(3) + vim.command('diffthis') + + + def _layout_0(self): + self._number_of_windows = 2 + self._current_layout = 0 + + # Open the layout + windows.close_all() + windows.vsplit() + + # Put the buffers in the appropriate windows + windows.focus(1) + self._current_buffer_first.open() + + windows.focus(2) + self._current_buffer_second.open() + + self.open_hud(3) + + windows.focus(3) + + def _layout_1(self): + self._number_of_windows = 2 + self._current_layout = 1 + + # Open the layout + windows.close_all() + windows.split() + + # Put the buffers in the appropriate windows + windows.focus(1) + self._current_buffer_first.open() + + windows.focus(2) + self._current_buffer_second.open() + + self.open_hud(3) + + windows.focus(3) + + + def key_original(self): + windows.focus(2) + buffers.original.open() + self._current_buffer_first = buffers.original + self.diff(self._current_diff_mode) + + self.redraw_hud() + + def key_one(self): + def open_one(winnr): + buffers.one.open(winnr) + if winnr == 2: + self._current_buffer_first = buffers.one + else: + self._current_buffer_second = buffers.one + self.diff(self._current_diff_mode) + self.redraw_hud() + + curwindow = windows.currentnr() + if curwindow == 1: + curwindow = 2 + + # If file one is showing, go to it. + windows.focus(2) + if buffers.current == buffers.one: + return + + windows.focus(3) + if buffers.current == buffers.one: + return + + # If both the original and result are showing, open file one in the + # current window. + windows.focus(2) + if buffers.current == buffers.original: + windows.focus(3) + if buffers.current == buffers.result: + open_one(curwindow) + return + + # If file two is in window 1, then we open file one in window 1. + windows.focus(2) + if buffers.current == buffers.two: + open_one(2) + return + + # Otherwise, open file one in the current window. + open_one(curwindow) + + def key_two(self): + def open_two(winnr): + buffers.two.open(winnr) + if winnr == 2: + self._current_buffer_first = buffers.two + else: + self._current_buffer_second = buffers.two + self.diff(self._current_diff_mode) + self.redraw_hud() + + curwindow = windows.currentnr() + if curwindow == 1: + curwindow = 2 + + # If file two is showing, go to it. + windows.focus(2) + if buffers.current == buffers.two: + return + + windows.focus(3) + if buffers.current == buffers.two: + return + + # If both the original and result are showing, open file two in the + # current window. + windows.focus(2) + if buffers.current == buffers.original: + windows.focus(3) + if buffers.current == buffers.result: + open_two(curwindow) + return + + # If file one is in window 2, then we open file two in window 2. + windows.focus(3) + if buffers.current == buffers.two: + open_two(3) + return + + # Otherwise, open file two in window 2. + open_two(curwindow) + + def key_result(self): + windows.focus(3) + buffers.result.open() + self._current_buffer_second = buffers.result + self.diff(self._current_diff_mode) + + self.redraw_hud() + + + def key_use(self): + active = (self._current_buffer_first, self._current_buffer_second) + + if buffers.result not in active: + return + + if buffers.one not in active and buffers.two not in active: + return + + current_diff = self._current_diff_mode + with windows.remain(): + self._diff_1() # diff the windows + + if buffers.current == buffers.result: + vim.command('diffget') + elif buffers.current in (buffers.one, buffers.two): + vim.command('diffput') + + self.diff(current_diff) + + + def goto_result(self): + self.key_result() + + + def hud_diagram(self): + first = buffers.labels[self._current_buffer_first.name] + second = buffers.labels[self._current_buffer_second.name] + + if self._current_layout == 0: + return [ + r'', + r'Layout -> %s %s' % (first, second), + r'', + ] + elif self._current_layout == 1: + return [ + r'', + r'Layout -> %s' % first, + r' %s' % second, + ] + +class PathMode(Mode): + def __init__(self): + self._id = 'path' + self._current_layout = int(setting('initial_layout_path', 0)) + self._current_diff_mode = int(setting('initial_diff_path', 0)) + self._current_scrollbind = boolsetting('initial_scrollbind_path') + + self._number_of_diff_modes = 5 + self._number_of_layouts = 2 + + self._current_mid_buffer = buffers.one + + return super(PathMode, self).__init__() + + + def _diff_0(self): + self.diffoff() + self._current_diff_mode = 0 + + def _diff_1(self): + self.diffoff() + self._current_diff_mode = 1 + + windows.focus(2) + vim.command('diffthis') + + windows.focus(4) + vim.command('diffthis') + + def _diff_2(self): + self.diffoff() + self._current_diff_mode = 2 + + windows.focus(2) + vim.command('diffthis') + + windows.focus(3) + vim.command('diffthis') + + def _diff_3(self): + self.diffoff() + self._current_diff_mode = 3 + + windows.focus(3) + vim.command('diffthis') + + windows.focus(4) + vim.command('diffthis') + + def _diff_4(self): + self.diffoff() + self._current_diff_mode = 4 + + windows.focus(2) + vim.command('diffthis') + + windows.focus(3) + vim.command('diffthis') + + windows.focus(4) + vim.command('diffthis') + + + def _layout_0(self): + self._number_of_windows = 3 + self._current_layout = 0 + + # Open the layout + windows.close_all() + windows.vsplit() + windows.vsplit() + + # Put the buffers in the appropriate windows + windows.focus(1) + buffers.original.open() + + windows.focus(2) + self._current_mid_buffer.open() + + windows.focus(3) + buffers.result.open() + + self.open_hud(4) + + windows.focus(4) + + def _layout_1(self): + self._number_of_windows = 3 + self._current_layout = 1 + + # Open the layout + windows.close_all() + windows.split() + windows.split() + + # Put the buffers in the appropriate windows + windows.focus(1) + buffers.original.open() + + windows.focus(2) + self._current_mid_buffer.open() + + windows.focus(3) + buffers.result.open() + + self.open_hud(4) + + windows.focus(4) + + + def key_original(self): + windows.focus(2) + + def key_one(self): + windows.focus(3) + buffers.one.open() + self._current_mid_buffer = buffers.one + self.diff(self._current_diff_mode) + windows.focus(3) + self.redraw_hud() + + def key_two(self): + windows.focus(3) + buffers.two.open() + self._current_mid_buffer = buffers.two + self.diff(self._current_diff_mode) + windows.focus(3) + self.redraw_hud() + + def key_result(self): + windows.focus(4) + + + def key_use(self): + current_diff = self._current_diff_mode + with windows.remain(): + self._diff_3() # diff the middle and result windows + + if buffers.current == buffers.result: + vim.command('diffget') + elif buffers.current in (buffers.one, buffers.two): + vim.command('diffput') + + self.diff(current_diff) + + + def goto_result(self): + windows.focus(4) + + + def hud_diagram(self): + if self._current_mid_buffer == buffers.one: + buf = 'One' + else: + buf = 'Two' + + if self._current_layout == 0: + return [ + r'', + r'Layout -> Original %s Result' % buf, + r'', + ] + elif self._current_layout == 1: + return [ + r' Original', + r'Layout -> %s' % buf, + r' Result', + ] + + +grid = GridMode() +loupe = LoupeMode() +compare = CompareMode() +path = PathMode() + + +def key_grid(): + global current_mode + current_mode = grid + grid.activate() + +def key_loupe(): + global current_mode + current_mode = loupe + loupe.activate() + +def key_compare(): + global current_mode + current_mode = compare + compare.activate() + +def key_path(): + global current_mode + current_mode = path + path.activate() diff -r 4995b244e11d -r cefc901de8a2 autoload/threesomelib/settings.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autoload/threesomelib/settings.py Tue Jun 28 17:48:57 2011 -0400 @@ -0,0 +1,16 @@ +import vim + + +def setting(name, default=None): + full_name = 'g:threesome_' + name + + if not int(vim.eval('exists("%s")' % full_name)): + return default + else: + return vim.eval(full_name) + +def boolsetting(name): + if int(setting(name, 0)): + return True + else: + False diff -r 4995b244e11d -r cefc901de8a2 autoload/threesomelib/util/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autoload/threesomelib/util/__init__.py Tue Jun 28 17:48:57 2011 -0400 @@ -0,0 +1,2 @@ +# This is kind of a dirty hack. Feels bad, man. +from bufferlib import buffers diff -r 4995b244e11d -r cefc901de8a2 autoload/threesomelib/util/bufferlib.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autoload/threesomelib/util/bufferlib.py Tue Jun 28 17:48:57 2011 -0400 @@ -0,0 +1,82 @@ +import os +import vim +import windows + +ap = os.path.abspath + +class Buffer(object): + def __init__(self, i): + self.number = i + 1 + self._buffer = vim.buffers[i] + self.name = self._buffer.name + + def open(self, winnr=None): + if winnr is not None: + windows.focus(winnr) + vim.command('%dbuffer' % self.number) + + def set_lines(self, lines): + self._buffer[:] = lines + + @property + def lines(self): + for line in self._buffer: + yield line + + + def __eq__(self, other): + return self.name == other.name + + def __ne__(self, other): + return self.name != other.name + + +class _BufferList(object): + @property + def original(self): + return Buffer(0) + + @property + def one(self): + return Buffer(1) + + @property + def two(self): + return Buffer(2) + + @property + def result(self): + return Buffer(3) + + @property + def hud(self): + return Buffer(int(vim.eval("bufnr('__Threesome_HUD__')")) - 1) + + + @property + def current(self): + bufname = ap(vim.eval('bufname("%")')) + + if bufname == ap(self.original.name): + return self.original + elif bufname == ap(self.one.name): + return self.one + elif bufname == ap(self.two.name): + return self.two + elif bufname == ap(self.result.name): + return self.result + + @property + def all(self): + return [self.original, self.one, self.two, self.result] + + + @property + def labels(self): + return { buffers.original.name: 'Original', + buffers.one.name: 'One', + buffers.two.name: 'Two', + buffers.result.name: 'Result' } + +buffers = _BufferList() + diff -r 4995b244e11d -r cefc901de8a2 autoload/threesomelib/util/io.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autoload/threesomelib/util/io.py Tue Jun 28 17:48:57 2011 -0400 @@ -0,0 +1,5 @@ +import sys + + +def error(m): + sys.stdout.write(str(m) + '\n') diff -r 4995b244e11d -r cefc901de8a2 autoload/threesomelib/util/keys.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autoload/threesomelib/util/keys.py Tue Jun 28 17:48:57 2011 -0400 @@ -0,0 +1,9 @@ +import vim + + +def bind(key, to, options='', mode=None, leader=''): + vim.command('nnoremap %s %s%s %s' % (options, leader, key, to)) + +def unbind(key, options='', leader=''): + vim.command('unmap %s %s%s' % (options, leader, key)) + diff -r 4995b244e11d -r cefc901de8a2 autoload/threesomelib/util/windows.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autoload/threesomelib/util/windows.py Tue Jun 28 17:48:57 2011 -0400 @@ -0,0 +1,36 @@ +import vim + + +def focus(winnr): + vim.command('%dwincmd w' % winnr) + +def close(winnr): + focus(winnr) + vim.command('wincmd c') + +def close_all(): + for winnr in range(len(vim.windows) - 1): + close(winnr) + +def split(): + vim.command('wincmd s') + +def vsplit(): + vim.command('wincmd v') + +def currentnr(): + return int(vim.eval('winnr()')) + +def pos(): + return vim.current.window.cursor + + +class remain: + def __enter__(self): + self.curwindow = currentnr() + self.pos = pos() + + def __exit__(self, type, value, traceback): + focus(self.curwindow) + vim.current.window.cursor = self.pos + diff -r 4995b244e11d -r cefc901de8a2 plugin/threesome.py --- a/plugin/threesome.py Mon Jun 13 23:01:59 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -import vim, os, sys - - -# Add the library to the Python path. -for p in vim.eval("&runtimepath").split(','): - plugin_dir = os.path.join(p, "plugin") - if os.path.exists(os.path.join(plugin_dir, "threesomelib")): - if plugin_dir not in sys.path: - sys.path.append(plugin_dir) - break - - -# Wrapper functions -threesome = None -def ThreesomeInit(): - global threesome - import threesomelib.init as init - init.init() - threesome = init - - -def ThreesomeOriginal(): - threesome.modes.current_mode.key_original() - -def ThreesomeOne(): - threesome.modes.current_mode.key_one() - -def ThreesomeTwo(): - threesome.modes.current_mode.key_two() - -def ThreesomeResult(): - threesome.modes.current_mode.key_result() - - -def ThreesomeGrid(): - threesome.modes.key_grid() - -def ThreesomeLoupe(): - threesome.modes.key_loupe() - -def ThreesomeCompare(): - threesome.modes.key_compare() - -def ThreesomePath(): - threesome.modes.key_path() - - -def ThreesomeDiff(): - threesome.modes.current_mode.key_diff() - -def ThreesomeDiffoff(): - threesome.modes.current_mode.key_diffoff() - -def ThreesomeScroll(): - threesome.modes.current_mode.key_scrollbind() - -def ThreesomeLayout(): - threesome.modes.current_mode.key_layout() - -def ThreesomeNext(): - threesome.modes.current_mode.key_next() - -def ThreesomePrev(): - threesome.modes.current_mode.key_prev() - -def ThreesomeUse(): - threesome.modes.current_mode.key_use() - -def ThreesomeUse1(): - threesome.modes.current_mode.key_use1() - -def ThreesomeUse2(): - threesome.modes.current_mode.key_use2() - diff -r 4995b244e11d -r cefc901de8a2 plugin/threesome.vim --- a/plugin/threesome.vim Mon Jun 13 23:01:59 2011 -0400 +++ b/plugin/threesome.vim Tue Jun 28 17:48:57 2011 -0400 @@ -7,187 +7,37 @@ " " ============================================================================ - -"{{{ Init - -" Loading check {{{ +" Init {{{ if !exists('g:threesome_debug') && (exists('g:threesome_disable') || exists('loaded_threesome') || &cp) finish endif let loaded_threesome = 1 -"}}} -" Vim version check {{{ - -if v:version < '703' - function! s:ThreesomeDidNotLoad() - echohl WarningMsg|echomsg "Threesome unavailable: requires Vim 7.3+"|echohl None - endfunction - command! -nargs=0 ThreesomeInit call s:ThreesomeDidNotLoad() - finish -endif - -"}}} -" Python version check {{{ - -if has('python') - let s:has_supported_python = 2 -python << ENDPYTHON -import sys, vim -if sys.version_info[:2] < (2, 5): - vim.command('let s:has_supported_python = 0') -ENDPYTHON -else - let s:has_supported_python = 0 -endif - -if !s:has_supported_python - function! s:ThreesomeDidNotLoad() - echohl WarningMsg|echomsg "Threesome requires Vim to be compiled with Python 2.5+"|echohl None - endfunction - command! -nargs=0 ThreesomeInit call s:ThreesomeDidNotLoad() - finish -endif - -"}}} -" Configuration variables {{{ - -if !exists('g:threesome_disable') " {{{ - let g:threesome_disable = 0 -endif " }}} -if !exists('g:threesome_initial_mode') " {{{ - let g:threesome_initial_mode = 'grid' -endif " }}} -if !exists('g:threesome_initial_layout_grid') " {{{ - let g:threesome_initial_layout_grid = 0 -endif " }}} -if !exists('g:threesome_initial_layout_loupe') " {{{ - let g:threesome_initial_layout_loupe = 0 -endif " }}} -if !exists('g:threesome_initial_layout_compare') " {{{ - let g:threesome_initial_layout_compare = 0 -endif " }}} -if !exists('g:threesome_initial_layout_path') " {{{ - let g:threesome_initial_layout_path = 0 -endif " }}} -if !exists('g:threesome_initial_diff_grid') " {{{ - let g:threesome_initial_diff_grid = 0 -endif " }}} -if !exists('g:threesome_initial_diff_loupe') " {{{ - let g:threesome_initial_diff_loupe = 0 -endif " }}} -if !exists('g:threesome_initial_diff_compare') " {{{ - let g:threesome_initial_diff_compare = 0 -endif " }}} -if !exists('g:threesome_initial_diff_path') " {{{ - let g:threesome_initial_diff_path = 0 -endif " }}} -if !exists('g:threesome_initial_scrollbind_grid') " {{{ - let g:threesome_initial_scrollbind_grid = 0 -endif " }}} -if !exists('g:threesome_initial_scrollbind_loupe') " {{{ - let g:threesome_initial_scrollbind_loupe = 0 -endif " }}} -if !exists('g:threesome_initial_scrollbind_compare') " {{{ - let g:threesome_initial_scrollbind_compare = 0 -endif " }}} -if !exists('g:threesome_initial_scrollbind_path') " {{{ - let g:threesome_initial_scrollbind_path = 0 -endif " }}} - -"}}} - -"}}} - -"{{{ Wrappers - -function! s:ThreesomeInit()"{{{ - let python_module = fnameescape(globpath(&runtimepath, 'plugin/threesome.py')) - exe 'pyfile ' . python_module - python ThreesomeInit() -endfunction"}}} - -function! s:ThreesomeGrid()"{{{ - python ThreesomeGrid() -endfunction"}}} -function! s:ThreesomeLoupe()"{{{ - python ThreesomeLoupe() -endfunction"}}} -function! s:ThreesomeCompare()"{{{ - python ThreesomeCompare() -endfunction"}}} -function! s:ThreesomePath()"{{{ - python ThreesomePath() -endfunction"}}} - -function! s:ThreesomeOriginal()"{{{ - python ThreesomeOriginal() -endfunction"}}} -function! s:ThreesomeOne()"{{{ - python ThreesomeOne() -endfunction"}}} -function! s:ThreesomeTwo()"{{{ - python ThreesomeTwo() -endfunction"}}} -function! s:ThreesomeResult()"{{{ - python ThreesomeResult() -endfunction"}}} - -function! s:ThreesomeDiff()"{{{ - python ThreesomeDiff() -endfunction"}}} -function! s:ThreesomeDiffoff()"{{{ - python ThreesomeDiffoff() -endfunction"}}} -function! s:ThreesomeScroll()"{{{ - python ThreesomeScroll() -endfunction"}}} -function! s:ThreesomeLayout()"{{{ - python ThreesomeLayout() -endfunction"}}} -function! s:ThreesomeNext()"{{{ - python ThreesomeNext() -endfunction"}}} -function! s:ThreesomePrev()"{{{ - python ThreesomePrev() -endfunction"}}} -function! s:ThreesomeUse()"{{{ - python ThreesomeUse() -endfunction"}}} -function! s:ThreesomeUse1()"{{{ - python ThreesomeUse1() -endfunction"}}} -function! s:ThreesomeUse2()"{{{ - python ThreesomeUse2() -endfunction"}}} - -"}}} +" }}} "{{{ Commands -command! -nargs=0 ThreesomeInit call s:ThreesomeInit() +command! -nargs=0 ThreesomeInit call threesome#ThreesomeInit() -command! -nargs=0 ThreesomeGrid call s:ThreesomeGrid() -command! -nargs=0 ThreesomeLoupe call s:ThreesomeLoupe() -command! -nargs=0 ThreesomeCompare call s:ThreesomeCompare() -command! -nargs=0 ThreesomePath call s:ThreesomePath() +command! -nargs=0 ThreesomeGrid call threesome#ThreesomeGrid() +command! -nargs=0 ThreesomeLoupe call threesome#ThreesomeLoupe() +command! -nargs=0 ThreesomeCompare call threesome#ThreesomeCompare() +command! -nargs=0 ThreesomePath call threesome#ThreesomePath() -command! -nargs=0 ThreesomeOriginal call s:ThreesomeOriginal() -command! -nargs=0 ThreesomeOne call s:ThreesomeOne() -command! -nargs=0 ThreesomeTwo call s:ThreesomeTwo() -command! -nargs=0 ThreesomeResult call s:ThreesomeResult() +command! -nargs=0 ThreesomeOriginal call threesome#ThreesomeOriginal() +command! -nargs=0 ThreesomeOne call threesome#ThreesomeOne() +command! -nargs=0 ThreesomeTwo call threesome#ThreesomeTwo() +command! -nargs=0 ThreesomeResult call threesome#ThreesomeResult() -command! -nargs=0 ThreesomeDiff call s:ThreesomeDiff() -command! -nargs=0 ThreesomeDiffoff call s:ThreesomeDiffoff() -command! -nargs=0 ThreesomeScroll call s:ThreesomeScroll() -command! -nargs=0 ThreesomeLayout call s:ThreesomeLayout() -command! -nargs=0 ThreesomeNext call s:ThreesomeNext() -command! -nargs=0 ThreesomePrev call s:ThreesomePrev() -command! -nargs=0 ThreesomeUse call s:ThreesomeUse() -command! -nargs=0 ThreesomeUse1 call s:ThreesomeUse1() -command! -nargs=0 ThreesomeUse2 call s:ThreesomeUse2() +command! -nargs=0 ThreesomeDiff call threesome#ThreesomeDiff() +command! -nargs=0 ThreesomeDiffoff call threesome#ThreesomeDiffoff() +command! -nargs=0 ThreesomeScroll call threesome#ThreesomeScroll() +command! -nargs=0 ThreesomeLayout call threesome#ThreesomeLayout() +command! -nargs=0 ThreesomeNext call threesome#ThreesomeNext() +command! -nargs=0 ThreesomePrev call threesome#ThreesomePrev() +command! -nargs=0 ThreesomeUse call threesome#ThreesomeUse() +command! -nargs=0 ThreesomeUse1 call threesome#ThreesomeUse1() +command! -nargs=0 ThreesomeUse2 call threesome#ThreesomeUse2() "}}} - -" vim:se fdm=marker:sw=4: diff -r 4995b244e11d -r cefc901de8a2 plugin/threesomelib/__init__.py diff -r 4995b244e11d -r cefc901de8a2 plugin/threesomelib/init.py --- a/plugin/threesomelib/init.py Mon Jun 13 23:01:59 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -import vim -import modes -from settings import setting -from util import buffers, keys, windows - - -CONFLICT_MARKER_START = '<<<<<<<' -CONFLICT_MARKER_MARK = '=======' -CONFLICT_MARKER_END = '>>>>>>>' - -def process_result(): - windows.close_all() - buffers.result.open() - - lines = [] - in_conflict = False - for line in buffers.result.lines: - if in_conflict: - if CONFLICT_MARKER_MARK in line: - lines.append(line) - if CONFLICT_MARKER_END in line: - in_conflict = False - continue - - if CONFLICT_MARKER_START in line: - in_conflict = True - continue - - lines.append(line) - - buffers.result.set_lines(lines) - -def bind_global_keys(): - keys.bind('g', ':ThreesomeGrid') - keys.bind('l', ':ThreesomeLoupe') - keys.bind('c', ':ThreesomeCompare') - keys.bind('p', ':ThreesomePath') - - keys.bind('o', ':ThreesomeOriginal') - keys.bind('1', ':ThreesomeOne') - keys.bind('2', ':ThreesomeTwo') - keys.bind('r', ':ThreesomeResult') - - keys.bind('d', ':ThreesomeDiff') - keys.bind('D', ':ThreesomeDiffoff') - keys.bind('s', ':ThreesomeScroll') - keys.bind('n', ':ThreesomeNext') - keys.bind('N', ':ThreesomePrev') - keys.bind('', ':ThreesomeLayout') - keys.bind('u', ':ThreesomeUse') - - keys.bind('q', ':wa:qa') - keys.bind('CC', ':cq') - -def setlocal_buffers(): - buffers.original.open() - vim.command('setlocal noswapfile') - vim.command('setlocal nomodifiable') - if setting('wrap'): - vim.command('setlocal ' + setting('wrap')) - - buffers.one.open() - vim.command('setlocal noswapfile') - vim.command('setlocal nomodifiable') - if setting('wrap'): - vim.command('setlocal ' + setting('wrap')) - - buffers.two.open() - vim.command('setlocal noswapfile') - vim.command('setlocal nomodifiable') - if setting('wrap'): - vim.command('setlocal ' + setting('wrap')) - - buffers.result.open() - if setting('wrap'): - vim.command('setlocal ' + setting('wrap')) - - buffers.hud.open() - vim.command('setlocal noswapfile') - vim.command('setlocal nomodifiable') - vim.command('setlocal nobuflisted') - vim.command('setlocal buftype=nofile') - vim.command('setlocal noundofile') - vim.command('setlocal nolist') - vim.command('setlocal ft=threesome') - vim.command('setlocal nowrap') - vim.command('resize ' + setting('hud_size', '3')) - -def create_hud(): - vim.command('new __Threesome_HUD__') - - -def init(): - process_result() - create_hud() - setlocal_buffers() - bind_global_keys() - - initial_mode = setting('initial_mode', 'grid').lower() - if initial_mode not in ['grid', 'loupe', 'compare', 'path']: - initial_mode = 'grid' - - modes.current_mode = getattr(modes, initial_mode) - modes.current_mode.activate() - - diff -r 4995b244e11d -r cefc901de8a2 plugin/threesomelib/modes.py --- a/plugin/threesomelib/modes.py Mon Jun 13 23:01:59 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,904 +0,0 @@ -from __future__ import with_statement - -import vim -from util import buffers, keys, windows -from settings import boolsetting, setting - - -current_mode = None - -class Mode(object): - def __init__(self): - return super(Mode, self).__init__() - - - def diff(self, diffmode): - with windows.remain(): - getattr(self, '_diff_%d' % diffmode)() - - # Reset the scrollbind to whatever it was before we diffed. - if not diffmode: - self.scrollbind(self._current_scrollbind) - - def key_diff(self, diffmode=None): - next_diff_mode = self._current_diff_mode + 1 - if next_diff_mode >= self._number_of_diff_modes: - next_diff_mode = 0 - self.diff(next_diff_mode) - - - def diffoff(self): - with windows.remain(): - for winnr in range(2, 2 + self._number_of_windows): - windows.focus(winnr) - curbuffer = buffers.current - - for buffer in buffers.all: - buffer.open() - vim.command('diffoff') - if setting('wrap'): - vim.command('setlocal ' + setting('wrap')) - - curbuffer.open() - - - def key_diffoff(self): - self.diff(0) - - - def scrollbind(self, enabled): - if self._current_diff_mode: - return - - with windows.remain(): - self._current_scrollbind = enabled - - for winnr in range(2, 2 + self._number_of_windows): - windows.focus(winnr) - - if enabled: - vim.command('set scrollbind') - else: - vim.command('set noscrollbind') - - if enabled: - vim.command('syncbind') - - def key_scrollbind(self): - self.scrollbind(not self._current_scrollbind) - - - def layout(self, layoutnr): - getattr(self, '_layout_%d' % layoutnr)() - self.diff(self._current_diff_mode) - self.redraw_hud() - - def key_layout(self, diffmode=None): - next_layout = self._current_layout + 1 - if next_layout >= self._number_of_layouts: - next_layout = 0 - self.layout(next_layout) - - - def key_original(self): - pass - - def key_one(self): - pass - - def key_two(self): - pass - - def key_result(self): - pass - - - def key_use(self): - pass - - - def activate(self): - self.layout(self._current_layout) - self.diff(self._current_diff_mode) - self.scrollbind(self._current_scrollbind) - - def deactivate(self): - pass - - - def key_next(self): - self.goto_result() - vim.command(r'exe "normal! /\=\=\=\=\=\=\=\"') - - def key_prev(self): - self.goto_result() - vim.command(r'exe "normal! ?\=\=\=\=\=\=\=\"') - - - def open_hud(self, winnr): - windows.split() - windows.focus(winnr) - buffers.hud.open() - vim.command('wincmd K') - self.redraw_hud() - - def hud_lines(self): - def pad(lines): - l = max([len(line) for line in lines]) - return [line.ljust(l) for line in lines] - - sep = ' | ' - - modes = pad([ - r'Threesome Modes', - r'x[G]rid y[C]ompare'.replace('x', self._id == 'grid' and '*' or ' ') - .replace('y', self._id == 'comp' and '*' or ' '), - r'x[L]oupe y[P]ath'.replace('x', self._id == 'loup' and '*' or ' ') - .replace('y', self._id == 'path' and '*' or ' '), - ]) - diagram = pad(self.hud_diagram()) - commands = pad([ - r'Threesome Commands', - r'd: cycle diffs n: next conflict space: cycle layouts', - r'D: diffs off N: prev conflict s: toggle scrollbind', - ]) - - lines = [] - for line in modes: - lines.append(line + sep) - for i, line in enumerate(diagram): - lines[i] += line + sep - for i, line in enumerate(commands): - lines[i] += line + sep - - for i, line in enumerate(lines): - lines[i] = line.rstrip() - - return lines - - def redraw_hud(self): - with windows.remain(): - windows.focus(1) - - vim.command('setlocal modifiable') - buffers.hud.set_lines(self.hud_lines()) - vim.command('setlocal nomodifiable') - - vim.command('set winfixheight') - vim.command('resize ' + setting('hud_size', '3')) - vim.command('wincmd =') - - -class GridMode(Mode): - """ - Layout 0 Layout 1 Layout 2 - +-------------------+ +--------------------------+ +---------------+ - | Original | | One | Result | Two | | One | - |2 | | | | | |2 | - +-------------------+ | | | | +---------------+ - | One | Two | | | | | | Result | - |3 |4 | | | | | |3 | - +-------------------+ | | | | +---------------+ - | Result | | | | | | Two | - |5 | |2 |3 |4 | |4 | - +-------------------+ +--------------------------+ +---------------+ - """ - - def __init__(self): - self._id = 'grid' - self._current_layout = int(setting('initial_layout_grid', 0)) - self._current_diff_mode = int(setting('initial_diff_grid', 0)) - self._current_scrollbind = boolsetting('initial_scrollbind_grid') - - self._number_of_diff_modes = 2 - self._number_of_layouts = 3 - - return super(GridMode, self).__init__() - - - def _layout_0(self): - self._number_of_windows = 4 - self._current_layout = 0 - - # Open the layout - windows.close_all() - windows.split() - windows.split() - windows.focus(2) - windows.vsplit() - - # Put the buffers in the appropriate windows - windows.focus(1) - buffers.original.open() - - windows.focus(2) - buffers.one.open() - - windows.focus(3) - buffers.two.open() - - windows.focus(4) - buffers.result.open() - - self.open_hud(5) - - windows.focus(5) - - def _layout_1(self): - self._number_of_windows = 3 - self._current_layout = 1 - - # Open the layout - windows.close_all() - windows.vsplit() - windows.vsplit() - - # Put the buffers in the appropriate windows - windows.focus(1) - buffers.one.open() - - windows.focus(2) - buffers.result.open() - - windows.focus(3) - buffers.two.open() - - self.open_hud(4) - - windows.focus(3) - - def _layout_2(self): - self._number_of_windows = 4 - self._current_layout = 2 - - # Open the layout - windows.close_all() - windows.split() - windows.split() - - # Put the buffers in the appropriate windows - windows.focus(1) - buffers.one.open() - - windows.focus(2) - buffers.result.open() - - windows.focus(3) - buffers.two.open() - - self.open_hud(4) - - windows.focus(3) - - - def _diff_0(self): - self.diffoff() - self._current_diff_mode = 0 - - def _diff_1(self): - self.diffoff() - self._current_diff_mode = 1 - - for i in range(2, self._number_of_windows + 2): - windows.focus(i) - vim.command('diffthis') - - - def key_original(self): - if self._current_layout == 0: - windows.focus(2) - elif self._current_layout == 1: - return - elif self._current_layout == 2: - return - - def key_one(self): - if self._current_layout == 0: - windows.focus(3) - elif self._current_layout == 1: - windows.focus(2) - elif self._current_layout == 2: - windows.focus(2) - - def key_two(self): - if self._current_layout == 0: - windows.focus(4) - elif self._current_layout == 1: - windows.focus(4) - elif self._current_layout == 2: - windows.focus(4) - - def key_result(self): - if self._current_layout == 0: - windows.focus(5) - elif self._current_layout == 1: - windows.focus(3) - elif self._current_layout == 2: - windows.focus(3) - - - def _key_use_0(self, target): - targetwin = 3 if target == 1 else 4 - - with windows.remain(): - self.diffoff() - - windows.focus(5) - vim.command('diffthis') - - windows.focus(targetwin) - vim.command('diffthis') - - def _key_use_12(self, target): - targetwin = 2 if target == 1 else 4 - - with windows.remain(): - self.diffoff() - - windows.focus(3) - vim.command('diffthis') - - windows.focus(targetwin) - vim.command('diffthis') - - - def key_use1(self): - current_diff = self._current_diff_mode - - if self._current_layout == 0: - self._key_use_0(1) - elif self._current_layout == 1: - self._key_use_12(1) - elif self._current_layout == 2: - self._key_use_12(1) - - if buffers.current == buffers.result: - vim.command('diffget') - elif buffers.current in (buffers.one, buffers.two): - vim.command('diffput') - - self.diff(current_diff) - - def key_use2(self): - current_diff = self._current_diff_mode - - if self._current_layout == 0: - self._key_use_0(2) - elif self._current_layout == 1: - self._key_use_12(2) - elif self._current_layout == 2: - self._key_use_12(2) - - if buffers.current == buffers.result: - vim.command('diffget') - elif buffers.current in (buffers.one, buffers.two): - vim.command('diffput') - - self.diff(current_diff) - - - def goto_result(self): - if self._current_layout == 0: - windows.focus(5) - elif self._current_layout == 1: - windows.focus(3) - elif self._current_layout == 2: - windows.focus(3) - - - def activate(self): - keys.bind('u1', ':ThreesomeUse1') - keys.bind('u2', ':ThreesomeUse2') - return super(GridMode, self).activate() - - def deactivate(self): - keys.unbind('u1') - keys.unbind('u2') - return super(GridMode, self).deactivate() - - - def hud_diagram(self): - if self._current_layout == 0: - return [ - r' Original', - r'Layout -> One Two', - r' Result', - ] - elif self._current_layout == 1: - return [ - r'', - r'Layout -> One Result Two', - r'', - ] - elif self._current_layout == 2: - return [ - r' One', - r'Layout -> Result', - r' Two', - ] - -class LoupeMode(Mode): - def __init__(self): - self._id = 'loup' - self._current_layout = int(setting('initial_layout_loupe', 0)) - self._current_diff_mode = int(setting('initial_diff_loupe', 0)) - self._current_scrollbind = boolsetting('initial_scrollbind_loupe') - - self._number_of_diff_modes = 1 - self._number_of_layouts = 1 - - self._current_buffer = buffers.result - - return super(LoupeMode, self).__init__() - - - def _diff_0(self): - self.diffoff() - self._current_diff_mode = 0 - - - def _layout_0(self): - self._number_of_windows = 1 - self._current_layout = 0 - - # Open the layout - windows.close_all() - - # Put the buffers in the appropriate windows - windows.focus(1) - self._current_buffer.open() - - self.open_hud(2) - - windows.focus(2) - - - def key_original(self): - windows.focus(2) - buffers.original.open() - self._current_buffer = buffers.original - self.redraw_hud() - - def key_one(self): - windows.focus(2) - buffers.one.open() - self._current_buffer = buffers.one - self.redraw_hud() - - def key_two(self): - windows.focus(2) - buffers.two.open() - self._current_buffer = buffers.two - self.redraw_hud() - - def key_result(self): - windows.focus(2) - buffers.result.open() - self._current_buffer = buffers.result - self.redraw_hud() - - - def key_use(self): - pass - - - def goto_result(self): - self.key_result() - - - def hud_diagram(self): - buf = buffers.labels[self._current_buffer.name] - - if self._current_layout == 0: - return [ - r'', - r'Layout -> %s ' % (buf,), - r'', - ] - -class CompareMode(Mode): - def __init__(self): - self._id = 'comp' - self._current_layout = int(setting('initial_layout_compare', 0)) - self._current_diff_mode = int(setting('initial_diff_compare', 0)) - self._current_scrollbind = boolsetting('initial_scrollbind_compare') - - self._number_of_diff_modes = 2 - self._number_of_layouts = 2 - - self._current_buffer_first = buffers.original - self._current_buffer_second = buffers.result - - return super(CompareMode, self).__init__() - - - def _diff_0(self): - self.diffoff() - self._current_diff_mode = 0 - - def _diff_1(self): - self.diffoff() - self._current_diff_mode = 1 - - windows.focus(2) - vim.command('diffthis') - - windows.focus(3) - vim.command('diffthis') - - - def _layout_0(self): - self._number_of_windows = 2 - self._current_layout = 0 - - # Open the layout - windows.close_all() - windows.vsplit() - - # Put the buffers in the appropriate windows - windows.focus(1) - self._current_buffer_first.open() - - windows.focus(2) - self._current_buffer_second.open() - - self.open_hud(3) - - windows.focus(3) - - def _layout_1(self): - self._number_of_windows = 2 - self._current_layout = 1 - - # Open the layout - windows.close_all() - windows.split() - - # Put the buffers in the appropriate windows - windows.focus(1) - self._current_buffer_first.open() - - windows.focus(2) - self._current_buffer_second.open() - - self.open_hud(3) - - windows.focus(3) - - - def key_original(self): - windows.focus(2) - buffers.original.open() - self._current_buffer_first = buffers.original - self.diff(self._current_diff_mode) - - self.redraw_hud() - - def key_one(self): - def open_one(winnr): - buffers.one.open(winnr) - if winnr == 2: - self._current_buffer_first = buffers.one - else: - self._current_buffer_second = buffers.one - self.diff(self._current_diff_mode) - self.redraw_hud() - - curwindow = windows.currentnr() - if curwindow == 1: - curwindow = 2 - - # If file one is showing, go to it. - windows.focus(2) - if buffers.current == buffers.one: - return - - windows.focus(3) - if buffers.current == buffers.one: - return - - # If both the original and result are showing, open file one in the - # current window. - windows.focus(2) - if buffers.current == buffers.original: - windows.focus(3) - if buffers.current == buffers.result: - open_one(curwindow) - return - - # If file two is in window 1, then we open file one in window 1. - windows.focus(2) - if buffers.current == buffers.two: - open_one(2) - return - - # Otherwise, open file one in the current window. - open_one(curwindow) - - def key_two(self): - def open_two(winnr): - buffers.two.open(winnr) - if winnr == 2: - self._current_buffer_first = buffers.two - else: - self._current_buffer_second = buffers.two - self.diff(self._current_diff_mode) - self.redraw_hud() - - curwindow = windows.currentnr() - if curwindow == 1: - curwindow = 2 - - # If file two is showing, go to it. - windows.focus(2) - if buffers.current == buffers.two: - return - - windows.focus(3) - if buffers.current == buffers.two: - return - - # If both the original and result are showing, open file two in the - # current window. - windows.focus(2) - if buffers.current == buffers.original: - windows.focus(3) - if buffers.current == buffers.result: - open_two(curwindow) - return - - # If file one is in window 2, then we open file two in window 2. - windows.focus(3) - if buffers.current == buffers.two: - open_two(3) - return - - # Otherwise, open file two in window 2. - open_two(curwindow) - - def key_result(self): - windows.focus(3) - buffers.result.open() - self._current_buffer_second = buffers.result - self.diff(self._current_diff_mode) - - self.redraw_hud() - - - def key_use(self): - active = (self._current_buffer_first, self._current_buffer_second) - - if buffers.result not in active: - return - - if buffers.one not in active and buffers.two not in active: - return - - current_diff = self._current_diff_mode - with windows.remain(): - self._diff_1() # diff the windows - - if buffers.current == buffers.result: - vim.command('diffget') - elif buffers.current in (buffers.one, buffers.two): - vim.command('diffput') - - self.diff(current_diff) - - - def goto_result(self): - self.key_result() - - - def hud_diagram(self): - first = buffers.labels[self._current_buffer_first.name] - second = buffers.labels[self._current_buffer_second.name] - - if self._current_layout == 0: - return [ - r'', - r'Layout -> %s %s' % (first, second), - r'', - ] - elif self._current_layout == 1: - return [ - r'', - r'Layout -> %s' % first, - r' %s' % second, - ] - -class PathMode(Mode): - def __init__(self): - self._id = 'path' - self._current_layout = int(setting('initial_layout_path', 0)) - self._current_diff_mode = int(setting('initial_diff_path', 0)) - self._current_scrollbind = boolsetting('initial_scrollbind_path') - - self._number_of_diff_modes = 5 - self._number_of_layouts = 2 - - self._current_mid_buffer = buffers.one - - return super(PathMode, self).__init__() - - - def _diff_0(self): - self.diffoff() - self._current_diff_mode = 0 - - def _diff_1(self): - self.diffoff() - self._current_diff_mode = 1 - - windows.focus(2) - vim.command('diffthis') - - windows.focus(4) - vim.command('diffthis') - - def _diff_2(self): - self.diffoff() - self._current_diff_mode = 2 - - windows.focus(2) - vim.command('diffthis') - - windows.focus(3) - vim.command('diffthis') - - def _diff_3(self): - self.diffoff() - self._current_diff_mode = 3 - - windows.focus(3) - vim.command('diffthis') - - windows.focus(4) - vim.command('diffthis') - - def _diff_4(self): - self.diffoff() - self._current_diff_mode = 4 - - windows.focus(2) - vim.command('diffthis') - - windows.focus(3) - vim.command('diffthis') - - windows.focus(4) - vim.command('diffthis') - - - def _layout_0(self): - self._number_of_windows = 3 - self._current_layout = 0 - - # Open the layout - windows.close_all() - windows.vsplit() - windows.vsplit() - - # Put the buffers in the appropriate windows - windows.focus(1) - buffers.original.open() - - windows.focus(2) - self._current_mid_buffer.open() - - windows.focus(3) - buffers.result.open() - - self.open_hud(4) - - windows.focus(4) - - def _layout_1(self): - self._number_of_windows = 3 - self._current_layout = 1 - - # Open the layout - windows.close_all() - windows.split() - windows.split() - - # Put the buffers in the appropriate windows - windows.focus(1) - buffers.original.open() - - windows.focus(2) - self._current_mid_buffer.open() - - windows.focus(3) - buffers.result.open() - - self.open_hud(4) - - windows.focus(4) - - - def key_original(self): - windows.focus(2) - - def key_one(self): - windows.focus(3) - buffers.one.open() - self._current_mid_buffer = buffers.one - self.diff(self._current_diff_mode) - windows.focus(3) - self.redraw_hud() - - def key_two(self): - windows.focus(3) - buffers.two.open() - self._current_mid_buffer = buffers.two - self.diff(self._current_diff_mode) - windows.focus(3) - self.redraw_hud() - - def key_result(self): - windows.focus(4) - - - def key_use(self): - current_diff = self._current_diff_mode - with windows.remain(): - self._diff_3() # diff the middle and result windows - - if buffers.current == buffers.result: - vim.command('diffget') - elif buffers.current in (buffers.one, buffers.two): - vim.command('diffput') - - self.diff(current_diff) - - - def goto_result(self): - windows.focus(4) - - - def hud_diagram(self): - if self._current_mid_buffer == buffers.one: - buf = 'One' - else: - buf = 'Two' - - if self._current_layout == 0: - return [ - r'', - r'Layout -> Original %s Result' % buf, - r'', - ] - elif self._current_layout == 1: - return [ - r' Original', - r'Layout -> %s' % buf, - r' Result', - ] - - -grid = GridMode() -loupe = LoupeMode() -compare = CompareMode() -path = PathMode() - - -def key_grid(): - global current_mode - current_mode = grid - grid.activate() - -def key_loupe(): - global current_mode - current_mode = loupe - loupe.activate() - -def key_compare(): - global current_mode - current_mode = compare - compare.activate() - -def key_path(): - global current_mode - current_mode = path - path.activate() diff -r 4995b244e11d -r cefc901de8a2 plugin/threesomelib/settings.py --- a/plugin/threesomelib/settings.py Mon Jun 13 23:01:59 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -import vim - - -def setting(name, default=None): - full_name = 'g:threesome_' + name - - if not int(vim.eval('exists("%s")' % full_name)): - return default - else: - return vim.eval(full_name) - -def boolsetting(name): - if int(setting(name, 0)): - return True - else: - False diff -r 4995b244e11d -r cefc901de8a2 plugin/threesomelib/util/__init__.py --- a/plugin/threesomelib/util/__init__.py Mon Jun 13 23:01:59 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -# This is kind of a dirty hack. Feels bad, man. -from bufferlib import buffers diff -r 4995b244e11d -r cefc901de8a2 plugin/threesomelib/util/bufferlib.py --- a/plugin/threesomelib/util/bufferlib.py Mon Jun 13 23:01:59 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -import os -import vim -import windows - -ap = os.path.abspath - -class Buffer(object): - def __init__(self, i): - self.number = i + 1 - self._buffer = vim.buffers[i] - self.name = self._buffer.name - - def open(self, winnr=None): - if winnr is not None: - windows.focus(winnr) - vim.command('%dbuffer' % self.number) - - def set_lines(self, lines): - self._buffer[:] = lines - - @property - def lines(self): - for line in self._buffer: - yield line - - - def __eq__(self, other): - return self.name == other.name - - def __ne__(self, other): - return self.name != other.name - - -class _BufferList(object): - @property - def original(self): - return Buffer(0) - - @property - def one(self): - return Buffer(1) - - @property - def two(self): - return Buffer(2) - - @property - def result(self): - return Buffer(3) - - @property - def hud(self): - return Buffer(int(vim.eval("bufnr('__Threesome_HUD__')")) - 1) - - - @property - def current(self): - bufname = ap(vim.eval('bufname("%")')) - - if bufname == ap(self.original.name): - return self.original - elif bufname == ap(self.one.name): - return self.one - elif bufname == ap(self.two.name): - return self.two - elif bufname == ap(self.result.name): - return self.result - - @property - def all(self): - return [self.original, self.one, self.two, self.result] - - - @property - def labels(self): - return { buffers.original.name: 'Original', - buffers.one.name: 'One', - buffers.two.name: 'Two', - buffers.result.name: 'Result' } - -buffers = _BufferList() - diff -r 4995b244e11d -r cefc901de8a2 plugin/threesomelib/util/io.py --- a/plugin/threesomelib/util/io.py Mon Jun 13 23:01:59 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -import sys - - -def error(m): - sys.stdout.write(str(m) + '\n') diff -r 4995b244e11d -r cefc901de8a2 plugin/threesomelib/util/keys.py --- a/plugin/threesomelib/util/keys.py Mon Jun 13 23:01:59 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -import vim - - -def bind(key, to, options='', mode=None, leader=''): - vim.command('nnoremap %s %s%s %s' % (options, leader, key, to)) - -def unbind(key, options='', leader=''): - vim.command('unmap %s %s%s' % (options, leader, key)) - diff -r 4995b244e11d -r cefc901de8a2 plugin/threesomelib/util/windows.py --- a/plugin/threesomelib/util/windows.py Mon Jun 13 23:01:59 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -import vim - - -def focus(winnr): - vim.command('%dwincmd w' % winnr) - -def close(winnr): - focus(winnr) - vim.command('wincmd c') - -def close_all(): - for winnr in range(len(vim.windows) - 1): - close(winnr) - -def split(): - vim.command('wincmd s') - -def vsplit(): - vim.command('wincmd v') - -def currentnr(): - return int(vim.eval('winnr()')) - -def pos(): - return vim.current.window.cursor - - -class remain: - def __enter__(self): - self.curwindow = currentnr() - self.pos = pos() - - def __exit__(self, type, value, traceback): - focus(self.curwindow) - vim.current.window.cursor = self.pos -