Hacker News new | past | comments | ask | show | jobs | submit login
Colorize Your CLI (danyspin97.org)
243 points by danyspin97 9 months ago | hide | past | favorite | 120 comments

I feel like we need a complete rewrite of terminal emulators/bash/whatever. It should be super easy to make a CLI with nice colors, good loading icons, etc. without having to deal with all kinds of color codes and cursor movement. When I press "enter" while a script is showing some progress bar, or resize the terminal window, it should handle it nicely like every other application.

I use the command line whenever possible over a GUI application, but sometimes I wish it wasn't still stuck in the 80s. Keep the speed an simplicity (I don't want images or anything), but make it easy to make robust applications with a clean text based UI. I shouldn't still have ghosting in my Vim setup, it's 2020.

I kinda like using tooling with 40 years of refinement. Is it perfect? No. Do I need to resize a window with a progress bar? No. Would it be nice? Yeah, I guess. Am I underestimating the benefits? Almost certainly.

But what are the other sharp edges that come with the shiny new thing? Would it be an electron app? Yes, probably. Would it work? Maybe, in a couple years. There would be some major bugs first, and a lot of dead batteries.

I don’t think new devs are specifically worse than old ones. I do think there is immense value in using something that has been actively improved for your (well, at least my) entire lifetime.

There are lessons buried in there we don’t even begin to understand. Starting over means forgetting those lessons too.

The grass is always greener on the other side of the fence is what I am saying.

It looks to me that the reality is closer to "40 years of hack over something that was not meant to be a standard (a popular hardware terminal from the 80s)".

I'll give you just one example of the madness that is sometimes required: the escape code \e[1m is doing "bold on". It's counterpart to reset \e[21m, is supposed to do "bold off", but in practice some terminals do "double underline" instead because this standard is not a real standard. As there is also no real way to detect capability, the only reliable way to do "bold off" that I could find is to intercept the stream of data sent to the terminal to compute the attribute state. When you want to do a "bold off" you do a \e[0m "reset all" instead and sent the control character to set the state again without bold [1].

A new standard would also allow to reliably use features like displaying images or links.

[1] https://github.com/MichaelMure/go-term-markdown/blob/master/...

So, what you're saying is, since there are too many competing and incompatible standards, what we need is another incompatible standard? :)

There are a lot of "better" terminal emulator standards out there. The problem is you need software that uses them. Perhaps this is the real "refinement" spoken of before -- these quirks are generally understood and software layers are built on top of them to abstract away the ugliness while keeping broad compatibility.

There are lots of ideas on how to make a better CLI -- from Plan9's rio/window to various XML/DOM based terminal emulator, to a smorgasbord of xterm-but-added-features emulators that add support for anything from inline images to transmitting entire files over the TTY. Ultimately, these are only as useful as the software that uses them, which often ends up being just a few tools the terminal emulator itself ships with.

Even Windows' alternative to TTYs has basically been supplanted by an xterm/VT-ish compatible TTY style interface for software compatibility reasons.

Relevant xkcd: https://xkcd.com/927/

I hate to say it, but the standard for C1 escape codes, ECMA-48, does list "\e[21m" as "double underline". I can see where one might think it does a "bold off" but alas, that isn't in the standard.

The standard also has a lot of redundancy, and some omissions (getting the size, but I think it was standardized long before TTYs were resizable).

A standard is a good idea, but I think ECMA-48 was a draft that was put into production too quickly.

My point exactly. Some terminals do the expected thing of doing "bold off" because that make the mapping of codes regular, some follow ECMA-48 and do "double underline" even if that means that "bold off" is not possible.

At the end, there is no way to reliably do either of them.

Not using bold properly means the terminal was written incorrectly, or the wrong termcap is being used to emulate a different terminal.

This isn't a bug with escape codes or with terminals that work. It is either that someone doesn't know which teminal they are using, or there is a bug in that specific terminal.

Not entirely. Well there is bold, normal, and dim. Early on someone realized there is no need for unbold and undim codes. So undim, 22 I believe, works for both, setting normal intensity. 21 was then free for something else.

I’d say all this is a feature.

This means that it’s difficult to write a flashy app with bold text, links and images.

I like programs with minimal text ui, so I don’t mind.

A new standard would also make it easier to fallback to no colors/decoration if the user wish so. At the moment, there is no way to do that without a flags or similar for each app. Even detecting if the terminal support colors is a pain.

> fallback to no colors/decoration if the user wish so

Fallbacks are frequently not implemented, not tested or not supported as well as the main feature.

> Even detecting if the terminal support colors is a pain.

As the end user, I don’t mind. This means that I’ll see colors only when it’s important.

I'm with you 100%, virtually nobody will take the time to code against a fallback profile like that. That's why most sites tend not to work without JavaScript regardless of whether their functionality strictly requires it.

Support for images concern many of us for that reason: sure it seems nice for a few cases used judiciously. But it feels counter-productive to the strengths of the CLI.

I would feel that way about curses/cli-based-gui too in theory, but in practice it's just top, vim, and less for the most part. Maybe I'm just too scared.

From what I've seen it's quite common to use a library to output those escape code. Given that, there is often a flag to disable all those colors/decoration at once without implementing a fallback specifically.

> Support for images concern many of us for that reason: sure it seems nice for a few cases used judiciously. But it feels counter-productive to the strengths of the CLI.

Of course those things should be used judiciously, but building CLI app on a broken standard only make it so much harder to build a quality app. You get a crappy end result just because it's difficult to do the "judiciously" part.

> I kinda like using tooling with 40 years of refinement

I would not call the modern terminal the result of 40 years of refinement - mostly for the reasons outlined by the parent poster, as well as those of the sibling posters.

If you look at the modern terminal through fresh eyes, 'buggy and inconsistent and clunky' would be how the average homo sapiens would describe it.

Just because there are reasons for why all of these warts are in place, doesn't mean that the program is not defective, as designed.

There are a lot of "Maybe"s in your second paragraph.

I'd say, yes, there are a lot of lessons buried in old code, but often, there is an equal amount of baggage we are too fearful to abandon because of backward compatibility and "bug became feature"-situations.

And even then, it's not you who is abandoning that, which makes the attitude even more baffling to me.

There still some pretty glaring issues, even after 40 years of refinement. Some I think could be iteratively fixed but not all of them (for example I believe #1 requires a significant breaking change to terminals).

1. You can't have an interactive program in a pipeline. For example, you can't do `gpg --decrypt foo.txt.gpg | nano | gpg --encrypt` because keyboard input on the console is handled through stdin. You can work around this by using a graphical editor in the pipeline, but this should be possible entirely over the command line.

2. You can't have hotkeys that are just modifier keys because the modifier keys only change the byte sent when pressing another key. So could couldn't have a hotkey "Shift" but you can have a hotkey "Shift-n".

3. How do you tell the difference between an escape sequence and the escape key? Escape sequences start with exactly the same byte used by the escape key

4. While we have escape sequences to move the cursor and detect the cursor location, in order to find dimensions of the terminal we have to resort to an ioctl.

5. Termcap. Because we can't assume some standard set of terminal features, and since my FreeBSD servers don't have a termcap file for alacritty, when I ssh into my FreeBSD servers my backspace key doesn't work (along with a lot of other things).

6. This ones a bit optional, but it would be nice to have a standard protocol for telling the terminal to render an image.

7. Abruptly killing a program that has put the terminal into raw mode leaves your terminal in raw mode.

What would I do to fix this:

1. Move keyboard input to a different file handle than pipes. This would require software to be patched, or at least a compatibility layer written to merge the pipes for legacy software.

2. Remap all the keyboard bytes. Every key press and every key up sends data to the keyboard input stream. Let the program maintain a keyup/keydown state map for handling modifier keys. This would require software to be patched or at least a compatibility layer written to remap the bytes.

3. As part of the new encoding for #2, we should make a better encoding for input. The current system seems a lot more "grown" than designed. I'd love to see something similar to UTF-8 where we get to encode a variable-length integer with the benefits of indicating byte length in the first byte and being able to detect if we're in a continuation byte. We could even use UTF-8 verbatim for most of the keyboard input but we'd need a special section for escape sequences like moving the cursor. I don't know enough about unicode to know if theres a section we could use for that, but worst case scenario we could use the 5 and 6-byte length utf-8 sequences that never made it to the final utf-8 spec despite being possible in the encoding.

4. As part of #3, add escape sequences to detect terminal dimensions.

5. Establish a new minimum set of features that are assumed to work, incorporating all these refinements over the past 40 years.

6. This could be part of the new encoding for #3

7. Automatically revert terminal to its original non-raw-mode state at the end of a program.

Finally, I'd recommend this blog post to appreciate how much of a mess terminal programming is: https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode...

> 2. You can't have hotkeys that are just modifier keys because the modifier keys only change the byte sent when pressing another key. So could couldn't have a hotkey "Shift" but you can have a hotkey "Shift-n".

Later model physical DEC terminals had a mode called PCTERM (with escape sequences to enter/exit it) in which the terminal would send PC keyboard scan codes for key presses. However, very few terminal emulators implement that.

The Telnet server and client in Windows NT implements a somewhat similar feature, the VTNT terminal type, in which keyboard scan codes and mouse movements are transmitted in a binary format which is based on the Windows console API. (Nowadays Telnet is mostly deprecated in favour of SSH; there is no reason why SSH clients and servers could not implement VTNT, but I haven't seen any do it.)

The technology already exists to solve this problem, and has for years. It is just that nobody appears to care about it enough for that technology to become widely adopted.

> For example, you can't do `gpg --decrypt foo.txt.gpg | nano | gpg --encrypt` because keyboard input on the console is handled through stdin.

I actually had a alias at one point that did something along the lines of (IIRC):

  | editor | -> | editor -i /dev/fd/3 -o /dev/fd/4 3<&0 4>&1 0<&2 1>&2 |
Since stderr (aka &2 aka /dev/pts/whatever) is opened read-write, you can dup it onto stdin to recover the terminal. Ideally, every editor should just support reading from stdin, interacting via stderr[0], and writing to stdout as a command line option though.

Edit: 0: or /dev/tty as jclulow suggested.

With respect to interactive programs in a pipeline, this can already work today if the software is written to allow it. While it is common for interactive software to use the standard descriptors for I/O they are not required to. You can instead open the magic device, /dev/tty, which gets you new handles to the controlling terminal for the process.

Here's a proposal to fix #2 and #3: http://www.leonerd.org.uk/hacks/fixterms/

1. You can have an interactive program in the pipeline, for example 'less' is usually called this way:

  cat some.file | less
Less reads 'stdin' and then reaches out to the actual console to respond to navigation keys. The console is reachable either via '/dev/tty' (POSIX) or, on Windows, via CreateFile()[1].

But yes, most programming tutorials (and probably many programs) make no distinction between the console and standard streams, hence the confusion. They absolutely should.

[1] https://docs.microsoft.com/en-us/windows/win32/api/fileapi/n...

> since my FreeBSD servers don't have a termcap file for alacritty, when I ssh into my FreeBSD servers my backspace key doesn't work (along with a lot of other things).

A hack I've got in .zshrc for this problem:

  function ssh {
   if [[ "${TERM}" = alacritty ]]; then
    env TERM=xterm-256color /usr/bin/ssh "$@"
    /usr/bin/ssh "$@"

Yeah, I create a .terminfo directory in my home folder on any box I ssh to and make sure it has the terminfo for the terminal I use.

For issue #3, it would have been nice had the TTY layer sent DLE ESC when someone hits the ESC key. As it is now, once you read the ESC key, you have to wait some number of milliseconds to see if more data is coming in, and if not, then just return a single key, else it's an escape sequence. Sigh.

I definitely enjoy the continuity, call me small-minded but I don’t want to see this stuff revolutionized either. Maybe because I came up in the 90s and am nostalgic for the VT220 etc, I don’t know. And it’s weird because I have little or no love for other old school stuff.

I would be happy if I never had to write a flaky text parser, for some command line tool, output again.

Then don’t, take json or some standard format with an off-the-shelf parser as stdin and write it as standard out. Then just use jq to munge data into json on one end and back out on the other.

> with an off-the-shelf parser as stdin

These only exist for well known tools. And, these usually explode if you're not careful about the characters in your filename.

That’s not what I’m saying: your program expects to receive standard input in json format. And uses your favorite JSON parsing library to handle stdin. Generate stdout as JSON with the same library. Then, use jq to generate the standard input and output.

I treated myself a deep dive into how CLIs work some time ago and features like:

* marking output from stderr different color (and don't interfere with commands's own formatting much);

* passing more involved keyboard shortcuts to the shell or a tui program, etc.;

* making last line of last command usable in next command or putting it to clipboard without mouse;

* general awareness of shell/terminal emulator of what's displayed (prompt, edited line, commands printing in parallel, stdout vs stderr, messages of shell (jobs))

are very tricky to achieve without reorganizing the whole stack of terminal emulator, shell, line discipline/readline and even kernel.

[0] http://www.linusakesson.net/programming/tty/index.php

[1] https://utcc.utoronto.ca/~cks/space/blog/unix/TTYLineDiscipl...

[2] https://github.com/sickill/stderred

[3] http://www.leonerd.org.uk/hacks/fixterms

[4] https://domterm.org/Wire-byte-protocol.html

I've spent a lot of time messing with terminal UIs, and I feel that the experience could be improved hugely just by adding a couple new escape sequences, for right aligned text and for filling to the rest of the width of the terminal with a character. Thanks to terminfo this shouldn't affect backwards compatibility.

I certainly don't think a full rewrite is necessary (we managed to tack on mouse support and even image rendering[0] no problem). Curses is a pain to work with directly, but this is not the fault of terminals or shells. It's really easy to create curses interfaces with libraries like blessings[1].

[0]: http://blog.z3bra.org/2014/01/images-in-terminal.html

[1]: https://github.com/erikrose/blessings

I can't agree more!!!

I wrote this simple SAS program/job scheduler (https://github.com/PrajwalSD/runSAS) using just bash script (with few utils) intentionally to allow for maximum adoption in projects and just made it more more colorful. In short 75% of the code in there is just handling the terminal (keys, scroll, progress bar etc.) and 25% is the actual load balancing logic.

> I feel like we need a complete rewrite of terminal emulators/bash/whatever.

A complete rewrite would be an opportunity to overlook important ideas, compromise on goals and make design mistakes.

I’d strongly prefer slow, iterative approach here.

To use a tortured metaphor: Like any pathfinding problem, sure slow and iterative is an important part of the algorithm but so is backtracking.

I'm inclined to "if it ain't broke don't fix it", but it's also just as true that this greedy algorithm just leaves us at a local optima.

I am not looking forward to using a new improved shell written in JS.

I rarely look forward to using the old, crufty shell, but I'm a madman who would like things like arrow keys and backspace and maybe even box select to actually work in a sane manner.

I don't need spreadsheets and rich markup in my terminal. I just want basic HCI to work - consistently.

The technical problem is you can’t effect worthwhile improvements in the terminal without also fixing the fundamental flaws below it: a huge mess of bloated, inconsistent, poorly-introspectable command executables, with only untagged, untyped “dumb” pipes to connect them together in the most laborious, unsafe way possible.

The logistical problem is, well… see all the other comments from those who don’t want it to change, whether through laziness, apathy, turf protection, or whatever. Next to the People Problem, the technical problem is the easy part to solve.

Incidentally, here’s what a good 1980s CLI looks like:


Whereas the nix craphouse we’re now stuck with isn’t even a good 1970s* CLI.

Honestly, at this point I wouldn’t even bother trying incremental improvement. The *nix CLI does what it was built to do, and that’s all. When substantive change does come to text UIs it will be as revolution, not evolution.

Draw a line under it. Learn its lessons, both the DOs and DON’Ts. Then whiteboard from the ground-up what needs to come next. Work out where UI/UX needs to be in 2040 to effectively serve the billions of users of the generations to come, and make a start on building that. Dash ahead of history for a change, not be shackled and dragged back by it.

As old, traditional divisions between text, voice, and touch interaction become increasingly frustrating impediments in modern mass-market devices, there’s a killing to be made in smashing down all those old artificial barriers and replacing them all a single unified interaction model that can transition seamlessly between all three modes as its users’ needs and wishes direct.

I agree. Nushell (https://github.com/nushell/nushell) is the best I have seen so far. It still lives in a standard terminal from the 80s - basically no graphics, limited mouse support, etc. But I guess you can't change everything at once. It's an enormous improvement on Bash at least!

I've wondered for a bit why in the Unix philosophy there isn't a standard /dev/progress or something for somewhat unified progress reporting already. It seems something that should be easy to standardize: make it append-only and take maybe a task name and a double [0, 1] (maybe, maybe optionally x of y counts, but a single double should be all you need). Let the terminal, the shell, and/or the GUI figure out how it wants to display things.

All of the major OSes today have some sort of dock/taskbar/activity panel standardized progress reporting API that is basically that simple, seems interesting we haven't pushed that idea back into the terminal. Makes you wonder what other sorts of GUI era pseudo-devices might be useful to add to Unix. In the other direction, imagine if some of these tools had been standardized as real devices in past terminals, like using something fun like an analog meter for progress operations.

> showing some progress bar, or resize the terminal window, it should handle it nicely like every other application.

I just added SIGWINCH (resize event) handling to my console/progress bar library, https://pypi.org/project/console/ , though it currently needs to be using the whole line. I will fix that in the future.

Inline images would be great too (bitmap or svg). There’d be a lot less need for something like jupyter if you could show images in the shell.

Why does a CLI need colours and icons? OK...colours have some value, but icons? Serious question.

On a basic level, a CLI with color adds visual information that's easily seen at a glance. In this example blog post, the author shows how adding color to `df` resulted in an immediate visual distinction between mostly empty and mostly occupied space, which would normally require scanning a column to find.

Icons? It's easier to show information in a smaller area when you can use the spot a character would take with an emoji or equivalent.

I get that. So bold, italics and half-tone could be good enough for many/most use cases, and icons are just eye candy, right?

Oh, please, no "color codes".

Some of us prefer a monochrome terminal, with the only distinction being bright/bold and regular text. I'm all for modernizing the classical unix tools, but turning them into kitsch Christmas trees is maybe not the best way.

You're telling me that you don't use colors with ls? This isn't even a matter of debate, ls with colors is superior and more efficient.

`ls -F` is good enough for me

One of the biggest upgrades from using fish is syntax highlighting / autocompletion. You can get fish-style syntax highlighting and autocomplete in zsh (which has the advantage of being more interoperable with bash generally):



Poster mentioned "modern alternatives exist" with good colorization options. Some of my favorite colorized feature-rich alternatives:

ls -> [exa](https://github.com/ogham/exa)

cat -> [bat](https://github.com/sharkdp/bat)

du -> [ncdu](https://dev.yorhel.nl/ncdu)

diff -> [delta](https://github.com/dandavison/delta)

In combination with all of the above, [fzf](https://github.com/junegunn/fzf) suddenly becomes a syntax-highlighter preview-pane via leveraging bat (or delta, as the case may be).

Poster here! ble.sh gives syntax highlighting for bash just like fish and zsh. I personally don't like zsh because it seems over engineered and fish have some design problems (I don't think they have yet fixed them).

The feature-rich alternatives you mentioned are exactly what I was thinking about (and using daily!).

There are a few things about zsh that "feel better" than bash (especially arrays), but given the ubiquity of bash, if I can get the same general quality-of-life upgrades that I experience from the zsh community add-ons, I may need to give ble.sh a go.

Edit: I gave ble.sh a try, and it is super-cool-magic, but does feel slow with quite noticeable input lag.

I've also aliased cat to bat but it causes me issues when I redirect the output of cat (bat) without \cat to a file as then the file contains color codes that are not expected by other users and tools and cause some tools to not behave correctly,while the issue is invisible to me (unless reading the generated file with \cat)

bat should not be doing that. It should perform exactly like cat when piped or redirected. At least it does for me, even if the text is colorized in a tty. Perhaps an issue with your pager settings? Dunno.

Thanks for the links! Could you say a bit more about how you use/configure fzf to work in combination with bat and delta?

fzf has a preview pane option. Typical OOTB usage is to use this to cat the output of the currently hovered item in your list. But fzf can fuzzy-find on any list, not just file lists, and use the preview pane to display anything based on your selected inputs. One very nice demonstration of this is [git-fuzzy](https://github.com/bigH/git-fuzzy)

The hardest part about leveraging the power of fzf is getting input into your --preview argument in the middle of some piped process. But that's also where it's true power becomes fully evident.

awk users have long had similar powers. And indeed you might find awk useful for reorganizing record separators in a pipe to fzf. But fzf is brilliant because it "just works" for 90% of cases.

I think we're probably going to see people sharing some pretty incredible workflows with fzf in the next few years. Something about being able to stick it in the middle of a Unix pipe just makes it really really special; it's compose-able!

As developer I think we use too many colors everywhere. It is really necessary? Some terminals looks like a rainbow festival.

A color for the user, a different color for the hostname, another one for the git branch... It is a directory? Let's add a new color. I think is too much.

I like to use themes like minimal-theme [https://github.com/anler/minimal-theme]. My eyes appreciate it.

Sounds like the problem is not colors, but the amount of stuff we're differentiating then. You could say the same thing about making things bold, italics, shades of grey, etc.

I would think people recognize different colors better than shades of grey or bold text though.

Interestingly, in a lot of Japanese advertisement it feels like all the ways of making something stand out have been exhausted.

To my brain, syntax coloring makes recognizing the shape of some code a more rapid/fluid process. It also provides a nice feedback loop for potential typos (in my cli setup, a misspelled command will be red instead of green, a string will be yellow, etc) so that you can catch an error before you execute/commit.

Outside of all of that, I enjoy the rainbow festival aesthetic. I coded a lot as a kid for fun, and was good at it, but got away from it as an adult. I think a huge part of transforming back into an enthusiast was all the attention to themes, fonts, ligatures, autocompletions, etc. I really enjoy "talking" with my computer, and all of the styling gives a sort of pseudo-personality, as the computer responds to my syntax with different colors as I'm writing it.

That said, you might not like rainbow personalities! That seems to make you an outlier, but it doesn't matter! One great thing about code is that it can be easily adapted to a users preferences...that is, as long as you're using tabs for indentation and spaces for alignment ;-)

It’s a good thing we can adapt it to our taste, then.

I agree. How about just reading the text? The human brain is excellent at quickly skimming through text and recognizing patterns. We don't need colors.

Differentiating by, and extracting meaning from, color is a very ancient and important part of our visual system and every day life. Why wouldn’t you want to take advantage of it, living in a black and white world?

Somewhat related:

My friend is developing a colour palette based on Solarized:


but with more perceptual uniformity.

I like it better but don't understand the desire for a near dark cyan background that each promotes.

alternate colours based on the same principles here: https://github.com/jan-warchol/selenized/blob/master/the-val...

It looks like he's only doing the dark mode. I wonder what selenized-light would look like.

It's available for terminals, but it's a work in progress for editors.

Looks really nice . Thanks for sharing

The GitHub link to Generic Colouriser points to an outdated and unofficial fork. The canonical one is at https://github.com/garabik/grc.

Fixed, thanks you for pointing this out!

I think in this day and age we should be making bigger jumps than wanting color in our CLI.

We should have more than one font, we should have pictures. We're visual creatures, us humans. I think something like Jupyter, with in-line images et al is the future, or should be, at least.

I strongly disagree. If we're going to use a TUI, it should embrace what it is. Turning it into a watered down GUI does not work to its strengths nor serve the needs of the users still working with it.

I dunno, Emacs works really well, and I line images and stuff is really nice. A good example of this is that you can have inline rendered LateX in your text buffer. And when you need to edit it, it turns about into texts.

Also inline graphs in org-mode is super nice.

I agree, but we're limited by terminal emulators. Not counting images in terminal (which can be done with a protocol few terminal supports), we don't even have Font Ligatures widely available.


Colorful prompts remind me of my time playing MUDs. The better ones did a good job colorizing everything so you could navigate almost by color alone.

Also set `CLICOLOR=1`. See https://bixense.com/clicolors/

A fair number of tools support it.

Instead of `ls` I use `lsd` https://github.com/Peltoche/lsd.

How does this compare to exa?


`exa` provides more functionality but is also much slower.

I find myself wishing for a CLI "design system". For example, given a script that calls some APIs (reads and writes) and does a couple of calculations, what is the best way to use color and space to produce understandable and useful console output?

Really tempted to install starship but I also do a bunch of sensitive stuff with my terminal. Should I be worried about using this? I understand it's open source, yet still not confident.

Starship maintainer here. I'm happy to answer any questions have about how it works.

Every render of the prompt is fully stateless. Starship has no tracking, telemetry, and never calls home. :)

Keep in mind that having bash history is already a treat since `~/.bash_history` is readable by every program you run.

If you want to be 100% safe you could just monitor the process and see if it opens any internet connection but I am confident it is just a local program.

> treat


starship looks good on paper, but the fact that all plugins are by default enabled (from what I can tell from the docs) is a no-go for me.

Why do people need all that information on their prompt? I understand showing the git status, but is it really necessary to know that your battery is discharging and you're currently using node v10.12.3 and elm v1.2.3 every single time you run a command in some directory?

Starship can be quickly configured to have a select few "modules" enabled. This can be configured with `prompt_order`, documented here: https://starship.rs/config/#prompt

I, for one, like to know what version of Node will be used when I'm jumping between projects, so I can know which features are available to me at runtime.

Eventually we'd like to include an interactive configuration tool to help folks find a configuration that meets their needs.

I do like to have colorized output for my interactive CLI tools, but I will never understand a prompt other than "$" or "#".

Do people really need to continuously see all the noise like the host name, their username, the working directory, the date, or even their current branch?

Is hostname, whoami, pwd, date, git branch, and git status really to cumbersome? At least with hostname and branch I'm usually piping to pbcopy anyway.

FWIW, the -F option for ls is really nice too.

If you do work on a number of different machines, in production and in dev, knowing what host you're on, what directory you're in, etc. helps avoid errors like killing a process in prod when you thought you were in dev.

While writing code, it's helpful to know what branch you're on with git, so you don't accidentally commit code to the wrong branch, etc.

I typically have something like 30-40 terminals open at a time, grouped into windows in tmux, so having everything categorized and visible at a glance is kind of a necessity.

I have ssh sessions to remote machines, I use multiple terminal windows, and multiple tabs. I don’t use tmux, is there something about tmux that makes it hard to know where you are?

There's nothing specific about tmux that makes it hard to know where you are, but it does let you keep any number of terminals open on one screen, which is super-helpful, but requires a lot of mental overhead to keep track of where everything is.

If you're able to keep track of the context of 50 windows without a prompt, more power to you, but that's not something I can do and I require some signage to ground where a specific prompt is.

> all the noise

I'm sure it takes some getting used to, if you're used to something more minimalistic, but it isn't noise to me. It's a persistent indicator of where you are, and is usually easily ignored.

The benefit of it for me is that I always have "where am I, where are files in relation to here" in the back of my mind. While switching terminals, if what's in my mind doesn't match the prompt it's really jarring and hard stops me from doing something stupid on the wrong system or directory or as the wrong user.

Do people really need to continuously see all the noise like .... the working directory...?

I can't imagine using a CLI prompt without knowing what directory I'm in. How would that even work?

I'm an anxious ls-er. I unconsiously ls while I'm thinking in a directory, so I usually have a pretty good sense of my location.

I guess I usually know what directory I'm in and if I ever need a reminder I use pwd.

With at least 6 months of commands in ~/.bash_history

$ history | grep pwd | wc -l


I usually have ~20 terminal windows open, some of which have sessions opened on 4 different machines. If the host name and current working directory are not in the prompt, I need to check both every time I switch windows. Otherwise there’s no way I won’t make a mistake and do some stuff in the wrong place or on the wrong server.

I can accept that my use case is not typical, but these things are actually useful.

For my local machines I don’t bother with hostname, whoami or date but the former two is essential on remote servers, so it’s good to have as defaults.

pwd is really useful since I’ve tons of terminals on tmux and typing pwd gets repetitive real quick.

Here's a snippet from my bash_aliases ...

  ### PROMPT ###
  function user_host_pwd() {
      printf "%c " '-'
      user -n
      printf "%c" '@'
      printf "%s" "${HOSTNAME%%.*}"
      printf "%c" ':'
      path "${PWD}"
  -() { user_host_pwd ; }
  prompt_command() {
      local current="$USER@$HOSTNAME:$PWD"
      local last_cmd
      if [ "$current" == "$USER_HOSTNAME_PWD" ]; then
          last_cmd="#$(history | tail -n 1 | sed -e 's/.*[0-9]  //' | cut -d ' ' -f 1)"
          for cmd in $COMMANDS_USER_HOST_PWD_PROMPT
              if [ "#${cmd}" == "$last_cmd" ]; then
      if [ "$current" != "$USER_HOSTNAME_PWD" ]; then
          export USER_HOSTNAME_PWD="$current"
  COMMANDS_USER_HOST_PWD_PROMPT="cd ssh sudo su login $(sed -e '/^#.*$/d' -e '/^$/d' -e 's@^.*/@@' /etc/shells | uniq | xargs)"
  PS1='$ '
  [ "`id -u`" -eq 0 ] && PS1='# '

> I will never understand a prompt other than "$" or "#"

I agree with that, but some legit useful information in the prompt is the exit status of the previous command. So you may have a slightly less minimalist PS1='$?\$ ' which is typically seen as "0$" unless something went wrong. Another legit and useful information is the number of background jobs (set up to the empty string for the common case of zero jobs). Other information like the cwd, the time or the git branch are of course idiotic.

It all depends on your mode of working. You want to have information showing the current state of stuff that changes.

If you only work as the same user, having $USER in the prompt is visual clutter, and you very soon learn to ignore it -- then why have it? If you only work as one user or "root", you can encode this difference in the "$"/"#" character.

Current directory... is very useful. I have worked for years without it (before it was available) and it really made a difference. Yes, it just saves you a command (pwd, dirs, ...), but it's nice to have this info right there.

Where I would agree is the git branch info. How do people use it in their prompt? This is filesystem-level data, totally independent from the current shell session. To give an example: I have two terms (shells) and in both I am in ~/mydir. They both show got branch "master". In one of them I change to another branch. That window's shell prompt gets updated but the other windows still shows me as being in "master". Do people press enter before each command to have the prompt updated to actual values?

about hostname in the prompt: if you are logged in to a bunch of server debugging a problem, it's good to see from the first sight on which system you are executing a command.

Nice article, 'starship' is new to me, just tried out, a bit verbose and took too much line space for me. 'highlight' should be replaced by 'bat' these days. 'grc' is nice and I first time learned it here. After read it and tried out, I just added 'grc' to my tool kit(though ubuntu 18.04 misses /etc/profile.d/grc.bashrc and I had to download it from github)

Just looking at the homepage of starship, I don't really understand what benefits it has. It says fast but simply has a gif? I understand a bit more via the docs, but it's annoying the home page doesn't really show any benefits and just wants you to install it asap.

Love starship. Fast, easily customizable, and best of all works on Windows as well as macOS/Linux. (Unsure about BSD, but I presume that as well)

For Windows, one could use this small color utility I've made last year, ColorThis


Colorizing is a red herring; it's akin to syntax highlighting: it's nice, but if you need it to determine important information then something's amiss.

I'd much prefer consistent and predictable information conveyance. Ie, I don't need Midnight Commander to be lit up like a christmas tree because I know immediately what information is displayed in its tables and panes.

> but if you need it to determine important information then something's amiss.

Not untrue, but define "need"; as eg [0] points out, distinctive colors make it much easier to notice things. (On the other hand, TFA seems to be advocating precisely the kind of syntax-based ice-cream-sprinkle-soup coloring that makes it harder to notice things, so not exactly the most convincing presentation there.)

0: https://buttondown.email/hillelwayne/archive/syntax-highligh... 0 dicussed: https://news.ycombinator.com/item?id=23902124

Colour is a bad tool, even if it is an effective tool; a not-insignificant portion of the population has difficulties with colour. Then there's that not all displays render the same, and not all editors colourize the same. Syntax and layout are superior.

I am immensely opposed to the notion that something being difficult or even wholely unusable for a "not-insignificant portion of the population" makes it a bad tool, rather than merely a situational one to which alternatives are also necessary[0]. The same reasoning, applied to the not-insignificant portions of the population with more severe disabilities than color-blindness, would condemn very nearly every tool in the history of technological civilization.

0: And in this case - as you yourself have pointed out - happily available.

The necessary alternatives, in CLI, are consistent and human readable syntax in a consistent and pleasing layout; and those alternatives are generally either present or not.

Moreover, they're useful to anyone regardless of their ability, and consistent syntax is easier to automatically colourize. Starting with colourizing is backwards.

At what point did I suggest starting with colorizing? I pointed out that[0] colorizing was sometimes so effective at drawing attention to important information that it was reasonable to describe it as needed, with the implication that coloring should be available in addition to other information channels.

0: for some people, which I perhaps should have explicitly noted, but it really ought to go without saying that no tool is equally effective for everyone.

You didn't; and neither did I suggest that colorizing was ineffective. It's bad because when using other tools it's unnecessary.

Microsoft's new Terminal is really customizable


Welcome to the 80s & 90s. :D

Better late than never. :)

`diff --color=auto` is nice, but `vimdiff` is superior

I myself have really enjoyed `delta` and the variety of configuration it has: https://github.com/dandavison/delta

There is also `colordiff` which works both as a standalone diff tool, but also as a colorizer filter for other diff tools. For example:

  diff -u a.txt b.txt | colordiff

Git ships with `diff-highlight` which is more than enough for me.

I use the following config.

      pager = /usr/share/git-core/contrib/diff-highlight | less

    [color "diff-highlight"]
      oldNormal = red
      oldHighlight = 16 bold red
      newNormal = green
      newHighlight = 16 bold green

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact