Skip to content

Commit fb8e3b5

Browse files
committed
Support any scm by assigning args at startup
Fix #13: add g:mergetool_args_order. Add g:mergetool_args_order to renames arguments as hidden files with the same names as git (BASE, REMOTE, LOCAL). This allows mergetool to behave as if invoked by git-mergetool for any scm.
1 parent 0275a85 commit fb8e3b5

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

autoload/mergetool.vim

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ endfunction
66
let g:mergetool_layout = get(g:, 'mergetool_layout', 'mr')
77
let g:mergetool_prefer_revision = get(g:, 'mergetool_prefer_revision', 'local')
88
let g:MergetoolSetLayoutCallback = get(g:, 'MergetoolSetLayoutCallback', function('s:noop'))
9+
let g:mergetool_args_order = get(g:, 'mergetool_args_order', '')
910

1011
" {{{ Public exports
1112

@@ -38,6 +39,16 @@ function! mergetool#start() "{{{
3839
let s:mergedfile_fileformat = &fileformat
3940
let s:mergedfile_filetype = &filetype
4041

42+
if !empty(g:mergetool_args_order)
43+
let success = s:apply_args_order(s:mergedfile_bufnr, g:mergetool_args_order)
44+
if !success
45+
echohl WarningMsg
46+
echo "g:mergetool_args_order didn't use the current file as MERGED. Ensure you're using the order as seen in :args."
47+
echohl None
48+
return
49+
endif
50+
endif
51+
4152
" Detect if we're run as 'git mergetool' by presence of BASE|LOCAL|REMOTE buf names
4253
let s:run_as_git_mergetool = bufnr('BASE') != -1 &&
4354
\ bufnr('LOCAL') != -1 &&
@@ -117,6 +128,38 @@ function! mergetool#toggle() " {{{
117128
endif
118129
endfunction " }}}
119130

131+
" Create hidden buffers that use git's special buffer names to support any
132+
" scm. We never create a MERGED buffer. Instead, return it so we can validate
133+
" it's as expected.
134+
function! s:apply_args_order(merged_bufnr, arg_order) " {{{
135+
let abbrevs = {
136+
\ 'M': 'MERGED',
137+
\ 'B': 'BASE',
138+
\ 'R': 'REMOTE',
139+
\ 'L': 'LOCAL' }
140+
141+
let i = 1
142+
for labbr in split(a:arg_order, '\zs')
143+
if labbr ==# 'M'
144+
let current_arg_bufnr = bufnr(argv(i - 1))
145+
if a:merged_bufnr != current_arg_bufnr
146+
" Fail -- input merged buffer number doesn't match arg order.
147+
return 0
148+
endif
149+
else
150+
execute i 'argument'
151+
execute 'file' abbrevs[labbr]
152+
setlocal buftype=nofile
153+
setlocal bufhidden=hide
154+
endif
155+
let i += 1
156+
endfor
157+
158+
execute "buffer " . a:merged_bufnr
159+
" Success
160+
return 1
161+
endfunction " }}}
162+
120163
" Opens set of windows with merged file and various file revisions
121164
" Supported layout options:
122165
" - w, 'MERGED' revision as passed by Git, or working tree version of merged file

readme.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,41 @@ Git detects whether merge was successful or not in two ways:
275275
`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.
276276

277277

278+
### Running as other scm mergetool
279+
280+
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:
281+
282+
gvim --nofork -c "let g:mergetool_args_order = 'MBRL'" -c "MergetoolStart" $MERGED $BASE $REMOTE $LOCAL
283+
284+
**MERGED should be the first file** because MergetoolStart is only valid in a file with conflict markers.
285+
286+
Your scm likely has its own names for these filenames. Check your documentation.
287+
288+
289+
#### Example: Subversion
290+
291+
Subversion names the files something like this:
292+
293+
* MERGED --> file.vim
294+
* BASE --> file.vim.r404217
295+
* REMOTE --> file.vim.r404563
296+
* LOCAL --> file.vim.mine
297+
298+
So you'd start a merge like this:
299+
300+
gvim --nofork -c "let g:mergetool_args_order = 'MBRL'" -c "MergetoolStart" file.vim file.vim.r404217 file.vim.r404563 file.vim.mine
301+
302+
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).
303+
304+
For TortoiseSVN, create a batchfile like this and set it as your mergetool:
305+
306+
set LOCAL=%1
307+
set REMOTE=%2
308+
set BASE=%3
309+
set MERGED=%4
310+
gvim --nofork -c "let g:mergetool_args_order = 'MBLR'" -c "Merge" "%MERGED%" "%BASE%" "%LOCAL%" "%REMOTE%"
311+
312+
278313
### Running directly from running Vim instance
279314
You can enter and exit merge mode from running Vim instance by opening a file with conflict markers, and running one of the commands:
280315

0 commit comments

Comments
 (0)