How to Not Suck (at Being a Programmer)

November 4th, 2013 about shells, vim, git, and regex

One of the lamest features of being a programmer is the overabundance of trivial tasks that are just plain boring and time-consuming. Fortunately, our craft lends itself very well to enabling laziness: not in a negative sense, but rather, a productivity-boosting, awesome sense. Traditionally, renaming a set of 5000 files to conform to a new naming convention (eg converting .JPG to .jpg) would take a tremendous amount of effort and an equally tremendous amount of forever. By being lazy, a programmer can expend a miniscule sliver of that effort and time to write a simple script that automates the whole process.

Update: even easier than I thought.

I'm a big fan of being lazy, so here's a bunch of tips to help you become a big fan of being lazy!


Learn to love terminals / shells and the incredible power and flexibility they offer you. A GUI cannot compete with a shell when it comes to raw power, extensibility, flexbility, or anything else that actually matters. Furthermore, there may be situations where you're confined to only a terminal and can't access a GUI. Knowing how to manipulate a shell is an incredibly understated skill in the programmer's arsenal.

Text editors

Use a real text editor. That means one that works through ssh, without a window manager. That means you need to get used to using a terminal. If you disagree with me on this point, that's fine, and I respect your opnion, but you're wrong and I hate you. GUI text editors get a few pretty features that a terminal editor simply can't support, but in the long run, they pale in comparison when it comes to features, power, and flexibility. Notice a theme here?

Regular Expressions

Regular expressions are like find-and-replace on mega steroids. I can't even count the number of times I've seen another person poking around a file, replacing a dozen function calls with a similar but slightly different function call. Not only is this a totally anti-lazy way of doing things, but it's error prone: one poor function call may go unnoticed and remain unchanged, leading to headaches for future you or future maintainers.

Version Control

This is the most important of all the things in this list. Everything else on this list is possible to argue against, but no one in their right mind would argue against using version control. Not using version control is completely imbecilic and unprofessional. Version control acts as a safety net against accidental hardware failures, file deletions, explosions, etc. Beyond that, it provides a whole host of awesome features that you should want to use anyway: easy collaboration, quick changelog summaries, project histories, systems to test new features or experiments, and more. Use version control or go home.

Neat Stuff

May 21st, 2013 about python and soofw

It's almost been two weeks since I open-sourced the web site and I haven't even written a post about it, so... here's a summary of things:

  • The new home page is alright. I didn't like the thoughts list being the front page, so I just made a small about page or something.
  • Layout, style, and usability improvements turned out pretty well, I think. Some notable improvements are the table of contents feature on each page, bigger line spacing, and a wider column. I also added tags/categories again, but I'm still pretty confident that Google does it better.
  • Updated projects and demos pages seem better as well. I pretty much just reorganized everything and updated the formatting a little bit.
  • A links page to archive all sorts of interesting articles I find.
  • An archive page that just lists all of my post headlines by category. Seems pretty alright.
  • Flask is awesome. I transitioned to it from my own framework and I'm blown away by how easy and powerful it was. The development server that comes packaged inside is phenomenal amnd makes development tremendously easy. Switching between web site projects is vastly easier than mucking with all the Apache configuration files.
  • nginx and gunicorn are awesome as well, and I'm really enjoying them a lot more than with Apache and mod_wsgi. Everything seems much clearer now and I feel like I have a stronger grasp on what's actually happening; whether that's because I've got more experience in general or these are actually easier tools to use is anyone's guess. Probably a combination of both.
  • Linode is magnitudes better than GoDaddy in terms of VPS hosting. Not only is it cheaper, but the dashboard and management web site is less cluttered and easier to navigate. Everything seems much more transparent, and I have more control over the server itself (eg picking my own distro from any possibility rather than a list of two or three). I subscribed for it a few months ago and haven't looked back. I even got a free upgrade, which is something GoDaddy never did in four years. Overall, the company just seems less scummy as well.
  • Delicious is okay. It gives me a quick way to bookmark links I enjoy, tag them, and then export them to a page on this site. It's nothing spectacular and I've encountered some small nuisances, but it works most of the time.
  • GitLab is awesome. I'm not using it for this site, but it's definitely a better option than paying for private repositories from GitHub. Honestly, I think it's better than GitHub in a lot of areas.

Why I Don't Have a Facebook

April 24th, 2013 about me

Summed up in this wonderful little passage:

...I count myself among those who are often very critical of Facebook. To be clear, I do not dislike Facebook as a company and I don't dislike the broad-stroke services it provides. For hundreds of millions of people, Facebook is an amazing product that helps them keep in touch with friends and family, plan events, play social games and plenty more. It brings the world closer together, there's no question.

For me personally, however, it's just awful.

The constant trivial updates, the recycled posts, the event invitations from people I haven't spoken to in 15 years, the app invitations, the game invitations, the fact that other people can check me into places and tag me in photos that appear on my page automatically... it gets infuriating.

Privacy settings help, of course, but then every time a new feature is added, users have to tweak their settings to block it. Most of the time, I'm not even aware new features roll out until I get some awful email notification about something that someone else posted on my wall. Then I have to log in, block the new feature and disable email notifications for another half-dozen list items.

Huge update!

March 29th, 2013 about soofw

Well, well, well... where to start. I've added a few new features to the site and made a ton of changes in the source. Here's really simple changelog:

  • SCSS instead of CSS ‒ oh my god why have I never used this before.
  • Some CSS3 transitions ‒ just because they're neat.
  • Projects page ‒ for my personal projects and whatnot.
  • Demos page style update ‒ to be more readable and consistent with the projects page.
  • New page header ‒ you know, up there ^^^ for navigating the site and stuff.
  • No JavaScript ‒ I had some JavaScript loading on each page for no particular reason... now I don't!
  • New error page ‒ because I needed one.
  • Refactored code ‒ because I needed to.
  • Almost open source ‒ the code is almost reaching a level where I feel comfortable letting everyone in the whole world see it.

The end.


March 19th, 2013 about soofw

Huzzah. A new site feature: snippets. At the moment, it only contains a few infrequently used chunks of shell scripts used to configure some stuff, but I have high hopes for it. Beyond the addition of snippets, I've also updated some of the code base and I'm slowly working towards a version that's acceptable for open-sourcing. I'm also working on updating the site's URIs, so a lot of old URIs and legacy URIs will now 301 Redirect to the new URIs. Posts should also have a "view source" link in the top right corner, just in case you want to view an individual post's Markdown source.

How to Learn Vim (Actually)

March 16th, 2013 about vim

When you first start learning Vim, it just sucks. Everyone (except a few lucky people) goes through the "this is stupid" phase, and a lot of those people just give up on Vim because it's so different. Don't. Vim has multitudes of advantages over traditional editors and IDEs; notably, its incredible efficiency and ease of access through remote shells like ssh. Since this article is about actually learning Vim, however, I'll be carrying on now...

Get Comfortable

Seriously. So many hardcore Vim users are dead set on fully immersing yourself immediately: "turn off the arrow keys", "don't use the mouse", etc. Wrong. You have to be comfortable before you can learn. If you're immediately thrown into a completely new editor with no sense of familiarity, you're going to go insane. It's hard to adapt to so much at one time, so take it slow. Start off with the very basics: arrows move, i enters insert mode, <Esc> leaves insert mode. That's it. Get comfortable with those things. If you want to use a mouse, try using the set mouse=a option in your .vimrc. You'll grow out of these habits eventually.

Learn Something New

Once you're comfortable using insert mode and the arrow keys / mouse, learn a few more neat tricks (check the bottom of this post for some starters). Don't try to learn a dozen; just pick one or two. Get comfortable with them. There's no point in learning a dozen commands if you won't remember any of them. Once you've gotten pretty comfortable and mostly mapped them to muscle memory, repeat the process and pick out one or two more. Take it slow and go at your own pace. There's no point to going too quickly because you won't retain as much. Notice a theme yet? Be comfortable.

Keep Out of Insert

You wan't to stay out of insert mode as much as possible. Only enter insert mode if you're actually going to be writing something. If you're just moving around the file, even if it's just a few lines or characters, get out! You're wasting keystrokes. Most of Vim's efficiency lies in normal mode, so spending all of your time in insert mode is just plain wrong. If you have to enter insert mode every time you want to delete a letter, it's a minimum of three keystrokes: i<Backspace><Esc> or a<Backspace><Esc>. If you're rocking out in normal mode, it's one: x. If you want to delete five letters, insert mode will be a minimum of seven keystrokes, while normal mode will be two: 5x. What if you want to delete a whole line? In insert mode, you have to move all the way to the end of the line with the arrow keys, enter insert, and hold backspace until you're done. Or just stay in normal mode and press dd or 0D, depending on whether you want the blank line to stay or not. Stop using insert mode. It's bad.

