Compare commits
2 commits
f1146661b4
...
1b6a59e952
Author | SHA1 | Date | |
---|---|---|---|
Gabe Venberg | 1b6a59e952 | ||
Gabe Venberg | c3c5c434f5 |
|
@ -1,5 +1,5 @@
|
||||||
+++
|
+++
|
||||||
title = "A modern CLI renaissance?"
|
title = "The modern CLI renaissance."
|
||||||
date = 2024-03-04T12:20:02-06:00
|
date = 2024-03-04T12:20:02-06:00
|
||||||
draft = true
|
draft = true
|
||||||
+++
|
+++
|
||||||
|
@ -83,10 +83,9 @@ xsel -bi
|
||||||
ls specifically can trace its history to 1961
|
ls specifically can trace its history to 1961
|
||||||
-->
|
-->
|
||||||
|
|
||||||
Take a look at this [table](#appendix-the-tools) at the bottom of the page.
|
Over the past few years, it seems like the rate at which new CLI tools are being written has picked back up again,
|
||||||
I'll wait.
|
accelerating after seeing relatively little activity between ~1995 and ~2015.
|
||||||
Notice the relative scarcity between ~1995 and ~2015?
|
I'd like to talk about this trend I've noticed,
|
||||||
Id like to talk about a trend I've seen these past few years,
|
|
||||||
where people are rewriting and rethinking staples of the command line interface,
|
where people are rewriting and rethinking staples of the command line interface,
|
||||||
why I think this trend might be happening,
|
why I think this trend might be happening,
|
||||||
and why I think this trend is a good thing.
|
and why I think this trend is a good thing.
|
||||||
|
@ -112,14 +111,6 @@ Terminal programs now coexist with graphical user interfaces,
|
||||||
and only a small subset of computer users even know they exist,
|
and only a small subset of computer users even know they exist,
|
||||||
whereas in the past, terminals were the only way one interacted with the computer.
|
whereas in the past, terminals were the only way one interacted with the computer.
|
||||||
|
|
||||||
Perhaps more importantly, our knowledge has expanded:
|
|
||||||
our knowledge of user interfaces,
|
|
||||||
of what works and what doesn't,
|
|
||||||
of what usecases are common and what usecases are niche,
|
|
||||||
the way that error messages can teach,
|
|
||||||
the value of a good out of the box experience,
|
|
||||||
and the value of documentation that is easy to find and digest.
|
|
||||||
|
|
||||||
These changes to the environment surrounding CLI apps in recent years have
|
These changes to the environment surrounding CLI apps in recent years have
|
||||||
led to a resurgence in development of command line utilities.
|
led to a resurgence in development of command line utilities.
|
||||||
Instead of just developing completely new tools or cloning old tools,
|
Instead of just developing completely new tools or cloning old tools,
|
||||||
|
@ -187,15 +178,15 @@ whats there.
|
||||||
|
|
||||||
Vim (top right) greatly improved on Vi, adding things such as syntax highlighting, line numbers, spellchecking, split windows, folding, and even basic autocompletion.
|
Vim (top right) greatly improved on Vi, adding things such as syntax highlighting, line numbers, spellchecking, split windows, folding, and even basic autocompletion.
|
||||||
However, everything but syntax highlighting is either extremely clunky or outright disabled without configuration.
|
However, everything but syntax highlighting is either extremely clunky or outright disabled without configuration.
|
||||||
(for example, the earliest things I did when I first made a `.vimrc` was to enable indent folding,
|
For example, the earliest things I did when I first made a `.vimrc` was to enable indent folding,
|
||||||
make some better keybinds for navigating windows, and adding a line number ruler to the side)
|
make some better keybinds for navigating windows, and adding a line number ruler to the side.
|
||||||
|
|
||||||
Neovim (bottom left) further improved on Vim, adding support for Treesitter and the Language Server Protocol,
|
Neovim (bottom left) further improved on Vim, adding support for Treesitter and the Language Server Protocol,
|
||||||
but the out of the box experience is the *exact* same as vim!
|
but the out of the box experience is the *exact* same as vim!
|
||||||
In order to take advantage of the LSP and Treesitter support, you have to install plugins,
|
In order to take advantage of the LSP and Treesitter support, you have to install plugins,
|
||||||
which means learning a Nvim package manager, learning how to configure LSPs,
|
which means learning a Nvim package manager, learning how to configure LSPs,
|
||||||
and configuring a new LSP for every language you want to use it with
|
and configuring a new LSP for every language you want to use it with
|
||||||
(or finding out about Mason and being OK with having multiple levels of package management in your Nvim install alone).
|
or finding out about Mason and being OK with having multiple levels of package management in your Nvim install alone.
|
||||||
Don't get me wrong: Neovim is a great editor once you get over the hump.
|
Don't get me wrong: Neovim is a great editor once you get over the hump.
|
||||||
I still use it as my daily driver, but so much of its functionality is simply hidden.
|
I still use it as my daily driver, but so much of its functionality is simply hidden.
|
||||||
|
|
||||||
|
@ -205,16 +196,92 @@ Helix doesn't have plugin support [yet](https://github.com/helix-editor/helix/di
|
||||||
but it has so much stuff in core that,
|
but it has so much stuff in core that,
|
||||||
looking through my neovim plugins,
|
looking through my neovim plugins,
|
||||||
pretty much all of them are in the core editor!
|
pretty much all of them are in the core editor!
|
||||||
(Ironically, the one feature that I feel helix is missing, [folding](https://github.com/helix-editor/helix/issues/1840),
|
Ironically, the one feature that I feel helix is missing, [folding](https://github.com/helix-editor/helix/issues/1840),
|
||||||
is a core part of neovim, albeit one that requires some configuration to get good use out of).
|
is a core part of neovim, albeit one that requires some configuration to get good use out of.
|
||||||
Helix does have a config file where you can change a huge amount of settings,
|
Helix does have a config file where you can change a huge amount of settings,
|
||||||
but its an extremely usable IDE out of the box thanks to having all of its features enabled by default.
|
but its an extremely usable IDE out of the box thanks to having all of its features enabled by default.
|
||||||
|
|
||||||
### Helpful error messages
|
### Helpful error messages
|
||||||
|
|
||||||
<!-- look at nushells error messages -->
|
<!-- look at nushells error messages -->
|
||||||
|
When the user does do something wrong, it is vital to let them know exactly what, where, and how it went wrong,
|
||||||
|
and if at all possible, what action the user can do to fix it.
|
||||||
|
`Operation Failed`, `Error` or `syntax error` on their own are horrible error messages.
|
||||||
|
They tell you that something *somewhere* failed, giving almost no information the user can use to troubleshoot.
|
||||||
|
In the worst case, they can even point you in a completely different direction than what is actually needed to fix things.
|
||||||
|
Git is a good example of this. As much as I love git, sometimes its error messages are the opposite of helpful.
|
||||||
|
To borrow an example from [Julia Evans](https://jvns.ca/blog/2024/04/10/notes-on-git-error-messages/#git-checkout-asdf),
|
||||||
|
if you run `git checkout SomeNonExistantBranch`, you get:
|
||||||
|
`error: pathspec 'SomeNonexistantBranch' did not match any file(s) known to git`.
|
||||||
|
This is confusing because you are trying to checkout a branch, you arent thinking about files.
|
||||||
|
|
||||||
TODO [before](../nushell)
|
Another example, I covered [before](../nushell) is the contrast between Bash and Nushell.
|
||||||
|
Consider the following script:
|
||||||
|
{{<highlight sh "linenos=false">}}
|
||||||
|
$ for i in $(ls -l | tr -s " " | cut --fields=5 --delimiter=" "); do
|
||||||
|
echo "$i / 1000" | bc
|
||||||
|
done
|
||||||
|
{{</highlight>}}
|
||||||
|
|
||||||
|
This gets the sizes of all the files in KiB. But what if we typo the cut field?
|
||||||
|
|
||||||
|
{{<highlight sh "linenos=false">}}
|
||||||
|
$ for i in $(ls -l | tr -s " " | cut --fields=6 --delimiter=" "); do
|
||||||
|
echo "$i / 1000" | bc
|
||||||
|
done
|
||||||
|
|
||||||
|
(standard_in) 1: syntax error
|
||||||
|
(standard_in) 1: syntax error
|
||||||
|
(standard_in) 1: syntax error
|
||||||
|
(standard_in) 1: syntax error
|
||||||
|
(standard_in) 1: syntax error
|
||||||
|
(standard_in) 1: syntax error
|
||||||
|
(standard_in) 1: syntax error
|
||||||
|
(standard_in) 1: syntax error
|
||||||
|
(standard_in) 1: syntax error
|
||||||
|
{{</highlight>}}
|
||||||
|
|
||||||
|
Due to the syntax error coming from bc rather than bash directly,
|
||||||
|
even the line number it gives you is misleading,
|
||||||
|
and in order to have the slightest clue whats going on,
|
||||||
|
you have to start print debugging.
|
||||||
|
|
||||||
|
The equivalent in nushell would be:
|
||||||
|
|
||||||
|
{{<highlight sh "linenos=false">}}
|
||||||
|
> ls | get size | each {|item| $item / 1000}
|
||||||
|
{{</highlight>}}
|
||||||
|
|
||||||
|
and the equivilant error would be:
|
||||||
|
{{<highlight sh "linenos=false">}}
|
||||||
|
> ls | get type | each {|item| $item / 1000}
|
||||||
|
Error: nu::shell::eval_block_with_input
|
||||||
|
|
||||||
|
× Eval block failed with pipeline input
|
||||||
|
╭─[entry #5:1:1]
|
||||||
|
1 │ ls | get type | each {|item| $item / 1000}
|
||||||
|
· ─┬
|
||||||
|
· ╰── source value
|
||||||
|
╰────
|
||||||
|
|
||||||
|
Error: nu::shell::type_mismatch
|
||||||
|
|
||||||
|
× Type mismatch during operation.
|
||||||
|
╭─[entry #5:1:30]
|
||||||
|
1 │ ls | get type | each {|item| $item / 1000}
|
||||||
|
· ──┬── ┬ ──┬─
|
||||||
|
· │ │ ╰── int
|
||||||
|
· │ ╰── type mismatch for operator
|
||||||
|
· ╰── string
|
||||||
|
╰────
|
||||||
|
|
||||||
|
{{</highlight>}}
|
||||||
|
|
||||||
|
Though the first error isnt helpful, the second one tells us right away that `$item` is not what we expect it to be,
|
||||||
|
hopefully pointing us to the `get type` mistake.
|
||||||
|
Nushells error messages are miles ahead of other shells just...
|
||||||
|
being useful, helping you find where you made an error,
|
||||||
|
rather than just telling you theres an error *somewhere*.
|
||||||
|
|
||||||
### Concise and discoverable documentation
|
### Concise and discoverable documentation
|
||||||
|
|
||||||
|
@ -325,9 +392,25 @@ allowing for more people to experiment with the design and ergonomics of CLI too
|
||||||
|
|
||||||
## Conclusion
|
## Conclusion
|
||||||
|
|
||||||
TODO
|
> If I have seen further than others, it is by standing on the shoulders of giants.
|
||||||
<!-- emphasize that the new tools are not 'better' just because they are new,
|
|
||||||
but because they take the old tools and learn what did and did not work for them. -->
|
-- Isaac Newton, 1675
|
||||||
|
|
||||||
|
Once again, Id like to state that I am not advocating for shiny new tools *because* they are shiny and new.
|
||||||
|
Likewise, I dont think the old tools are *bad*, nor does their age alone count against them.
|
||||||
|
However, new tools have the opportunity to learn from their predecessors and build upon them.
|
||||||
|
In this way, the new tools are a tribute to those tools that came before;
|
||||||
|
a recognition of their strengths, an acknowledgement of their weaknesses.
|
||||||
|
|
||||||
|
Now, these new tools are not the be-all end-all of the command line interface.
|
||||||
|
Just because this new generation of tools improve on the old ones,
|
||||||
|
it does not mean they are themselves perfect.
|
||||||
|
As we use these tools, we will become familiar with them,
|
||||||
|
and we will discover their sharp edges,
|
||||||
|
or their common usecase will change,
|
||||||
|
or we develop a new usecase entirely.
|
||||||
|
And when these things happen, we will develop yet another generation of tools,
|
||||||
|
one further polished and adapted to new usecases.
|
||||||
|
|
||||||
## Appendix: the tools
|
## Appendix: the tools
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue