Is it possible to highlight the non-breakable space in zsh / terminal?

This highlighting is IMHO more easily implemented in the terminal emulator than in the shell. And as a benefit you get the highlighting independent from the shell -- so it's even working with less etc. Since you are fine with switching the shell, I suppose you are fine with switching to URxVt, too.

In conjunction with the perl extentions urxvt-perls it is possible to make URLs etc. clickable. But we can abuse this feature just to underline the non-breakable spaces.

The configuration is done in ~/.Xdefaults:

URxvt.perl-ext:           default,matcher
URxvt.matcher.button:     2
URxvt.matcher.pattern.0:  (\\240)
URxvt.matcher.launcher.0: /bin/true
  • line 1 activates the appropriate extension
  • line 2 configures the usage of the middle mouse button for clicking on the ,,hyperlink''
  • line 3 defines the regex to match, here every non-breakable space; A0 (hex) = 240 (oct)
  • line 4 defines the action, in your case you don't want to open up a browser or any program, so /bin/true should be fine

Reload ~/.Xdefaults by restarting the X server (this might be overkill, but I'm not sure if a xrdb ~/.Xdefaults is sufficient...) and you get your desired result. With a magnifying glass it is even possible to distinguish between non-breakable spaces an underscores (notice the shift by 1 pixel) ;):

enter image description here


The following is kind of a proof of concept for a "backend" solution. Be aware, that this will break a lot of things, namely interactive programs like man, less etc. (vim is complaining but still working). This approach was posted by Atom Smasher on the zsh-users mailinglist on Sat, 16 May 2009 to colorize STDERR. I adopted it to your requirements:

# ## highlight_nbs.zsh ##

zmodload zsh/terminfo zsh/system
autoload colors is-at-least

if [[ "${terminfo[colors]}" -ge 8 ]] { colors }

highlight_nbs() {
  while sysread line
  do
    syswrite "${line//$'\xC2\xA0'/${bg[red]} ${terminfo[sgr0]}}"
  done
}

precmd() { sleep 0 }

## i'm not sure exactly how far back it's safe to go with this
## 4.3.4 works; 4.2.1 hangs.
is-at-least 4.3.4 && exec  > >(highlight_nbs)

The tricky part is exec > >(highlight_nbs) which processes the complete output of the replacing shell through the highlight_nbs function. The precmd definition is necessary to avoid a race condition, otherwise the new prompt is printed before the actual output of the executed command.

Here is a demo:

enter image description here


Sure.

$ echo -e "[\xC2\xA0]|[ ]" | cat -A
[M-BM- ]|[ ]