Thoughts on software development, technology, and other random philosophical matters.
Daryl Wright /     (6 mins)

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:

ci demo

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.

Daryl Wright's picture
About Daryl Wright

Daryl is an experienced technology advisor who specializes in creating innovative software solutions and solving novel problems. He has spent over a decade providing technical expertise in various industries and is well versed in a wide variety of programming languages, tools, and frameworks. Daryl is the owner of Golden Path Technologies, a proud father, husband, and dog parent.

22 posts Miramichi, New Brunswick, Canada https://goldenpath.ca Github Reddit Mastodon Bluesky