Can I push/pop attributes with tput?

94 Views Asked by At

In the answer to this question, it uses the following (simplified):

echo "this is $(tput bold)bold$(tput sgr0) but this isn't"

But that tput sgr0 resets all of the text attributes.

I'd like to output coloured text, with only some of it in bold. So I want something like this:

echo "$(tput setaf 1)this is red; $(tput bold)this is bold; $(tput unbold)this is red, but not bold"

But tput unbold isn't a thing.

Is there any way to push/pop the terminal attributes so that I could do something like the following?

echo "$(tput setaf 1)this is red; $(tput push; tput bold)this is bold; $(tput pop)this is red, but not bold"
2

There are 2 best solutions below

0
On

No - tput has no notion of push/pop. Just set: like a pun, tput is a more general tool than tset, as noted in the manual page:

  • SVr3 replaced that, a year later, by a more extensive program whose init and reset subcommands (more than half the program) were incorporated from the reset feature of BSD tset written by Eric Allman.

tput does nothing like push/pop, because it would have to rely upon asking the terminal what the current video attributes are (something that only a minority of the terminals could do).

Some terminals could/can do this, e.g., the DEC VT420's DECRQSS control mentioned in XTerm Control Sequences. Most do not (even limiting this to xterm-imitators).

tput works with terminal capabilities; none of the predefined ones in terminfo(5) deal with stacks.

That's not to say that someone might develop an application like tput which could work with a terminal that supports stacking, either by supporting push/pop or set/get controls. (xterm does both).

2
On

My tput has in the man page:

bold=`tput smso` offbold=`tput rmso`
     Set the shell variables bold, to begin stand-out mode sequence, and offbold, to  end  standout  mode  se‐
     quence,  for  the current terminal.  This might be followed by a prompt: echo "${bold}Please type in your
     name: ${offbold}\c"

So example would be:

echo "$(tput setaf 1)this is red; $(tput bold)this is bold; $(tput rmso)this is red, but not bold"