Is multi-line alignment possible with tput?












2















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?










share|improve this question




















  • 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
















2















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?










share|improve this question




















  • 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














2












2








2








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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 17 '17 at 14:25









Jeff Schaller

41.4k1056131




41.4k1056131










asked Nov 17 '17 at 12:36









RadvanskyRadvansky

316




316








  • 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














  • 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








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










3 Answers
3






active

oldest

votes


















3














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






share|improve this answer


























  • 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





















2














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-emulator in 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 65
stty rows 15 columns 60
ping www.google.com
printf 'e[?6le[se[?69le[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





  • 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






share|improve this answer


























  • +1: On OS X it works with iTerm2, but not with the built-in Terminal.

    – Daniel
    Mar 18 '18 at 22:27



















0














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.






share|improve this answer

























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    3














    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






    share|improve this answer


























    • 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


















    3














    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






    share|improve this answer


























    • 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
















    3












    3








    3







    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






    share|improve this answer















    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







    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 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





















    • 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



















    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















    2














    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-emulator in 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 65
    stty rows 15 columns 60
    ping www.google.com
    printf 'e[?6le[se[?69le[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





    • 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






    share|improve this answer


























    • +1: On OS X it works with iTerm2, but not with the built-in Terminal.

      – Daniel
      Mar 18 '18 at 22:27
















    2














    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-emulator in 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 65
    stty rows 15 columns 60
    ping www.google.com
    printf 'e[?6le[se[?69le[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





    • 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






    share|improve this answer


























    • +1: On OS X it works with iTerm2, but not with the built-in Terminal.

      – Daniel
      Mar 18 '18 at 22:27














    2












    2








    2







    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-emulator in 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 65
    stty rows 15 columns 60
    ping www.google.com
    printf 'e[?6le[se[?69le[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





    • 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






    share|improve this answer















    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-emulator in 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 65
    stty rows 15 columns 60
    ping www.google.com
    printf 'e[?6le[se[?69le[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





    • 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







    share|improve this answer














    share|improve this answer



    share|improve this answer








    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



















    • +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











    0














    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.






    share|improve this answer






























      0














      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.






      share|improve this answer




























        0












        0








        0







        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.






        share|improve this answer















        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.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 17 '17 at 14:28

























        answered Nov 17 '17 at 14:08









        ThorThor

        11.8k13459




        11.8k13459






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            How to make a Squid Proxy server?

            第一次世界大戦

            Touch on Surface Book