New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tab behavior in console apps #629

Closed
muesli opened this Issue Mar 10, 2018 · 3 comments

Comments

Projects
None yet
3 participants
@muesli
Contributor

muesli commented Mar 10, 2018

When a terminal app asks me for input and I press tab, it adds 4 spaces (as expected).
If I press backspace now, it will only remove one space visually (the cursor jumps to the left by 1 character, but 3 spaces remain), but it actually deletes the entire tab logically.

This doesn't happen if I start the same app with bash: here backspace deletes all 4 spaces.

Note: this only seems to happen the first time an app expects user-input. The second time around it works as expected.

@krader1961

This comment has been minimized.

krader1961 commented Mar 11, 2018

I had to read the problem statement a couple of times before I understood the issue. The first thing to note is this has nothing to do with whether your terminal or app has tab stops every 4 or 8 spaces. The second thing is that the unexpected behavior occurs with other shells such as fish.

It helps to use a concrete example since phrases like "terminal app" could mean practically anything. The easiest way to reproduce the problem is to use cat | cat -evt. The pipe into cat -evt is to make it clear whether or not the tab has been removed (or replaced by spaces) regardless of what you see in the terminal. Using the script command is also useful to capture everything written to the terminal.

Run script x elvish, then press [tab], [backspace], [enter], [ctrl-d], [ctrl-d]. Then run cat -evt x to see the contents of the captured output. This is the relevant portion:

[17C^[[?25h^M$
^[[?7h^[[?2004l^I^H^H^H^H^H^M$
$^M$

The first line is the point where you pressed [enter] after typing the cat | cat -evt command. The next line shows a couple of escape sequences written by elvish followed by the [tab] key and the result of pressing [backspace]. The multiple ^H ([ctrl-h]) chars you see are because the OS tty driver is trying to move the cursor to where it was before [tab] was pressed. It outputs the wrong number (five instead of eight) because it thinks you already typed eleven (8 + 3) characters. Why does it think that? Look at what appears on the line before the ^I (tab) char: ^[[?7h^[[?2004. If you ignore the two escape (^[) chars like the tty driver you'll see there are eleven chars. The OS tty driver thinks you typed those chars. It doesn't know they're ANSI escape sequences which don't affect the cursor position.

Now do the same experiment only starting with script x bash:

bash-4.4$ cat | cat -evt^M$
^I^H^H^H^H^H^H^H^H^M$
$^M$

Notice the absence of ANSI escape sequences. This means that after the ^M (carriage-return) on the first line the OS tty driver thinks the cursor is in column one rather than column twelve.

The solution is to output a carriage-return after the escape sequences to reset the terminal state. The carriage return will cause the tty driver to think the cursor is in column one but should otherwise have no other effect.

@muesli

This comment has been minimized.

Contributor

muesli commented Mar 11, 2018

@krader1961 Sorry for the crude description, I merely pasted it together from an IRC discussion we had yesterday. Thanks for the detailed analysis!

@xiaq xiaq added the type:bug label Mar 12, 2018

@xiaq

This comment has been minimized.

Member

xiaq commented Mar 12, 2018

@krader1961 Thank you for the excellent analysis!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment