" 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 '.g:VCSCommandMenuRoot.'.'.'Manage'.' '.':VCSManager' 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 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: /'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 s :. call VCSManagerSync() " vnoremap s :call VCSManagerSync() nnoremap u :call VCSManagerUpdate() nnoremap c :call VCSManagerCommit() nnoremap d :call VCSManagerDelete() " nnoremap a :call ChangeArguments() nnoremap i :call VCSManagerChangeIgnore() " nnoremap q :call VCSManagerQuit() " nnoremap o :call VCSManagerOpen() nnoremap :call VCSManagerOpen() nnoremap <2-Leftmouse> :call VCSManagerOpen() call SetupSyntax() " Open the first diff " call VCSManagerNext() endfunction function 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 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 VCSManagerOpen() function VCSManagerOpen() " First dehighlight the last marked call 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 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 HighlightLine() let fileA = GetFileNameFromLine(line) if IsOnly(line) " We open the file " let fileSrc = ParseOnlySrc(line) " if (fileSrc == "A") " let fileToOpen = fileA " elseif (fileSrc == "B") " let fileToOpen = fileB " endif " split " wincmd k " silent exec "edit ". EscapeFileName(fileToOpen) " " Fool the window saying that this is diff " diffthis " wincmd j " " Resize the window " exe("resize " . g:VCSManagerWindowSize) " exe (b:currentDiff) elseif IsDiffer(line) "Open the diff windows split wincmd k silent exec "edit ".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 VCSManagerCommit() let fileList = GetFileList() let files = join(fileList, ' ') echo 'Commit ' . files VCSCommit '.files endfunction " get list of files to commit function GetFileList() let filelist = [] let reLine = '^'.s:VCSManagerDifferLine.'\s\+\S\+$' let filename = "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 CloseDiffWindows() if (AreDiffWinsOpened()) wincmd k " Ask the user to save if buffer is modified call AskIfModified() bd! " User may just have one window opened, we may not need to close " the second diff window if (&diff) call AskIfModified() bd! endif endif endfunction function 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 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 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 IsDiffer(line) " return (match(a:line, "^ *" . s:VCSManagerDifferLine . "\\|^==> " . s:VCSManagerDifferLine ) == 0) return 1 endfunction " The given line begins with the "Only in" function IsOnly(line) " return (match(a:line, "^ *" . s:VCSManagerDiffOnlyLine . "\\|^==> " . s:VCSManagerDiffOnlyLine ) == 0) return 0 endfunction function 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 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 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 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 VCSManagerOpen() endfunction " Ask the user to save if the buffer is modified " function 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 VCSManagerUpdate() call s:VCSManager() endfunction " Delete File function VCSManagerDelete() let filename = 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 VCSManagerUpdate() endfunction " Ignore current line function VCSManagerChangeIgnore() setlocal modifiable exe "normal 0I#\" setlocal nomodified setlocal nomodifiable endfunction