loading...

Sam's dotfiles highlights

samthor profile image Sam Thorogood Updated on ・3 min read

Blog-A-Day in June (19 Part Series)

1) Rebuild only when necessary in Node 2) Civilization is a game you never lose 3 ... 17 3) Arrow functions break JavaScript parsers 4) Detecting Select All on the Web 5) Declaring JS Variables in 2019 6) Sam's dotfiles highlights 7) Automate Reading Form Results with 🤖 Chrome 8) Beyond appendChild: Better convenience methods for HTML 9) AMA, Sam 10-yr Googler in Web DevRel 10) Disable a HTML form while in-flight using fieldset 11) PWAs that download like apps 🗜️ 12) Matching elements with selectors in JS 13) Install This PWA To Continue 14) Google Assistant now supports "Open/Close" devices 15) Modern Web Components 16) What To Expect When You're Expecting To Drop IE11 🗑️ 17) Divert Vertical Scroll To The Side ↔️ 18) Graceful Shutdown Is A Lie 19) Progress Indicator With Fetch

Most developers end up creating some sort of dotfiles repo to contain configuration files for their *nix-like machines (macOS, Linux, etc). Rather than just setting up every machine you access in an ad-hoc way, you can create a repo to keep the same environment for your terminal everywhere.

There's a lot of starting points out there that you could clone from. If you know git, my advice would be to follow how to manage them with git—this guide lets you use a special dotfiles command.

My dotfiles are pretty boring, but I think there's a few parts that make mine special. Let's talk through them. I use bash, the default in most places.

  1. Layout—what calls what and how things are run
  2. Platform Help—distinguish macOS and Linux
  3. Helpers—take a look inside my scripts

Layout

My layout is pretty simple. The .bash_profile file immediately runs .bashrc, so there's no difference in how you log in (the two files being different is a big source of confusion for newbies—so just merge them! 🤣).

Bash layout

One file that I've used for years is .bash_functions (originally written by a friend back in ~2009). It provides a few helpers that make dealing with paths "safe". Here's a simple example—both pathprepend and ssource check that the path or file exists before using it:

#!/bin/bash

source "${HOME}/.bash_functions"  # first line of .bash_profile

# adds to $PATH if the directory exists
pathprepend "/opt/local/sbin"
pathprepend "/opt/local/bin"
pathprepend "${HOME}/.local/bin"

# runs contents of .bash_local if it exists (not checked in, for
# custom changes on each machine)
ssource "${HOME}/.bash_local"

A Note On SSH

🚨 While I do check in my id_rsa.pub file to every machine—this is the public, sharable part of your identity—I don't include id_rsa in my dotfiles repo. I keep it only on machines I have physical access to, such as my laptop or a server in my house.

This is important. Your id_rsa (or id_dsa?) is private and even if it has a password, is going to be cracked if you accidentally upload it somewhere public.

Platform Help

At the top of my .bashrc, I set a handy variable:

IS_MAC=""
UNAME=$(uname)
if [ "${UNAME}" == "Darwin" ]; then
  IS_MAC="yes"
fi

I switch between macOS (which is really BSD and has older versions of things) and Linux, so this helps make a choice if things work differently, as it does for the params to ls:

if [ $IS_MAC ]; then
  alias ls='ls -lGho'  # macOS doesn't support `--color=auto`, needs `-G`
else
  alias ls='ls -lh --color=auto'  # on Linux, `-G` means "no groups"?!
fi

Helpers

I've got a few scripts inside my ~/.local/bin folder. Some of which I use almost daily. 📜❗#️⃣

Image Compression

I have two scripts—crush and pcrush—which compress a single PNG image, or compress many in parallel. I never remember the arguments to run the tools pngcrush or zopflipng (better), but it's always worth shrinking your images before you upload them (gotta go fast!).

I built pcrush so I could also take advantage of multiple CPUs—turns out both the tools above run on a single CPU only, but if I have 100s of images, I want to crush them fast. I can make my CPUs do this:

parallel compression

Git Status

I have a script called gstate which outputs a number of things based on the current Git repository. It includes branches, normal status, any stashed changes, and known divergence from upstream (i.e., the remote repo you've mirrored from).

It's handy and honestly burned into my muscle memory forever now. 💪

If you're curious, check it out here.

That's All!

I hope today's short view into my environment has been interesting! Got your own handy scripts you can't live without? Let me know! 🗣️💬

(This Blog-A-Day post goes out to my partner: holding a screaming baby while I write.)

6 👋

Blog-A-Day in June (19 Part Series)

1) Rebuild only when necessary in Node 2) Civilization is a game you never lose 3 ... 17 3) Arrow functions break JavaScript parsers 4) Detecting Select All on the Web 5) Declaring JS Variables in 2019 6) Sam's dotfiles highlights 7) Automate Reading Form Results with 🤖 Chrome 8) Beyond appendChild: Better convenience methods for HTML 9) AMA, Sam 10-yr Googler in Web DevRel 10) Disable a HTML form while in-flight using fieldset 11) PWAs that download like apps 🗜️ 12) Matching elements with selectors in JS 13) Install This PWA To Continue 14) Google Assistant now supports "Open/Close" devices 15) Modern Web Components 16) What To Expect When You're Expecting To Drop IE11 🗑️ 17) Divert Vertical Scroll To The Side ↔️ 18) Graceful Shutdown Is A Lie 19) Progress Indicator With Fetch

Posted on by:

samthor profile

Sam Thorogood

@samthor

Developer Relations for Web at Google.

Discussion

markdown guide
 

Do you mind sharing how you alias gstate since it's a script not a function...?

 

I just put the gstate file inside my $PATH. I personally have a folder ~/.local/bin where this stuff lives.

 

So...

alias gstate='bash ~/.local/bin/gstate.sh'

?

Well, if ~/.local/bin/ is in your $PATH (if you're on Windows I'm not sure what this would look like), then you can just type "gstate.sh", or just remove the extension and type "gstate". There's no need for the alias in this case.

 

Fantastic. Thank you! I like your gstate script output. :)