Programming is the closest thing to magic I’ve found. But even in programming, there’s no shortage of mundane nearly-identical tasks. They accumulate like dirty dishes with dismal regularity, sapping our time and willpower.
Maybe you’re a freelancer billing hours, so every day you print out the repo’s git commits, copy your commits, format and save them to your worklog. Endless, like the dishes. But what if you could do it once and be done, forever?
# Print and format git commits - credit: https://github.com/abaldwin88
alias git-today='git --no-pager log --pretty="- %s. %b" --author=[YOUR GIT USERNAME/EMAIL] --since=midnight --all --no-merges --reverse'
# remove lines with "index on", remove duplicate lines, remove empty lines, add new line delimiter for \*
git-today-clean() { git-today | awk '!/^index on/' | awk '!x[$0]++' | sed 's/\*/\'$'\n\*/g' | sed '/^$/d' }
gitToday() { git-today-clean && git-today-clean | pbcopy }
Still too much work? Set it on a cronjob appending to a work_log.txt
file with aliases sourced and loaded, and never think of it again.
When you see a repetitive task, even an easy one, remember: Wizards don’t do dishes, they automate. You should too.
What Makes a Good Spellbook?
Any high-frequency, verbose, or hard to research command that makes your life easier is worth keeping. And once you’ve started amassing a treasure trove of one-liners you need a spellbook to put them in. By ‘spellbook’, I mean a modifiable, instantly accessible, and referenceable codebase that is always at your fingertips. Files like .bashrc
and .zshrc
(RC meaning “run commands”) are great. Cheat sheets, reference notes, and tools like tldr or navi also work, provided they’re command line accessible. Aliases and code editor snippets are perfect as they’re tailored to your use cases and always in your dev environment.
Make your spellbook easy to add to and even easier to search. If it gets too big to browse, tag and grep it. Once your system is set up you can solve a problem once and have the solution ready to go forever.
Start simple
As a junior I was drowning in database commands, unfamiliar syntax and lengthy api calls. I needed something more organized and durable than my bash history, but more seamless than my notes app. So I made my first custom tool. I created a ~/.cheatsheet.txt
file and added two simple bash functions to my .zshrc
.
# ~/.zshrc
function csadd() { echo "$1" >> ~/.cheatsheet.txt; }
function cs() { cat ~/.cheatsheet.txt | grep "\#$1"; }
# Add a snippet
$ csadd '| python -m json.tool #json'
# Return all tags labeled '#json'
$ cs json
#=> '| python -m json.tool #json'
In two lines of code, I had a working cheatsheet. Not a feature-rich CLI like Navi, just some crude glue around cat
and a .txt
, but I could already reference commands, add snippets, search, and pipe data in seconds.
Keep commands short
It’s worth speeding up even the simplest actions, if they’re frequent enough. Surprisingly, some of my best time gains are aliases for cd’ing into commonly used directories and project setup.
# ~/.zshrc or ~`/.bashrc`
# -------
# Files and Project
# -------
alias notes="cd ~/Documents/notes/"
alias todo="code ~/work/todo.md"
alias project_notes="open ~/work/my_project/daily_notes.md"
alias spinup="cd ~/work/my_app && bundle exec rails server -p 3000"
# -------
# Git Aliases
# -------
alias ga="git add "
alias gb="git branch "
alias gc="git commit "
alias gd="git diff "
alias gm="git merge "
alias go="git checkout "
alias go="git checkout "
alias gp="git pull "
alias gs="git status "
#...
You might ask, isn’t that overkill?
Short answer: No. Your brain has a very small attention buffer (7 ± 2). The faster you move the less that precious buffer decays.
Why use more chars when few chars do trick?
– Kevin Malone
Your dev environment should fit you, even outside the command line. Getting hacky, you can make a js script to fill out forms or dummy logins, save your localhost app url on chrome Site Search settings so you can simply type @l to go to it.
Example: pryrc
Let’s show how you might start this process with a Ruby .pryrc
file for Rails projects. The .pryrc
(or .irbrc
, if you use irb) functions pretty much like bashrc in that it gives us a place to load up commands and config so we can access them in our pry or irb console.
Let’s load up our handy .pryrc
spellbook and set some default models and convenience methods.
# ~/my_rails_app/.pryrc
# initial boilerplate
if defined?(Rails)
module Rails::ConsoleMethods
alias r reload!
def any_method
end
end
end
Default models
Now let’s write some common model variables models so we don’t have to type them each time by hand.
# convenience variable
def admin
User.where(admin: true).first
end
# memoized convenience variable
def user
@user ||= User.first
end
# longer queries
def late_books
Book.where("due_date < ?", Date.today)
end
Custom commands
Want to save a large output to your clipboard without fiddly mousework?
def rbcopy(arg)
`echo "#{arg}" | pbcopy`
end
# alternate: IO.popen('pbcopy', 'w') { | io | io.puts arg }
Or maybe execute sql in the rails console without typing 50+ lines?
def ex_sql(sql)
results = ActiveRecord::Base.connection.execute(sql)&.entries
results.presence
end
Or make benchmarking easier?
# credit: https://gist.github.com/justin808/387d4754d3a3aec35bde64c979857170
# Usage: do_time(20) { expensive_query }
def do_time(repetitions = 100, &block)
require 'benchmark'
Benchmark.bm { |b| b.report { repetitions.times(&block) } }
end
Or add a hacky class name alias?
def rl
ReallyLongModelNameYouAlwaysTypeWrong
end
# Now you can call rl.where() instead of ReallyLongModelNameYouAlwaysTypeWrong.where()
Check out what other amazing devs have done in their pryrcs and irbrcs. The possibilities are endless!
Many thanks to Justin Weiss and Rishi Pithadiya’s blogposts for upping my pryrc game.
Loved the article? Hated it? Didn’t even read it?
We’d love to hear from you.