Is multi-line alignment possible with tput?
I would like to position the cursor at a specific row/column and print a multi-line file/command that stays aligned to its first coordinate, so that
tput clear
tput cup 5 15
ping www.google.com
would output all subsequent lines in the 15th column. As it is, the first line prints correctly but the following lines are reset to the left. Is it possible using tput or any other method?
shell-script text-processing terminal tput
add a comment |
I would like to position the cursor at a specific row/column and print a multi-line file/command that stays aligned to its first coordinate, so that
tput clear
tput cup 5 15
ping www.google.com
would output all subsequent lines in the 15th column. As it is, the first line prints correctly but the following lines are reset to the left. Is it possible using tput or any other method?
shell-script text-processing terminal tput
1
tputdoesn'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 15the 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
add a comment |
I would like to position the cursor at a specific row/column and print a multi-line file/command that stays aligned to its first coordinate, so that
tput clear
tput cup 5 15
ping www.google.com
would output all subsequent lines in the 15th column. As it is, the first line prints correctly but the following lines are reset to the left. Is it possible using tput or any other method?
shell-script text-processing terminal tput
I would like to position the cursor at a specific row/column and print a multi-line file/command that stays aligned to its first coordinate, so that
tput clear
tput cup 5 15
ping www.google.com
would output all subsequent lines in the 15th column. As it is, the first line prints correctly but the following lines are reset to the left. Is it possible using tput or any other method?
shell-script text-processing terminal tput
shell-script text-processing terminal tput
edited Nov 17 '17 at 14:25
Jeff Schaller
41.4k1056131
41.4k1056131
asked Nov 17 '17 at 12:36
RadvanskyRadvansky
316
316
1
tputdoesn'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 15the 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
add a comment |
1
tputdoesn'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 15the 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
1
1
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 from tput 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
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 from tput 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
add a comment |
3 Answers
3
active
oldest
votes
One way to do it could be to set a tab stop at that position:
trap 'tabs -8' EXIT INT TERM # restore to default tab stops every 8 columns
# upon exit or signal
tput tbc # clear tab stops
tput cup 5 15
tput hts # set one and only tab stop
printf 'r' # move back to the beginning of the line
printf 't%sn' foo bar baz
ping www.google.com | paste /dev/null -
That does affect the behaviour of the terminal and could cause problems when suspended for instance.
Advantages over @Thor's cup based approach is that it sends less output (not really a concern unless you're on a 300 baud satellite link) and behaves more gracefully if some other process like syslog is also writing text to the terminal.
Another approach to makes sure each line starts at position 15, would be to prefix each line with r$(tput cuf 15):
tput cup 5 15
ping www.google.com | PREFIX=$(tput cr; tput cuf 15) awk '
{print ENVIRON["PREFIX"] $0}'
See also the csr capability to set a scrolling region.
If using zsh, see also its zcurses builtin
Both @thor answer and yours produce the result I was after. I was already commenting to ask how to implement the output of the ping command with your method when you edited the answer. As it is, it does seem a cleaner approach. Do you agree? By the way, what exactly does thetabs -8do?
– Radvansky
Nov 17 '17 at 14:44
@Radvansky, as seen in the comment, it restores the default tab stops. You may also want to add thattabs -8to a SIGINT/TERMtrapto make sure the tabs are restored if that script is interrupted. It's one way in that it's less "clean": it affects the behaviour of the terminal. That can also cause problems if the script is suspended for instance. It would not work afterstty -tabs(but people would only do that on terminals that don't support tabs in the first place anyway).
– Stéphane Chazelas
Nov 17 '17 at 14:52
add a comment |
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:
console-terminal-emulatorin the nosh toolset
- XTerm
- Tera Term
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;%dre[?69he[%d;%dse[?6he[H' 5 20 5 65although 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).
stty rows 15 columns 60
ping www.google.com
printf 'e[?6le[se[?69le[r'
stty rows 25 columns 80
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
VT420 Programmer Reference Manual. EK-VT420-RM-002. February 1992. Digital.
VT520/VT525 Video Terminal Programmer Information. EK-VT520-RM. July 1994. Digital.
Control Functions for Coded Character Sets. ECMA-48. 5th edition. 1991. ECMA International.
Information technology — Open Document Architecture (ODA) and interchange format: Document structures. T.412. International Telecommunication Union.
Information technology — Open Document Architecture (ODA) and interchange format: Character content architectures. T.416. International Telecommunication Union.
Information technology— Open Document Architecture (ODA) and Interchange Format: Character content architectures. ISO/IEC 8613-6:1994. International Organization for Standardization.- https://unix.stackexchange.com/a/289871/5132
- https://unix.stackexchange.com/a/243320/5132
+1: On OS X it works with iTerm2, but not with the built-in Terminal.
– Daniel
Mar 18 '18 at 22:27
add a comment |
Short answer: No.
However, you can simulate the effect by emitting a tput cup before every new line, e.g.:
i=5
tput clear
tput cup $i 15
ping google.com |
while read; do
tput cup $((++i)) 15
echo "$REPLY"
done
Or as a single "command":
i=5; tput clear; tput cup $i 15; ping google.com |
while read; do tput cup $((++i)) 15; echo "$REPLY"; done
Depending on how complicated your cursor manipulation is, you may want to implement it in ncurses. Another alternative might be Bash Simple Curses.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f405244%2fis-multi-line-alignment-possible-with-tput%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
One way to do it could be to set a tab stop at that position:
trap 'tabs -8' EXIT INT TERM # restore to default tab stops every 8 columns
# upon exit or signal
tput tbc # clear tab stops
tput cup 5 15
tput hts # set one and only tab stop
printf 'r' # move back to the beginning of the line
printf 't%sn' foo bar baz
ping www.google.com | paste /dev/null -
That does affect the behaviour of the terminal and could cause problems when suspended for instance.
Advantages over @Thor's cup based approach is that it sends less output (not really a concern unless you're on a 300 baud satellite link) and behaves more gracefully if some other process like syslog is also writing text to the terminal.
Another approach to makes sure each line starts at position 15, would be to prefix each line with r$(tput cuf 15):
tput cup 5 15
ping www.google.com | PREFIX=$(tput cr; tput cuf 15) awk '
{print ENVIRON["PREFIX"] $0}'
See also the csr capability to set a scrolling region.
If using zsh, see also its zcurses builtin
Both @thor answer and yours produce the result I was after. I was already commenting to ask how to implement the output of the ping command with your method when you edited the answer. As it is, it does seem a cleaner approach. Do you agree? By the way, what exactly does thetabs -8do?
– Radvansky
Nov 17 '17 at 14:44
@Radvansky, as seen in the comment, it restores the default tab stops. You may also want to add thattabs -8to a SIGINT/TERMtrapto make sure the tabs are restored if that script is interrupted. It's one way in that it's less "clean": it affects the behaviour of the terminal. That can also cause problems if the script is suspended for instance. It would not work afterstty -tabs(but people would only do that on terminals that don't support tabs in the first place anyway).
– Stéphane Chazelas
Nov 17 '17 at 14:52
add a comment |
One way to do it could be to set a tab stop at that position:
trap 'tabs -8' EXIT INT TERM # restore to default tab stops every 8 columns
# upon exit or signal
tput tbc # clear tab stops
tput cup 5 15
tput hts # set one and only tab stop
printf 'r' # move back to the beginning of the line
printf 't%sn' foo bar baz
ping www.google.com | paste /dev/null -
That does affect the behaviour of the terminal and could cause problems when suspended for instance.
Advantages over @Thor's cup based approach is that it sends less output (not really a concern unless you're on a 300 baud satellite link) and behaves more gracefully if some other process like syslog is also writing text to the terminal.
Another approach to makes sure each line starts at position 15, would be to prefix each line with r$(tput cuf 15):
tput cup 5 15
ping www.google.com | PREFIX=$(tput cr; tput cuf 15) awk '
{print ENVIRON["PREFIX"] $0}'
See also the csr capability to set a scrolling region.
If using zsh, see also its zcurses builtin
Both @thor answer and yours produce the result I was after. I was already commenting to ask how to implement the output of the ping command with your method when you edited the answer. As it is, it does seem a cleaner approach. Do you agree? By the way, what exactly does thetabs -8do?
– Radvansky
Nov 17 '17 at 14:44
@Radvansky, as seen in the comment, it restores the default tab stops. You may also want to add thattabs -8to a SIGINT/TERMtrapto make sure the tabs are restored if that script is interrupted. It's one way in that it's less "clean": it affects the behaviour of the terminal. That can also cause problems if the script is suspended for instance. It would not work afterstty -tabs(but people would only do that on terminals that don't support tabs in the first place anyway).
– Stéphane Chazelas
Nov 17 '17 at 14:52
add a comment |
One way to do it could be to set a tab stop at that position:
trap 'tabs -8' EXIT INT TERM # restore to default tab stops every 8 columns
# upon exit or signal
tput tbc # clear tab stops
tput cup 5 15
tput hts # set one and only tab stop
printf 'r' # move back to the beginning of the line
printf 't%sn' foo bar baz
ping www.google.com | paste /dev/null -
That does affect the behaviour of the terminal and could cause problems when suspended for instance.
Advantages over @Thor's cup based approach is that it sends less output (not really a concern unless you're on a 300 baud satellite link) and behaves more gracefully if some other process like syslog is also writing text to the terminal.
Another approach to makes sure each line starts at position 15, would be to prefix each line with r$(tput cuf 15):
tput cup 5 15
ping www.google.com | PREFIX=$(tput cr; tput cuf 15) awk '
{print ENVIRON["PREFIX"] $0}'
See also the csr capability to set a scrolling region.
If using zsh, see also its zcurses builtin
One way to do it could be to set a tab stop at that position:
trap 'tabs -8' EXIT INT TERM # restore to default tab stops every 8 columns
# upon exit or signal
tput tbc # clear tab stops
tput cup 5 15
tput hts # set one and only tab stop
printf 'r' # move back to the beginning of the line
printf 't%sn' foo bar baz
ping www.google.com | paste /dev/null -
That does affect the behaviour of the terminal and could cause problems when suspended for instance.
Advantages over @Thor's cup based approach is that it sends less output (not really a concern unless you're on a 300 baud satellite link) and behaves more gracefully if some other process like syslog is also writing text to the terminal.
Another approach to makes sure each line starts at position 15, would be to prefix each line with r$(tput cuf 15):
tput cup 5 15
ping www.google.com | PREFIX=$(tput cr; tput cuf 15) awk '
{print ENVIRON["PREFIX"] $0}'
See also the csr capability to set a scrolling region.
If using zsh, see also its zcurses builtin
edited Nov 17 '17 at 15:24
answered Nov 17 '17 at 14:22
Stéphane ChazelasStéphane Chazelas
305k57576930
305k57576930
Both @thor answer and yours produce the result I was after. I was already commenting to ask how to implement the output of the ping command with your method when you edited the answer. As it is, it does seem a cleaner approach. Do you agree? By the way, what exactly does thetabs -8do?
– Radvansky
Nov 17 '17 at 14:44
@Radvansky, as seen in the comment, it restores the default tab stops. You may also want to add thattabs -8to a SIGINT/TERMtrapto make sure the tabs are restored if that script is interrupted. It's one way in that it's less "clean": it affects the behaviour of the terminal. That can also cause problems if the script is suspended for instance. It would not work afterstty -tabs(but people would only do that on terminals that don't support tabs in the first place anyway).
– Stéphane Chazelas
Nov 17 '17 at 14:52
add a comment |
Both @thor answer and yours produce the result I was after. I was already commenting to ask how to implement the output of the ping command with your method when you edited the answer. As it is, it does seem a cleaner approach. Do you agree? By the way, what exactly does thetabs -8do?
– Radvansky
Nov 17 '17 at 14:44
@Radvansky, as seen in the comment, it restores the default tab stops. You may also want to add thattabs -8to a SIGINT/TERMtrapto make sure the tabs are restored if that script is interrupted. It's one way in that it's less "clean": it affects the behaviour of the terminal. That can also cause problems if the script is suspended for instance. It would not work afterstty -tabs(but people would only do that on terminals that don't support tabs in the first place anyway).
– Stéphane Chazelas
Nov 17 '17 at 14:52
Both @thor answer and yours produce the result I was after. I was already commenting to ask how to implement the output of the ping command with your method when you edited the answer. As it is, it does seem a cleaner approach. Do you agree? By the way, what exactly does the
tabs -8 do?– Radvansky
Nov 17 '17 at 14:44
Both @thor answer and yours produce the result I was after. I was already commenting to ask how to implement the output of the ping command with your method when you edited the answer. As it is, it does seem a cleaner approach. Do you agree? By the way, what exactly does the
tabs -8 do?– Radvansky
Nov 17 '17 at 14:44
@Radvansky, as seen in the comment, it restores the default tab stops. You may also want to add that
tabs -8 to a SIGINT/TERM trap to make sure the tabs are restored if that script is interrupted. It's one way in that it's less "clean": it affects the behaviour of the terminal. That can also cause problems if the script is suspended for instance. It would not work after stty -tabs (but people would only do that on terminals that don't support tabs in the first place anyway).– Stéphane Chazelas
Nov 17 '17 at 14:52
@Radvansky, as seen in the comment, it restores the default tab stops. You may also want to add that
tabs -8 to a SIGINT/TERM trap to make sure the tabs are restored if that script is interrupted. It's one way in that it's less "clean": it affects the behaviour of the terminal. That can also cause problems if the script is suspended for instance. It would not work after stty -tabs (but people would only do that on terminals that don't support tabs in the first place anyway).– Stéphane Chazelas
Nov 17 '17 at 14:52
add a comment |
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:
console-terminal-emulatorin the nosh toolset
- XTerm
- Tera Term
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;%dre[?69he[%d;%dse[?6he[H' 5 20 5 65although 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).
stty rows 15 columns 60
ping www.google.com
printf 'e[?6le[se[?69le[r'
stty rows 25 columns 80
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
VT420 Programmer Reference Manual. EK-VT420-RM-002. February 1992. Digital.
VT520/VT525 Video Terminal Programmer Information. EK-VT520-RM. July 1994. Digital.
Control Functions for Coded Character Sets. ECMA-48. 5th edition. 1991. ECMA International.
Information technology — Open Document Architecture (ODA) and interchange format: Document structures. T.412. International Telecommunication Union.
Information technology — Open Document Architecture (ODA) and interchange format: Character content architectures. T.416. International Telecommunication Union.
Information technology— Open Document Architecture (ODA) and Interchange Format: Character content architectures. ISO/IEC 8613-6:1994. International Organization for Standardization.- https://unix.stackexchange.com/a/289871/5132
- https://unix.stackexchange.com/a/243320/5132
+1: On OS X it works with iTerm2, but not with the built-in Terminal.
– Daniel
Mar 18 '18 at 22:27
add a comment |
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:
console-terminal-emulatorin the nosh toolset
- XTerm
- Tera Term
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;%dre[?69he[%d;%dse[?6he[H' 5 20 5 65although 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).
stty rows 15 columns 60
ping www.google.com
printf 'e[?6le[se[?69le[r'
stty rows 25 columns 80
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
VT420 Programmer Reference Manual. EK-VT420-RM-002. February 1992. Digital.
VT520/VT525 Video Terminal Programmer Information. EK-VT520-RM. July 1994. Digital.
Control Functions for Coded Character Sets. ECMA-48. 5th edition. 1991. ECMA International.
Information technology — Open Document Architecture (ODA) and interchange format: Document structures. T.412. International Telecommunication Union.
Information technology — Open Document Architecture (ODA) and interchange format: Character content architectures. T.416. International Telecommunication Union.
Information technology— Open Document Architecture (ODA) and Interchange Format: Character content architectures. ISO/IEC 8613-6:1994. International Organization for Standardization.- https://unix.stackexchange.com/a/289871/5132
- https://unix.stackexchange.com/a/243320/5132
+1: On OS X it works with iTerm2, but not with the built-in Terminal.
– Daniel
Mar 18 '18 at 22:27
add a comment |
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:
console-terminal-emulatorin the nosh toolset
- XTerm
- Tera Term
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;%dre[?69he[%d;%dse[?6he[H' 5 20 5 65although 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).
stty rows 15 columns 60
ping www.google.com
printf 'e[?6le[se[?69le[r'
stty rows 25 columns 80
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
VT420 Programmer Reference Manual. EK-VT420-RM-002. February 1992. Digital.
VT520/VT525 Video Terminal Programmer Information. EK-VT520-RM. July 1994. Digital.
Control Functions for Coded Character Sets. ECMA-48. 5th edition. 1991. ECMA International.
Information technology — Open Document Architecture (ODA) and interchange format: Document structures. T.412. International Telecommunication Union.
Information technology — Open Document Architecture (ODA) and interchange format: Character content architectures. T.416. International Telecommunication Union.
Information technology— Open Document Architecture (ODA) and Interchange Format: Character content architectures. ISO/IEC 8613-6:1994. International Organization for Standardization.- https://unix.stackexchange.com/a/289871/5132
- https://unix.stackexchange.com/a/243320/5132
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:
console-terminal-emulatorin the nosh toolset
- XTerm
- Tera Term
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;%dre[?69he[%d;%dse[?6he[H' 5 20 5 65although 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).
stty rows 15 columns 60
ping www.google.com
printf 'e[?6le[se[?69le[r'
stty rows 25 columns 80
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
VT420 Programmer Reference Manual. EK-VT420-RM-002. February 1992. Digital.
VT520/VT525 Video Terminal Programmer Information. EK-VT520-RM. July 1994. Digital.
Control Functions for Coded Character Sets. ECMA-48. 5th edition. 1991. ECMA International.
Information technology — Open Document Architecture (ODA) and interchange format: Document structures. T.412. International Telecommunication Union.
Information technology — Open Document Architecture (ODA) and interchange format: Character content architectures. T.416. International Telecommunication Union.
Information technology— Open Document Architecture (ODA) and Interchange Format: Character content architectures. ISO/IEC 8613-6:1994. International Organization for Standardization.- https://unix.stackexchange.com/a/289871/5132
- https://unix.stackexchange.com/a/243320/5132
edited Feb 2 at 19:54
answered Nov 18 '17 at 9:14
JdeBPJdeBP
34.9k470163
34.9k470163
+1: On OS X it works with iTerm2, but not with the built-in Terminal.
– Daniel
Mar 18 '18 at 22:27
add a comment |
+1: On OS X it works with iTerm2, but not with the built-in Terminal.
– Daniel
Mar 18 '18 at 22:27
+1: On OS X it works with iTerm2, but not with the built-in Terminal.
– Daniel
Mar 18 '18 at 22:27
+1: On OS X it works with iTerm2, but not with the built-in Terminal.
– Daniel
Mar 18 '18 at 22:27
add a comment |
Short answer: No.
However, you can simulate the effect by emitting a tput cup before every new line, e.g.:
i=5
tput clear
tput cup $i 15
ping google.com |
while read; do
tput cup $((++i)) 15
echo "$REPLY"
done
Or as a single "command":
i=5; tput clear; tput cup $i 15; ping google.com |
while read; do tput cup $((++i)) 15; echo "$REPLY"; done
Depending on how complicated your cursor manipulation is, you may want to implement it in ncurses. Another alternative might be Bash Simple Curses.
add a comment |
Short answer: No.
However, you can simulate the effect by emitting a tput cup before every new line, e.g.:
i=5
tput clear
tput cup $i 15
ping google.com |
while read; do
tput cup $((++i)) 15
echo "$REPLY"
done
Or as a single "command":
i=5; tput clear; tput cup $i 15; ping google.com |
while read; do tput cup $((++i)) 15; echo "$REPLY"; done
Depending on how complicated your cursor manipulation is, you may want to implement it in ncurses. Another alternative might be Bash Simple Curses.
add a comment |
Short answer: No.
However, you can simulate the effect by emitting a tput cup before every new line, e.g.:
i=5
tput clear
tput cup $i 15
ping google.com |
while read; do
tput cup $((++i)) 15
echo "$REPLY"
done
Or as a single "command":
i=5; tput clear; tput cup $i 15; ping google.com |
while read; do tput cup $((++i)) 15; echo "$REPLY"; done
Depending on how complicated your cursor manipulation is, you may want to implement it in ncurses. Another alternative might be Bash Simple Curses.
Short answer: No.
However, you can simulate the effect by emitting a tput cup before every new line, e.g.:
i=5
tput clear
tput cup $i 15
ping google.com |
while read; do
tput cup $((++i)) 15
echo "$REPLY"
done
Or as a single "command":
i=5; tput clear; tput cup $i 15; ping google.com |
while read; do tput cup $((++i)) 15; echo "$REPLY"; done
Depending on how complicated your cursor manipulation is, you may want to implement it in ncurses. Another alternative might be Bash Simple Curses.
edited Nov 17 '17 at 14:28
answered Nov 17 '17 at 14:08
ThorThor
11.8k13459
11.8k13459
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f405244%2fis-multi-line-alignment-possible-with-tput%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
tputdoesn'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 15the 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