gitv plugin.
authorIain Patterson <me@iain.cx>
Mon, 27 Jan 2014 13:46:47 +0000 (13:46 +0000)
committerIain Patterson <me@iain.cx>
Mon, 27 Jan 2014 14:51:02 +0000 (14:51 +0000)
.vim/doc/gitv.txt [new file with mode: 0644]
.vim/ftplugin/gitv.vim [new file with mode: 0644]
.vim/plugin/gitv.vim [new file with mode: 0644]
.vim/syntax/gitv.vim [new file with mode: 0644]

diff --git a/.vim/doc/gitv.txt b/.vim/doc/gitv.txt
new file mode 100644 (file)
index 0000000..262ca34
--- /dev/null
@@ -0,0 +1,391 @@
+gitv -- gitk for vim.
+
+AUTHOR:   Greg Sexton <gregsexton@gmail.com>                      *gitv-author*
+WEBSITE:  http://www.gregsexton.org/portfolio/gitv/
+LICENSE:  Same terms as Vim itself (see :help license).
+NOTES:    Much of the credit for gitv goes to Tim Pope and the fugitive plugin
+          where this plugin either uses functionality directly or was inspired
+          heavily.
+
+gitv                                                                     *gitv*
+
+1. Introduction              |gitv-introduction|
+2. Installation              |gitv-installation|
+3. Usage                     |gitv-usage|
+4. Configuration Options     |gitv-config-options|
+5. Changelog                 |gitv-changelog|
+6. Misc                      |gitv-misc|
+
+==============================================================================
+1. Introduction                                             *gitv-introduction*
+
+|gitv| is a 'gitk clone' plugin for the text editor Vim. The goal is to give
+you a similar set of functionality as a repository viewer. Using this plugin
+you can view a repository's history including branching and merging, you can
+see which commits refs point to. You can quickly and easily view what changed
+to which files and when. You can perform arbitrary diffs (using Vim's
+excellent built in diff functionality) and you can easily check out whole
+commits and branches or just individual files if need be.
+
+Throw in the fact that it is running in Vim and you get for free: the ability
+to move over repository history quickly and precisely using Vim's built in
+movement operators. You get excellent code syntax highlighting due to Vim's
+built in ability. You can open up all sorts of repository views in multiple
+windows and position them exactly how you like. You can take advantage of
+Vim's registers to copy multiple fragments of code from previous commits. The
+list goes on.
+
+This plugin is an extension of the |fugitive| plugin.
+
+I hope you like it!
+
+==============================================================================
+2. Installation                                             *gitv-installation*
+
+Install in ~/.vim, or in ~\vimfiles if you're on Windows. This plugin should
+be fully pathogen compatible if you want to install it this way.
+
+|gitv| was developed against Vim 7.3 but earlier versions of Vim should work.
+Vim 7.2+ is recommended as it ships with syntax highlighting for many Git file
+types. You will also need the |fugitive| plugin installed and working for
+|gitv| to work.
+
+==============================================================================
+3. Usage                                                           *gitv-usage*
+
+|gitv| defines the following command.
+
+:Gitv[!] [args]   Invoking this command on a buffer that belongs to a git
+                  repository causes the gitv browser to open. '!' causes gitv
+                  to open in file mode rather than browser mode. Any [args]
+                  supplied are passed on to the gitv viewer and can be used to
+                  narrow the commits that are shown. If this command is run
+                  on a buffer not belonging to a git repository a message
+                  stating 'Not a git repository.' is displayed.
+
+The following abbreviation is also defined so that you can type :gitv without
+capitalisation.
+>
+    cabbrev gitv Gitv
+<
+
+3.1 Browser mode
+
+|gitv| has two distinct modes. Browser mode and file mode. The browser mode is
+opened in a new tab and allows the repository history to be viewed for all
+files. This is activated by running :Gitv without a '!'.
+
+In this mode you can view the entire repository history and see which files
+were changed with each commit. This mode tries to closely resemble gitk.
+
+3.2 File mode
+
+File mode is opened in a |preview-window| above the buffer you are currently in.
+This view is tailored to act on the buffer that :Gitv! was run from, the
+"focused" file. Whilst in this mode all actions performed are specific to the
+single focused file. The browser only shows commits where the focused file
+changed.  Selecting a commit, views the focused file as it was in that commit.
+Performing a check out only checks the focused file out as it was in the
+commit. And so on. See 3.4 for the differences.
+
+3.3 Arguments
+
+You can pass arguments to the :Gitv command. These allow you to filter and
+narrow the commits shown. Essentially, gitv is a glorified 'git log' wrapper
+and so any flag that 'git log' accepts so will gitv. gitv does not inspect the
+arguments passed on to 'git log' and so may not work if they don't make sense.
+
+Without any arguments gitv behaves just like gitk and git log without
+arguments. It will display the commit history for the currently checked out
+branch.
+
+Here are some particularly useful examples of arguments that could be
+passed to :Gitv. For more info see 'git help log' and in particular the
+section: "Commit Limiting".
+
+    Flag              Description ~
+
+    --all             View repository history for all refs.
+
+    <since>..<until>  Show only commits between the named two commits. When
+                      either <since> or <until> is omitted, it defaults to
+                      HEAD, i.e. the tip of the current branch. For a more
+                      complete list of ways to spell <since> and <until>,
+                      see gitrevisions(7).
+
+    --merges          View only merge commits.
+
+    -S<string>        Look for differences that introduce or remove an
+                      instance of <string>. Note that this is different than
+                      the string simply appearing in diff output; see the
+                      pickaxe entry in gitdiffcore(7) for more details.
+
+    -G<regex>         Look for differences whose added or removed line
+                      matches the given <regex>.
+
+3.4 Key mappings.
+
+This is a list of key mappings that will work only in the gitv browser window.
+Where appropriate the differences in action is described for the two modes.
+
+    Mode        Map     Description~
+
+    normal      <cr>    Opens a commit. In browser mode this will show the
+                        commit header information including the commit
+                        message. It will also dispaly a full diff showing all the
+                        changes to files.
+
+                        Tip: if you press <cr> on anything sensible you can
+                        view the expected output. For example pressing <cr> on
+                        the line beginning a file diff, it will display the
+                        diff using Vim's built in diff viewing capability.
+                        Pressing <cr> on the tree sha will list all the files
+                        in the commit and pressing <cr> on one of these will
+                        show that file as it was in the commit. And so on.
+
+                        Pressing <cr> on the line "-- Load More --" will load
+                        |g:Gitv_CommitStep| more commits.
+
+                        In file mode this will open the focused file as it was
+                        in the currently selected diff. This allows you to
+                        easily go back in time and look at the focused file.
+
+                        Pressing <cr> on the top line in file mode opens the
+                        current working copy of the focused file.
+
+    normal      o       The same as <cr> but opens in a new |split|.
+    normal      O       The same as <cr> but opens in a new |tab|.
+    normal      s       The same as <cr> but opens in a new |vsplit|.
+
+    normal      <c-cr>  This performs the same thing as <cr> in browser mode.
+                        In file mode it opens the commit details rather than
+                        the focused file.
+
+    normal      q       Quits gitv. In browser mode this will close the entire
+                        tab. In file mode this closes only the |preview-window|.
+                        Note: in browser mode this will close the tab
+                        regardless of any windows you may have opened as well
+                        as the gitv windows.
+
+    normal      u       Forces an update of the content of the browser window.
+
+    normal      co      Performs a 'git checkout' of the commit the cursor is
+                        on. In both modes this will present you with a choice
+                        of whether you would like to checkout the sha or any
+                        ref that might point to this commit.
+
+                        File mode differs in that it doesn't check out the
+                        entire commit but just the focused file in that
+                        commit.
+
+                        Tip: in gVim this will present you with a pop up dialog.
+                        You can make this a text choice by performing ':set
+                        guioptions+=c.'
+
+    normal      D       Performs a diff using Vim's built in diff viewing
+                        capabilities. This does nothing in browser mode. In
+                        file mode it will diff the current file with the
+                        focused file in the commit under the cursor.
+
+    visual      D       In visual mode this performs a diff against the file
+                        in the commit at the top of the selection against the
+                        file in the commit at the bottom of the selection. The
+                        newest file is always on the right.
+
+    normal      S       This works for both browser and file mode. It opens a
+                        diffstat of everything that has changed since the
+                        commit under the cursor.
+
+    visual      S       In visual mode this works in exactly the same way as
+                        normal mode. However, it only shows what has changed in
+                        the range of commits that are highlighted.
+
+Here is a list of extra key mappings that can be used to efficiently move
+around a repository history in the browser window.
+
+    Mode        Map     Description~
+
+    normal      x       Jumps the cursor forward to the next branching point
+                        in the history.
+
+    normal      X       Jumps the cursor backward to the previous branching
+                        point in the history.
+
+    normal      r       Jumps the cursor forward to the next ref in the
+                        history.
+
+    normal      R       Jumps the cursor backward to the previous ref in the
+                        history.
+
+    normal      P       Jumps the cursor to the commit referenced by HEAD.
+
+3.5 Commands
+
+Running the |:Git| command in the commit browser window, in either mode, will
+cause the |:Git| command to be run as expected but the commit history will
+automatically update to reflect any changes too.
+
+3.6 Windows
+
+In browser mode, two windows are opened initially. The "browser window" that
+displays the commit history and the "preview window" that shows the currently
+selected commit.
+
+In file mode, a |preview-window| is opened above the current file. This is a
+browser window filtered to show commits only affecting the focused file. The
+window holding the focused file acts as the preview window in this mode.
+
+NOTE: In both modes the buffer in the preview window is wiped after replacing
+it.  This is to stop the quick build up of fugitive buffers. A buffer will not
+be wiped if it contains unsaved changes. Buffers are not wiped when opening a
+commit in a split, vsplit or a new tab.
+
+When opening a commit, the window it will be opened in is determined by simple
+rules. If in browser mode and the layout is vertical it will open in the
+window to the immediate right (exactly as if you performed <c-w>l). If in a
+horizontal layout, it will be opened in the window immediately below (exactly
+as if you performed <c-w>j). If in file mode, it will open exactly like
+browser mode split horizontally. NOTE: It is for this reason that you should
+not move the browser window as it will cause commits to be opened in
+unexpected places.
+
+3.7 Folding
+
+Folding of branches is supported in the browser window. Initially all folds
+are always open and will open on a reload. You can collapse any branch by
+using Vim's built in fold operators. See |folding| for more details.
+
+==============================================================================
+4. Configuration Options                               *gitv-config-options*
+
+You can set the following options in your .vimrc to override the values used
+by |gitv|. The defaults are shown.
+
+4.1 Commit Step
+
+This is the number of commits to show each time. When pressing <cr> on
+"-- Load More --", the number of extra commits loaded is g:Gitv_CommitStep.
+The default is a screen's worth of lines. This should be set to an integer
+number. Setting this to a value _really_ high will load the entire repo in one
+go.
+>
+    g:Gitv_CommitStep = &lines
+<
+
+4.2 Open Horizontal
+
+This is the default layout to use in browser mode. If set to 0 then browser
+mode will open in a vertical split. If set to 1 then browser mode will open in
+a horizontal split. If set to 'auto' then browser mode will open in a vertical
+split unless the content fits better in a horizontal split, in which case it
+will open horizontally.
+
+The commit browser width and height is automatically sized to best fit the
+content in all modes and settings.
+>
+    g:Gitv_OpenHorizontal = 0
+<
+
+4.3 Git Executable
+
+This is the name of the git executable to use to run commands. This should be
+a string.
+>
+    g:Gitv_GitExecutable = 'git'
+<
+4.4 Wipe All on Close
+
+This option should be set to either 0 (to disable) or 1 (to enable). If set to
+1 then on closing the browser mode by using the q key all buffers displayed in
+a window in the tab will be wiped before the tab is closed. This option allows
+you to limit the number of fugitive buffers that accumulate in the use of gitv.
+
+NOTE: This will not wipe any buffer with unsaved content. It will however
+mercilessly wipe all buffers in the tab regardless of the file they hold.
+>
+    g:Gitv_WipeAllOnClose = 0
+<
+
+4.5 Wrap Lines
+
+If set to 1 then line wrapping is enabled. This is useful if you have
+occasional very long commit messages.
+>
+    g:Gitv_WrapLines = 0
+<
+
+4.6 Truncate Commit Subjects
+
+If set to 1 then commit subject truncation is enabled. This will truncate
+commit subjects, where necessary, so that the whole line will fit in one
+screen width. If this is set, then automatically switching to a horizontal
+layout will no longer work as commits will be truncated to always fit in a
+vertical split. NOTE: It is possible that this can truncate any refs pointing
+at a commit. In this situation it will not be possible to check out any of
+these refs. This is due to gitv being unable to recognise that they are refs.
+>
+    g:Gitv_TruncateCommitSubjects = 0
+<
+==============================================================================
+5. Changelog                                                *gitv-changelog*
+
+1.0         First release. I hope you enjoy gitv!
+
+==============================================================================
+6. Misc                                                          *gitv-misc*
+
+6.1 Tips and tricks
+
+I use the following mappings to make working with |gitv| easier.
+>
+    nmap <leader>gv :Gitv --all<cr>
+    nmap <leader>gV :Gitv! --all<cr>
+<
+
+The following abbreviation makes running arbitrary git commands much easier.
+>
+    cabbrev git Git
+<
+
+The function: 'Gitv_OpenGitCommand(command, windowCmd)' is provided to allow
+the more advanced user to create their own commands. This function will
+execute the git command provided in the new window created using windowCmd.
+
+By using this function you get for free: the buffer set up for read only git
+output, including syntax highlighting and many other tailored options. You
+also get mappings for 'u' to update the output and 'q' to easily close the
+window.
+
+Here is an example of getting diff output both cached and not, in a vertical
+and horizontal split respectively.
+>
+    call Gitv_OpenGitCommand("diff --no-color --cached", 'vnew')
+    call Gitv_OpenGitCommand("diff --no-color", 'new')
+<
+
+I like my diff colors to be green for added lines and red for removed lines,
+just like in the shell. Adding this to your vimrc will accomplish this.
+>
+    highlight diffAdded guifg=#00bf00
+    highlight diffRemoved guifg=#bf0000
+<
+
+I highly recommend adding to your vimrc:
+>
+    set lazyredraw
+<
+
+This stops Vim from redrawing the screen during complex operations and results
+in much smoother looking plugins.
+
+
+6.2 Bugs, issues, features and contributing.
+
+There are no known bugs. Hopefully there are not too many unknown. Please see
+below to help.
+
+Bugs, suggestions, pull requests and patches are all very welcome. If you find
+issues with |gitv| please add them to the issues page on the github project.
+Anything else, feel free to email me: gregsexton@gmail.com.
+
+ vim:tw=78:ts=8:ft=help:norl:
diff --git a/.vim/ftplugin/gitv.vim b/.vim/ftplugin/gitv.vim
new file mode 100644 (file)
index 0000000..90fa45c
--- /dev/null
@@ -0,0 +1,48 @@
+"AUTHOR:   Greg Sexton <gregsexton@gmail.com>
+"WEBSITE:  http://www.gregsexton.org/portfolio/gitv/
+"LICENSE:  Same terms as Vim itself (see :help license).
+"NOTES:    Much of the credit for gitv goes to Tim Pope and the fugitive plugin
+"          where this plugin either uses functionality directly or was inspired heavily.
+
+"enabling these next lines breaks settings when reloading the buffer
+"if exists("b:did_ftplugin") | finish | endif
+"let b:did_ftplugin = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal fdm=expr
+
+fu! Foldlevelforbranch() "{{{
+    let line = getline(v:lnum)
+
+    if line == "-- Load More --"
+        return 0
+    endif
+    if line =~ "^-- \\[.*\\] --$"
+        return 0
+    endif
+
+    let line = substitute(line, "\\s", "", "g")
+    let level = match(line, "*") + 1
+    return level == 0 ? -1 : level
+endfu "}}}
+setlocal foldexpr=Foldlevelforbranch()
+
+fu! BranchFoldText() "{{{
+    "get first non-blank line
+    let fs = v:foldstart
+    while getline(fs) =~ '^\s*$' | let fs = nextnonblank(fs + 1)
+    endwhile
+    if fs > v:foldend
+        let line = getline(v:foldstart)
+    else
+        let line = getline(fs)
+    endif
+    return line
+endf "}}}
+setlocal foldtext=BranchFoldText()
+setlocal foldlevel=99
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
diff --git a/.vim/plugin/gitv.vim b/.vim/plugin/gitv.vim
new file mode 100644 (file)
index 0000000..6ef6ff0
--- /dev/null
@@ -0,0 +1,689 @@
+"AUTHOR:   Greg Sexton <gregsexton@gmail.com>
+"WEBSITE:  http://www.gregsexton.org/portfolio/gitv/
+"LICENSE:  Same terms as Vim itself (see :help license).
+"NOTES:    Much of the credit for gitv goes to Tim Pope and the fugitive plugin
+"          where this plugin either uses functionality directly or was inspired heavily.
+
+if exists("g:loaded_gitv") || v:version < 700
+  finish
+endif
+let g:loaded_gitv = 1
+
+let s:savecpo = &cpo
+set cpo&vim
+
+"configurable options:
+"g:Gitv_CommitStep             - int
+"g:Gitv_OpenHorizontal         - {0,1,'AUTO'}
+"g:Gitv_GitExecutable          - string
+"g:Gitv_WipeAllOnClose         - int
+"g:Gitv_WrapLines              - {0,1}
+"g:Gitv_TruncateCommitSubjects - {0,1}
+
+if !exists("g:Gitv_CommitStep")
+    let g:Gitv_CommitStep = &lines
+endif
+
+if !exists('g:Gitv_GitExecutable')
+    let g:Gitv_GitExecutable = 'git'
+endif
+
+if !exists('g:Gitv_WipeAllOnClose')
+    let g:Gitv_WipeAllOnClose = 0 "default for safety
+endif
+
+if !exists('g:Gitv_WrapLines')
+    let g:Gitv_WrapLines = 0
+endif
+
+if !exists('g:Gitv_TruncateCommitSubjects')
+    let g:Gitv_TruncateCommitSubjects = 0
+endif
+
+"this counts up each time gitv is opened to ensure a unique file name
+let g:Gitv_InstanceCounter = 0
+
+let s:localUncommitedMsg = '*  Local uncommitted changes, not checked in to index.'
+let s:localCommitedMsg   = '*  Local changes checked in to index but not committed.'
+
+command! -nargs=* -bang Gitv call s:OpenGitv(shellescape(<q-args>), <bang>0)
+cabbrev gitv Gitv
+
+"Public API:"{{{
+fu! Gitv_OpenGitCommand(command, windowCmd, ...) "{{{
+    "returns 1 if command succeeded with output
+    "optional arg is a flag, if present runs command verbatim
+
+    "this function is not limited to script scope as is useful for running other commands.
+    "e.g call Gitv_OpenGitCommand("diff --no-color", 'vnew') is useful for getting an overall git diff.
+
+    let [result, finalCmd] = s:RunGitCommand(a:command, a:0)
+
+    if type(result) == type(0)
+        return 0
+    endif
+    if type(result) == type("") && result == ""
+        echom "No output."
+        return 0
+    else
+        if a:windowCmd == ''
+            silent setlocal modifiable
+            silent setlocal noreadonly
+            1,$ d
+        else
+            let goBackTo       = winnr()
+            let dir            = s:GetRepoDir()
+            let workingDir     = fnamemodify(dir,':h')
+            let cd             = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
+            let bufferDir      = getcwd()
+            let tempSplitBelow = &splitbelow
+            let tempSplitRight = &splitright
+            try
+                set nosplitbelow
+                set nosplitright
+                execute cd.'`=workingDir`'
+                exec a:windowCmd
+                let newWindow = winnr()
+            finally
+                exec goBackTo . 'wincmd w'
+                execute cd.'`=bufferDir`'
+                if exists('newWindow')
+                    exec newWindow . 'wincmd w'
+                endif
+                exec 'set '. (tempSplitBelow ? '' : 'no') . 'splitbelow'
+                exec 'set '. (tempSplitRight ? '' : 'no') . 'splitright'
+            endtry
+        endif
+        if !(&modifiable)
+            return 0
+        endif
+        let b:Git_Command = finalCmd
+        silent setlocal ft=git
+        silent setlocal buftype=nofile
+        silent setlocal nobuflisted
+        silent setlocal noswapfile
+        silent setlocal bufhidden=wipe
+        silent setlocal nonumber
+        if g:Gitv_WrapLines
+            silent setlocal wrap
+        else
+            silent setlocal nowrap
+        endif
+        silent setlocal fdm=syntax
+        silent setlocal foldlevel=0
+        nmap <buffer> <silent> q :q!<CR>
+        nmap <buffer> <silent> u :if exists('b:Git_Command')<bar>call Gitv_OpenGitCommand(b:Git_Command, '', 1)<bar>endif<cr>
+        call append(0, split(result, '\n')) "system converts eols to \n regardless of os.
+        silent setlocal nomodifiable
+        silent setlocal readonly
+        1
+        return 1
+    endif
+endf "}}} }}}
+"General Git Functions: "{{{
+fu! s:RunGitCommand(command, verbatim) "{{{
+    "if verbatim returns result of system command, else
+    "switches to the buffer repository before running the command and switches back after.
+    if !a:verbatim
+        "switches to the buffer repository before running the command and switches back after.
+        let dir        = s:GetRepoDir()
+        let workingDir = fnamemodify(dir,':h')
+        if workingDir == ''
+            return 0
+        endif
+
+        let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
+        let bufferDir = getcwd()
+        try
+            execute cd.'`=workingDir`'
+            let finalCmd = g:Gitv_GitExecutable.' --git-dir="' .dir. '" ' . a:command
+            let result   = system(finalCmd)
+        finally
+            execute cd.'`=bufferDir`'
+        endtry
+    else
+        let result   = system(a:command)
+        let finalCmd = a:command
+    endif
+    return [result, finalCmd]
+endfu "}}}
+fu! s:GetRepoDir() "{{{
+    let dir = fugitive#buffer().repo().dir()
+    if dir == ''
+        echom "No git repository could be found."
+    endif
+    return dir
+endfu "}}} }}}
+"Open And Update Gitv:"{{{
+fu! s:OpenGitv(extraArgs, fileMode) "{{{
+    let sanatizedArgs = a:extraArgs   == "''" ? '' : a:extraArgs
+    let sanatizedArgs = sanatizedArgs == '""' ? '' : sanatizedArgs
+    let g:Gitv_InstanceCounter += 1
+    if !s:IsCompatible() "this outputs specific errors
+        return
+    endif
+    try
+        if a:fileMode
+            call s:OpenFileMode(sanatizedArgs)
+        else
+            call s:OpenBrowserMode(sanatizedArgs)
+        endif
+    catch /not a git repository/
+        echom 'Not a git repository.'
+        return
+    endtry
+endf "}}}
+fu! s:IsCompatible() "{{{
+    if !exists('g:loaded_fugitive')
+        echoerr "gitv requires the fugitive plugin to be installed."
+    endif
+    return exists('g:loaded_fugitive')
+endfu "}}}
+fu! s:OpenBrowserMode(extraArgs) "{{{
+    "this throws an exception if not a git repo which is caught immediately
+    let fubuffer = fugitive#buffer()
+    silent Gtabedit HEAD
+
+    if s:IsHorizontal()
+        let direction = 'new gitv'.'-'.g:Gitv_InstanceCounter
+    else
+        let direction = 'vnew gitv'.'-'.g:Gitv_InstanceCounter
+    endif
+    if !s:LoadGitv(direction, 0, g:Gitv_CommitStep, a:extraArgs, '')
+        return 0
+    endif
+    call s:SetupBufferCommands(0)
+    "open the first commit
+    silent call s:OpenGitvCommit("Gedit", 0)
+endf "}}}
+fu! s:OpenFileMode(extraArgs) "{{{
+    let relPath = fugitive#buffer().path()
+    pclose!
+    if !s:LoadGitv(&previewheight . "new gitv".'-'.g:Gitv_InstanceCounter, 0, g:Gitv_CommitStep, a:extraArgs, relPath)
+        return 0
+    endif
+    set previewwindow
+    set winfixheight
+    let b:Gitv_FileMode = 1
+    let b:Gitv_FileModeRelPath = relPath
+    call s:SetupBufferCommands(1)
+endf "}}}
+fu! s:LoadGitv(direction, reload, commitCount, extraArgs, filePath) "{{{
+    if a:reload
+        let jumpTo = line('.') "this is for repositioning the cursor after reload
+    endif
+
+    if !s:ConstructAndExecuteCmd(a:direction, a:reload, a:commitCount, a:extraArgs, a:filePath)
+        return 0
+    endif
+    call s:SetupBuffer(a:commitCount, a:extraArgs, a:filePath)
+    exec exists('jumpTo') ? jumpTo : '1'
+    call s:SetupMappings() "redefines some of the mappings made by Gitv_OpenGitCommand
+    call s:ResizeWindow(a:filePath!='')
+
+    echom "Loaded up to " . a:commitCount . " commits."
+    return 1
+endf "}}}
+fu! s:ConstructAndExecuteCmd(direction, reload, commitCount, extraArgs, filePath) "{{{
+    if a:reload "run the same command again with any extra args
+        if exists('b:Git_Command')
+            "substitute in the potentially new commit count taking account of a potential filePath
+            let newcmd = b:Git_Command
+            if a:filePath != ''
+                let newcmd = substitute(newcmd, " -- " . a:filePath . "$", "", "")
+            endif
+            let newcmd = substitute(newcmd, " -\\d\\+$", " -" . a:commitCount, "")
+            if a:filePath != ''
+                let newcmd .= ' -- ' . a:filePath
+            endif
+            silent let res = Gitv_OpenGitCommand(newcmd, a:direction, 1)
+            return res
+        endif
+    else
+        let cmd  = "log " . a:extraArgs 
+        let cmd .= " --no-color --decorate --pretty=format:\"%d %s__SEP__%ar__SEP__%an__SEP__[%h]\" --graph -" 
+        let cmd .= a:commitCount
+        if a:filePath != ''
+            let cmd .= ' -- ' . a:filePath
+        endif
+        silent let res = Gitv_OpenGitCommand(cmd, a:direction)
+        return res
+    endif
+    return 0
+endf "}}}
+fu! s:SetupBuffer(commitCount, extraArgs, filePath) "{{{
+    silent set filetype=gitv
+    let b:Gitv_CommitCount = a:commitCount
+    let b:Gitv_ExtraArgs   = a:extraArgs
+    silent setlocal modifiable
+    silent setlocal noreadonly
+    silent %s/refs\/tags\//t:/ge
+    silent %s/refs\/remotes\//r:/ge
+    silent %s/refs\/heads\///ge
+    silent %call s:Align("__SEP__", a:filePath)
+    silent %s/\s\+$//e
+    call s:AddLoadMore()
+    call s:AddLocalNodes(a:filePath)
+    if a:filePath != ''
+        call append(0, '-- ['.a:filePath.'] --')
+    endif
+    silent setlocal nomodifiable
+    silent setlocal readonly
+    silent setlocal cursorline
+endf "}}}
+fu! s:AddLocalNodes(filePath) "{{{
+    let suffix = a:filePath == '' ? '' : ' -- '.a:filePath
+    let gitCmd = "diff --no-color --cached" . suffix
+    let [result, cmd] = s:RunGitCommand(gitCmd, 0)
+    if result != ""
+        call append(0, s:localCommitedMsg)
+    endif
+    let gitCmd = "diff --no-color" . suffix
+    let [result, cmd] = s:RunGitCommand(gitCmd, 0)
+    if result != ""
+        call append(0, s:localUncommitedMsg)
+    endif
+endfu "}}}
+fu! s:AddLoadMore() "{{{
+    call append(line('$'), '-- Load More --')
+endfu "}}}
+fu! s:SetupMappings() "{{{
+    "operations
+    nmap <buffer> <silent> <cr> :call <SID>OpenGitvCommit("Gedit", 0)<cr>
+    nmap <buffer> <silent> o :call <SID>OpenGitvCommit("Gsplit", 0)<cr>
+    nmap <buffer> <silent> O :call <SID>OpenGitvCommit("Gtabedit", 0)<cr>
+    nmap <buffer> <silent> s :call <SID>OpenGitvCommit("Gvsplit", 0)<cr>
+    "force opening the fugitive buffer for the commit
+    nmap <buffer> <silent> <c-cr> :call <SID>OpenGitvCommit("Gedit", 1)<cr>
+
+    nmap <buffer> <silent> q :call <SID>CloseGitv()<cr>
+    nmap <buffer> <silent> u :call <SID>LoadGitv('', 1, b:Gitv_CommitCount, b:Gitv_ExtraArgs, <SID>GetRelativeFilePath())<cr>
+    nmap <buffer> <silent> co :call <SID>CheckOutGitvCommit()<cr>
+
+    nmap <buffer> <silent> D :call <SID>DiffGitvCommit()<cr>
+    vmap <buffer> <silent> D :call <SID>DiffGitvCommit()<cr>
+
+    nmap <buffer> <silent> S :call <SID>StatGitvCommit()<cr>
+    vmap <buffer> <silent> S :call <SID>StatGitvCommit()<cr>
+
+    "movement
+    nmap <buffer> <silent> x :call <SID>JumpToBranch(0)<cr>
+    nmap <buffer> <silent> X :call <SID>JumpToBranch(1)<cr>
+    nmap <buffer> <silent> r :call <SID>JumpToRef(0)<cr>
+    nmap <buffer> <silent> R :call <SID>JumpToRef(1)<cr>
+    nmap <buffer> <silent> P :call <SID>JumpToHead()<cr>
+endf "}}}
+fu! s:SetupBufferCommands(fileMode) "{{{
+    silent command! -buffer -nargs=* -complete=customlist,s:fugitive_GitComplete Git call <sid>MoveIntoPreviewAndExecute("Git <args>",1)|normal u
+endfu "}}}
+fu! s:ResizeWindow(fileMode) "{{{
+    if a:fileMode "window height determined by &previewheight
+        return
+    endif
+    if !s:IsHorizontal()
+        "size window based on longest line
+        let longest = max(map(range(1, line('$')), "virtcol([v:val, '$'])"))
+        if longest > &columns/2
+            "potentially auto change to horizontal
+            if s:AutoHorizontal()
+                "switching to horizontal
+                let b:Gitv_AutoHorizontal=1
+                wincmd K
+                call s:ResizeWindow(a:fileMode)
+                return
+            else
+                let longest = &columns/2
+            endif
+        endif
+        exec "vertical resize " . longest
+    else
+        "size window based on num lines
+        call s:ResizeHorizontal()
+    endif
+endf "}}} }}}
+"Utilities:"{{{
+fu! s:GetGitvSha(lineNumber) "{{{
+    let l = getline(a:lineNumber)
+    let sha = matchstr(l, "\\[\\zs[0-9a-f]\\{7}\\ze\\]$")
+    return sha
+endf "}}}
+fu! s:GetGitvRefs() "{{{
+    let l = getline('.')
+    let refstr = matchstr(l, "^\\(\\(|\\|\\/\\|\\\\\\|\\*\\)\\s\\?\\)*\\s\\+(\\zs.\\{-}\\ze)")
+    let refs = split(refstr, ', ')
+    return refs
+endf "}}}
+fu! s:RecordBufferExecAndWipe(cmd, wipe) "{{{
+    "this should be used to replace the buffer in a window
+    let buf = bufnr('%')
+    exec a:cmd
+    if a:wipe
+        "safe guard against wiping out buffer you're in
+        if bufnr('%') != buf && bufexists(buf)
+            exec 'bwipeout ' . buf
+        endif
+    endif
+endfu "}}}
+fu! s:MoveIntoPreviewAndExecute(cmd, tryToOpenNewWin) "{{{
+    if winnr("$") == 1 "is the only window
+        call s:AttemptToCreateAPreviewWindow(a:tryToOpenNewWin, a:cmd)
+        return
+    endif
+    let horiz      = s:IsHorizontal()
+    let filem      = s:IsFileMode()
+    let currentWin = winnr()
+
+    if horiz || filem
+        wincmd j
+    else
+        wincmd l
+    endif
+
+    if currentWin == winnr() "haven't moved anywhere
+        call s:AttemptToCreateAPreviewWindow(a:tryToOpenNewWin, a:cmd)
+        return
+    endif
+
+    silent exec a:cmd
+    if horiz || filem
+        wincmd k
+    else
+        wincmd h
+    endif
+endfu "}}}
+fu! s:AttemptToCreateAPreviewWindow(shouldAttempt, cmd) "{{{
+    if a:shouldAttempt
+        call s:CreateNewPreviewWindow()
+        call s:MoveIntoPreviewAndExecute(a:cmd, 0)
+    else
+        echoerr "No preview window detected."
+    endif
+endfu "}}}
+fu! s:CreateNewPreviewWindow() "{{{
+    "this should not be called by anything other than AttemptToCreateAPreviewWindow
+    let horiz      = s:IsHorizontal()
+    let filem      = s:IsFileMode()
+    if horiz || filem
+        Gsplit HEAD
+    else
+        Gvsplit HEAD
+    endif
+    wincmd x
+endfu "}}}
+fu! s:IsHorizontal() "{{{
+    "NOTE: this can only tell you if horizontal while cursor in browser window
+    let horizGlobal = exists('g:Gitv_OpenHorizontal') && g:Gitv_OpenHorizontal == 1
+    let horizBuffer = exists('b:Gitv_AutoHorizontal') && b:Gitv_AutoHorizontal == 1
+    return horizGlobal || horizBuffer
+endf "}}}
+fu! s:AutoHorizontal() "{{{
+    return exists('g:Gitv_OpenHorizontal') && 
+                \ type(g:Gitv_OpenHorizontal) == type("") && 
+                \ g:Gitv_OpenHorizontal ==? 'auto'
+endf "}}}
+fu! s:IsFileMode() "{{{
+    return exists('b:Gitv_FileMode') && b:Gitv_FileMode == 1
+endf "}}}
+fu! s:ResizeHorizontal() "{{{
+    let lines = line('$')
+    if lines > (&lines/2)-2
+        let lines = (&lines/2)-2
+    endif
+    exec "resize " . lines
+endf "}}}
+fu! s:GetRelativeFilePath() "{{{
+    return exists('b:Gitv_FileModeRelPath') ? b:Gitv_FileModeRelPath : ''
+endf "}}}
+fu! s:OpenRelativeFilePath(sha, geditForm) "{{{
+    let relPath = s:GetRelativeFilePath()
+    if relPath == ''
+        return
+    endif
+    let cmd = a:geditForm . " " . a:sha . ":" . relPath
+    let cmd = 'call s:RecordBufferExecAndWipe("'.cmd.'", '.(a:geditForm=='Gedit').')'
+    call s:MoveIntoPreviewAndExecute(cmd, 1)
+endf "}}} }}}
+"Mapped Functions:"{{{
+"Operations: "{{{
+fu! s:OpenGitvCommit(geditForm, forceOpenFugitive) "{{{
+    if getline('.') == "-- Load More --"
+        call s:LoadGitv('', 1, b:Gitv_CommitCount+g:Gitv_CommitStep, b:Gitv_ExtraArgs, s:GetRelativeFilePath())
+        return
+    endif
+    if s:IsFileMode() && getline('.') =~ "^-- \\[.*\\] --$"
+        call s:OpenWorkingCopy(a:geditForm)
+        return
+    endif
+    if getline('.') == s:localUncommitedMsg
+        call s:OpenWorkingDiff(a:geditForm, 0)
+        return
+    endif
+    if getline('.') == s:localCommitedMsg
+        call s:OpenWorkingDiff(a:geditForm, 1)
+        return
+    endif
+    let sha = s:GetGitvSha(line('.'))
+    if sha == ""
+        return
+    endif
+    if s:IsFileMode() && !a:forceOpenFugitive
+        call s:OpenRelativeFilePath(sha, a:geditForm)
+    else
+        let cmd = a:geditForm . " " . sha
+        let cmd = 'call s:RecordBufferExecAndWipe("'.cmd.'", '.(a:geditForm=='Gedit').')'
+        call s:MoveIntoPreviewAndExecute(cmd, 1)
+    endif
+endf
+fu! s:OpenWorkingCopy(geditForm)
+    let fp = s:GetRelativeFilePath()
+    let form = a:geditForm[1:] "strip off the leading 'G'
+    let cmd = form . " " . fugitive#buffer().repo().tree() . "/" . fp
+    let cmd = 'call s:RecordBufferExecAndWipe("'.cmd.'", '.(form=='edit').')'
+    call s:MoveIntoPreviewAndExecute(cmd, 1)
+endfu
+fu! s:OpenWorkingDiff(geditForm, staged)
+    let winCmd = a:geditForm[1:] == 'edit' ? '' : a:geditForm[1:]
+    if s:IsFileMode()
+        let fp = s:GetRelativeFilePath()
+        let suffix = ' -- '.fp
+        let g:Gitv_InstanceCounter += 1
+        let winCmd = 'new gitv'.'-'.g:Gitv_InstanceCounter
+    else
+        let suffix = ''
+    endif
+    if a:staged
+        let cmd = 'call Gitv_OpenGitCommand(\"diff --no-color --cached'.suffix.'\", \"'.winCmd.'\")'
+    else
+        let cmd = 'call Gitv_OpenGitCommand(\"diff --no-color'.suffix.'\", \"'.winCmd.'\")'
+    endif
+    let cmd = 'call s:RecordBufferExecAndWipe("'.cmd.'", '.(winCmd=='').')'
+    call s:MoveIntoPreviewAndExecute(cmd, 1)
+endfu "}}}
+fu! s:CheckOutGitvCommit() "{{{
+    let allrefs = s:GetGitvRefs()
+    let sha = s:GetGitvSha(line('.'))
+    if sha == ""
+        return
+    endif
+    let refs   = allrefs + [sha]
+    let refstr = join(refs, "\n")
+    let choice = confirm("Checkout commit:", refstr . "\nCancel")
+    if choice == 0
+        return
+    endif
+    let choice = get(refs, choice-1, "")
+    if choice == ""
+        return
+    endif
+    let choice = substitute(choice, "^t:", "", "")
+    let choice = substitute(choice, "^r:", "", "")
+    if s:IsFileMode()
+        let relPath = s:GetRelativeFilePath()
+        let choice .= " -- " . relPath
+    endif
+    exec "Git checkout " . choice
+endf "}}}
+fu! s:CloseGitv() "{{{
+    if s:IsFileMode()
+        q
+    else
+        if g:Gitv_WipeAllOnClose
+            silent windo setlocal bufhidden=wipe
+        endif
+        let moveLeft = tabpagenr() == tabpagenr('$') ? 0 : 1
+        tabc
+        if moveLeft && tabpagenr() != 1
+            tabp
+        endif
+    endif
+endf "}}}
+fu! s:DiffGitvCommit() range "{{{
+    if !s:IsFileMode()
+        echom "Diffing is not possible in browser mode."
+        return
+    endif
+    let shafirst = s:GetGitvSha(a:firstline)
+    let shalast  = s:GetGitvSha(a:lastline)
+    if shafirst == "" || shalast == ""
+        return
+    endif
+    if a:firstline != a:lastline
+        call s:OpenRelativeFilePath(shafirst, "Gedit")
+    endif
+    call s:MoveIntoPreviewAndExecute("Gdiff " . shalast, a:firstline != a:lastline)
+endf "}}} 
+fu! s:StatGitvCommit() range "{{{
+    let shafirst = s:GetGitvSha(a:firstline)
+    let shalast  = s:GetGitvSha(a:lastline)
+    if shafirst == "" || shalast == ""
+        return
+    endif
+    let cmd  = 'diff '.shafirst
+    if shafirst != shalast
+        let cmd .= ' '.shalast
+    endif
+    let cmd .= ' --stat'
+    let cmd = "call s:SetupStatBuffer('".cmd."')"
+    if s:IsFileMode()
+        exec cmd
+    else
+        call s:MoveIntoPreviewAndExecute(cmd, 1)
+    endif
+endf
+fu! s:SetupStatBuffer(cmd)
+    silent let res = Gitv_OpenGitCommand(a:cmd, s:IsFileMode()?'vnew':'')
+    if res
+        silent set filetype=gitv
+    endif
+endfu "}}} }}}
+"Movement: "{{{
+fu! s:JumpToBranch(backward) "{{{
+    if a:backward
+        silent! ?|/\||\\?-1
+    else
+        silent! /|\\\||\//+1
+    endif
+endf "}}}
+fu! s:JumpToRef(backward) "{{{
+    if a:backward
+        silent! ?^\(\(|\|\/\|\\\|\*\)\s\=\)\+\s\+\zs(
+    else
+        silent! /^\(\(|\|\/\|\\\|\*\)\s\?\)\+\s\+\zs(/
+    endif
+endf "}}}
+fu! s:JumpToHead() "{{{
+    silent! /^\(\(|\|\/\|\\\|\*\)\s\?\)\+\s\+\zs(HEAD/
+endf "}}}
+"}}} }}}
+"Align And Truncate Functions: "{{{
+fu! s:Align(seperator, filePath) range "{{{
+    let lines = getline(a:firstline, a:lastline)
+    call map(lines, 'split(v:val, a:seperator)')
+
+    let newlines = copy(lines)
+    call filter(newlines, 'len(v:val)>1')
+    let maxLens = s:MaxLengths(newlines)
+
+    let newlines = []
+    for tokens in lines
+        if len(tokens)>1
+            let newline = []
+            for i in range(len(tokens))
+                let token = tokens[i]
+                call add(newline, token . repeat(' ', maxLens[i]-strlen(token)+1))
+            endfor
+            call add(newlines, newline)
+        else
+            call add(newlines, tokens)
+        endif
+    endfor
+
+    if g:Gitv_TruncateCommitSubjects
+        call s:TruncateLines(newlines, a:filePath)
+    endif
+
+    call map(newlines, "join(v:val)")
+    call setline(a:firstline, newlines)
+endfu "}}}
+fu! s:TruncateLines(lines, filePath) "{{{
+    "truncates the commit subject for any line > &columns
+    call map(a:lines, "s:TruncateHelp(v:val, a:filePath)")
+endfu "}}}
+fu! s:TruncateHelp(line, filePath) "{{{
+    let length = strlen(join(a:line))
+    let maxWidth = s:IsHorizontal() ? &columns : &columns/2
+    let maxWidth = a:filePath != '' ? winwidth(0) : maxWidth
+    if length > maxWidth
+        let delta = length - maxWidth
+        "offset = 3 for the elipsis and 1 for truncation
+        let offset = 3 + 1
+        if a:line[0][-(delta + offset + 1):] =~ "^\\s\\+$"
+            let extension = "   "
+        else
+            let extension = "..."
+        endif
+        let a:line[0] = a:line[0][:-(delta + offset)] . extension
+    endif
+    return a:line
+endfu "}}}
+fu! s:MaxLengths(colls) "{{{
+    "precondition: coll is a list of lists of strings -- should be rectangular
+    "returns a list of maximum string lengths
+    let lengths = []
+    for x in a:colls
+        for y in range(len(x))
+            let length = strlen(x[y])
+            if length > get(lengths, y, 0)
+                if len(lengths)-1 < y
+                    call add(lengths, length)
+                else
+                    let lengths[y] = length
+                endif
+            endif
+        endfor
+    endfor
+    return lengths
+endfu "}}} }}}
+"Fugitive Functions: "{{{
+"These functions are lifted directly from fugitive and modified only to work with gitv.
+function! s:fugitive_sub(str,pat,rep) abort "{{{
+  return substitute(a:str,'\v\C'.a:pat,a:rep,'')
+endfunction "}}}
+function! s:fugitive_GitComplete(A,L,P) abort "{{{
+  if !exists('s:exec_path')
+    let s:exec_path = s:fugitive_sub(system(g:fugitive_git_executable.' --exec-path'),'\n$','')
+  endif
+  let cmds = map(split(glob(s:exec_path.'/git-*'),"\n"),'s:fugitive_sub(v:val[strlen(s:exec_path)+5 : -1],"\\.exe$","")')
+  if a:L =~ ' [[:alnum:]-]\+ '
+    return fugitive#buffer().repo().superglob(a:A)
+  elseif a:A == ''
+    return cmds
+  else
+    return filter(cmds,'v:val[0 : strlen(a:A)-1] ==# a:A')
+  endif
+endfunction "}}} }}}
+
+let &cpo = s:savecpo
+unlet s:savecpo
+
+ " vim:fdm=marker
diff --git a/.vim/syntax/gitv.vim b/.vim/syntax/gitv.vim
new file mode 100644 (file)
index 0000000..e238549
--- /dev/null
@@ -0,0 +1,89 @@
+" Vim syntax file
+" Language:    Custom git log output
+" Maintainer:  Greg Sexton <gregsexton@gmail.com>
+" Last Change: 2011-04-08
+"
+
+if exists("b:current_syntax")
+    finish
+endif
+
+"set conceallevel=2
+"set concealcursor=n
+
+syn match gitvSubject /.*/ 
+
+syn match gitvDate /\(\d\+ years\?, \)\?\d\+ \%(second\|seconds\|minute\|minutes\|hour\|hours\|day\|days\|week\|weeks\|month\|months\|year\) ago/ contained containedin=gitvSubject
+syn match gitvHash /\[[0-9a-f]\{7}\]$/ contained containedin=gitvSubject
+
+syn match  gitvGraphEdge9 /\(|\|\/\|\\\|\*\)\s\?/ nextgroup=gitvRef,gitvSubject skipwhite
+syn match  gitvGraphEdge8 /\(|\|\/\|\\\|\*\)\s\?/  nextgroup=gitvGraphEdge9,gitvRef,gitvSubject skipwhite
+syn match  gitvGraphEdge7 /\(|\|\/\|\\\|\*\)\s\?/  nextgroup=gitvGraphEdge8,gitvRef,gitvSubject skipwhite
+syn match  gitvGraphEdge6 /\(|\|\/\|\\\|\*\)\s\?/  nextgroup=gitvGraphEdge7,gitvRef,gitvSubject skipwhite
+syn match  gitvGraphEdge5 /\(|\|\/\|\\\|\*\)\s\?/  nextgroup=gitvGraphEdge6,gitvRef,gitvSubject skipwhite
+syn match  gitvGraphEdge4 /\(|\|\/\|\\\|\*\)\s\?/  nextgroup=gitvGraphEdge5,gitvRef,gitvSubject skipwhite
+syn match  gitvGraphEdge3 /\(|\|\/\|\\\|\*\)\s\?/  nextgroup=gitvGraphEdge4,gitvRef,gitvSubject skipwhite
+syn match  gitvGraphEdge2 /\(|\|\/\|\\\|\*\)\s\?/  nextgroup=gitvGraphEdge3,gitvRef,gitvSubject skipwhite
+syn match  gitvGraphEdge1 /\(|\|\/\|\\\|\*\)\s\?/  nextgroup=gitvGraphEdge2,gitvRef,gitvSubject skipwhite
+syn match  gitvGraphEdge0 /^\(\(|\|\/\|\\\|\*\)\s\?\)/  nextgroup=gitvGraphEdge1,gitvRef,gitvSubject skipwhite
+
+syn match gitvRef /\s*(.\{-})/ nextgroup=gitvSubject skipwhite
+syn match gitvRefTag /t:\zs.\{-}\ze\(, \|)\)/ contained containedin=gitvRef
+syn match gitvRefRemote /r:\zs.\{-}\ze\(, \|)\)/ contained containedin=gitvRef
+
+syn match gitvLoadMore /^-- Load More --$/
+syn match gitvWorkingCopy /^-- \[.*\] --$/ contained containedin=gitvSubject
+syn match gitvLocalUncommit /^\*  Local uncommitted changes, not checked in to index\.$/
+syn match gitvLocalCommited /^\*  Local changes checked in to index but not committed\.$/
+syn match gitvLocalCommitedNode /\*/ contained containedin=gitvLocalCommited
+syn match gitvLocalUncommitNode /\*/ contained containedin=gitvLocalUncommit
+
+syn match gitvAddedMarks /|\s\+\d\+ \zs+*-*\ze$/ contained containedin=gitvSubject
+syn match gitvAddedMarks /|\s\+Bin \zs\d\+ -> \d\+\ze bytes$/ contained containedin=gitvSubject
+syn match gitvRemovedMarks /-*$/ contained containedin=gitvAddedMarks
+syn match gitvRemovedMarks /\d\+\ze ->/ contained containedin=gitvAddedMarks
+syn match gitvSeperatorMarks /\s\+->\s\+/ contained containedin=gitvAddedMarks
+
+hi def link gitvHash              Number
+hi def link gitvRef               Directory
+hi def link gitvRefTag            String
+hi def link gitvRefRemote         Statement
+hi def link gitvDate              Statement
+hi def link gitvSubject           Normal
+hi def link gitvLoadMore          Question
+hi def link gitvWorkingCopy       Question
+
+hi def link gitvAddedMarks        diffAdded
+hi def link gitvRemovedMarks      diffRemoved
+hi def link gitvSeperatorMarks    Normal
+
+hi def link gitvGraphEdge0        Delimiter
+
+if &background == "dark"
+    highlight default gitvGraphEdge1 ctermfg=magenta     guifg=green1
+    highlight default gitvGraphEdge2 ctermfg=green       guifg=yellow1
+    highlight default gitvGraphEdge3 ctermfg=yellow      guifg=orange1
+    highlight default gitvGraphEdge4 ctermfg=cyan        guifg=greenyellow
+    highlight default gitvGraphEdge5 ctermfg=red         guifg=springgreen1
+    highlight default gitvGraphEdge6 ctermfg=yellow      guifg=cyan1
+    highlight default gitvGraphEdge7 ctermfg=green       guifg=slateblue1
+    highlight default gitvGraphEdge8 ctermfg=cyan        guifg=magenta1
+    highlight default gitvGraphEdge9 ctermfg=magenta     guifg=purple1
+else
+    highlight default gitvGraphEdge1 ctermfg=darkyellow  guifg=orangered3
+    highlight default gitvGraphEdge2 ctermfg=darkgreen   guifg=orange2
+    highlight default gitvGraphEdge3 ctermfg=blue        guifg=yellow3
+    highlight default gitvGraphEdge4 ctermfg=darkmagenta guifg=olivedrab4
+    highlight default gitvGraphEdge5 ctermfg=red         guifg=green4
+    highlight default gitvGraphEdge6 ctermfg=darkyellow  guifg=paleturquoise3
+    highlight default gitvGraphEdge7 ctermfg=darkgreen   guifg=deepskyblue4
+    highlight default gitvGraphEdge8 ctermfg=blue        guifg=darkslateblue
+    highlight default gitvGraphEdge9 ctermfg=darkmagenta guifg=darkviolet
+endif
+
+highlight default gitvLocalCommitedNode ctermfg=green guifg=green
+highlight default gitvLocalUncommitNode ctermfg=red   guifg=red
+highlight default gitvLocalCommited     gui=bold
+highlight default gitvLocalUncommit     gui=bold
+
+let b:current_syntax = "gitv"