Make Your Own .vimrc

Don't download a suite of plugins and fully configured files. Instead, just start with a nice color scheme and some "essential" settings like line numbers. Get what you "need" to be effective, but try to keep it to a minimum. Just like learning too many commands, if you configure too many options or plugins you won't remember what you've done. Just start simple and build it up on your own.

Take Notes

Even better, write them using Vim. Open a file in your home directory and write down every new command you learn with a short description of how it's used or what it does. Check back on it every once in while. Alternately, make a cheat sheet or even buy one. Even if you take your learning slowly, you might forget one or two commands after a day off. It's critical to review your notes or have a nice cheat sheet to refer to.

Learn Vim's Grammar

Vim's commands aren't discrete parts designed to be used separately; they were designed to be a fluid language that can be combined and used together to multiply the results. If you're trying to compound commands as one single command, you should take some time to read about Vim's grammar. It'll give you a huge boost once you start getting some of the advanced motions mastered.

Starting Commands


  • i enters insert mode before the cursor
  • I enters insert mode before first non-whitespace character on the line
  • a enters insert mode after the cursor
  • A enters insert mode at the end of the line
  • o inserts a new line below the cursor and enters insert mode
  • O inserts a new line above the cursor and enters insert mode
  • <Esc> leaves insert / visual mode


  • hjkl move the cursor
  • h moves left (it's the leftmost key)
  • j moves down (it looks like an arrow pointing down)
  • k moves up (because)
  • l moves right (it's the rightmost key)
  • Learn these once you're comfortable with a few others.
  • 0 moves to the first character
  • ^ moves to the first non-blank character
  • $ moves to the last character
  • gg moves the cursor to the first line
  • G moves the cursor to the last line
  • :X or XG moves the cursor to line number X
  • e moves to the end of the current word, or the end of the next if you're already at the end of a word
  • w moves to the beginning of the next word
  • b moves to the beginning of the current word, or the beginning of the previous if you're already at the beginning
  • EWB are similar but use whitespace as the word delimeter instead of punctuation (commonly referred to as WORDs instead)
  • tX moves the cursor to the first occurence of character x
  • fX moves the character onto the first occurence of character x
  • TX is the same as tX but searches left
  • FX is the same as fX but searches left
  • /search will search the whole file for the term 'search'
  • n will find the next occurrence of your search term
  • N will find the previous occurrence of your search term
  • starting the search with ?search will automatically start in reverse search mode


  • x deletes the character under the cursor
  • dd deletes the current line
  • D erases everything on the line after the cursor
  • yy yank (copy) the current line into the default register (a register is like a clipboard)
  • p pastes the default register after / below the cursor
  • P pastes the default register before / above the cursor
  • :wq saves and quites; :w just saves; :q just quits; :q! quits and discards unsaved changes.
  • cc or S erases the current line and enters insert mode
  • C erases everything after the cursor and enters insert mode
  • s erases the character under the cursor and enters insert mode
  • ciX erases everthing inside the delimeter X and enters insert mode. X can be several items:
  • ( or ) will select inside the pair
  • [ or ] will select inside the pair
  • { or } will select inside the pair
  • ' or " will select inside the pair
  • w or W will select inside the word or WORD
  • t or T will select inside the HTML/XML tag
  • caX erases everything around the delimeter X (including X) and enters insert mode. You can use the same options as with ciX
  • diX and daX work like ciX and caX
  • rX replaces the character under the cursor with X
  • R enters replace mode, causing any characters typed to replace the character under the cursor

"Essential" .vimrc settings

Just add these to your ~/.vimrc file and Vim will load them every time it starts up. If you're looking for more powerful options, check my GitHub.

  • set number will turn on line numbers
  • set incsearch will turn on incremental search. This jumps to search terms as you type them
  • set hlsearch will highlight all matching search terms
  • set ignorecase will ignore case while searching
  • set smartcase same as ignorecase UNLESS you use a capital letter in your search
  • set tabstop=X set the number of spaces that represent a tab
  • syntax on turns on syntax highlighting