Filed under code

Coming back to vim

It's time for my monthly or so post! I wanted to go through and post about my OpenBSD firewall I built but that's not 100%. Also I'm not ready to go on about anything amazing with puppet because without my lab being done puppet isn't useful so lets go back to talking about my dev environment!

I know Justin has been asking for this for a little while.

Preface: Going "back" to vim

As a sysadmin at work I use vi a lot. Not even vim; vi. We have lots of unix boxes that default to vi as the installed editor and we don't just go installing vim on everything. Personally I use vim a good amount on my machine since I spend a lot of command line time anyways. I know more than just a few of the commands but I really only consider myself a second or maybe third year vim user1 since I never used it full time to write code. I live the motion and use things like ci[ and C-v 5j x but I still fail to use multiple registers, buffers, or tabs… or even the leader commands.

I'm an amateur software developer at best; I have serious aspirations about seeing if I have the chops to go pro but right now I'm honing edges. Irregardless of how developer or not I may be, I am developer lazy so I spend money on tools that make my life easier. I've been using PyCharm to help me write utilities and my mini apps and it's just the best. Sometimes I worry about leaning on IDE tools stunting my abilities so I took some time a month back to stand up and step back from PyCharm and instead just use vim…

This is the setup.

Part One: My keyboard

I use a slick trick on my Mac so I have no access to Caps and my CapsLock key acts as BOTH a Ctrl and Escape. If I tap the Caps it's esc, if I chord it with anything else it registers Ctrl… I pinkie reach for nothing. Here is the the instructions, 10.8 approved so YMMV for other versions.

  1. Go to System Preferences -> Keyboard -> Modifier Keys. Set Caps Lock to ^ Control.
  2. Install KeyRemap4MacBook - Software for OS X.
  3. In KeyRemap4MacBook, enable Control_L to Control_L (+ when you type Control_L only, send Escape. Search will help.
  4. Reboot and enjoy.

Part Two: The Development Server.

You didn't think I was just going to vim and take off did you? No.

If I'm going to work from the shell I want to make it so I can work from anywhere while I am at it. I have a Mac OS X server that would love to be my dev box so away I go. Open some ports, SSH keys, virtualenv, python3 from brew… tada! But it's not ready yet.

OpenSSH is my best friend. I keep keys close at all times and use cools scripts on my laptop to help manage them. However SSH is not enough and this is where Mosh: the mobile shell comes in. Mosh isn't a total end to end transport solution but it's high speed udp style and local echo features make it supreme when then connection starts lagging and you don't want it to slow down your code. Best yet? brew install mobile-shell on both boxes… done…

If only we had a windows client already.

If you want some portable keys help check out the following;

Just remember to not make these your ONLY keys, all posable keys should be password encoded and easily revokable so keep a backup and list of your emergency to revoke when it gets lost.

Part Three: The Terminal

I need a sweet terminal so I use zsh with oh-my-zsh and a while bunch of personal mods. Remember the whole lazy part? Yes. Here is the highlights of my zsh configs;

The second major part is tmux. Whatever you are using now… drop it and use tmux. I remapped all my common tmux commands to vi-mode style and C-a for my leader because now ctrl and a are touching. For the full list of my configs which I won't get too deep into check out tmux.conf at master · onlyhavecans/dotfiles · GitHub.

My main tmux window generally looks like this

    |    Chat   |           |
    |     or    |           |
    |extra shell|    VIM    |
    |-----------|           |
    |           |           |
    |    IRC    |-----------|
    |           | MiniShell |

Chat is my flux buffer that gets changed between a personal chat and second work buffer. IRC is my ever present wee-chat connection. The mini shell is a little shell I keep in the same dir as vim so I can quick run python -m unittest discover module over and over or whatever. When I'm playing with Flask it's running there. Depending on where my focus is the vertical split is usually about 65% weighted to the work to squish distractions without cutting them all out or I am on the 11' MacBook Air screen instead of a 20+' external display.

I often have a second window but the latest version added C-a z for window zoom and that's GREAT when I really wanna focus on something or blow up the mini-shell while I am debugging something.

Part Four: Into VIM

First and foremost I keep an 8.5x11 copy of Beautiful Vim Cheat-Sheet Poster & Printable Downloads on my desk. It's a nice way to keep reminding me of all the features I NEED to be using and if you don't want to give someone 10USD for it there is a free link right on the page for a low res.

tl;dr the configs

dotfiles/vim at master · onlyhavecans/dotfiles · GitHub

A lot of my inital vim config like most was stolen from somewhere but over time I have stripped out everything I didn't adapt in. I started with YADR and then seriously hacked it to death. In the end there is still yadr references but you shouldn't take anything that claims being from yadr in there still is. I'm just lazy about renaming files for scuz.


There you go! I know it feels like I'm skimming the VIM part of the vim writeup but there is really only so much you can do TO VIM itself. It's the development environment you put around it and what you put out with it. Hopefully I will be putting out great things once I learn how to use tags and rope and all that other stuff to get back to ultra fast code sifting and editing.

Part Five: Wishlist

Auto-running tests

Just something that PyCharm and Komono before that spoiled me on. :w running my tests since I very often TDD would save a lot of window jumping


I'll never get deep code intelligence with vim and that's kinda the point but PyCharm saved somewhere around a billion keystrokes when you learned when to hit the auto complete right.

Part Six: Warnings

This allows me to do some awesome stuff and so far I am happy with with it outside of a few small caveats.

  1. It's damn fiddly. So much and learn and fiddle with distracts from the work.
  2. Sometimes cruising around inside of vim, inside of tmux can make for some finger dancing that I don't care for; C-a l C-a k C-w l… until I trip over my own keystrokes. C-a ; is really useful when popping between panes when it comes to mind

Part Seven: Going forward

I can connect in technically from anything I trust enough to plug my key jump-drive into. I currently have bought a YubiKey and am seriously considering switching right over to two-factor OTP which makes me LESS afraid of plugging in the key into something.

Another area I am considering going forward with is I technically won't even need my computer to work. I could just work with my iPad and a keyboard! I'm really sure these articles had just a little bit to do with my idea of moving over to all command line vim. I don't know if I am there but it is tempting;

Was this more in depth than you expected? Do you want more? Lemme know.

  1. See Just Use Sublime Text - Andrew Ray's Github Blog for details on what I mean by that. 

Tagged ,

Git-Fu Advice

Now who would have thought, I start blogging about git and people have advice. This post isn't just my personal learning but also some advice I received from others!

git reset HEAD^

From Alexis: Something I'm doing a lot is when I mess up with git, I sometimes need to uncommit something but keep the changes I had just before the commit.

git add -i

From Alexis: "Use this…" Brief but powerful advice. I never thought of using the interactive mode personally but if you are doing a complex commit or want to double over your work git's interactive mode is fairly robust.

cd my_git_repo
echo 'git push' > .git/hooks/post-commit
chmod 755 .git/hooks/post-commit

I mentioned this in an earlier post. This hook trick is for the lazy at heart. This script runs a push after every commit. If you always have access to your origin repo when you are coding, ie like you are a cubicle worker, this might not be too bad. This might get annoying of you are the type of coder that likes to write a lot of little commits on the road and then push in bundles.

    git diff --cached [--ext-diff]

As mentioned in my last post I'm big for double-checking my commits before go. This long command (that deserves an alias) pops open a diff of everything in your index ready to commit. Always a quick check before proceed!


Honing my Git-Fu Part 1


My git-fu sucks. I have to use an awesome git tool called SourceTree to do the git wizardry that I do. It's totally free and for the Mac so if you want to just jump into git and have expert features clicks away go download this. I bought it back when it cost money but now you can have it for free. I'll wait…

Anyways, I've been rolling around in the lap of GIT/SourceTree luxury these past months; clicking away and using features I only wished SVN could ever touch. However when jumping around between machines and VMs it would be faster to just use the command line. Now a days I'm now on the development team of a well sized open source project and having to fumble around git & github while testing submissions and making patches to help other people test is just NOT COOL. I think it all came to a head when the main project maintainer started flaunting some of his git-fu when submitting and fixing patches… well honestly since I just love cramming as much into my head as possible I thought I would hone my git foo.

Now back when I bought the McCullough and Berglund on Mastering Git - O'Reilly Media video's while they were on stupid sale and decided to double up with the newly released version of Version Control with Git, 2nd Edition - O'Reilly Media. Time to get my learn on.

What? Studying DISASM, Developing software, working a full time job AND now deep studying a VCS is too much? PISH, I'm single and have the time.

The point

SnowLprd wanted me to get some documenting on and take notes on what I find useful. Over the next month or so I am going to litter this blog with some posts on the "next steps" for git. While I organize my thoughts and really get my git-fu on it may be a bit all over the place. Sorry to anyone who finds this too rudimentary at points but I am going to try to focus on skimming the core concepts while posting lots of gotcha real world commands and why you would use them.

Starter Commands

I'm not gonna put up how to clone a repo here. SRSLY if you haven't gotten past 101 I'm not going to be useful. This is supposed to be 105b.

git remote set-url origin
git remote add upstream git://
git remote add MyExBF git://

Ok, so this one could be obvious but double check to make sure you have everything linked properly. You want the the R/W link to any repos you are pushing to. You might want to change your auth or connect style if you've say… been made a repo maintainer. For sakes of safety/neatness you should still treat your upstream as R/O and make all your changes in push requests and patches. Also add the R/O of your major contributors and co-developers so you can test their patches easier.

git pull upstream master && git push origin

There really should be a shortcut in this for git. Maybe I'll discover it later. I don't do my work on getpelican/pelican, I have the onlyhavecans/pelican fork! Each time I want to work on something I branch, code, commit, push, pull-request. It's an endless cycle. I never really touch my master, I just want to keep it up to date with the upstream. I don't know an amazing shortcut for that so the above micro shell script does the trick.

git push origin --delete <branchname>

I branch for every single patch to maintain tree neatness… however this becomes ugly fast on a good code month. This quickly dumps a branch and deletes it from github. Don't do this before it's been merged into master though, you are asking for pain the first time you make that mistake. Try to remember, branches aren't too expensive disk-wise so don't g too crazy on deleting them.

git add -p <file||.>

Don't add whole files to your staging area! Jeez! Who does that anymore! Be 37337 and review every change you make as you add to staging by committing at the patch level instead of at the file level by using the -p flag

git log HEAD^^ -p

This one took me a minute to figure out. So git show shows the patch for the last commit with patch if applicable but what happens when I want to spew the patches from the last three commits on someone else's branch to get a quick idea of what they are fuffng up? This one! Don't blindly follow my ^^ syntax either, learn about it below.

git commit --amend -c HEAD && git push --force

Ok, for bigger things --fixup or --squash might be better but when you open up a PR and instantly realize you are a total moron and everyone is gonna see how dumb your are because of your misspelling/typo/misscommited line… this squished one liner will recommit your quickly staged fix (letting you tweak the commit message in case that's your problem too) and replace your commit in the Pull Request with this much more awesome one.

Concepts to think of

Revision bad4dad

All revisions are named with SHA-1's of the actual commit contents. Then it uses something called treeish to sparse that down to the first 5-8 unique (to the repo) hex. That's why your commit's name is bad1dea. Obviously since repo's are distributed there is no way to create linear counters so all repo's are actually a linked list of commits. Everything from branches, to tags, to HEAD is just pointers to SHA-1.


Now then what's the ^? Well everyone knows HEAD is an alias to the most recent commit. Well you can add the ^ to any repo name and it's now the previous one. So bad1dea^ means the previous bad idea, while HEAD^ literally just means the previous commit. What's better is it's stackable HEAD^^ is two back. Now you probably don't wanna stack 10 ^'s so just use the shorthand HEAD~10 for ten revisions back.

Ahhh? History is a Linked list! so this traverses the linked list and returns all the revisions! Good for putting together a change log. To just see the last two commits git log HEAD^..HEAD Yea? Thats the cool stuff.