Welcome to the lab.

Using howzit as a task runner

[Tweet : nvALT]

I’ve become fairly dependent on howzit for running my builds and deploys (and other tasks). By setting up a buildnotes.md file for each project, containing @run(task) lines for each section, I can always run howzit -r build to build or deploy, no matter what task runner/build system I set up for it. npm, yarn, gulp, grunt, rake, make, it doesn’t matter. I can get the right build command every time without a second thought.

As a shortcut, I have a function called bld that runs howzit -r with a default argument of “build” but accepting alternate arguments. In Bash that’s as easy as howzit -r ${1:build}, but in Fish I have to use my fallback function:

# Fish functions for howzit shortcuts

function fallback --description 'allow a fallback value for variable'
  if test (count $argv) = 1
    echo $argv
  else
    echo $argv[1..-2]
  end
end

function bld -d "Run howzit build system"
  howzit -r (fallback $argv build)
end

Shell Completion

In the latest version of howzit (published today), I added some new options for getting completion-compatible lists of sections. The -L switch does the same as -l (list all sections), but without color, header, or list markers. The -R and -T switches list all sections containing @run (or @copy, @open, etc.) directives that could be run with howzit -r. The -R version makes the list verbose, showing exactly what each section will run, and -T gives you just a “task list”, perfect for completion. The repository now includes some Fish tab-completion commands using these options. I haven’t set them up for other shells yet, but all the ingredients are there now.

Supplemental: Let’s Get Weird With That

Recently I got one of those fancy MacBook Pros with the Touch Bar. (Obviously I got it about a month before Apple announced the 16” with the better keyboard, as would be my persistent luck.) Nonetheless, I’ve been trying — really trying — to make that Touch Bar useful on the machine I have. BetterTouchTool is a hoot with it, but I think I finally found a use that’s truly a time-saver. At least a little.

It started when I found the “touchrunner” package for Fish that checks for a package.json file when you switch into a directory, setting the function keys in the Touch Bar to any npm tasks listed there. Great if you do everything with npm (or yarn), but with howzit I could make that universal. So I did.

I’m just showing it off here. I’m happy to share the plugin (a hack of touchrunner) upon request, but given that it requires the very specific combination of iTerm, Fish, a Touch Bar Mac, and the use of howzit, it seems like a pretty narrow slice of audience to deal with packaging it for general use. Just a neat trick for now.

Forgiveness, peace, and productivity

[Tweet : nvALT]

The surest way for me to not get anything done is to get overwhelmed by the guilt of not getting anything done. I’ve worked for years to solve this little quandary, and I’ve found a key element in the solution: forgiveness.

Forgiveness is something I’ve gotten much better in recent years. I’ve never been one to hold grudges — I don’t have the memory to pull that off — but I would get irate with people in the moment for all manner of perceived slights and infractions. Recently, my mantra has become “everybody is doing their best.” It’s the idea that I don’t know what this particular person is living with, what they’re going through in their life, or what just happened to them the minute before. All I can do is believe that they’re doing their best, and that puts me in a place of compassion. (It doesn’t work quite as well when I interpret something to be intentionally malicious, but it’s still better than interpreting everything as malicious.)

You’d think it would be easy enough to apply this same mantra to myself. I mean, of all people, I should know that I’m doing my best. But I’m always the first to disagree. I think I could have done better, that I could be doing better. My mind calls bullshit as soon as I try to show a little compassion to myself.

Web Excursions for November 12, 2019

[Tweet : nvALT]

Brett holding map

Web excursions brought to you in partnership with Codecademy, the easiest way to learn to code.

renameutils
I’m loving this tiny set of CLIs for renaming files. This links to the project page, but you can install them through Homebrew (brew install renameutils). qmv and qcp open a list of target files in an editor, where you can rename them using whatever editor tools you need, and then save to apply the changes. imv and icp provide readline editing of a filename in place. Super handy.
While you’re at it, check out rename, also on Homebrew, for a pipeline approach, and the vidir command from moreutils for another approach to the qmv trick.
Augmented Text Editing on Mobile: The New iOS 13 Gestures
From the Ulysses blog but not Ulysses-specific, a rundown of new gestures for text editing on iOS 13. Did you know there are 3-finger pinch commands for copy, cut, and paste? I didn’t.
Clicker for Hulu
I’m a user of the Mac app Clicker for Netflix, and was happy to see that DBK Labs now has the same type of player for Hulu. It integrates native macOS features with the service’s players, and include PIP and hacks for things like skipping the stupid mini-player that Hulu brings up when you close a show. Some interesting touch bar support, too.
rhydlewis/search-omnifocus
An Alfred workflow that allows free text searching of OmniFocus tasks and projects. A really nice example of Alfred’s power. Now someone needs to make this for LaunchBar…
How to display the size of an app’s frontmost window
Thanks to Rob Griffiths I now have a mouse gesture that shows me the pixel dimensions of whatever window I have in the foreground. Which is actually something I happened to need…

Codecademy Pro

Fish: further exploration

[Tweet : nvALT]

Over the past few months I’ve been playing with Fish, the Friendly Interactive SHell, and I’ve posted a couple of times on the topic. I think I’m sold on it now, and you’ll probably be seeing a lot more Fish posts than Bash ones (though I’ll try to offer Bash equivalents when possible).

So I’ve officially chsh‘d to /usr/local/bin/fish and am 100% comfortable using it day to day. For the record, I did spend some time with Zsh as well, but it just didn’t tickle the same fancy as Fish has for me.

Here are some of my tips, tricks, and observations since my last post.

Hook 1.3

[Tweet : nvALT]

Hook is a productivity app from CogSci Apps that connects your files, emails, web urls, and other digital breadcrumbs to each other. I’ve mentioned it here and there, but my most detailed writeup was at Lifehacker a little while back.

Hook applies a principle from cognitive productivity: “deep work requires rapidly re-accessing pertinent information without searching.” Hook allows you to stay in flow by keeping all of your related resources a couple of keystrokes away, no matter what you’re working on.

The latest update to Hook (v1.3) brings a streamlined UI, reorganized menu commands (with more keyboard shortcuts), and the ability to navigate links without leaving the Hook window.

You can check Hook out for free. BrettTerpstra.com readers who decide to dive into Hook Pro can use the coupon UH1ME-ttscoff for 20% off the list price (which is currently $19, but will be going up to $24 soon!).

To apply the coupon for a discount purchase of Hook, visit the checkout page. During the checkout process, which is mediated by Paddle.com (the merchant of record), there will be an “Add Coupon” link in small font below “Your total is $…”. Tick the checkbox, and then enter the coupon code.

Howzit: Remember how what you work on works

[Tweet : nvALT]

Back in April I posted a short script for keeping track of the various build systems I use in my projects. You know when you open a directory you haven’t worked on for a while and there’s a Gulp file, a Rakefile, a node_modules folder, and various other cruft that means you’ll have to dig through to recall what commands you were using to build and deploy the project? Or when you know there were specific flags you were using to get the build to work, but you never got around to automating them? It’s for those situations, and other general sanity.

Over the rest of this year I’ve slowly modified and expanded the script as I’ve wanted it to do things differently or better. I’ve been hesitant to post the results because it really feels like something nobody else is going to need and it’s entirely possible that I’ve put too much time into it already. I did stop myself before turning it into a fully packaged gem, so good on me.

Fish (shell) fun: event handlers

[Tweet : nvALT]

In my last post on the Fish shell, I brazenly stated that “because of the way that Fish handles the prompt function, there’s no easy way to hook it without modifying the original theme files.” That was 100% incorrect, as I figured out the next day.

Fish has the ability to specify that any function act as an event handler. You can attach to the event fish_prompt to have the function run right before the prompt displays. So my revised function in my init file is:

function __should_na --on-event fish_prompt
  set -l cmd (history --max=1|awk '{print $1;}')
  set -l cds cd z j popd g
  if contains $cmd $cds
    test -s (basename $PWD)".taskpaper" && ~/scripts/fish/na
  end
end

Now I no longer need to edit the theme files directly at all, which is much more how I’d prefer things to be. As an alternative to fish_prompt, you can also attach to variables changing, which means you can use PWD to run the function any time the working directory changes. That would look like:

function __should_na --on-variable PWD
	...

Also, any function can use the emit command to add its own hook. The example from the docs is nice and succinct:

function event_test --on-event test_event
    echo event test: $argv
end

emit test_event something

This is one area where the Fish documentation seems lacking: there’s no list of available hooks nor (that I can find) any way to retrieve a list of emitted events in the shell. It’s been trial and error for me thus far. Hopefully someone will correct me if I’m wrong here. Update, someone (evanrelf) did correct me in the comments: you can find a list of all named events using function -h.

Ok, so that’s an extended correction to my last post, but it’s a cool enough aspect of Fish that it seemed worth covering on its own.