Useful Shell Prompt (2020)
solovyov.net
solovyov.net
It's very feature-rich, showing suitable context for a variety of tools, and can be customised if the defaults don't provide the information you're after.
Is there any reason why a prompt is written in rust?
> Is there any reason why a prompt is written in rust?
The prompt program supports a bunch of different shells. I imagine that's going to be easier to maintain in Rust than in bash.
There is great love from many for more capable shells, but the flaws of these are visible to all; "man bash" plainly states that it's "too big and too slow."
Minimal dash compiles to under 80k for i686, and Arch Linux asserts it to be 4x faster than bash.
It is with some regret that we did not adopt a shell syntax that could be cleanly LR-parsed with yacc and lex, but that was the fault of the founders.
Bill Joy has admitted his own flaws in the C shell, and Brian Kernigan should have torn that code apart, replacing it with awk syntax upon a shell. In a parallel world, it would have been a much more capable shell.
As things stand, we must struggle with the Algol of our forbearers, that requires an extremely advanced parser, and to make due with what is permitted to us.
"I am a strong believer that Bourne-derived languages are extremely bad, on the same order of badness as Perl, for programming, and consider programming sh for any purpose other than as a super-portable, lowest-common-denominator platform for build or bootstrap scripts and the like, as an extremely misguided endeavor."
what else may come in mind to use?
Many of those sh tricks you link to are better even in the common ksh/bash/zsh subset than in pure POSIX.
Because the shell needs such an advanced parser, it shows that the language is full of ambiguity and pitfalls.
The slides for the parent presentation have this gem:
Quiz: Which is the command that outputs \\ ?
1 echo "\\\"
2 echo "\\\\"
3 echo "\\\\\\"
The language should be clearer, and less ambiguous.
function prompt_epoch() {
MYEPOCH=$(/bin/date +%s | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta')
p10k segment -f 66 -t ${MYEPOCH}
}
It looks like this in action: $ zmodload -F zsh/datetime p:EPOCHSECONDS
$ printf "%'d" $EPOCHSECONDS
1,648,943,504 function prompt_epoch() {
p10k segment -f 66 -t ${MYEPOCH} <-- replace MYEPOCH with EPOCHSECONDS but with commas?
}
EDIT: printf can assign output to a variable using -v. Therefore my function can be rewritten as: function prompt_epoch() {
printf -v COMMA_EPOCH "%'d" ${EPOCHSECONDS}
p10k segment -f 66 -t ${COMMA_EPOCH}
}Powerlevel10k is very customisable, faster, can be configured to function exactly like Pure out of the box and in my experience, more reliable.
I would recommend powerlevel10k over Pure any day. But it’s just an anecdotal datapoint.
Edit: Well that was easier than expected, their initial setup daemon is pretty well made, and the "instant prompt" is pretty cool. Feels snappy.
(last command returned 1.)
»
Or, if the previous command terminates due to a signal: (last command got signal SIGTERM.)
»
Color doesn't survive c/p in practically any medium, and the exit status is useful when showing things to co-workers.The bigger hint also highlights when a command unexpectedly errors (e.g., while emitting text to the effect of "Success!") and the opposite case, where a command appears to fail and exits with success anyways.
I've tried to highlight roughly the relevant bits.
The basics of it is that we lazy-load an associative array between exit statuses that are signals and their prettified names. (Which we more or less build by querying Python, to get at what's, essentially, defined in signal.h.)
Once we have that assoc. array, when we get a non-zero exit, we see if it's in the array. If it is, look up the pretty name, print message. If not, just print message with raw exit status. Red & bold so it shows up. (Should probably also use bright red, too. But my work laptop is macOS, & so it's iTerm2, and iTerm2 interprets "bold" to mean "bright & bold".)
I also use zsh, which is able to be considerably more expressive in what it can accomplish in a PS1 than bash can. Note that the syntax,
${+VAR}
which appears in there is zsh-specific. It can be done in bash, but it isn't as neat. I don't recall if bash has associative arrays or just arrays, too… PROMPT=[$r][ $P ][ $t ]$_$g
Appearance is along these lines: [0][ C:\bin\4nt ][ 15:30:07 ]
>
Super useful. It's good to get advance warning of strange exit codes when trying things out interactively with a view to using them in some automated process. The exit code also shows the exception type if the process terminates due to an exception - alway handy to know.I also like always having the same amount of space for the command, visually, regardless of the working folder.
It uses 2 lines, which is actually really nice. It gives space to show where you are and git status/branch, while still allowing you to write long commands.
Most of the time I'm within a repo directory, I don't care in which branch or state it's in as I have other apps to take care of that and there are better info to be had like cwd, who you're, host name, exit code, time and time last command took for a prompt.
But sure, if you are not using hit in your shell, then you don’t need fit in your shell.
A big problem I had at a former employer was that `git status` would take 2+ seconds to return (for various reasons) and the default oh-my-zsh prompt would parse the results of `git status` to display the repository. People thought it was normal to wait more than half a second to get a prompt back! I lost trust in 3rd party prompts from that experience, and while I have sunk at least a few hours into my own prompt, I know exactly how it works, what calls it's making, and where things go wrong (when they do).
PS1='$?:[$(date +%m%d:%H%M%S)]:\h:\w\$ '
you have
- termination status of the last command
- date and time the prompt was last redrawn in [MMDD:HHMMSS] form.
- host, working dir, prompt character #-root $-user
* a newline before your current prompt
* a newline after all your context and right before your "$ "
This helped me tremendously with scanning terminal output for years. More default $PS1's should do this.
It would be cool in tmux to have a shortcut to a quick popup showing more git info (status, log origin.., which of the patches have pull requests.) You could do that stuff with a shell command or a vim plugin, but tmux is the common thread, so adding it there seems a better place for it. Kind of like a sticky window in a tiling wm (mod space in i3) but in the terminal.
The default prompt with the status arrow and directory are awesome. You can also extend ZSH functionality with plugins. I can't live without git and timer plugins anymore.