Welcome to the lab.

Web Excursions for November 17, 2017

[Tweet : nvALT]

Web excursions brought to you by MightyDeals.com, featuring great deals on software, training, and design resources.

Insight.io GitHub code browser
I’ve long used the OctoTree Chrome extension for browsing GitHub with a full tree view of the folders and files. Insight.io adds some full-fledged IDE features to this. Code navigation, class and method references search, definition lookup, and more. (Also see my other favorite Chrome extensions)
Tetra - Automatic Call Notes
An AI-based notetaker for phone calls. You can tag a spot in the conversation as a marker, and get a summary of the call afterward. I would love to figure out a way to do this with podcasting, getting show notes and markers delivered to me automatically…
Datasette: instantly create and publish an API for your SQLite databases
A tool for creating and publishing JSON APIs for SQLite databases, instantly creating a url-based interface for accessing (but not writing) your data via JSON(o) calls.
Neal Preston: Exhilarated and Exhausted
“I want the reader at the end of this book to feel like they’ve just spent a year on the road with Zeppelin with one day off, then six months with Guns ‘n’ Roses, with one day off and then five years with Bruce Springsteen. Exhilarated and exhausted.” -Neal Preston
: Legendary rock tour photographer Neal Preston’s coffee table book. I haven’t bought this, yet, but it’s on my wish list.
How to use sudo with Touch ID on your Mac
Cabel Sasser tweeted a tip for enabling MacBook Pro Touch Bar touch ID for sudo commands in Terminal. Serenity Caldwell explains it in detail on iMore.

Universal Mac organization with Unclutter (and it’s 40% off!)

[Tweet : nvALT]

Unclutter has been around for a while now, and it’s just as intriguing to me as it was when it was released. It’s a utility that combines clipboard history, interim file management, and a notepad all in one app with a clever (and elegant) interface.

(Oh, hey. If you already know about Unclutter and just want the sale link, here you go.)

To open the Unclutter panel, you just put your cursor over the menu bar at the top of the screen and scroll down (i.e. 2-finger swipe down, or a scroll wheel, or possibly a ball if you still like those mighty mouse things and the ball didn’t gum up on you years ago.) The gesture to open it can also be customized with alternatives like holding down a modifier key or having it just open automatically after a delay.

When the panel slides down, you have three panes across your screen. Clipboard, files, and notes. The widths can be configured and individual panels can be rearranged and be disabled, so Unclutter can fill just the functions you need without being, well, cluttered.

Clipboard history

The clipboard pane provides a history of everything you copy. Text, images, files, etc., and you can choose items from the history to re-paste. I honestly don’t know how people survive without some kind of clipboard history (e.g. Keyboard Maestro, LaunchBar, Alfred, etc.). Having to constantly remember that you put something in your clipboard and it will disappear if you forget to paste it before you copy something else is agitating.

Unclutter’s clipboard history works perfectly for any standard usage, providing a visual overview of what’s been in your clipboard with any item clickable to paste it again. You can also star items to add them to favorites and keep an easily-accessible list of common clippings available.


The files pane is a primarily a temporary holding area. Like Yoink and the Dropzone Drop Bar, you can use it as a place to drag files to while you get to the place where you want to put them. Collect files from multiple places, switch Finder windows or apps, and drag them back out.

Unlike Yoink and other tools, Unclutter actually moves the file to an interim folder rather than using File Promises. Generally I prefer the “promises” method, but there are a few nice things about this method: files persist between app launches and reboots, and you can set the temporary folder to be in Dropbox, so you can actually have your “holding area” sync across multiple machines and devices.

Folders in the files pane can be dragged to, so you can create various organization systems. You can also hold down Option to copy a file/folder into the file pane, or hold down Command-Option to create an alias. Using an alias means you can have a permanent reference to a folder without actually moving it, so you can do things like alias your Documents or Applications folder (or any folder you move files to frequently) to make dragging files there easy from any application.

Files in the files pane can be searched by name right from within Unclutter. You can view them as a list or as auto-arranged icons, organized by name, kind, or date.


