2

When I already have a text typed out on the terminal, can I modify its properties?

(I want to tput rev my command prompt upon preexec().)

Jens
  • 69,818
  • 15
  • 125
  • 179
user569825
  • 2,369
  • 1
  • 25
  • 45

2 Answers2

1

Terminals let you color text as you write the text. If you want to change the color for some text, you'll have to know what's already there — and rewrite it (bracketed by tput rev and tput sgr0 commands, of course).

Rewriting the prompt means you'd have to know the position on the screen where the prompt was written. For the simple case (where your prompt was not at the bottom of the screen, causing it to scroll up when you enter the command), you could save the current cursor position (using tput sc) and restore that to return to the prompt for rewriting it (using tput rc).

However, that would only help for a simple case, since multiline (or scrolled) commands would make it infeasible to return to the prompt and rewrite that.

People write applications like that using curses — but zsh's terminfo support won't give that level of control over what's on the screen.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • Any way to fetch "what's already there"? (Including it's current properties/colors); For multiline, I could maybe somehow search backwards until I encounter a certain symbol that precedes my prompt - it's quite unique in my case. Any hint on how to do that search? – user569825 Apr 23 '17 at 12:36
0

Maybe you could get an approximation by manipulating the color palette. In an xterm-256color you can dynamically change each of the 256 colors and assign it an arbitrary RGB value with a control-sequence. For example to turn your palette into a 256 level neutral step wedge, use this gray_colors function (and reset_colors to undo it). This is best when you have a color test (color cube) on your screen.

# Operating System Control.
OSC=$(printf '\033]')

BEL=$(printf '\a')

reset_colors () {
  printf "${OSC}104${BEL}"
}

gray_colors () {
  c=0
  while test $c -lt 256; do
    printf "${OSC}4;$c;rgb:%02x/%02x/%02x${BEL}" $c $c $c
    : $((++c))
  done
}

Now if your current command shall be red and turn gray once executed, allocate like 10 colors to the same red hue, and once the next prompt is displayed, change it to gray and use the next red color slot for the new prompt. Then cycle through the 10 red colors (assuming that's about the number of commands on the screen at any time). Adjust to your liking.

Jens
  • 69,818
  • 15
  • 125
  • 179