GLVS
This commit is contained in:
parent
121cd1ddca
commit
f8ab290619
@ -38,5 +38,5 @@ ScriptID SourceID Filename
|
||||
2975 22815 fugitive.vim
|
||||
2830 22798 csv.vim
|
||||
3849 22637 git-time-lapse
|
||||
4932 22787 diffchar.vim
|
||||
4955 22442 Merginal
|
||||
4932 22924 diffchar.vim
|
||||
4955 22916 Merginal
|
||||
|
@ -140,15 +140,30 @@ endfunction
|
||||
|
||||
"Like merginal#runGitCommandInTreeReturnResult but split result to lines
|
||||
function! merginal#runGitCommandInTreeReturnResultLines(repo,command)
|
||||
let l:dir=getcwd()
|
||||
execute 'cd '.fnameescape(a:repo.tree())
|
||||
try
|
||||
return split(merginal#system(a:repo.git_command().' '.a:command),'\r\n\|\n\|\r')
|
||||
finally
|
||||
execute 'cd '.fnameescape(l:dir)
|
||||
endtry
|
||||
return split(merginal#runGitCommandInTreeReturnResult(a:repo, a:command),
|
||||
\ '\r\n\|\n\|\r')
|
||||
endfunction
|
||||
|
||||
function! s:cleanup_term_codes(s)
|
||||
let s = substitute(a:s, '\t', ' ', 'g')
|
||||
" Remove terminal escape codes for colors (based on
|
||||
" www.commandlinefu.com/commands/view/3584/).
|
||||
let s = substitute(s, '\v\[([0-9]{1,3}(;[0-9]{1,3})?)?[m|K]', '', 'g')
|
||||
return s
|
||||
endfunction
|
||||
|
||||
function! merginal#runGitCommandInTreeEcho(repo,command)
|
||||
let l:lines = merginal#runGitCommandInTreeReturnResultLines(a:repo, a:command)
|
||||
if len(l:lines) == 1
|
||||
" Output a single/empty line to make Vim wait for Enter.
|
||||
echo ' '
|
||||
endif
|
||||
for l:line in l:lines
|
||||
echo "[output]" s:cleanup_term_codes(l:line)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
|
||||
"Returns 1 if there was a merginal bufffer to close
|
||||
function! merginal#closeMerginalBuffer()
|
||||
let l:merginalWindowNumber=bufwinnr('Merginal:')
|
||||
@ -300,6 +315,53 @@ function! merginal#fileDetails(lineNumber)
|
||||
return l:result
|
||||
endfunction
|
||||
|
||||
"For the commit in the specified line, retrieve it's hash
|
||||
function! merginal#commitHash(lineNumber)
|
||||
if !exists('b:merginal_repo')
|
||||
throw 'Unable to get commit details outside the merginal window'
|
||||
endif
|
||||
if line(a:lineNumber)<=b:headerLinesCount
|
||||
throw 'Unable to get commit details for the header of the merginal window'
|
||||
endif
|
||||
"echo a:lineNumber
|
||||
if type(0) == type(a:lineNumber)
|
||||
let l:lineNumber = a:lineNumber
|
||||
else
|
||||
let l:lineNumber = line(a:lineNumber)
|
||||
endif
|
||||
while b:headerLinesCount < l:lineNumber && !empty(getline(l:lineNumber))
|
||||
let l:lineNumber -= 1
|
||||
endwhile
|
||||
let l:lineNumber += 1
|
||||
return split(getline(l:lineNumber))[0]
|
||||
endfunction
|
||||
|
||||
"For the commit in the specified line, retrieve:
|
||||
" - fullHash
|
||||
" - authorName
|
||||
" - timestamp
|
||||
" - subject
|
||||
" - body
|
||||
function! merginal#commitDetails(lineNumber)
|
||||
let l:commitHash = merginal#commitHash(a:lineNumber)
|
||||
let l:entryFormat = join(['%H', '%aN', '%aE', '%ai', '%B'], '%x01')
|
||||
let l:commitLines = split(
|
||||
\ merginal#system(b:merginal_repo.git_command('--no-pager', 'log', '-1', '--format='.l:entryFormat, l:commitHash)),
|
||||
\ '\%x01')
|
||||
let l:result = {}
|
||||
|
||||
let l:result.fullHash = l:commitLines[0]
|
||||
let l:result.authorName = l:commitLines[1]
|
||||
let l:result.authorEmail = l:commitLines[2]
|
||||
let l:result.timestamp = l:commitLines[3]
|
||||
|
||||
let l:commitMessage = split(l:commitLines[4], '\r\n\|\n\|\r')
|
||||
let l:result.subject = l:commitMessage[0]
|
||||
let l:result.body = join(l:commitMessage[2 :], "\n")
|
||||
|
||||
return l:result
|
||||
endfunction
|
||||
|
||||
function! merginal#getLocalBranchNamesThatTrackARemoteBranch(remoteBranchName)
|
||||
"Get verbose list of branches
|
||||
let l:branchList=split(merginal#system(b:merginal_repo.git_command('branch','-vv')),'\r\n\|\n\|\r')
|
||||
@ -351,6 +413,8 @@ function! merginal#openBranchListBuffer(...)
|
||||
endfunction
|
||||
|
||||
augroup merginal
|
||||
autocmd!
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> q <C-w>q
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> R :call merginal#tryRefreshBranchListBuffer(0)<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> C :call <SID>checkoutBranchUnderCursor()<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> cc :call <SID>checkoutBranchUnderCursor()<Cr>
|
||||
@ -364,12 +428,14 @@ augroup merginal
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> mm :call <SID>mergeBranchUnderCursor()<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> mf :call <SID>mergeBranchUnderCursorUsingFugitive()<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> rb :call <SID>rebaseBranchUnderCursor()<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> ps :call <SID>remoteActionForBranchUnderCursor('push',0)<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> pS :call <SID>remoteActionForBranchUnderCursor('push',1)<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> pl :call <SID>remoteActionForBranchUnderCursor('pull',0)<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> pf :call <SID>remoteActionForBranchUnderCursor('fetch',0)<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> ps :call <SID>remoteActionForBranchUnderCursor('push',[])<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> pS :call <SID>remoteActionForBranchUnderCursor('push',['--force'])<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> pl :call <SID>remoteActionForBranchUnderCursor('pull',[])<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> pr :call <SID>remoteActionForBranchUnderCursor('pull',['--rebase'])<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> pf :call <SID>remoteActionForBranchUnderCursor('fetch',[])<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> gd :call <SID>diffWithBranchUnderCursor()<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> rn :call <SID>renameBranchUnderCursor()<Cr>
|
||||
autocmd User Merginal_BranchList nnoremap <buffer> gl :call <SID>historyLogForBranchUnderCursor()<Cr>
|
||||
augroup END
|
||||
|
||||
"If the current buffer is a branch list buffer - refresh it!
|
||||
@ -380,12 +446,11 @@ function! merginal#tryRefreshBranchListBuffer(jumpToCurrentBranch)
|
||||
|
||||
setlocal modifiable
|
||||
"Clear the buffer:
|
||||
normal ggdG
|
||||
silent normal! gg"_dG
|
||||
"Write the branch list:
|
||||
call setline(1,l:branchList)
|
||||
setlocal nomodifiable
|
||||
|
||||
|
||||
if a:jumpToCurrentBranch
|
||||
"Find the current branch's index
|
||||
let l:currentBranchIndex=-1
|
||||
@ -409,7 +474,7 @@ endfunction
|
||||
function! s:checkoutBranchUnderCursor()
|
||||
if 'Merginal:Branches'==bufname('')
|
||||
let l:branch=merginal#branchDetails('.')
|
||||
echo merginal#runGitCommandInTreeReturnResult(b:merginal_repo,'--no-pager checkout '.shellescape(l:branch.handle))
|
||||
call merginal#runGitCommandInTreeEcho(b:merginal_repo,'--no-pager checkout '.shellescape(l:branch.handle))
|
||||
call merginal#reloadBuffers()
|
||||
call merginal#tryRefreshBranchListBuffer(0)
|
||||
endif
|
||||
@ -427,11 +492,11 @@ function! s:trackBranchUnderCursor(promptForName)
|
||||
let l:newBranchName=input('Track `'.l:branch.handle.'` as: ',l:newBranchName)
|
||||
if empty(l:newBranchName)
|
||||
echo ' '
|
||||
echo 'Branch tracking canceled by the user'
|
||||
echom 'Branch tracking canceled by user.'
|
||||
return
|
||||
endif
|
||||
endif
|
||||
echo merginal#runGitCommandInTreeReturnResult(b:merginal_repo,'--no-pager checkout -b '.shellescape(l:newBranchName).' --track '.shellescape(l:branch.handle))
|
||||
call merginal#runGitCommandInTreeEcho(b:merginal_repo,'--no-pager checkout -b '.shellescape(l:newBranchName).' --track '.shellescape(l:branch.handle))
|
||||
call merginal#reloadBuffers()
|
||||
call merginal#tryRefreshBranchListBuffer(0)
|
||||
endif
|
||||
@ -443,10 +508,10 @@ function! s:promptToCreateNewBranch()
|
||||
let l:newBranchName=input('Branch `'.b:merginal_repo.head().'` to: ')
|
||||
if empty(l:newBranchName)
|
||||
echo ' '
|
||||
echo 'Branch creation canceled by the user'
|
||||
echom 'Branch creation canceled by user.'
|
||||
return
|
||||
endif
|
||||
echo merginal#runGitCommandInTreeReturnResult(b:merginal_repo,'--no-pager checkout -b '.shellescape(l:newBranchName))
|
||||
call merginal#runGitCommandInTreeEcho(b:merginal_repo,'--no-pager checkout -b '.shellescape(l:newBranchName))
|
||||
call merginal#reloadBuffers()
|
||||
call merginal#tryRefreshBranchListBuffer(1)
|
||||
endif
|
||||
@ -465,8 +530,7 @@ function! s:deleteBranchUnderCursor()
|
||||
endif
|
||||
if l:answer
|
||||
if l:branch.isLocal
|
||||
echo ' '
|
||||
echo merginal#runGitCommandInTreeReturnResult(b:merginal_repo,'--no-pager branch -D '.shellescape(l:branch.handle))
|
||||
call merginal#runGitCommandInTreeEcho(b:merginal_repo,'--no-pager branch -D '.shellescape(l:branch.handle))
|
||||
else
|
||||
execute '!'.b:merginal_repo.git_command('push').' '.shellescape(l:branch.remote).' --delete '.shellescape(l:branch.name)
|
||||
endif
|
||||
@ -474,7 +538,7 @@ function! s:deleteBranchUnderCursor()
|
||||
call merginal#tryRefreshBranchListBuffer(0)
|
||||
else
|
||||
echo ' '
|
||||
echo 'Branch deletion canceled by the user'
|
||||
echom 'Branch deletion canceled by user.'
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
@ -483,8 +547,7 @@ endfunction
|
||||
function! s:mergeBranchUnderCursor()
|
||||
if 'Merginal:Branches'==bufname('')
|
||||
let l:branch=merginal#branchDetails('.')
|
||||
echo ' '
|
||||
echo merginal#runGitCommandInTreeReturnResult(b:merginal_repo,'merge --no-commit '.shellescape(l:branch.handle))
|
||||
call merginal#runGitCommandInTreeEcho(b:merginal_repo,'merge --no-commit '.shellescape(l:branch.handle))
|
||||
call merginal#reloadBuffers()
|
||||
if v:shell_error
|
||||
call merginal#openMergeConflictsBuffer(winnr())
|
||||
@ -512,8 +575,7 @@ endfunction
|
||||
function! s:rebaseBranchUnderCursor()
|
||||
if 'Merginal:Branches'==bufname('')
|
||||
let l:branch=merginal#branchDetails('.')
|
||||
echo ' '
|
||||
echo merginal#runGitCommandInTreeReturnResult(b:merginal_repo,'rebase '.shellescape(l:branch.handle))
|
||||
call merginal#runGitCommandInTreeEcho(b:merginal_repo,'rebase '.shellescape(l:branch.handle))
|
||||
call merginal#reloadBuffers()
|
||||
if v:shell_error
|
||||
call merginal#openRebaseConflictsBuffer(winnr())
|
||||
@ -522,7 +584,7 @@ function! s:rebaseBranchUnderCursor()
|
||||
endfunction
|
||||
|
||||
"Run various remote actions
|
||||
function! s:remoteActionForBranchUnderCursor(remoteAction,force)
|
||||
function! s:remoteActionForBranchUnderCursor(remoteAction,flags)
|
||||
if 'Merginal:Branches'==bufname('')
|
||||
let l:branch=merginal#branchDetails('.')
|
||||
if l:branch.isLocal
|
||||
@ -597,9 +659,9 @@ function! s:remoteActionForBranchUnderCursor(remoteAction,force)
|
||||
endif
|
||||
|
||||
let l:gitCommandWithArgs=[a:remoteAction]
|
||||
if a:force
|
||||
call add(l:gitCommandWithArgs,'--force')
|
||||
endif
|
||||
for l:flag in a:flags
|
||||
call add(l:gitCommandWithArgs,l:flag)
|
||||
endfor
|
||||
|
||||
let l:reloadBuffers=0
|
||||
|
||||
@ -645,10 +707,7 @@ function! s:diffWithBranchUnderCursor()
|
||||
if 'Merginal:Branches'==bufname('')
|
||||
\|| 'Merginal:RebaseAmend'==bufname('')
|
||||
let l:branch=merginal#branchDetails('.')
|
||||
if l:branch.isCurrent
|
||||
throw 'Can not diff against the current branch'
|
||||
endif
|
||||
call merginal#openDiffFilesBuffer(l:branch)
|
||||
call merginal#openDiffFilesBuffer(l:branch.handle)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@ -663,10 +722,10 @@ function! s:renameBranchUnderCursor()
|
||||
let l:newName=input('Rename `'.l:branch.handle.'` to: ',l:branch.name)
|
||||
echo ' '
|
||||
if empty(l:newName)
|
||||
echo 'Branch rename canceled by the user'
|
||||
echom 'Branch rename canceled by user.'
|
||||
return
|
||||
elseif l:newName==l:branch.name
|
||||
echo 'Branch name was not modified'
|
||||
echom 'Branch name was not modified.'
|
||||
return
|
||||
endif
|
||||
|
||||
@ -677,6 +736,16 @@ function! s:renameBranchUnderCursor()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Opens the history log buffer
|
||||
function! s:historyLogForBranchUnderCursor()
|
||||
if 'Merginal:Branches'==bufname('')
|
||||
\|| 'Merginal:RebaseAmend'==bufname('')
|
||||
let l:branch=merginal#branchDetails('.')
|
||||
call merginal#openHistoryLogBuffer(l:branch)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
|
||||
"Open the merge conflicts buffer for resolving merge conflicts
|
||||
@ -691,6 +760,7 @@ function! merginal#openMergeConflictsBuffer(...)
|
||||
endfunction
|
||||
|
||||
augroup merginal
|
||||
autocmd User Merginal_MergeConflicts nnoremap <buffer> q <C-w>q
|
||||
autocmd User Merginal_MergeConflicts nnoremap <buffer> R :call merginal#tryRefreshMergeConflictsBuffer(0)<Cr>
|
||||
autocmd User Merginal_MergeConflicts nnoremap <buffer> <Cr> :call <SID>openMergeConflictUnderCursor()<Cr>
|
||||
autocmd User Merginal_MergeConflicts nnoremap <buffer> A :call <SID>addConflictedFileToStagingArea()<Cr>
|
||||
@ -719,7 +789,7 @@ function! s:refreshConflictsBuffer(fileToJumpTo,headerLines)
|
||||
|
||||
setlocal modifiable
|
||||
"Clear the buffer:
|
||||
normal ggdG
|
||||
silent normal! gg"_dG
|
||||
"Write the branch list:
|
||||
call setline(1,a:headerLines+l:conflicts)
|
||||
let b:headerLinesCount=len(a:headerLines)
|
||||
@ -773,7 +843,7 @@ function! s:addConflictedFileToStagingArea()
|
||||
if empty(l:file.name)
|
||||
return
|
||||
endif
|
||||
echo merginal#runGitCommandInTreeReturnResult(b:merginal_repo,'--no-pager add '.shellescape(fnamemodify(l:file.name,':p')))
|
||||
call merginal#runGitCommandInTreeEcho(b:merginal_repo,'--no-pager add '.shellescape(fnamemodify(l:file.name,':p')))
|
||||
|
||||
if 'Merginal:Conflicts'==bufname('')
|
||||
if merginal#tryRefreshMergeConflictsBuffer(0)
|
||||
@ -789,7 +859,7 @@ function! s:addConflictedFileToStagingArea()
|
||||
else
|
||||
if merginal#tryRefreshRebaseConflictsBuffer(0)
|
||||
echo 'Added the last file of this patch.'
|
||||
echo 'Continue to the next patch(y/n)?'
|
||||
echo 'Continue to the next patch (y/N)?'
|
||||
let l:answer=getchar()
|
||||
if char2nr('y')==l:answer || char2nr('Y')==l:answer
|
||||
call s:rebaseAction('continue')
|
||||
@ -800,19 +870,20 @@ function! s:addConflictedFileToStagingArea()
|
||||
endfunction
|
||||
|
||||
|
||||
"Open the diff files buffer for diffing agains another branch
|
||||
function! merginal#openDiffFilesBuffer(diffBranch,...)
|
||||
"Open the diff files buffer for diffing agains another branch/commit
|
||||
function! merginal#openDiffFilesBuffer(diffTarget,...)
|
||||
if merginal#openTuiBuffer('Merginal:Diff',get(a:000,1,bufwinnr('Merginal:')))
|
||||
doautocmd User Merginal_DiffFiles
|
||||
endif
|
||||
|
||||
let b:merginal_diffBranch=a:diffBranch
|
||||
let b:merginal_diffTarget=a:diffTarget
|
||||
|
||||
"At any rate, refresh the buffer:
|
||||
call merginal#tryRefreshDiffFilesBuffer()
|
||||
endfunction
|
||||
|
||||
augroup merginal
|
||||
autocmd User Merginal_DiffFiles nnoremap <buffer> q <C-w>q
|
||||
autocmd User Merginal_DiffFiles nnoremap <buffer> R :call merginal#tryRefreshDiffFilesBuffer()<Cr>
|
||||
autocmd User Merginal_DiffFiles nnoremap <buffer> <Cr> :call <SID>openDiffFileUnderCursor()<Cr>
|
||||
autocmd User Merginal_DiffFiles nnoremap <buffer> ds :call <SID>openDiffFileUnderCursorAndDiff('s')<Cr>
|
||||
@ -859,16 +930,16 @@ function! merginal#diffFileDetails(lineNumber)
|
||||
return l:result
|
||||
endfunction
|
||||
|
||||
"If the current buffer is a branch list buffer - refresh it!
|
||||
"If the current buffer is a diff files buffer - refresh it!
|
||||
function! merginal#tryRefreshDiffFilesBuffer()
|
||||
if 'Merginal:Diff'==bufname('')
|
||||
let l:diffBranch=b:merginal_diffBranch
|
||||
let l:diffFiles=merginal#runGitCommandInTreeReturnResultLines(b:merginal_repo,'diff --name-status '.shellescape(l:diffBranch.handle))
|
||||
let l:diffTarget=b:merginal_diffTarget
|
||||
let l:diffFiles=merginal#runGitCommandInTreeReturnResultLines(b:merginal_repo,'diff --name-status '.shellescape(l:diffTarget))
|
||||
let l:currentLine=line('.')
|
||||
|
||||
setlocal modifiable
|
||||
"Clear the buffer:
|
||||
normal ggdG
|
||||
silent normal! gg"_dG
|
||||
"Write the diff files list:
|
||||
call setline(1,l:diffFiles)
|
||||
setlocal nomodifiable
|
||||
@ -903,7 +974,7 @@ function! s:openDiffFileUnderCursorAndDiff(diffType)
|
||||
endif
|
||||
|
||||
let l:repo=b:merginal_repo
|
||||
let l:diffBranch=b:merginal_diffBranch
|
||||
let l:diffTarget=b:merginal_diffTarget
|
||||
|
||||
"Close currently open git diffs
|
||||
let l:currentWindowBuffer=winbufnr('.')
|
||||
@ -919,11 +990,11 @@ function! s:openDiffFileUnderCursorAndDiff(diffType)
|
||||
|
||||
call merginal#openFileDecidedWindow(l:repo,l:diffFile.fileFullPath)
|
||||
|
||||
execute ':G'.a:diffType.'diff '.fnameescape(l:diffBranch.handle)
|
||||
execute ':G'.a:diffType.'diff '.fnameescape(l:diffTarget)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Checks out the file from the other branch to the current branch
|
||||
"Checks out the file from the diff target to the current branch
|
||||
function! s:checkoutDiffFileUnderCursor()
|
||||
if 'Merginal:Diff'==bufname('')
|
||||
let l:diffFile=merginal#diffFileDetails('.')
|
||||
@ -937,13 +1008,13 @@ function! s:checkoutDiffFileUnderCursor()
|
||||
let l:answer='yes'==input('Override `'.l:diffFile.fileInTree.'`? (type "yes" to confirm) ')
|
||||
endif
|
||||
if l:answer
|
||||
echo merginal#runGitCommandInTreeReturnResult(b:merginal_repo,'--no-pager checkout '.shellescape(b:merginal_diffBranch.handle)
|
||||
call merginal#runGitCommandInTreeEcho(b:merginal_repo,'--no-pager checkout '.shellescape(b:merginal_diffTarget)
|
||||
\.' -- '.shellescape(l:diffFile.fileFullPath))
|
||||
call merginal#reloadBuffers()
|
||||
call merginal#tryRefreshDiffFilesBuffer()
|
||||
else
|
||||
echo ' '
|
||||
echo 'File checkout canceled by the user'
|
||||
echo
|
||||
echom 'File checkout canceled by user.'
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
@ -961,6 +1032,7 @@ function! merginal#openRebaseConflictsBuffer(...)
|
||||
endfunction
|
||||
|
||||
augroup merginal
|
||||
autocmd User Merginal_RebaseConflicts nnoremap <buffer> q <C-w>q
|
||||
autocmd User Merginal_RebaseConflicts nnoremap <buffer> R :call merginal#tryRefreshRebaseConflictsBuffer(0)<Cr>
|
||||
autocmd User Merginal_RebaseConflicts nnoremap <buffer> <Cr> :call <SID>openMergeConflictUnderCursor()<Cr>
|
||||
autocmd User Merginal_RebaseConflicts nnoremap <buffer> A :call <SID>addConflictedFileToStagingArea()<Cr>
|
||||
@ -986,7 +1058,7 @@ endfunction
|
||||
function! s:rebaseAction(remoteAction)
|
||||
if 'Merginal:Rebase'==bufname('')
|
||||
\|| 'Merginal:RebaseAmend'==bufname('')
|
||||
echo merginal#runGitCommandInTreeReturnResult(b:merginal_repo,'--no-pager rebase --'.a:remoteAction)
|
||||
call merginal#runGitCommandInTreeEcho(b:merginal_repo,'--no-pager rebase --'.a:remoteAction)
|
||||
call merginal#reloadBuffers()
|
||||
if merginal#isRebaseMode()
|
||||
call merginal#tryRefreshRebaseConflictsBuffer(0)
|
||||
@ -1012,15 +1084,18 @@ function! merginal#openRebaseAmendBuffer(...)
|
||||
call merginal#tryRefreshRebaseAmendBuffer()
|
||||
endfunction
|
||||
|
||||
augroup merginal
|
||||
autocmd User Merginal_RebaseAmend nnoremap <buffer> q <C-w>q
|
||||
autocmd User Merginal_RebaseAmend nnoremap <buffer> R :call merginal#tryRefreshRebaseAmendBuffer()<Cr>
|
||||
autocmd User Merginal_RebaseAmend nnoremap <buffer> ra :call <SID>rebaseAction('abort')<Cr>
|
||||
autocmd User Merginal_RebaseAmend nnoremap <buffer> rs :call <SID>rebaseAction('skip')<Cr>
|
||||
autocmd User Merginal_RebaseAmend nnoremap <buffer> rc :call <SID>rebaseAction('continue')<Cr>
|
||||
autocmd User Merginal_RebaseAmend nnoremap <buffer> gd :call <SID>diffWithBranchUnderCursor()<Cr>
|
||||
autocmd User Merginal_RebaseAmend nnoremap <buffer> gl :call <SID>historyLogForBranchUnderCursor()<Cr>
|
||||
augroup END
|
||||
|
||||
function! merginal#tryRefreshRebaseAmendBuffer()
|
||||
if 'Merginal:RebaseAmend'==bufname('')
|
||||
"let l:gitStatusOutput=split(merginal#system(b:merginal_repo.git_command('status','--all')),'\r\n\|\n\|\r')
|
||||
let l:currentLine=line('.')
|
||||
let l:newBufferLines=[]
|
||||
let l:amendedCommit=readfile(b:merginal_repo.dir('rebase-merge','amend'))
|
||||
@ -1042,7 +1117,7 @@ function! merginal#tryRefreshRebaseAmendBuffer()
|
||||
|
||||
setlocal modifiable
|
||||
"Clear the buffer:
|
||||
normal ggdG
|
||||
silent normal! gg"_dG
|
||||
"Write the new buffer lines:
|
||||
call setline(1,l:newBufferLines)
|
||||
"call setline(1,l:branchList)
|
||||
@ -1050,3 +1125,113 @@ function! merginal#tryRefreshRebaseAmendBuffer()
|
||||
endif
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"Open the history log buffer
|
||||
function! merginal#openHistoryLogBuffer(logBranch,...)
|
||||
let l:currentFile=expand('%:~:.')
|
||||
if merginal#openTuiBuffer('Merginal:HistoryLog',get(a:000,1,bufwinnr('Merginal:')))
|
||||
doautocmd User Merginal_HistoryLog
|
||||
endif
|
||||
|
||||
let b:merginal_branch=a:logBranch
|
||||
|
||||
"At any rate, refresh the buffer:
|
||||
call merginal#tryRefreshHistoryLogBuffer()
|
||||
endfunction
|
||||
|
||||
augroup merginal
|
||||
autocmd User Merginal_HistoryLog nnoremap <buffer> q <C-w>q
|
||||
autocmd User Merginal_HistoryLog nnoremap <buffer> R :call merginal#tryRefreshHistoryLogBuffer()<Cr>
|
||||
autocmd User Merginal_HistoryLog nnoremap <buffer> <C-p> :call <SID>moveToNextOrPreviousCommit(-1)<Cr>
|
||||
autocmd User Merginal_HistoryLog nnoremap <buffer> <C-n> :call <SID>moveToNextOrPreviousCommit(1)<Cr>
|
||||
autocmd User Merginal_HistoryLog nnoremap <buffer> S :call <SID>printCommitUnderCurosr('fuller')<Cr>
|
||||
autocmd User Merginal_HistoryLog nnoremap <buffer> ss :call <SID>printCommitUnderCurosr('fuller')<Cr>
|
||||
autocmd User Merginal_HistoryLog nnoremap <buffer> C :call <SID>checkoutCommitUnderCurosr()<Cr>
|
||||
autocmd User Merginal_HistoryLog nnoremap <buffer> cc :call <SID>checkoutCommitUnderCurosr()<Cr>
|
||||
autocmd User Merginal_HistoryLog nnoremap <buffer> gd :call <SID>diffWithCommitUnderCursor()<Cr>
|
||||
augroup END
|
||||
|
||||
function! merginal#tryRefreshHistoryLogBuffer()
|
||||
if 'Merginal:HistoryLog'==bufname('')
|
||||
let l:entryFormat = '%h %aN%n%ai%n%s%n'
|
||||
let l:logLines = split(
|
||||
\ merginal#system(b:merginal_repo.git_command(
|
||||
\ '--no-pager', 'log', '--format='.l:entryFormat, b:merginal_branch.handle)),
|
||||
\ '\r\n\|\n\|\r')
|
||||
if empty(l:logLines[len(l:logLines) - 1])
|
||||
call remove(l:logLines, len(l:logLines) - 1)
|
||||
endif
|
||||
let l:currentLine=line('.')
|
||||
|
||||
setlocal modifiable
|
||||
"Clear the buffer:
|
||||
silent normal! gg"_dG
|
||||
"Write the log lines:
|
||||
call setline(1,l:logLines)
|
||||
setlocal nomodifiable
|
||||
|
||||
execute l:currentLine
|
||||
endif
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
"Exactly what it says on tin
|
||||
function! s:printCommitUnderCurosr(format)
|
||||
if 'Merginal:HistoryLog'==bufname('')
|
||||
let l:commitHash = merginal#commitHash('.')
|
||||
"Not using merginal#runGitCommandInTreeEcho because we are insterested
|
||||
"in the result as more than just git command output. Also - using
|
||||
"git-log with -1 instead of git-show because for some reason git-show
|
||||
"ignores the --format flag...
|
||||
echo merginal#system(b:merginal_repo.git_command('--no-pager', 'log', '-1', '--format='.a:format, l:commitHash))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Exactly what it says on tin
|
||||
function! s:checkoutCommitUnderCurosr()
|
||||
if 'Merginal:HistoryLog'==bufname('')
|
||||
let l:commitHash = merginal#commitHash('.')
|
||||
call merginal#runGitCommandInTreeEcho(b:merginal_repo,'--no-pager checkout '.shellescape(l:commitHash))
|
||||
call merginal#reloadBuffers()
|
||||
call merginal#tryRefreshBranchListBuffer(0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Opens the diff files buffer
|
||||
function! s:diffWithCommitUnderCursor()
|
||||
if 'Merginal:HistoryLog'==bufname('')
|
||||
let l:commitHash = merginal#commitHash('.')
|
||||
call merginal#openDiffFilesBuffer(l:commitHash)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:moveToNextOrPreviousCommit(direction)
|
||||
if 'Merginal:HistoryLog'==bufname('')
|
||||
let l:line = line('.')
|
||||
|
||||
"Find the first line of the current commit
|
||||
while !empty(getline(l:line - 1))
|
||||
let l:line -= 1
|
||||
endwhile
|
||||
|
||||
"Find the first line of the next/prev commit
|
||||
let l:line += a:direction
|
||||
while !empty(getline(l:line - 1))
|
||||
let l:line += a:direction
|
||||
endwhile
|
||||
|
||||
if l:line <= 0 || line('$') <= l:line
|
||||
"We reached past the first/last commit - go back!
|
||||
let l:line -= a:direction
|
||||
while !empty(getline(l:line - 1))
|
||||
let l:line -= a:direction
|
||||
endwhile
|
||||
endif
|
||||
execute l:line
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
Author: Idan Arye <https://github.com/idanarye/>
|
||||
License: Same terms as Vim itself (see |license|)
|
||||
|
||||
Version: 1.4.0
|
||||
Version: 1.5.0
|
||||
|
||||
INTRODUCTION *merginal*
|
||||
|
||||
@ -19,6 +19,7 @@ offers interactive TUI for:
|
||||
* Rebasing branches
|
||||
* Solving merge conflicts
|
||||
* Renaming branches
|
||||
* Viewing git history for branches
|
||||
|
||||
|
||||
REQUIREMENTS *merginal-requirements*
|
||||
@ -51,7 +52,8 @@ THE BRANCH LIST *merginal-branch-list*
|
||||
The branch list shows a list of branches. While in that list, you can use the
|
||||
following keymaps to interact with the branches:
|
||||
|
||||
R Refresh the buffer list.
|
||||
q Close the branch list.
|
||||
R Refresh the branch list.
|
||||
cc Checkout the branch under the cursor.
|
||||
ct Track the remote branch under the cursor.
|
||||
cT Track the remote branch under the cursor, prompting for a name.
|
||||
@ -74,10 +76,13 @@ rb Rebase the currently checked out branch against the branch under the
|
||||
ps Prompt to choose a remote to push the branch under the cursor.
|
||||
pS Prompt to choose a remote to force push the branch under the cursor.
|
||||
pl Prompt to choose a remote to pull the branch under the cursor.
|
||||
pr Prompt to choose a remote to pull-rebase the branch under the cursor.
|
||||
pf Prompt to choose a remote to fetch the branch under the cursor.
|
||||
gd Open |merginal-diff-files| buffer to diff against the branch under the
|
||||
cursor.
|
||||
rn Prompt to rename the branch under the cursor.
|
||||
gl Open |merginal-history-log| buffer to view the history of the branch
|
||||
under the cursor.
|
||||
|
||||
|
||||
MERGE CONFLICTS *merginal-merge-conflicts*
|
||||
@ -85,6 +90,7 @@ MERGE CONFLICTS *merginal-merge-conflicts*
|
||||
The merge conflicts buffer is used to solve merge conflicts. It shows all the
|
||||
files that have merge conflicts and offers the following keymaps:
|
||||
|
||||
q Close the merge conflicts list.
|
||||
R Refresh the merge conflicts list.
|
||||
<Cr> Open the conflicted file under the cursor.
|
||||
aa Add the conflicted file under the cursor to the staging area. If that
|
||||
@ -105,7 +111,7 @@ aa Add the conflicted file under the cursor to the staging area. If that
|
||||
was the last conflicted file, prompt the user to continue to the next
|
||||
patch.
|
||||
A Same as aa.
|
||||
ra Abort the rebase
|
||||
ra Abort the rebase.
|
||||
rc Continue to the next patch.
|
||||
rs Skip the current patch
|
||||
|
||||
@ -114,29 +120,51 @@ REBASE AMEND *merginal-rebase-amend*
|
||||
|
||||
The rebase amend buffer is shown when you amend a patch during a rebase. It
|
||||
shows the amended commit's shortened hash and commit message. Additionally, it
|
||||
shows all the branches so you can diff against them while the patch. If offers
|
||||
the folloing keymaps:
|
||||
shows all the branches so you can diff against them. If offers the following
|
||||
keymaps:
|
||||
|
||||
q Close the rebase amend buffer.
|
||||
R Refresh the rebase amend buffer.
|
||||
gd Open |merginal-diff-files| buffer to diff against the branch under the
|
||||
cursor.
|
||||
ra Abort the rebase
|
||||
gl Open |merginal-history-log| buffer to view the history of the branch
|
||||
under the cursor.
|
||||
ra Abort the rebase.
|
||||
rc Continue to the next patch.
|
||||
rs Skip the current patch
|
||||
rs Skip the current patch.
|
||||
|
||||
|
||||
DIFF FILES *merginal-diff-files*
|
||||
|
||||
The diff files buffer is used to diff against another branch. It displays all
|
||||
the differences between the currently checked out branch and the branch it was
|
||||
opened against, and offerts the following keymaps:
|
||||
opened against, and offers the following keymaps:
|
||||
|
||||
q Close the diff files list.
|
||||
R Refresh the diff files list.
|
||||
<Cr> Open the file under the cursor (if it exists in the currently checked
|
||||
out branch).
|
||||
ds Split-diff against the file under the cursor (if it exists in the other
|
||||
branch)
|
||||
ds VSplit-diff against the file under the cursor(if it exists in the other
|
||||
branch)
|
||||
branch).
|
||||
dv VSplit-diff against the file under the cursor (if it exists in the other
|
||||
branch).
|
||||
co Check out the file under the cursor (if it exists in the other branch)
|
||||
into the current branch.
|
||||
|
||||
|
||||
HISTORY LOG *merginal-history-log*
|
||||
|
||||
The history log buffer is used to show the history of a branch. It shows, for
|
||||
each commit in the branch, the author, date and commit message subject, and
|
||||
offers the following keymaps:
|
||||
|
||||
q Close the history log buffer.
|
||||
R Refresh the history log buffer.
|
||||
<C-p> Move the cursor to the previous commit.
|
||||
<C-n> Move the cursor to the next commit.
|
||||
ss Echo the commit details(using git's --format=fuller).
|
||||
S Same as ss.
|
||||
cc Checkout the commit under the cursor.
|
||||
C Same as cc.
|
||||
gd Open |merginal-diff-files| buffer to diff against the commit under the
|
||||
cursor.
|
||||
|
@ -65,11 +65,17 @@
|
||||
" "OND" : E.W.Myers, "An O(ND) Difference Algorithm and Its Variations"
|
||||
" "Basic" : basic algorithm using edit graph and shortest edit distance
|
||||
"
|
||||
" DiffCharExpr(iet, exd) function for the diffexpr option
|
||||
" iet: 1 = internal algorithm, 0 = external diff command,
|
||||
" else = threshold value of differences to apply either
|
||||
" DiffCharExpr(mxi, exd) function for the diffexpr option
|
||||
" mxi: the maximum number of total lines of both windows to apply internal
|
||||
" algorithm, apply external diff command when more lines
|
||||
" exd: 1 = initially show exact differences, 0 = vim original ones
|
||||
"
|
||||
" Update : 4.9
|
||||
" * Fixed DiffCharExpr() to check the number of total lines, not different
|
||||
" lines only, of both windows and apply either internal algorithm or
|
||||
" external diff command, in order to keep the appropriate performance
|
||||
" for large files.
|
||||
"
|
||||
" Update : 4.81
|
||||
" * Enhanced to make DiffCharExpr() a bit faster by using uniq() or so.
|
||||
"
|
||||
@ -209,15 +215,15 @@
|
||||
" the initial version.
|
||||
"
|
||||
" Author: Rick Howe
|
||||
" Last Change: 2015/01/13
|
||||
" Last Change: 2015/02/18
|
||||
" Created:
|
||||
" Requires:
|
||||
" Version: 4.81
|
||||
" Version: 4.9
|
||||
|
||||
if exists("g:loaded_diffchar")
|
||||
finish
|
||||
endif
|
||||
let g:loaded_diffchar = 4.81
|
||||
let g:loaded_diffchar = 4.9
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
@ -294,15 +300,12 @@ endif
|
||||
" Set a diff expression
|
||||
if !exists("g:DiffExpr") || g:DiffExpr
|
||||
if empty(&diffexpr)
|
||||
let &diffexpr = "DiffCharExpr(200, 1)" " set threshold and show exact diffs
|
||||
" let &diffexpr = "DiffCharExpr(1, 1)" " apply int algo and show exact diffs
|
||||
" let &diffexpr = "DiffCharExpr(1, 0)" " apply int algo and show vim original
|
||||
" let &diffexpr = "DiffCharExpr(0, 1)" " apply ext cmd and show exact diffs
|
||||
let &diffexpr = "DiffCharExpr(200, 1)" " set # of lines and show exact diffs
|
||||
" let &diffexpr = "DiffCharExpr(0, 0)" " apply ext cmd and show vim original
|
||||
endif
|
||||
endif
|
||||
|
||||
function! DiffCharExpr(iet, exd)
|
||||
function! DiffCharExpr(mxi, exd)
|
||||
" read both files to be diff traced
|
||||
let [f1, f2] = [readfile(v:fname_in), readfile(v:fname_new)]
|
||||
|
||||
@ -312,35 +315,8 @@ function! DiffCharExpr(iet, exd)
|
||||
return
|
||||
endif
|
||||
|
||||
" decide either internal or external
|
||||
if a:iet > 1
|
||||
" too short to check
|
||||
if len(f1 + f2) < a:iet
|
||||
let int = 1
|
||||
else
|
||||
" check how many differences and compare with a:iet
|
||||
if exists("*uniq")
|
||||
let int = (2 * len(uniq(sort(f1 + f2))) -
|
||||
\len(uniq(sort(copy(f1)))) -
|
||||
\len(uniq(sort(copy(f2))))) < a:iet
|
||||
else
|
||||
for k in [1, 2]
|
||||
let d{k} = {}
|
||||
for s in f{k}
|
||||
let d{k}[empty(s) ?
|
||||
\nr2char(10) : s] = 0
|
||||
endfor
|
||||
endfor
|
||||
let int = (- len(d1) - len(d2) + 2 *
|
||||
\len(extend(d1, d2, "keep"))) < a:iet
|
||||
endif
|
||||
endif
|
||||
else
|
||||
let int = a:iet
|
||||
endif
|
||||
|
||||
" get a list of diff commands
|
||||
let dfcmd = int ?
|
||||
let dfcmd = (len(f1 + f2) <= a:mxi) ?
|
||||
\s:ApplyIntDiffAlgorithm(f1, f2) : s:ApplyExtDiffCommand()
|
||||
|
||||
" write to output file
|
||||
|
Loading…
x
Reference in New Issue
Block a user