The notepad pane is similar in interface to nvALT and its ilk. Just a place where you can quickly take plain text notes and quickly reference them. Notes are displayed in a list, sorted by date added. The search feature is fast and full-text, so finding notes quickly doesn’t generally require a lot of scrolling. You can jump to search with ⌘F, but you do have to click in the pane you want to search before that will work. If you (like me) prefer nvALT’s more modal, keyboard-based interface, you can always disable the notes pane as well.

In summary, Unclutter is a great utility, combining 3 tools that would otherwise require dedicated apps or a more complex app with additional capabilities that not everyone needs. It’s also inexpensive at $9.99. And right now it’s on sale for $5.99 (40% off). I’m a little late in mentioning the sale, so there’s only one day left to grab it (sale ends Nov 17).

macOS KeyBindings for SearchLink

[Tweet : nvALT]

SearchLink is one of the tools I’ve created that I use almost every day, so I’ve added a few bindings for it to my KeyBindings project. These will insert the basic syntax for SearchLink input, and you can add custom bindings for custom searches.

For details on adding these to your system, see the KeyBindings project as well as my original blog post on this project.

Once these are installed, you can use them in any Cocoa application. They’re all bound to ⌃⌘g (control-command-g), with the various search types bound to the next letter. So hitting ⌃⌘g and then typing g will wrap the selected text as [selected text](!g) for a Google search with SearchLink. Included bindings are:

SearchLink commands (⌃⌘g)
⌃⌘g g SearchLink Syntax: Google ([text](!g))
⌃⌘g ⇧a SearchLink Syntax: Amazon ([text](!a))
Apple (a)
⌃⌘g a i SearchLink Syntax: iOS App ([text](!itu))
⌃⌘g a m SearchLink Syntax: Mac App Store ([text](!mas))
⌃⌘g s SearchLink Syntax: Software ([text](!s))
⌃⌘g t SearchLink Syntax: Twitter User ([text](!@t))

Here’s the code. You can also find this in context on GitHub:

"^@g" = { // SearchLink commands
  // SearchLink Syntax: Google
  "g" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "](!g)", moveRight:, deleteBackward:, moveLeft:);
  // SearchLink Syntax: Amazon
  "A" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "](!a)", moveRight:, deleteBackward:, moveLeft:);
  "a" = { // Apple
    // SearchLink Syntax: iOS App
    "i" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "](!itu)", moveRight:, deleteBackward:, moveLeft:);
    // SearchLink Syntax: Mac App Store
    "m" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "](!mas)", moveRight:, deleteBackward:, moveLeft:);
    // SearchLink Syntax: Apple Music
    // "m" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "](!g)", moveRight:, deleteBackward:, moveLeft:);
  // SearchLink Syntax: Software
  "s" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "](!s)", moveRight:, deleteBackward:, moveLeft:);
  // SearchLink Syntax: Twitter User
  "t" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "](!@t)", moveRight:, deleteBackward:, moveLeft:);

As an example there are a couple I use for my own blog searches. It should be pretty obvious how to modify these…

SearchLink custom searches
⌃⌘g b SearchLink Syntax: BrettTerpstra.com ([text](!bt))
⌃⌘g p SearchLink Syntax: BrettTerpstra.com Projects ([text](!btp))
⌃⌘g m SearchLink Syntax: IMDB ([text](!imdb))

And here’s the code for that (include this within the ^⌘g section from above):

  // SearchLink Syntax: BrettTerpstra.com
  "b" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "](!bt)", moveRight:, deleteBackward:, moveLeft:);
  // SearchLink Syntax: BrettTerpstra.com Projects
  "p" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "](!btp)", moveRight:, deleteBackward:, moveLeft:);
  // SearchLink Syntax: IMDB
  "m" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "](!imdb)", moveRight:, deleteBackward:, moveLeft:);

Read more about how to use these and see the full set on the KeyBindings project page. And seriously, if you haven’t dug into SearchLink yet

An update to PopMaker extension generator for PopClip

[Tweet : nvALT]

Back in 2014 I created a little app that generates custom PopClip extensions. It broke on 10.13, so I’m updating it for the latest OS.

PopMaker was created in response to the number of requests I got for what were essentially the same extension. Either one to surround text with custom prefix/suffix, or to create a custom search extension to send the selected text to a search engine or a local url handler (Evernote, nvALT, etc.).

The new version still only creates search and text surround extensions. I started working on a whole system for custom script extensions, but ultimately it was too much effort that needed to go elsewhere. If you know enough about coding to write a custom script, you can probably figure out the rest.

I added a project page with details. See below for the updated download.

PopMaker v0.2

A Mac application for generating customizable PopClip extensions

Updated Mon May 12 2014.

DonateMore info…

WALTR 2 is 30% off

[Tweet : nvALT]

Because I’ve written about WALTR 2 previously, I wanted to mention it’s on sale with a 30% discount right now. WALTR 2 is the insanely fast tool for getting video and audio in any format (including FLAC and 4K) from your Mac to your iOS device’s audio/video collections. It works over USB or WiFi with just a drag and drop for automatic conversion and transfer.

The 20% discount on Paw I mentioned recently ends today, so if you’re a dev working with REST APIs, don’t miss out on that one.

The iTextEditors “purge”

[Tweet : nvALT]

iTextEditors LogoOoh, scary. The latest round of updates to iTextEditors saw a significantly higher number of deletions than additions. A purge of the chart to match The App Store Purge. Sad to see almost 20 editors go, but the list is trimmer now, and the good ones are easier to spot. Happy Halloween.

I haven’t had time to go out and dig for the latest additions, so if you have a new favorite that’s not listed, please submit it!

A few new shell tricks

[Tweet : nvALT]

As part of my continuing “Bash Fun” series, I have a few more tricks for Terminal junkies. These work in Bash and Zsh, and probably elsewhere.

To use any of these, just put them in a file and source them from your login profile (~/.bash_profile, etc.).

Write a quick Markdown list

This first one is super simple. It just takes a tab-indented list from STDIN and outputs a Markdown bullet list in Terminal. It removes blank lines and maintains indentation using sed.

You can just run qlist and type the list in Terminal, ending input with ⌃d on a blank line, or pipe input in from pbpaste or a file.

The qlistpb alias at the end is just a shortcut for piping the output to the clipboard instead of STDOUT.

qlist: quick markdown list
# output a quick markdown list from stdin to stdout
qlist() {
    sed -E '/^[     ]*$/d'|sed -E 's/^([    ]*)/\1* /'
# quick list to clipboard
alias qlistpb="qlist|pbcopy"

Quickly list IP addresses for the current machine

Next, a function to quickly list internal and WAN ip addresses. It uses ifconfig for the local IP, and then dig with the OpenDNS resolver for the WAN address. It works just as well with icanhazip.com using curl -sS icanhazip.com instead of the dig command, but I have more faith in the OpenDNS method being futureproof.

Updated: Thanks to comments from Keith Rollin and Daniel Whicker the script now iterates through all available network interfaces to find one that’s active.

**Also, Kai Wells has created a fish version of lips.

lips: list ip addresses
# l(ist)ips Get local and WAN IP adddresses
# Updated based on comments from Keith Rollin and Daniel Whicker
# $ lips
#    Local IP:
# External IP:
lips() {
	local interface ip
	for interface in $(networksetup -listallhardwareports | awk '/^Device: /{print $2}'); do
		ip=$(ipconfig getifaddr $interface)
		[ "$ip" != "" ] && break

	local locip extip

	[ "$ip" != "" ] && locip=$ip || locip="inactive"

	ip=`dig +short myip.opendns.com @resolver1.opendns.com`
	[ "$ip" != "" ] && extip=$ip || extip="inactive"

	printf '%11s: %s\n%11s: %s\n' "Local IP" $locip "External IP" $extip

Convert HEX to RGB

Lastly, a function to convert hex color string to RGB using printf. This one takes a 6-character hex code (e.g. #faf1cb) and converts it to an RGB string, (e.g. rgb(250,241,203)).

The leading hash (#) is optional and will be cleared out if it exists. The hex string is case-insensitive, so FAF1CB will work as well. If the input given is 3 characters, it will be automatically expanded, doubling each character, so #666 becomes #666666.

If you want to include a CSS transparency indicator in the output (RGBA), you can include a second argument that consists of a float between 0 and 1, e.g. 0.5. hex2rgb 010 .5 becomes rgba(0,17,0,.5).

If you want just the numbers without the rgb(), change the line local css=true to local css=. Then hex2rgb faf1cb returns 250,241,203.

hex2rgb: convert hex color strings to rgb
# Convert hex string to rgb
# @param 1 (String) 3 or 6 character hex string
#   Case insensitive, leading # optional (01a, fff1b1, #ABB)
# @param 2 (Float) optional float from 0 to 1
#   If provided, outputs an rgba() string
# $ hex2rgb FA0133
# rgb(250,1,51)
# $ hex2rgb FA0133 .5
# rgba(250,1,51,.5)
hex2rgb() {
    local css=true
    local printstring
    local hex="$(tr '[:lower:]' '[:upper:]' <<< ${1#\#})"
    # Convert ABC to AABBCC
    if [[ $hex =~ ^[A-F0-9]{3}$ ]]; then
        hex=$(sed -e 's/\(.\)/\1\1/g' <<< $hex)

    # If the first param is a valid hex string, convert to rgb
    if [[ $hex =~ ^[A-F0-9]{6}$ ]]; then
        # If second param exists and is a float between 0 and 1, output rgba
        if [[ -n $2 && $2 =~ ^(0?\.[0-9]+|1(\.0)?)$ ]]; then
            [[ $css ]] && printstring="rgba(%d,%d,%d,%s)" || printstring="%d,%d,%d,%s"
            printf $printstring  0x${hex:0:2} 0x${hex:2:2} 0x${hex:4:2} $2
            [[ $css ]] && printstring="rgb(%d,%d,%d)" || printstring="%d,%d,%d"
            printf $printstring 0x${hex:0:2} 0x${hex:2:2} 0x${hex:4:2}
    # If it's not valid hex, return the original string
        echo -n $@

For fish users, a simplified version of this function from Kai Wells.

Things I’ve learned from doing yoga

[Tweet : nvALT]

I missed my yoga class this morning due to an upset stomach. I want to take a minute here while it’s giving me a break to talk about why I don’t like missing yoga.

Last time I posted about exercise, I’d lost 20 pounds and was feeling better every day. As I write this, I’ve lost 60 pounds an have maintained that for 6 months. I’ve been focusing on building strength and flexibility in the areas I was weakest, and that’s preventing all of the injuries I used to be most susceptible to. I’ve even gotten my carpal tunnel issues under control with daily wrist stretches and strengthening. And all of this is great, amazing even, but there are a few things about yoga specifically that have helped me in areas I didn’t expect.

These are things that they talk about in yoga classes, but as someone just coming in and trying to understand the moves, it’s hard to focus on the finer aspects. But it was worth it when the concepts finally clicked for me.


Breath is focus, and in yoga (and Tai Chi and other flow-based practices), breath is essential. You move with your breath, and it leads you into and out of each movement in the flow. Inhale into down dog, exhale into lunge, inhale up, exhale forward fold, and so on. Learning to focus my movements on my breath and keep my breath slow and even requires just enough concentration to clear my head of everything else.

When I go into a twist or stretch, it’s easy to find myself holding my breath. But once I’m in a position, exhaling slowly almost always allows me to move deeper into it. I’ve often heard the phrase “breathe into your [body part]” from instructors, which sounds corny at first but it’s a mental game that I’ve found very helpful.

In my daily life, learning to breathe has been a game changer. I’ve practiced multiple breathing exercises (Prāṇāyāma) and each has a different and surprisingly profound effect on my state of mind. Ujjayi breath, or whisper breath, is basically just constricting the back of your throat slightly as if you were going to whisper. It’s a loud breath that makes it easier for me to focus. If you have an Apple Watch bugging you to breath, using Ujjayi breath makes the little break more effective.

I learned Sitali Pranayama, or cooling breath, which is basically just curling your tongue into a straw (if you’re genetically disposed to that) and breathing deeply through it. It looks ridiculous, but I use it when running in warmer weather. It works.

I learned Sama Vritti Pranayama, or breath of equal holds, which has been what I use when I feel overwhelmed or even just frustrated by a bug in a program. The basic idea is to inhale slowly for a count, hold for the same count, exhale at the same rate, hold at the bottom for the count. Increase the count as you go, slowing your breathing, your pulse, and your racing thoughts.

Breathing is never a bad idea for animals of any kind, and Pranayama exercises require concentration, creating focus. It takes no special equipment, and I can do it anywhere I happen to be.

Holding Weight and Letting Go

The hardest thing for me to pick up was being able to tell where I’m holding weight in a pose. Most poses in yoga are supported by a finite group of muscles, but it’s easy to flex the wrong muscles for balance, or just because you’re not paying attention. Closing my eyes and scanning to see where I’m straining allows me to let go of the muscles that don’t need to be active. Which, if I’m being honest, almost always makes me lose my balance, but it gets easier with practice.

My neck has always been a problem for me, with tension in my shoulders and the base of my skull, leading to headaches (and a lot of grouchiness). There are a lot of poses in yoga (especially in Forrest Yoga) where you need to relax your neck. If you ever want to fall over, try getting into a position that requires muscular balance and then completely relaxing your shoulders and neck. It makes you realize how much you were using your upper body to balance, and as I developed core strength I was — literally and figuratively — able to take a lot of weight off my shoulders.

I find this applicable in my work, which is 100% in front of a computer. I’ve always had horrible posture in a chair. The most useful part of a standing desk for me is a reduction in lower back pain, but once my hands are on a keyboard, my shoulders tense even when I’m vertical. I’ve gotten good enough that I can just breathe into my shoulders and drop them, which relieves a plethora of physical ailments stemming from a long work day.


Obviously. As with any practice, whether it’s martial arts or going to cardio classes, just getting yourself there on a regular basis over an extended period of time takes discipline. For me, I had never stuck with anything like that for more than a few weeks. The difference with yoga is that it always felt good. Working out has never felt good to me. Yoga was peaceful, and I leave feeling better than when I got there. Which has made it easy to keep going, 3 or more times a week for over a year now.

Strength and Flexibility

As I mentioned at the top, developing strength and flexibility have reduced the number of injuries I sustain by tenfold. I used to strain my back for a couple days just shoveling a driveway (which is something I do a lot here in Minnesota). Hell, I used to injure my knees and back just walking for anything more than 10 minutes. Things have changed drastically.

Flexibility especially has been a big deal in my life. I increasingly enjoy physical activity the more flexible I get. I can straighten my legs all the way in poses like down dog and shoulder stand, wrap my legs and arms all the way in Eagle pose, and easily incorporate twisting warrior into salutations. That means that in daily life, I don’t lose my balance or hurt my back when picking up weight from awkward positions.

I’m not suggesting that yoga is going to be the answer for everyone else. There were a lot of factors that went into me regaining my health, and my weight loss isn’t directly from yoga, but the principles I’ve learned there have been key in implementing many other health and wellness practices. I’m willing to bet that everyone eventually finds something that has the same benefits. I can only talk about my own path.

One More Thing (for the boys)…

Here’s a free tip for guys. Eagle legs, where you cross one leg all the way over the other and wrap your foot around the back of the stationary leg, can be anatomically painful for males. It took me a long time to figure out that wearing looser clothing allowed me to use gravity (and a little hip jiggling) to get things out of the way. Looser, not tighter, because things need to move in different directions for cobra than they do for arm balance with eagle legs.

If you have the room to let gravity do the work, eagle legs are actually easier upside down…