Welcome to the lab.

Managing Ruby Gems using Homebrew

Whenever I publish a gem like doing, howzit, or na, I always suggest that if you have any trouble installing with gem install X, you should use sudo gem install X. This is because the preferred way is to do it without sudo (for multiple reasons), but those who don’t do anything else with Ruby and just want to use tools distributed as gems are almost definitely using the system Ruby, which won’t allow updating its gem folder without sudo. I was recently turned onto another option, though, which is perfect for people who use Homebrew and don’t care much about Ruby: brew-gem.

You can install brew-gem with brew install brew-gem. Once installed, instead of gem install X, you can run brew gem install X, and then your gems will be installed to your Cellar and managed with Homebrew. To upgrade to the latest version of a gem, just run brew gem upgrade X. If you want to use a brew-installed version of Ruby, just add --homebrew-ruby to any install/upgrade command.

This is an ideal solution in a lot of cases. For those not using rbenv, RVM, asdf, or other environment manager, it means not having to use sudo and install your gems to system directories, plus you get update management via Homebrew. Nice. I’ll be updating my various README’s to point to this.

Homebrew and /usr/local/bin on M1 Macs

I have a tip for M1 Mac users (who spend time in the terminal). You know how up until you got your new Mac, you could always count on your command line utilities being in /usr/local/bin? But now Homebrew installs to /opt/homebrew/bin instead? And all of those scripts that hardcoded /usr/local/bin/utility have to be updated, and the PKG installer for tools like Gather leave it outside of your PATH? Never fear, symlinks are here.

I was a little nervous about doing this because it just seemed like the kind of thing that would eventually get me in trouble, but I did it a year ago and haven’t had a single problem. Basically, you’re just running a mirror of /opt/homebrew/bin in /usr/local/bin. You can use either willy nilly this way.

