How to Not Suck (at Being a Programmer)

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.

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!

Shells

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.

Terminals Can Have Colors!

I love using terminal emulators. I think they're pretty neat, and I think they're pretty powerful too, but I also think they can be pretty hard to use without some moderate customization. Conveniently enough, I love personalizing my gadgets, tools, and programs. I've spent a lot of time in the last two years collecting tiny snippets and adding them to my .bashrc, and all of this accumulation has resulted in a rather personal terminal / prompt set up. I'll try to highlight the best features in this post so anyone else can use them.

Before starting, I would like to point out that this is my prompt and is designed to suit my needs. You might have different needs, wants, and goals, so this might not be a perfect set up for you, but I'm hoping you'll at least learn something new. I would also like to point out that (almost) all of my Linux dotfiles are available on my GitHub page.

Why bother?

Many people use the command line every day and never bother to customize their prompts. It’s just a bit of text that’s printed before every command — why should you waste time learning how to customize it?

I feel that the most important aspect of my command line work is the prompt. Your prompt is something you’ll see literally thousands of times a day. Why not take 30 minutes and customize it into something that’s much more useful?

I firmly believe I’m right in thinking this way. 30 minutes (or even 3 hours) of customization to make your work easier for the rest of your life (or at least however long you stay with your current shell) is worth it.

That's why. Even more importantly, most default prompts are completely unusable. They usually lack any color highlighting which makes them blend into large command output. Some even lack the current working directory, and most are in such a compact form that it can be hard to distinguish one part from another without colors. For example:

Without even reading my own prompt, I can determine I'm logged into my desktop and working in a git repository. After reading, I can tell you that the repository has untracked files but no modifications, I'm 4 commits ahead of the remote repository, and I'm currently tracking my project time with clk. I can't say anything good about the alternative.

Colors, Font, and Terminal

For a terminal emulator, I use GNOME Terminal or the Secure Shell Chrome Extension when on my Chromebook or a non-Linux machine. I'm using Proggy Clean (Slashed Zeros) 12pt for my font, although I find the size varies from machine to machine and terminal to terminal. Make sure you always find the appropriate size for Proggy or it will look like garbage; pixel fonts are atrocious unless they're sized correctly. My background is black with approximately 80% transparency. I use a customized 16-color palette that really likes to mess with color-highlighted output, so copying it exactly may not be the best idea unless you can put up with the occasional color mistakes. The first 8 colors are all varying shades of gray, while the next 8 are some rainbowy accent colors:

Default: Light gray #0 #D9D9D9

Color 0: Dark gray #1 #2E3338

Color 1: Dark gray #2 #454C54

Color 2: Dark gray #3 #5C6670

Color 3: Gray #1 #737F8C

Color 4: Gray #2 #8F99A3

Color 5: Light gray #1 #ABB3BA

Color 6: Light gray #2 #C7CCD1

Color 7: Light gray #3 #E3E6E8

Color 8: Red #FF4D6A

Color 9: Orange #FFA64D

Color 10: Yellow #E1FF4D

Color 11: Green #6AFF4D

Color 12: Seafoam #4DFFA6

Color 13: Cyan #4DE1FF

Color 14: Blue #4DA6FF

Color 15: Purple #A64DFF

Shell and Prompt

I'm using bash as my shell. I've heard great things about zsh, but I find that bash is more universally available. It's also the default shell on most machines, so this post should hopefully be applicable to most people.

My prompt leads with the history number of the current command. This seemed like an excellent feature at first, but I'm starting to use it less frequently than I used to. Essentially, having the line number be so visible makes it much easier to use bash's !### history lookup, where ### is the history line. In practice, I find myself using ctrl-r and !partial more frequently. In bash, ctrl-r allows you to reverse search through the history by typing part of a command, while !partial will automatically reverse search the history and be replaced by the first command that starts with partial. For example, frequently editing a file with vim file.c and compiling with make can be repeated with !v and !m. That can get a little tricky if you suddenly use a man page however, as !m will find the most recent command that started with m.

Immediately following the history number is my username and the hostname, color-coded according to the host. For example, my desktop prompt is purple, while my web server is yellow and my Raspberry Pi is raspberry red. If I'm logged in as root, my username will also turn red, and the command separator will turn into a #. After the hostname is my current working directory highlighted in green. The neatest part, in my opinion, is the current git repository status between the working directory and command separator. While I'm currently in a git repository, the working branch shows up in red. If the current repository has no changes but contains untracked files, a question mark will be appended after the branch. If the repository has staged or unstaged changes, an asterisk will be appended. If the repository is ahead of the remote, a +X will be appended to notify me of how long it's been since I last pushed my commits. Lastly, the command separator (normally a $, but # when root) changes colors based on my clk status: green means I have no clock data for this directory, red means I'm clocked in and tracking my time, and yellow means I'm clocked out and not tracking my time.

Conclusion

I'll try to elaborate more on how to add these features in the future, but I just wanted to give a nice sample of my prompt. For the adventurous, you can check out my .bashrc at GitHub.

Using Chrome as a Terminal

I love terminals, and I love Chrome, so it's no wonder that I love Google's official Secure Shell app. It's just a Chrome/ium extension that lets you open a terminal and connect to a machine via ssh. It's certainly not a replacement for my standard gnome-terminal, but it's pretty close. I've already started using it on my Cr-48 to connect to my desktop and it's been working perfectly. It's also a much nicer way to ssh from a Windows machine than PuTTY.

I would absolutely love to have a terminal that supported Chromium style tabbing. I love Chromium's tabs because of their minimalism and sleek style, but that's unfortunately an area where using this as a real terminal falls short. If you launch the app in a standard tab and drag it out as a new window, you're stuck looking at the unnecessary address and bookmark bars. Or, if you launch it in windowed mode, you get the address and bookmark bars hidden, but you also lose the tabs. Bummer. Furthermore, it doesn't support a fully transparent background (one that shows the desktop/programs behind it) which is a feature that I find absolutely necessary in a terminal. Even worse than those two options, however, is the fact that it doesn't support a local shell option outside of ssh-ing into localhost, which kinda sucks.

If you're interested in trying it, I actually recommend signing up to the Google Group and installing the dev version instead, as it has support for changing the default color palette. I just learned about this version today, which was an incredible find because I've been struggling with the default colors. There's just something about not using my own color scheme that irks me just enough to completely disrupt my focus.