Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support any scm by assigning args at startup #17

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions autoload/mergetool.vim
Original file line number Diff line number Diff line change
@@ -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 &&
@@ -117,6 +128,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 'silent' i 'argument'
execute 'silent 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
35 changes: 35 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -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: