git-svn-id: https://vimsuite.svn.sourceforge.net/svnroot/vimsuite/trunk@217 eb2d0018-73a3-4aeb-bfe9-1def61c9ec69
394 lines
12 KiB
VimL
394 lines
12 KiB
VimL
|
|
" Default Variables. You can override these in your global variables
|
|
" settings.
|
|
"
|
|
" For VCSManagerExcludes and VCSManagerIgnore, separate different patterns with a
|
|
" ',' (comma and no space!).
|
|
"
|
|
" eg. in your .vimrc file: let g:VCSManagerExcludes = "CVS,*.class,*.o"
|
|
" let g:VCSManagerIgnore = "Id:"
|
|
" " ignore white space in diff
|
|
" let g:VCSManagerAddArgs = "-w"
|
|
"
|
|
" You can set the pattern that diff excludes. Defaults to the CVS directory
|
|
if !exists("g:VCSManagerExcludes")
|
|
let g:VCSManagerExcludes = ""
|
|
endif
|
|
" This is the -I argument of the diff, ignore the lines of differences that
|
|
" matches the pattern
|
|
if !exists("g:VCSManagerIgnore")
|
|
let g:VCSManagerIgnore = ""
|
|
endif
|
|
if !exists("g:VCSManagerSort")
|
|
let g:VCSManagerSort = 1
|
|
endif
|
|
if !exists("g:VCSManagerWindowSize")
|
|
let g:VCSManagerWindowSize = 14
|
|
endif
|
|
if !exists("g:VCSManagerInteractive")
|
|
let g:VCSManagerInteractive = 0
|
|
endif
|
|
if !exists("g:VCSManagerIgnoreCase")
|
|
let g:VCSManagerIgnoreCase = 0
|
|
endif
|
|
" Additional arguments
|
|
if !exists("g:VCSManagerAddArgs")
|
|
let g:VCSManagerAddArgs = ""
|
|
endif
|
|
|
|
" Regular Expression for changed files
|
|
if !exists("g:VCSManagerReChanged")
|
|
" let g:VCSManagerReChangedFile = '[ADMRC?!]'. '[ MC]'.'[ L]'.'[ +]'.'[ S]'.'[ KOTB]'.'[ *]'
|
|
let g:VCSManagerReChangedFile = '[ADMRC]'. '[ MC]'.'[ L]'.'[ +]'.'[ S]'.'[ KOTB]'.'[ *]'
|
|
let g:VCSManagerReChangedProps = '[ ADMRCX?!~]'. '[MC]'.'[ L]'.'[ +]'.'[ S]'.'[ KOTB]'.'[ *]'
|
|
let g:VCSManagerReChangedAdd = '[ ADMRCX?!~]'.'[ MC]'.'[ L]'. '[+]'.'[ S]'.'[ KOTB]'.'[ *]'
|
|
let g:VCSManagerReStatus = '[ ADMRCX?!~]'.'[ MC]'.'[ L]'.'[ +]'.'[ S]'.'[ KOTB]'.'[ *]'
|
|
let g:VCSManagerReChanged = g:VCSManagerReChangedFile
|
|
endif
|
|
|
|
" String used for the English equivalent "Only in ")
|
|
if !exists("g:VCSManagerTextOnlyIn")
|
|
let g:VCSManagerTextOnlyIn = "Only in "
|
|
endif
|
|
|
|
" String used for the English equivalent ": ")
|
|
if !exists("g:VCSManagerTextOnlyInCenter")
|
|
let g:VCSManagerTextOnlyInCenter = ": "
|
|
endif
|
|
|
|
" Set some script specific variables:
|
|
"
|
|
let s:VCSManagerFirstDiffLine = 6
|
|
|
|
exe 'amenu <silent> '.g:VCSCommandMenuRoot.'.'.'Manage'.' '.':VCSManager<CR>'
|
|
|
|
command VCSManager call s:VCSManager()
|
|
function s:VCSManager()
|
|
|
|
" open cwd in buffer
|
|
exe 'edit '.getcwd()
|
|
"return
|
|
" open status window in cwd
|
|
exe "VCSStatus '.'"
|
|
" close old buffer
|
|
wincmd k
|
|
bd!
|
|
|
|
" Mark the current location of the line
|
|
let b:currentDiff = line(".")
|
|
|
|
" set comment string
|
|
let b:commentstring = '# '
|
|
|
|
" Check for an internationalized version of diff ?
|
|
call <SID>GetDiffStrings()
|
|
|
|
" add some help
|
|
call append(0, "")
|
|
" call append(0, "Diff Args:" . cmdarg)
|
|
" call append(0, "Options: 'u'=update,'x'=set excludes,'i'=set ignore,'a'=set args" )
|
|
call append(0, "Usage: <Enter>/'o'=open,'c'=commit,'\\dj'=next,'\\dk'=prev, 'q'=quit")
|
|
" go to the beginning of the file
|
|
0
|
|
setlocal nomodified
|
|
setlocal nomodifiable
|
|
setlocal buftype=nowrite
|
|
setlocal bufhidden=delete
|
|
setlocal nowrap
|
|
|
|
" Set up local key bindings
|
|
" nnoremap <buffer> s :. call <SID>VCSManagerSync()<CR>
|
|
" vnoremap <buffer> s :call <SID>VCSManagerSync()<CR>
|
|
nnoremap <buffer> u :call <SID>VCSManagerUpdate()<CR>
|
|
nnoremap <buffer> c :call <SID>VCSManagerCommit()<CR>
|
|
nnoremap <buffer> d :call <SID>VCSManagerDelete()<CR>
|
|
" nnoremap <buffer> a :call <SID>ChangeArguments()<CR>
|
|
nnoremap <buffer> i :call <SID>VCSManagerChangeIgnore()<CR>
|
|
" nnoremap <buffer> q :call <SID>VCSManagerQuit()<CR>
|
|
|
|
" nnoremap <buffer> o :call <SID>VCSManagerOpen()<CR>
|
|
nnoremap <buffer> <CR> :call <SID>VCSManagerOpen()<CR>
|
|
nnoremap <buffer> <2-Leftmouse> :call <SID>VCSManagerOpen()<CR>
|
|
call <SID>SetupSyntax()
|
|
|
|
" Open the first diff
|
|
" call <SID>VCSManagerNext()
|
|
endfunction
|
|
|
|
function <SID>GetDiffStrings()
|
|
let s:VCSManagerDiffOnlyLineCenter = g:VCSManagerTextOnlyInCenter
|
|
let s:VCSManagerDiffOnlyLine = g:VCSManagerTextOnlyIn
|
|
let s:VCSManagerDifferLine = g:VCSManagerReChanged
|
|
let s:VCSManagerStatus = g:VCSManagerReStatus
|
|
return
|
|
endfunction
|
|
|
|
" Set up syntax highlighing for the diff window
|
|
function <SID>SetupSyntax()
|
|
if has("syntax") && exists("g:syntax_on")
|
|
" syn match VCSManagerSrcA "\[A\]"
|
|
" syn match VCSManagerSrcB "\[B\]"
|
|
syn match VCSManagerUsage "^Usage.*"
|
|
syn match VCSManagerOptions "^Options.*"
|
|
exec 'syn match VCSManagerFiles "' . s:VCSManagerDifferLine .'"'
|
|
exec 'syn match VCSManagerOnly "' . s:VCSManagerDiffOnlyLine . '"'
|
|
" syn match VCSManagerSelected "^==>.*"
|
|
" contains=VCSManagerSrcA,VCSManagerSrcB
|
|
|
|
" hi def link VCSManagerSrcA Directory
|
|
" hi def link VCSManagerSrcB Type
|
|
hi def link VCSManagerUsage Special
|
|
hi def link VCSManagerOptions Special
|
|
hi def link VCSManagerFiles PreProc
|
|
hi def link VCSManagerOnly PreProc
|
|
" hi def link VCSManagerSelected DiffChange
|
|
endif
|
|
endfunction
|
|
|
|
command VCSManagerOpen call <SID>VCSManagerOpen()
|
|
function <SID>VCSManagerOpen()
|
|
" First dehighlight the last marked
|
|
call <SID>DeHighlightLine()
|
|
|
|
" Mark the current location of the line
|
|
let b:currentDiff = line(".")
|
|
|
|
" Save the number of this window, to which we wish to return
|
|
" This is required in case there are other windows open
|
|
let thisWindow = winnr()
|
|
|
|
call <SID>CloseDiffWindows()
|
|
|
|
" Ensure we're in the right window
|
|
exec thisWindow.'wincmd w'
|
|
|
|
let line = getline(".")
|
|
" Parse the line and see whether it's a "Only in" or "Files Differ"
|
|
call <SID>HighlightLine()
|
|
let fileA = <SID>GetFileNameFromLine(line)
|
|
if <SID>IsOnly(line)
|
|
" We open the file
|
|
" let fileSrc = <SID>ParseOnlySrc(line)
|
|
" if (fileSrc == "A")
|
|
" let fileToOpen = fileA
|
|
" elseif (fileSrc == "B")
|
|
" let fileToOpen = fileB
|
|
" endif
|
|
" split
|
|
" wincmd k
|
|
" silent exec "edit ". <SID>EscapeFileName(fileToOpen)
|
|
" " Fool the window saying that this is diff
|
|
" diffthis
|
|
" wincmd j
|
|
" " Resize the window
|
|
" exe("resize " . g:VCSManagerWindowSize)
|
|
" exe (b:currentDiff)
|
|
elseif <SID>IsDiffer(line)
|
|
"Open the diff windows
|
|
split
|
|
wincmd k
|
|
silent exec "edit ".<SID>EscapeFileName(fileA)
|
|
silent exec "VCSVimDiff"
|
|
" go to left window
|
|
wincmd h
|
|
|
|
" Go back to the diff window
|
|
wincmd j
|
|
" Resize the window
|
|
" exe("resize " . g:VCSManagerWindowSize)
|
|
" exe (b:currentDiff)
|
|
" Center the line
|
|
" exe ("normal z.")
|
|
else
|
|
echo "There is no diff at the current line!"
|
|
endif
|
|
endfunction
|
|
|
|
" commit selected files
|
|
function <SID>VCSManagerCommit()
|
|
let fileList = <SID>GetFileList()
|
|
let files = join(fileList, ' ')
|
|
echo 'Commit ' . files
|
|
VCSCommit '.files
|
|
endfunction
|
|
|
|
" get list of files to commit
|
|
function <SID>GetFileList()
|
|
let filelist = []
|
|
let reLine = '^'.s:VCSManagerDifferLine.'\s\+\S\+$'
|
|
let filename = "<SID>GetFileNameFromLine(getline(line('.')))"
|
|
let addFileToList = 'call add(filelist, '.filename.')'
|
|
let command = 'g/'.reLine.'/'.addFileToList
|
|
" echo command
|
|
exe command
|
|
return filelist
|
|
endfunction
|
|
|
|
" Close the opened diff comparison windows if they exist
|
|
function <SID>CloseDiffWindows()
|
|
if (<SID>AreDiffWinsOpened())
|
|
wincmd k
|
|
" Ask the user to save if buffer is modified
|
|
call <SID>AskIfModified()
|
|
bd!
|
|
" User may just have one window opened, we may not need to close
|
|
" the second diff window
|
|
if (&diff)
|
|
call <SID>AskIfModified()
|
|
bd!
|
|
endif
|
|
endif
|
|
endfunction
|
|
|
|
function <SID>HighlightLine()
|
|
let savedLine = line(".")
|
|
exe (b:currentDiff)
|
|
setlocal modifiable
|
|
let line = getline(".")
|
|
if (match(line, "^ ") == 0)
|
|
s/^ /==> /
|
|
endif
|
|
setlocal nomodifiable
|
|
setlocal nomodified
|
|
exe (savedLine)
|
|
redraw
|
|
endfunction
|
|
|
|
function <SID>DeHighlightLine()
|
|
let savedLine = line(".")
|
|
exe (b:currentDiff)
|
|
let line = getline(".")
|
|
setlocal modifiable
|
|
if (match(line, "^==> ") == 0)
|
|
s/^==> / /
|
|
endif
|
|
setlocal nomodifiable
|
|
setlocal nomodified
|
|
exe (savedLine)
|
|
redraw
|
|
endfunction
|
|
|
|
" Return filename
|
|
function <SID>GetFileNameFromLine(line)
|
|
let reFile = '^'.s:VCSManagerStatus.'\s\+.\{-}\(\S\+\)$'
|
|
let fileToProcess = substitute(a:line, reFile, '\1', '')
|
|
" echom "line : " . a:line. "reFile:".reFile.": File to Process:" . fileToProcess . ":"
|
|
return fileToProcess
|
|
endfunction
|
|
|
|
" The given line begins with the "Files"
|
|
function <SID>IsDiffer(line)
|
|
" return (match(a:line, "^ *" . s:VCSManagerDifferLine . "\\|^==> " . s:VCSManagerDifferLine ) == 0)
|
|
return 1
|
|
endfunction
|
|
|
|
" The given line begins with the "Only in"
|
|
function <SID>IsOnly(line)
|
|
" return (match(a:line, "^ *" . s:VCSManagerDiffOnlyLine . "\\|^==> " . s:VCSManagerDiffOnlyLine ) == 0)
|
|
return 0
|
|
endfunction
|
|
|
|
function <SID>ParseOnlyFile(line)
|
|
let regex = '^.*' . s:VCSManagerDiffOnlyLine . '\[.\]\(.*\)' . s:VCSManagerDiffOnlyLineCenter . '\(.*\)'
|
|
let root = substitute(a:line, regex , '\1', '')
|
|
let file = root . s:sep . substitute(a:line, regex , '\2', '')
|
|
return file
|
|
endfunction
|
|
|
|
function <SID>AreDiffWinsOpened()
|
|
let currBuff = expand("%:p")
|
|
let currLine = line(".")
|
|
wincmd k
|
|
let abovedBuff = expand("%:p")
|
|
if (&diff)
|
|
let abovedIsDiff = 1
|
|
else
|
|
let abovedIsDiff = 0
|
|
endif
|
|
" Go Back if the aboved buffer is not the same
|
|
if (currBuff != abovedBuff)
|
|
wincmd j
|
|
" Go back to the same line
|
|
exe (currLine)
|
|
if (abovedIsDiff == 1)
|
|
return 1
|
|
else
|
|
" Aboved is just a bogus buffer, not a diff buffer
|
|
return 0
|
|
endif
|
|
else
|
|
exe (currLine)
|
|
return 0
|
|
endif
|
|
endfunction
|
|
|
|
function <SID>EscapeFileName(path)
|
|
if (v:version >= 702)
|
|
return fnameescape(a:path)
|
|
else
|
|
" This is not a complete list of escaped character, so it's
|
|
" not as sophisicated as the fnameescape, but this should
|
|
" cover most of the cases and should work for Vim version <
|
|
" 7.2
|
|
return escape(a:path, " \t\n*?[{`$\\%#'\"|!<")
|
|
endif
|
|
endfunction
|
|
|
|
function <SID>VCSManagerNext()
|
|
" If the current window is a diff, go down one
|
|
if (&diff == 1)
|
|
wincmd j
|
|
endif
|
|
" if the current line is <= 6, (within the header range), we go to the
|
|
" first diff line open it
|
|
if (line(".") < s:VCSManagerFirstDiffLine)
|
|
exe (s:VCSManagerFirstDiffLine)
|
|
let b:currentDiff = line(".")
|
|
endif
|
|
silent exe (b:currentDiff + 1)
|
|
call <SID>VCSManagerOpen()
|
|
endfunction
|
|
|
|
" Ask the user to save if the buffer is modified
|
|
"
|
|
function <SID>AskIfModified()
|
|
if (&modified)
|
|
let input = confirm("File " . expand("%:p") . " has been modified.", "&Save\nCa&ncel", 1)
|
|
if (input == 1)
|
|
w!
|
|
endif
|
|
endif
|
|
endfunction
|
|
|
|
" Update status
|
|
function <SID>VCSManagerUpdate()
|
|
call s:VCSManager()
|
|
endfunction
|
|
|
|
" Delete File
|
|
function <SID>VCSManagerDelete()
|
|
let filename = <SID>GetFileNameFromLine(getline(line('.')))
|
|
echo filename
|
|
" switch to file (VSCDelete needs this)
|
|
let oldCwd = getcwd()
|
|
exe 'edit '.filename
|
|
let command = 'VCSDelete'
|
|
if !filereadable(filename)
|
|
write
|
|
let command = command.' --force'
|
|
endif
|
|
silent exe command
|
|
wincmd k
|
|
bd!
|
|
call VCSCommandChdir(oldCwd)
|
|
call <SID>VCSManagerUpdate()
|
|
endfunction
|
|
|
|
" Ignore current line
|
|
function <SID>VCSManagerChangeIgnore()
|
|
setlocal modifiable
|
|
exe "normal 0I#\<ESC>"
|
|
setlocal nomodified
|
|
setlocal nomodifiable
|
|
endfunction
|