VT100 positioning outside of the terminal's window - terminal

Some time ago I designed the telnet client, having 80*24 window size. Now I have a bug report, and it became clear that server positions the cursor out of the window - at the line 25. My client displays black lines, while Windows telnet seems to skip number of lines required to position to the desired line - in this case - automatically adds 25-24=1 blank line, and sets cursor at the last line 24 before displaying anything else.
I can not find any information how telnet client must behave when server positions cursor out of the window using Esc [ Line;Column H or Esc [ Line;Column f. All the sources I researched just state something like "Moves the cursor to row n, column m. The values are 1-based, and default to 1 (top left corner) if omitted."

Related

Stop XTerm from moving text upwards on window resize, when cursor is at last row?

In the Alternate Screen Buffer mode in XTerm-like terminal emulators, when the cursor is on the last row and the terminal window is resized so that it has less rows, all text in the terminal is shifted upwards.
Can anyone point me to what is going on here? I can't find any related escape sequences to turn this behavior off, or any way to intercept SIGWINCH to move the cursor before the shift happens. It seems like it may be related to scrolling to keep the cursor on the screen.
I'd really like the screen display to not change, even if the cursor is no longer on screen after a resize.
I'm not using ncurses or other libraries, just escape sequences and system calls.

Space tab mystery, in git vs vim

I am on Ubuntu and use Gvim. Based on my understanding,I have set tab to expand to 4 spaces. I did not even touch the line that has create_namespace but git diff shows it as shifted by a character. It seems perfectly fine in the editor or when I run cat. Same issue is when I added a new line of txt cluster_token and it shows as shifted by a character in git diff. I have wasted hours trying to understand this silly issue but no clue. What is the issue and how do I fix it?
- echo "--create_namespace"
+ echo "--create_namespace" //Did not even touch this line
echo "--all"
echo "--custom_merge_pipeline_commands"
+ echo "--cluster_token" //Looks fine in editor
If this is TL;DR, skip down to the bolded text below.
As I noted in a comment, the issue of spaces vs tabs sets off flame wars, so I'm going to attempt to be completely neutral on the subject. (Note: I did say attempt. :-) ) It's also worth covering a bit of history, i.e., how we got here in the first place. Also, there is an entirely separate, though currently beta, StackExchange web site devoted to vi / vim at https://vi.stackexchange.com/ so I am not going to get into the many vim settings available here.
First, note that tabs go back to the days of mechanical typewriters (well, probably even before then).
Different models had different features, but most had a key labeled TAB that, when pressed, caused the platen—the rubber roller that holds the paper—to slide leftward (assuming a Western-style, left-to-right carriage typewriter) from its current position to the next tab stop. Tab stops were set mechanically, since all of this was run by wires and springs. Since the type bars would always strike the paper at the center where the ribbon was held against the paper, sliding the platen leftward has the effect of making the next character come out somewhere to the right. How far to the right, depends on the current column and, of course, the tab stop settings.
Early computer interfaces used or emulated mechanical typewriters—well, more precisely, teletype interrfaces—sometimes complete with the exact same mechanically-controlled tab stops. When glass ttys came out, they tended to emulate the existing TTYs. Over time, the terminals got smarter, to the point where some had software-adjustable tab stops.
Others, however, limited tab stops in software to simply "every N columns", where N was variable. DEC chose 10 for some of their early systems, but 8 proved more popular and became the default. Here, sending an ASCII TAB (code 9 decimal) byte to the display terminal caused the terminal to move the cursor from whichever column it was in now, to one up-to-but-not-exceeding N (usually 8) characters to the right. (The behavior of a cursor close to the end of the physical screen line varied, and still varies in software emulations, but the VT100 behavior is pretty common now.)
We no longer use any of these bits of hardware—at least, not commonly—but we do emulate them. Pressing the TAB key in an editor tends to move the cursor to "the next tab stop", wherever that may be. Terminal emulators will emulate whatever terminal—often, again, the VT100, which has variable tab stops (set via escape sequences) but defaults to every eighth column (columns 9, 17, 25, and so on, if we number the first column 1—as is traditional—instead of the proper mathematical column zero :-) ).
For storing text in files, however, there is an option: we can store the literal ASCII TAB character (or the Unicode equivalent which is U+0009), or we can store however many spaces it might take to get to the selected column. If we store a literal TAB, it is up to whatever it is that displays the file to choose which column is the desired column. If we store literal space characters, whatever is displaying the file must display that many space characters.1 The effect is that if we store literal TABs, the display depends on previous output (since the cursor column depends on previous output), but if we store literal spaces, it does not.
Meanwhile, when git diff displays lines, it inserts one character in front of each line. If the line being displayed starts with a literal TAB followed by the word old, what happens is that git diff writes a space or plus or minus character, then a TAB, then the next character. Assuming your terminal has its tab-stops at columns 9, 17, 25, and so on, the character after the TAB shows up in column 9:
0 1
1234567890123456789
- old
If, on the other hand, the line in the file starts with eight spaces followed by the word new, what you see is the git diff character, then eight spaces, then the word in column 10:
0 1
1234567890123456789
+ new
Stacking these atop one another we get:
0 1
1234567890123456789
- old
+ new
which is what you are seeing. This means that your claim:
- echo "--create_namespace"
+ echo "--create_namespace" //Did not even touch this line
is at best half-true: you might not have touched the line, but your editor did. It replaced at least one literal TAB character with spaces. (We cannot tell from here how many such characters were changed—perhaps, for instance, it replaced one TAB with four spaces, leaving four existing spaces in place, if you have everything rigged up to use columns 5, 9, 13, 17, and so on.)
1It is now time to avoid an entire separate aside on fixed vs variable pitch fonts. :-)

