diff --git a/vimfiles.stefan/plugin/vcsManager.vim b/vimfiles.stefan/plugin/vcsManager.vim new file mode 100644 index 0000000..afeb608 --- /dev/null +++ b/vimfiles.stefan/plugin/vcsManager.vim @@ -0,0 +1,393 @@ + +" 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 diff --git a/vimfiles.stefan/vimrc b/vimfiles.stefan/vimrc index 83ffac3..854cd96 100644 --- a/vimfiles.stefan/vimrc +++ b/vimfiles.stefan/vimrc @@ -249,3 +249,8 @@ let g:DoxygenToolkit_dox_attention = "yes" " Add sa to Dox if you want let g:DoxygenToolkit_dox_sa = "yes" +" ----------- +" VCS Command +" ----------- +let g:VCSCommandMenuRoot = '&VCS' +