Creating a sick CLI

2023-10-11

written by @ parth

At Lockbook we strongly believe in dogfooding. So we knew alongside a great, native, markdown editing experience we would want a sick CLI. Having a sick CLI creates interesting opportunities for a niche type of user who is familiar with a terminal environment:

In this post I’m going to tackle 3 topics:

  1. What makes a CLI sick?

  2. How do you go about realizing some of those “interesting opportunities” using our CLI?

  3. What’s next for our CLI?

What makes a CLI sick?

It’s tab completions. For me, tab completions are what I use to initially explore what a CLI can do. Later, if the CLI is sick , I use tab completions to speed up my workflow. I don’t just want to tab complete the structure of the CLI (subcommands and flags). I want to tab complete dynamic values, in Lockbook's case, this means completing file paths and IDs.

If you're creating a CLI most libraries make you choose between a few bad options:

Rust is no exception here, clap has some support for static completions, but no way to invoke dynamic completions without writing a completion file for each shell.

And so we set out to solve this problem for the Rust ecosystem, and created cli-rs. A parsing library, similar to clap but with explicit design priorities around creating a great tab completion experience. As soon as cli-rs was stable enough we re-wrote lockbook's CLI using it so we could pass on these gains to our users

Cli-rs is simple, you describe your CLI like this:

This gives the parser all the information it needs to offer the best tab completion behavior. It handles all the static completions internally and then invokes your program when it’s time to dynamically populate a field with your user’s data.

We also invested a ton of effort in the infrastructure that deploys our CLI to our customer's machines so that tab completions would be set up for most people by default.

Exciting Opportunities for Power Users

Use your favorite text editor

You can lockbook edit any path you have access to and our CLI will invoke vim, utilizing any custom .vimrc that may exist. You can override the selected editor by setting the LOCKBOOK_EDITOR env var or using the --editor flag. So far we support vim, nvim, subl, code, emacs and nano.

If we don’t support your favorite editor, send us a PR or hop in our discord and tell us.

Extending Lockbook

We want Lockbook to be maximally extensible, this extensibility will take many forms, one of which is our CLI. Let's explore some of the interesting things you can accomplish with our CLI.

Let’s say you wanted a snapshot of everything in your second brain decrypted and without any proprietary format for tin-foil-hat backup reasons. You can easily set a cron that will simply lockbook sync and lockbook backup however often you want. lockbook export can be used to write any folder or document from Lockbook to your file system, paving the way for automated updates of a blog. Edit a note on your phone, and see the change live on your blog in seconds. lockbook import lets you do the opposite. Want to continuously back up a folder from your computer to Lockbook? Setup a cron that will simply Lockbook import and then lockbook sync.

Ultra secure

I like to think about security as the product of a few numbers. So if, for example, you’re product is closed source, one of those numbers in your multiplication chain is a big fat zero. And there’s nothing you can do to pretend it’s secure. Similarly, the age of a product is one of those numbers. Newer is worse, and this is one of Lockbook’s current weaknesses.

But one of Lockbook’s strengths is how much you can reduce the total amount of code it takes to interact with Lockbook. On one end of the spectrum, you have software that requires a full browser installation to perform the most basic tasks. Slightly better than that is software that runs natively, and on the other end of the spectrum is software that doesn’t even rely on a UI library. This is where our CLI comes into play: if you wanted to run Lockbook on a libre-booted Thinkpad running an ultra-minimal operating system, Lockbook wouldn’t require you to add the Google Chrome dependency tree to your setup.

Remote Lockbook

Sometimes you find yourself employed by a financial institution that heavily restricts what you can do on their machines. Without thinking too much more about your situation you may want to simply add something to your grocery list without pulling out your phone. Unfortunately, IT has locked down your remote Windows 7 installation, and not only can you not install our Windows app (which does not require administrator privileges to install) but you cannot visit GitHub itself!

Maybe in this environment, it’s not worth it to update your grocery list, but you identify with the likes of Ron Swanson, and you will not be defeated by your IT department. How? Because you port forwarded your desktop and memorized a lengthy SSH password. So you ssh in, use your favorite text editor, and you update that grocery list. There’s no stopping you.

What’s next for our CLI

Our CLI has come a long way, we've experimented with various ways of allowing you to quickly find a note and edit it. In the past we experimented with piping output to programs like fzf, we even tried implementing a custom full-screen search. This is the approach that feels the best to us and we think is going to stand the test of time. But work is never done, so here are some of the things we plan to tackle in our CLI: