Yes.
… without needing to post-process the output of the program in question, or have it change its behaviour because it thinks that it is talking to a pipe and not to a terminal character device (as some programs indeed do).
tput
is not capable of this, because there are no terminfo capabilities for the requisite functionality. Moreover, this functionality is specific to a particular class of terminals, those that implement several control sequences from the DEC VT family of terminals.
But it is possible.
That is a small number of terminals. Emulating the DEC VTs and their control sequences is a popular thing for terminal emulators. But not all terminal emulators understand and implement the specific DEC VT control sequences that are necessary for this. Ones that do include:
Such terminals have the DEC VT notion of settable margins. Margins control scrolling and automatic margin wrap behaviour of normal output. The terminals also have the DEC VT notion of origin mode. This is a mode setting which, when set on, makes margins also control absolute cursor positioning done with the CUP and HVP control sequences. Finally, they implement all of the margins, including the newer ones provided by the later DEC VT models.
So when your program is started or continued:
- Set the top and bottom margins by emitting the DECSTBM control sequence.
- Enable the left and right margin mechanism by turning the DECLRMM mode on.
- Set the left and right margins by emitting the DECSLRM control sequence.
- Turn the DECOM mode on.
- Home the cursor, just in case it was outwith the margins when you turned origin mode on and turning origin mode on does not automatically move the cursor.
and do the reverse to restore the screen to normal when your program exits, is suspended, or is terminated. You also need to keep the information about the terminal size held in the line discipline correct, so that programs that use cursor addressing mode know the size of the margin area rather than the size of the whole screen.
At first pass, that will be something like
printf '\e[%d;%dr\e[?69h\e[%d;%ds\e[?6h\e[H' 5 20 5 65
stty rows 15 columns 60
ping www.google.com
printf '\e[?6l\e[s\e[?69l\e[r'
stty rows 25 columns 80
although you should vastly improve the cleanup behaviour of that in the face of the script being terminated, as well as be more clever about restoring the rows and columns in the line discipline to the
correct values (rather than making bad assumptions as I have done here for the sake of brevity).
For lesser functionality, these terminal emulators respect top and bottom margins, but do not have the left and right margin mechanism that you specifically want here:
- urxvt
- Konsole
- dtterm
- PuTTY
Note that margins have to be set independently for the primary and alternate screen buffers. So programs that switch to the alternate screen buffer when switching to cursor addressing mode will not be affected by this. That group includes programs like NeoVIM and less. Programs that do cursor addressing without switching to the alternate screen buffer will be, however. That latter group includes things like ZLE in the Z shell.
Further reading
tput
doesn't effect any kind of complex state change in the terminal; it just writes a few bytes to standard output. The terminal treats the bytes fromtput cup 5 15
the same as it does a linefeed; as an instruction to move the cursor one time before continuing with the following bytes. – chepner Nov 17 '17 at 14:22