How to disable the console cursor from moving automatically

Situation:
I am crating an console application for windows using rust. Fore that I use winapi and kernel32.
Lets say my cursor position within the console is at 4,4 (X,Y) then I print an character like print!("#"); at position 4,4. Then the console automatically moves the cursor one to the right 5,4 for the next character to be printed there.
Question
Is it possible to prevent this default behavior, and have the cursor stay at 4,4 instead of moving to the next cell, usingwinapi/kernel32? What I mean by that is that the console should not change cursor position in any case until I manually tell the console to change the cursor position to another cell.
Example or solution maybe in any language.

Terminal - clear half screen

I know that using cmd + K can clear the entire screen buffer.
I am wondering is there a way to just clear half of the screen buffer?
cmd+K maps to the menu item for clearing the visible screen (the screen buffer). That does not include the scrollback (it is a similar question, but different).
iTerm2's preferences and menu do not show any direct way to clear half of the screen.
However, iTerm2 emulates (like Terminal.app) most of the VT100 control sequences. You could add a binding in your shell which (given a suitable key of your choice) tells the shell to echo a control sequence which clears from the current cursor position (a) until the beginning of the screen or (b) to the end of the screen. Since it honors the save/restore cursor controls, you could even make it clear exactly half of the screen if you know the size, e.g.,
save the cursor position
jump to the middle of the screen
clear (which half?) half of the screen
restore the cursor position
Since it would use your shell, I called that indirect.
As noted, Terminal.app implements most of the VT100 control sequences. In ncurses, the appropriate TERM would be nsterm which is known to provide the VT100-style save/restore cursor. You can use tput to extract the corresponding strings for sc, rc and cup from the terminal database. However (if you wanted to erase to the beginning of the screen), you would provide your own string, since that particular flavor is not part of termcap/terminfo.
You can find the relevant VT100 control sequences documented in XTerm Control Sequences:
ESC 7 Save Cursor (DECSC).
ESC 8 Restore Cursor (DECRC).
CSI Ps ; Ps H
Cursor Position [row;column] (default = [1,1]) (CUP).
CSI Ps J Erase in Display (ED).
Ps = 0 -> Erase Below (default).
Ps = 1 -> Erase Above.
Ps = 2 -> Erase All.
Ps = 3 -> Erase Saved Lines (xterm).
Refering answer
# Get ceiling eg: 7/2 = 4
ceiling_divide() {
ceiling_result=$((($1+$2-1)/$2))
}
clear_rows() {
POS=$1
# Insert Empty Rows to push & preserve the content of screen
for i in {1..$((LINES-POS-1))}; echo
# Move to POS, after clearing content from POS to end of screen
tput cup $((POS-1)) 0
}
# Clear quarter
alias ptop='ceiling_divide $LINES 4; clear_rows $ceiling_result'
# Clear half
alias pmid='ceiling_divide $LINES 2; clear_rows $ceiling_result'
# Clear 3/4th
alias pdown='ceiling_divide $((3*LINES)) 4; clear_rows $ceiling_result'

Unable to turn off automatic margins by termcap in Mac

I need to turn automatic margins off according the following statement from Screen's manual in my Mac
If your terminal is a "true"
auto-margin terminal (it doesn't allow
the last position on the screen
to be updated without scrolling the screen) consider using a version
of your terminal's termcap that
has automatic margins turned off.
How can you turn automatic margins off by your terminal's termcap?
Most terminal emulators, including the mac default terminal, are not "true auto-margin terminals" in the sense being discussed here - they emulate a vt100-series terminal, which had "smart" wraparound. You can check by running cat and typing to the end of the last line - after you type the last character, the cursor remains at the end of the line (highlighting the character you just typed) until you type another character.
The only consequence of a 'true auto-margin terminal' is that a character cannot be displayed in the lower right hand corner (though some programs are able to work around that by shifting a character into place with ich/ich1)
According to XTerm Control Sequences, this sequence should do what was asked:
CSI ? 7 l
That is,
printf '\033[?7l'
The 7 is documented as
Ps = 7 -> Wraparound Mode (DECAWM).
and the final character l (lowercase L) denotes this as a reset rather than a set control.
For whatever reason, the terminfo name for this is more obscure: "automatic margins". These terminfo capabilities deal with the feature (see terminfo(5)):
auto_right_margin am am terminal has auto‐
matic margins
enter_am_mode smam SA turn on automatic
margins
exit_am_mode rmam RA turn off automatic
margins
Interestingly, the vt100-nam terminal description in ncurses (which apparently no one uses) initializes the terminal to use automargins margins using this string:
rs2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h,
(the \E[?7h sets it), and asserts that the terminal does not use automatic margins by cancelling am. It also has the terminfo capabilities rmam and smam. So you could do this to prove that it works:
tput rmam
stty columns 999
ps -efwwwwwl
and (for the ordinary user) see the ps listing nicely truncated against the right margin of the terminal window.
The other variants vt220-nam and vt320-nam appear correct...
By the way, for Mac, you would use the terminfo names such as rmcup rather than the termcap RA, because OSX uses ncurses' tput (terminfo) rather than the BSD variant.
Further reading:
tput, reset - initialize a terminal or query terminfo
database
history section for tput
history section for tset
Occasionally someone asks about suppressing automargins because they suppose that terminals can pan/scroll left/right to show the information which was not wrapped to a new line. Terminals which do this are rare, and OSX Terminal is not one of those. It behaves like a subset of xterm, which itself emulates the series of DEC terminals vt52/vt100/vt220/etc. In this question, OP is concerned/confused about this paragraph from the screen manual:
If your terminal is a "true" auto-margin terminal (it doesn't allow the
last position on the screen to be updated without scrolling the screen)
consider using a version of your terminal's termcap that has automatic
margins turned off. This will ensure an accurate and optimal update of
the screen in all circumstances. Most terminals nowadays have "magic"
margins (automatic margins plus usable last column). This is the VT100
style type and perfectly suited for screen. If all you've got is a
"true" auto-margin terminal screen will be content to use it, but
updating a character put into the last position on the screen may not
be possible until the screen scrolls or the character is moved into a
safe position in some other way. This delay can be shortened by using a
terminal with insert-character capability.
That last position on the screen refers to the lower-right corner of the terminal. In the normal case, if your cursor is on the lower-right corner and you print a character, you would expect the display to scroll up by one line and show the character on the next line. Also (because terminals can be implemented in different ways), some could scroll up when you print a character in the last position. The VT100 does not do this. Not only does it not scroll up in that case, but it ignores non-printing characters while on the margin (see xterm FAQ That description of wrapping is odd, say more?). There is a terminfo flag xenl which is set to show when the terminal does this special behavior. About a third of the terminal descriptions in the terminal database have this flag. While most of those are for terminals which you likely will never encounter, keep in mind that the advice in the manual page was written back in an era when those other terminals were as likely to be found as a VT100-lookalike. The early change-history for screen is poor, but the text was in screen's second posting to Usenet in 1992. The initial posting in 1987 said something similar:
Screen
never writes in the last position of the screen, unless the boolean
capability LP is found in the termcap entry of the terminal.
Usually,
screen
cannot predict whether or not a particular terminal scrolls when
a character is written in the last column of the last line;
LP indicates that it is safe to write in this position.
Note that the LP capability is independent of am (automatic
margins); for certain terminals, such as the VT100, it is reasonable
to set am as well as LP in the corresponding termcap entry
(the VT100 does not move the cursor when a character is written in
the last column of each line).
The later wording reflects the fact that the terminfo system was prevalent, and the name LP was not termcap name chosen for corresponding with xenl (it is xn).
The point of all of this is that screen attempts to convert between programs writing to different terminal types and make them all appear like one type of terminal — which means that it tries to put text on the terminal's display in all of the locations. The lower-right corner is a problem because some terminals would scroll up, spoiling the attempt to write there. As a workaround, some terminals provided an alternative:
using a different mode (insert),
put the cursor on the next to last position of the display,
write characters to fill in, pushing a character into the last position, and
turn insert-mode off once it is done (otherwise a nuisance).
About two thirds of the descriptions in the terminal database have the capability to do this insert-mode (smir). That still was not perfect, but it certainly was worth mentioning in 1992. About a quarter implement a similar similar feature ich1. Some implement both (and vi could get confused by those, by trying to do both methods).
VT100-lookalikes provide a third way to write that last position; screen checks for and uses whatever is there.
If I understand you correctly you're looking to set the autowrap feature to NO using terminfo database. If so I believe you can use the -nam flag to turn it off - something like vt100-nam should do it. You can also check by looking at the man pages for terminfo.
If this solves your question, mark this up. (^_^) If not... well comment back and I'll check again for you. Cheers!
Update: There's also a shortcut that may apply to you to toggle the wrap off and on. Check out the shortcut sheet here. And additional information for Screen can be found here (search for wrap). You can also check here on how to use setterm (section 17.14 Changing the Terminal Settings). Also check here for examples of changing settings.
Good luck again. (^_^)

Resources