To set it up:

  1. If you do have a /usr/local/bin folder, move all of its contents into /opt/homebrew/bin (mv /usr/local/bin/* /opt/homebrew/bin/). Then delete the directory (rm -rf /usr/local/bin)
  2. Symlink /opt/homebrew/bin to /usr/local/bin with ln -s /opt/homebrew/bin /usr/local/bin. If everything worked, you should be able to run ls /usr/local/bin/ and see all of your Homebrew binaries there.

Now if something does install to /usr/local/bin, it will actually go into /opt/homebrew/bin, and everything in /opt/homebrew/bin will be accessible at /usr/local/bin.

This has solved many problems for me. So many that I often forget that not everyone has /usr/local/bin anymore…

Revamping na (Next Action CLI)

I have a friend (hi Jeff) who has really dug into using some of my command line tools like Howzit and na. Working with him on setting them up in his own environment has inspired some refactoring of both tools. I mentioned some major updates to Howzit last month, but had only made minor fixes to na up until this week.

I had a sleepless night on Sunday and decided to dig into patching up na. It was an unwieldy Bash script that was a real pain to fix, and took extra finagling to make it work in shells other than Bash. So I completely rewrote it and turned it into a gem-based CLI. The new CLI is backwards compatible, but adds new features and is a more manageable tool.

Now you can install na as easily as gem install na (you may need sudo gem install na, depending on your Ruby setup). Run na help for a list of all commands, and run na help COMMAND for options and details on each command. All of that output is laid out in the docs.

So let me back up and explain a bit for those who haven’t already heard of na. It’s a tool for adding and viewing project-specific “next actions” in a TaskPaper file stored in each project directory. When you need to make a note about a new feature you want to add or a bug you discovered in project you’re working on, you just run na add "Fix output formatting @bug" --priority 4 and the task is added to a TaskPaper file in an Inbox project, creating a new file if needed. Running na next will show you all the next actions in all TaskPaper files in the current directory. It can traverse subdirectories as well, and it stores a database of every TaskPaper file it sees so you can call up a project’s actions with na next PROJECT_NAME, even when you’re not in that directory.

I love using na with prompt hooks. It can now output and install prompt hooks for Bash, Zsh, and Fish. Just run na prompt install and it will detect your current shell and install the appropriate file. Once installed, every time you cd into a project, it will automatically show you your next actions for that project. It’s nifty.

When it was a Bash script you had to use environment variables to save configuration options. Now you can set flags like alternate file extensions or default next action tag and save them to a config file in one command: na --ext md --na_tag next initconfig.

You can also now search your TaskPaper files by tag (and tag value) or fuzzy search strings, allowing you to organize your todos in a flexible way. Want to see just your @maybe tasks? na tagged maybe. You can do boolean searches for multiple tags matching tasks containing any or all tags specified.

As I mentioned, I kept it backwards compatible for the sake of anyone who’s already had it integrated into their workflow. It’s subcommand-based now, so you run commands like na next and na add, whereas previously you would run na and na -a. The latter still works. Once users have had a chance to transition to the new subcommand format, I’ll remove some of the legacy switches and flags.

Check out the na project page for installation and usage instructions. It’s not as massive a tool as something like Doing, but it does what it needs to quite well and has long been an indispensable part of my toolkit.

Gather, Shortcuts, Bookmarklets, and Paywalled Content

Gather is constantly improving at this point, and a lot of its rough edges have already been polished. I’m loving all the feedback I’m getting, both for fixing bugs and for adding new features. It’s hard to test something like Gather on every possible permutation of a web layout, so I appreciate hearing about edge cases (even if I do have to weigh how much effort they’re worth).

I’d recommend upgrading to the latest version before trying anything in this post. As of this writing, that’s v2.0.33. If you installed via Homebrew, you’re just a brew upgrade gather-cli away. Otherwise, please download the PKG file and update.

If you have Homebrew installed but ran into errors trying to install gather-cli, try running sudo xcode-select -s /Applications/Xcode.app/Contents/Developer. It fixes 90% of the issues I’ve seen.

Pesky Paywalls

So anyway, one common thing that people want to clip from the web is paywalled content, which makes sense as it’s harder to search and more convenient to have in your own personal, local notes. But Gather can’t access a web page that isn’t public. You can select all the text, copy it, then run Gather with gather --paste --html to convert it, but it’s never perfect. The better solution is bookmarklets.

Gather to nvUltra

I got a request to add a --title-only option to Gather. Makes sense; when you’re using it to save Markdown to notes, you’d want the title of the page to be the title of the note. You could parse that out of the Markdown version in several ways, but in some cases it might be easier to just call gather --title-only URL and get an undecorated string back. So that’s been added in v2.0.29.

That got me to thinking, though… I clip all my notes to nvUltra. I’ve been trying to convince Fletcher that we should build a web clipper into nvUltra, but until then I’ve been using Gather to create Markdown notes out of web pages I want to reference. So, for purely selfish reasons, I’ve added a couple of commands to Gather that will markdownify a page and create a titled note all in one fell swoop (using nvUltra’s URL handler). I even added it to a Shortcut that I can trigger with LaunchBar. Now I’m a few keystrokes away from turning any page into a note in nvUltra. See the notes on the project page if you happen to be on the nvUltra beta and would like to try this. I’ll even throw in a link to the Shortcut.

Since it’s a compatible URL handler, I also added options for creating Notational Velocity/nvALT links/notes. If this sounds great but you’re not into nvALT/nvUltra, let me know if there’s a note platform you use with a url handler that I could also incorporate. I’m open to making your life simpler.

By the way, if you’re not using Gather via Homebrew, you really should be. Imagine how easy your life would be right now if all you had to do was run brew upgrade gather-cli instead of locating, downloading, and clicking all the install screens for the update…

Gather on Homebrew

I considered calling this post “Gather round for a brew” but I says to myself, I says “dammit, Brett, you’re better than that.”

I knew the best way to distribute my new Gather tool was going to be via Homebrew. No worries about notarization, installing to the wrong folder, or requiring finicky steps from users. But the Homebrew documentation is… intense. I got a little scared at first, but then I found an NSHipster tutorial that made the process super simple. Like five, ten minutes max, plus another five to add it to the build automation for updates. So, as of today, Gather is available for installation via brew.

To install via Homebrew, just run two commands:

brew tap ttscoff/thelab
brew install gather-cli

Done. You’ll have a working copy of gather that you can keep updated using Homebrew. It’s a way better solution than the Package installers, though that option will still be available for those who aren’t brew-savvy.

To learn more about Gather, visit the project page. Oh, and let me know if my brilliant solution doesn’t work for some stupid reason. It’s been one of those weeks.

PopClip WebMarkdown fix and other codesigning adventures

So the first project I worked on with the libraries that went into Gather was the WebMarkdown extension for PopClip. It worked great… for me. I suffered from the all-too-common hacker mistake summed up as “well, it works on my machine.”

I codesigned the binary embedded in the extension, but when you download a file from a website, it adds a quarantine bit that requires what Apple calls “notarization,” and you can’t notarize a single binary (or a zipped package like a PopClip extension). You have to distribute it as a notarized package file and installer, which is what I’m doing with Gather itself now.

A .pkg isn’t really a good option for a PopClip extension, though, so I found another workaround. Without the binary the extension should install without error just by double clicking. When you select some text and click WebMD, it looks for the gather CLI in /usr/local/bin on your machine. If it doesn’t find it there, it offers to download and run the Gather installer for you. You can just hit the OK buttons, and when it’s done, the new, improved WebMarkdown extension should work for you.

Please give it a shot!

Brett's PopClip Extensions v1.41

A few PopClip extensions for Markdown writing and other useful tools

Published 11/30/14.

Updated 09/02/22. Changelog

DonateMore info…