Share to Mastodon
I've released a terminal application that helps navigate directories quickly and easily. Check out
the source of ci
- Interactive cd
on GitHub and
be sure to download the latest release.
See it in action:
Background#
In August 2021, I was in between homes after a cross-country move (still am as of this writing). I was one month into the new location at that point. Things were tough, especially with an infant child in tow. I'd spend a lot of time ruminating, hoping that would ease the stress of the situation. Sometimes I would watch videos online, or sometimes I'd come up with a bunch of ideas that I'd shelve and never get back to.
Inspiration#
During one rumination session, a random idea popped in my head. What if there was a terminal app that
made cd
much easier to use? Like the vi
of cd
? At that moment, ci
was born, at least in concept.
Given the nature of the internet, it was very likely that someone, somewhere had already created
something similar to what I was thinking of.
I wasn't going to waste my time coding something, only to find out that someone else did it better. I would just use their app in that case, or contribute to it if it didn't have enough features that I liked.
A few Google searches later, I came across a StackExchange question that seemingly confirmed my suspicions. I sifted through the answers until I found a solution that was similar to what I was thinking of doing.
The imperfect interactive cd
#
A fellow by the name of Antônio Oliveira created a shell script called CDI. At first glance, it looked like a really awesome user experience. Enter the command, and then use the arrow keys to navigate directories. As someone who uses the IJKL arrow scheme on a secondary keyboard layer, it's a really pleasurable user experience. However, CDI wasn't quite what I wanted as it suffered from a few problems.
First, CDI isn't multiplatform. This is something that was more understandable ages ago, but not in the era of platform-agnostic programming languages and frameworks. I use and love Linux, but my daily driver is a Windows machine. Windows Terminal and WSL gives me the best of both worlds despite their shortcomings (namely, not being native enough to replace standalone Linux). It would have been nice to have a similar tool that works with PowerShell as well.
Second, CDI has a number of issues that make it problematic to use. The screen flickers on each screen update. Long directory lists require a manual scroll to see cut off directories. When selecting the next directory, the screen flickers again, and you're still unable to see the obscured directory without manually scrolling again. Directory names containing spaces are tokenized into their non-whitespaced parts (i.e. 'Visual Studio 2019' becomes 'Visual', 'Studio', and '2019', none of which were navigable in my case). Root directory handling is non-existent and requires an exit to escape endless untraversable numerical directories.
I think I've made my point. Despite these shortcomings, it's an interesting project that the owner appeared to put a lot of effort into. Give it a try if you're interested in it and feel it could satisfy your use case.
Prototyping#
After an unsuccessful search for an app that satisfied what I wanted in a terminal navigator, I set out
to start prototyping what would eventually become ci
(I would
much later find out
about ncdu
, but its use case is different enough that ci
was worth it
to create).
I wanted something that could operate in PowerShell as well, so it was a must to write this tool in a multiplatform language. Doing this via script would mean at least two versions of the same code. Not a fan, to say the least.
My choices, for something that I wanted to be relevant for the long term, were Go or Rust. I was already a tiny bit familiar with Go via its tutorial and playground, so I decided to go 👀 with that.
Rust would have been a perfectly fine choice, but I decided to go with the option that appeared to have a larger ecosystem and a more vibrant community. I knew I wouldn't have trouble finding a library to suit my needs if I went with Go. I didn't have a lot of free time, so the faster I could learn a new language and integrate different libraries, the better.
My next step was to figure out how to create a terminal UI. One of the most famous examples of this is
vi
. vi
uses ncurses
to render its UI. I
didn't think there was a Go version of ncurses
. Besides, ncurses
would require Cygwin or MinGW to
run on Windows. Not a very good multiplatform solution.
I came across a library called Tcell that enabled Go applications to write to the terminal screen. It did exactly what I wanted, to a point. While Tcell is good for simply drawing to the screen, I would have had to create a user interface from scratch. Ain't nobody got time for that!™
So I switched my focus to finding a library that could easily create shapes and widgets in the terminal.
Enter tview
. When I found tview
, I was quickly impressed by all the different widgets it provides,
from simple boxes to multi-field forms. It even uses Tcell extensively under the hood. tview
was
exactly what I needed, and I got straight to work on a
quick prototype.
...And the rest is for another story#
This is a good place to end for now. The process of developing ci
into what it is today is worthy
of its own content. Before developing ci
, I had absolutely no experience with Go other than a single
pass through the official tutorial a year or so beforehand. By the time I completed
v1.0.0
I had been completely
converted into a Gopher. I love everything about Go and now have it in
my toolbox of goto languages (pun twice intended, I'm a dad after all).
I hope for ci
to be the beginning of more content featuring the Go language, and I also hope that it
helps make your terminal experience as pleasurable as developing it was.