How I work, part 2: the command line

The 'How I work' post series documents how I work. This part is about working productively on the command line.

This is the second part of my “How I work” series. In case you missed it, read the first part here. In this part I describe the tools I use on the command line.

I keep the configuration of most tools inside a dotfiles repository. This setup lets me sync my configuration between machines. To manage the dotfiles, I use rcm and version them with git.

While most tools do one thing well, chaining them with pipes (|) or redirecting their output (>, <) makes the command line powerful and efficient. Need only a part of the output? Pipe it to awk and extract what you need.

Although I like green characters on a dark background scrolling by, they need to get out of the way quickly. I clear the scrollback buffer with Cmd+K often.

A screenshot of iTerm2 running ZSH and homebrew

ZSH and its configuration

zsh is my shell of choice. I started with the oh-my-zsh configuration framework years ago and switched to prezto recently. The main reason was the time it took to start a new session. With prezto the startup time improved noticeably. It comes with an auto-suggestion feature out of the box, so it saves you some typing later.

My .zshrc contains many aliases to save me some typing on recurring tasks. Some configuration options stand out, and I’ll describe what they do in the next sections.

Move the cursor by words with Alt + arrow keys

To use Alt+ and Alt+ to jump words with the cursor, add this to your .zshrc:

bindkey "^[^[[C" forward-word
bindkey "^[^[[D" backward-word

history + ! = 💕

history lists recent commands. Each line has a prefixed number. Type that number with an exclamation mark, for example !1729, and hit space to expand it to that command.

I search the history with history | grep foobar often. To make things easier, I’ve set up an alias for it:

alias hgrep="history | grep"

You can also search using Ctrl+R or run history | sk (see below for sk).

Beside cd and cd .. (in zsh you can omit cd and type just .. or even ….), I use pushd and popd to move back and forth between directories.

Whenever I create a new directory with mkdir -p ~/whatever/foo/bar/baz, I change to it directly with cd $_.

z: jump between recently visited directories

ZSH-z lets you jump between directories you’ve visited recently. It fuzzy matches and switches to the most-used path.

z foobar changes the working directory to e.g. /Users/gil/projects/foobar/.

Version and package managers

Since I write code, I need to install the environment to run that code in. Because every project has its own needs, one globally installed version rarely works. I used rvm and nvm before switching to asdf-vm.

  • asdf-vm: a version manager for multiple installed versions of programming languages.

Since I work with Ruby and NodeJS a lot, I need their package managers, too:

I don’t bother installing software manually on my machine. Homebrew exists, and I can find almost anything to brew install.

  • homebrew: macOS package management, including the installation of GUI applications (so-called casks).

Standard tools

What follows is a list of tools I use with a short description. Most of them are installable with Homebrew out of the box. Try brew search foobar.

Finding files, content or directories

  • find (the GNU coreutils one, please): finds files and directories by their name, type, etc.
  • mc: good old Midnight Commander, a two-pane file manager.
  • rg: super fast search for files containing your query.
  • skim: a (general purpose) fuzzy finder.

Create, read, manipulate, save and delete files

  • echo, touch, grep, cat, tail, less, more, man, rm: goes without saying.
  • jq: a cli JSON processor. Mostly I’m piping output into it to pretty print.
  • ncdu: NCurses Disk Usage. Finds large files and directories and lets you delete them inside the convenient UI.
  • pup: what jq is for JSON, pup is for HTML.
  • rpl: replaces text inside files with another text (useful when I forget the inline edit options of grep)
  • vim: my default editor on remote machines. I don’t know how to quit other editors like emacs. ¯\_(ツ)_/¯

Miscellaneous

The following tools are also in my toolbox. I file them under Miscellaneous because the number would not justify categories on their own in this post. That does not mean I use them less; most are invaluable.

These are helpful when dealing with (not only) remote systems:

  • ansible: automates the setup of new systems.
  • htop: an interactive process viewer. One of the first things I install.
  • ssh: a protocol that allows you to connect to remote servers securely.
  • rsync: synchronizes files quickly (supports binary deltas).
  • tmux: a terminal window multiplexer.

Sometimes you want to download something or need to make raw HTTP requests:

  • aria2: universal download utility (HTTP, FTP, BitTorrent, magnet, …).
  • curl: for HTTP requests and debugging them. I can’t work without it.
  • youtube-dl: download video and audio (not only from YouTube).

Using ffmpeg with youtube-dl illustrates the power of the command line. Basic example:

youtube-dl -f bestaudio --exec 'ffmpeg -i {} {}.mp3 && rm {}'

Outlook

That’s it for the second part. The third part will cover the GUI applications I use on macOS. Stay tuned.