diff --git a/autoload/mergetool.vim b/autoload/mergetool.vim index f13288e..b7b84b6 100644 --- a/autoload/mergetool.vim +++ b/autoload/mergetool.vim @@ -6,6 +6,7 @@ endfunction let g:mergetool_layout = get(g:, 'mergetool_layout', 'mr') let g:mergetool_prefer_revision = get(g:, 'mergetool_prefer_revision', 'local') let g:MergetoolSetLayoutCallback = get(g:, 'MergetoolSetLayoutCallback', function('s:noop')) +let g:mergetool_args_order = get(g:, 'mergetool_args_order', '') " {{{ Public exports @@ -38,6 +39,16 @@ function! mergetool#start() "{{{ let s:mergedfile_fileformat = &fileformat let s:mergedfile_filetype = &filetype + if !empty(g:mergetool_args_order) + let success = s:apply_args_order(s:mergedfile_bufnr, g:mergetool_args_order) + if !success + echohl WarningMsg + echo "g:mergetool_args_order didn't use the current file as MERGED. Ensure you're using the order as seen in :args." + echohl None + return + endif + endif + " Detect if we're run as 'git mergetool' by presence of BASE|LOCAL|REMOTE buf names let s:run_as_git_mergetool = bufnr('BASE') != -1 && \ bufnr('LOCAL') != -1 && @@ -144,6 +155,38 @@ function! mergetool#toggle() " {{{ endif endfunction " }}} +" Create hidden buffers that use git's special buffer names to support any +" scm. We never create a MERGED buffer. Instead, return it so we can validate +" it's as expected. +function! s:apply_args_order(merged_bufnr, arg_order) " {{{ + let abbrevs = { + \ 'M': 'MERGED', + \ 'B': 'BASE', + \ 'R': 'REMOTE', + \ 'L': 'LOCAL' } + + let i = 1 + for labbr in split(a:arg_order, '\zs') + if labbr ==# 'M' + let current_arg_bufnr = bufnr(argv(i - 1)) + if a:merged_bufnr != current_arg_bufnr + " Fail -- input merged buffer number doesn't match arg order. + return 0 + endif + else + execute i 'argument' + execute 'file' abbrevs[labbr] + setlocal buftype=nofile + setlocal bufhidden=hide + endif + let i += 1 + endfor + + execute "buffer " . a:merged_bufnr + " Success + return 1 +endfunction " }}} + " Opens set of windows with merged file and various file revisions " Supported layout options: " - w, 'MERGED' revision as passed by Git, or working tree version of merged file diff --git a/readme.md b/readme.md index 9599ce9..a6bcaad 100644 --- a/readme.md +++ b/readme.md @@ -275,6 +275,41 @@ Git detects whether merge was successful or not in two ways: `vim-mergetool` supports both options. On quit, if merge was unsuccessful, it both discards any unsaved changes to buffer without touching file's `ctime` and returns non-zero exit code. +### Running as other scm mergetool + +You can set the g:mergetool_args_order variable when you start vim to tell vim-mergetool that your arguments are the files to use for merging. Setup your scm to start vim like this: + + gvim --nofork -c "let g:mergetool_args_order = 'MBRL'" -c "MergetoolStart" $MERGED $BASE $REMOTE $LOCAL + +**MERGED should be the first file** because MergetoolStart is only valid in a file with conflict markers. + +Your scm likely has its own names for these filenames. Check your documentation. + + +#### Example: Subversion + +Subversion names the files something like this: + +* MERGED --> file.vim +* BASE --> file.vim.r404217 +* REMOTE --> file.vim.r404563 +* LOCAL --> file.vim.mine + +So you'd start a merge like this: + + gvim --nofork -c "let g:mergetool_args_order = 'MBRL'" -c "MergetoolStart" file.vim file.vim.r404217 file.vim.r404563 file.vim.mine + +vim-mergetool will act like it does as a git-mergetool (no extra tab and won't try to access git to load other files). + +For TortoiseSVN, create a batchfile like this and set it as your mergetool: + + set LOCAL=%1 + set REMOTE=%2 + set BASE=%3 + set MERGED=%4 + gvim --nofork -c "let g:mergetool_args_order = 'MBLR'" -c "Merge" "%MERGED%" "%BASE%" "%LOCAL%" "%REMOTE%" + + ### Running directly from running Vim instance You can enter and exit merge mode from running Vim instance by opening a file with conflict markers, and running one of the commands: