permacomputing

Source repository for the main permacomputing wiki site
git clone http://git.permacomputing.net/repos/permacomputing.git # read-only access
Log | Files | Refs

spacehobo.mdwn (4138B)


      1 # Just a Rum-Soaked Space Hobo with an Inordinate Fondness for Makefiles
      2 
      3 Hello, I'm from the [London Permacomputing Group](https://london.permacomputing.net).  I've been using Unix and The Internet since the 1980s, and Linux since the mid-90s.  I like small open software I can wrap my head around, but I'm not a fan of those "suckless" fash types.
      4 
      5 ## Prompt Engineering
      6 
      7 Check out my neat `bash` prompt, which I put in eik's `/etc/bash_completion.d/prompt.sh` so everyone gets it:
      8 
      9  * [Prompt Engineering](https://git.permacomputing.net/prompt-engineering/files.html)
     10 
     11 
     12 The `$PS1` text expansion environment is fairly limited.  It can do parameter expansion, reference expansion, arithmetic expansion, and a couple other neat tricks.  You can shell out, but if you do that it can overwrite the variable that contains the last exit code (`$?`).  A lot of heavyweight systems like [powerline](https://github.com/b-ryan/powerline-shell) or [starship](https://starship.rs/) will tuck this data away before running loads of programs every time you hit return at the shell.  I wanted to see if I could do more with less.
     13 
     14 Tools such as the `$(__git_ps1)` hacks do their best to only use features of bash that work internally to bash itself.  They make internal functions that try not to fork off processes if they can help it.  I was inspired by the Debian `$PS1`'s handling of their `$debian_chroot` variable, and decided to try and make a dynamic prompt that only shows information if it's relevant.
     15 
     16 ### Implementation Details
     17 
     18 This prompt uses the `_noop` array (with only `${_noop[0]}` defined) to turn arithmetic expressions into defined/undefined responses.  This lets us use some of the brace-expansion features to specify alternate output, so we can display the error code or number of jobs in the background *only* if they're non-zero, and we can style them with a high degree of freedom.
     19 
     20 It also only displays the hostname if the `$XDG_SESSION_TYPE` is `"tty"` or if we have variables set by `ssh`, `sudo`, or `doas`.  It dynamically displays the `$SUDO_USER` and `$DOAS_USER`, if either is defined.  
     21 
     22 ### Behaviour
     23 
     24 What this means is that when you log in on your local desktop system, your prompt is merely:
     25 
     26     ~$
     27 
     28 But the same prompt on a remote system will show the more common:
     29 
     30     user@hostname:~$
     31 
     32 And if you are sudo'd in a chroot with two background processes while looking at a git repo after a command that exited with an error code of `1`:
     33 
     34     (1)[2](thechroot)root<user>@hostname:/home/user/src/therepo{main $%}#
     35 
     36 Each of these dynamic pieces of information will be bold and colour-coded, if `tput setaf 1` was successful on your terminal or if your `$TERM` seems likely to support it.  Otherwise you get a plain text version.  
     37 
     38 #### Here's the plain text version so you can see how it works:
     39 
     40 ```sh
     41 unset _tty
     42 _tty=$SSH_CONNECTION$SUDO_USER$DOAS_USER
     43 [ "$XDG_SESSION_TYPE" = "tty" ] && _tty="yes"
     44 # We use defined/undef logic on array indices to detect non-zero values inside
     45 # the prompt, which is faster than shelling out
     46 _noop[0]='array accesses turn 0/nonzero into defined/undef!'
     47   PS1='${_noop[$(($?==0))]:+($?)}${_noop[$((\j==0))]:+[\j]}'
     48   PS1+='${debian_chroot:+($debian_chroot)}'
     49   PS1+='${_tty:+\u${DOAS_USER:+<$DOAS_USER>}${SUDO_USER:+<$SUDO_USER>}@}'
     50   PS1+='${SSH_CONNECTION:+\h:}\w'
     51   type -t __git_ps1 > /dev/null && PS1+='$(__git_ps1 "{%s}")'
     52   PS1+='\$ '
     53 ```
     54 
     55 ### Here's how we detect colour support
     56 
     57 Most terminals support [the standard ANSI escape sequences](https://en.wikipedia.org/wiki/ANSI_escape_code) now, but we still have to be careful.  This catches ghostty, kitty, foot, and any terminal type with `color` in the name (such as `tmux-256color` or `xterm-256color-bce`).
     58 
     59 ```
     60 case "$TERM" in 
     61     *[is]tty*|foot*|*color*) color_prompt=yes;; 
     62     *) [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null && color_prompt=yes;;
     63 esac
     64 ```
     65 
     66 If it doesn't find your terminal in that list, and the system you're on has `ncurses` installed, then it will try to send the code for red text to `/dev/null` with the `tput` command, and keep you colour-free if that fails.
     67 
     68 # I just think it's neat!