Skip to content

Instantly share code, notes, and snippets.

@gvaughn
Last active August 29, 2015 14:03
Show Gist options
  • Save gvaughn/d3273a9285824f636cd3 to your computer and use it in GitHub Desktop.
Save gvaughn/d3273a9285824f636cd3 to your computer and use it in GitHub Desktop.
Vim and Git in Code Demos

Vim and Git in Code Demos

I want to give a code demo that shows progression of the code. I thought it would be great if I could craft the series of commits on a branch and have a single vim keystroke that would checkout the next (or previous) commit and force my buffers to reload. That would allow me to show one commit, then give me the freedom to live code how the next step is done, but when I advance to the next commit I know I'll have working code. It's like a safety harness for live coding.

Here's how it's supposed to work:

  • I created a test_forward branch, and, yeah, it's hardcoded in the vimscript :-(
  • Then I created 3 consecutive commits with one line changes in my README
  • optional: I used "git tag $tag_name" to give a friendly name in my bash prompt for each commit (I wish the fugitive statusline would use it too though)
  • I checked out the 1st of the demo commits
  • Now I can <Leader><Space> and vim shows the step2 code! etc.
  • <Leader>m takes me back a step (because you know someone in the audience will want that)

How I understand the mechanics of it (which may be imperfect because StackOverflow was involved):

  • That subshell git command "git rev-list head..test_forward" is going to list the commits from where I currently am (head) to the tip of the test_forward branch.
  • "tail -n 1" gets the last of those commits (they're reversed from what I would have expected)
  • then we reset --hard onto it
  • the windo vimscript command is going to force reload each window ignoring any unsaved changes. The extra pipe after that is most definitely cargo culted but seems to make things work when the quickfix window is open. Otherwise an open quickfix window (such as gitgrep results) would be duplicated into another window -- most annoying.
  • redraw! fixes some screen artifacts I'd see without it. Perhaps due to running vim within tmux.

Summary

I'm pleased with this initial prototype and plan to use it at a talk soon. I suppose I need to get back to the actual content of my talk now :-) But I wanted to share, and of course, I'd love to hear improvements. It's my first "from scratch" vimscript, so it's probably ... less than optimal.

function! AdvanceCommitAndReload()
" test_forward is the branch name to move along. Only works on straight line branches
execute '!git reset --hard $(git rev-list head..test_forward | tail -n 1)'
windo e! | !:
redraw!
endfunction
function! RetreatCommitAndReload()
execute '!git reset --hard head~'
windo e! | !:
redraw!
endfunction
nmap <Leader><Space> :silent call AdvanceCommitAndReload()<CR>
nmap <leader>m :silent call RetreatCommitAndReload()<CR>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment