Skip to content
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

Reverse wraparound #2724

Merged
merged 18 commits into from May 3, 2020
Merged

Reverse wraparound #2724

merged 18 commits into from May 3, 2020

Conversation

jerch
Copy link
Member

@jerch jerch commented Feb 16, 2020

There are a few things to consider, see @egmontkob's listing here: https://gitlab.gnome.org/GNOME/vte/issues/62

Basic implementation is done. I had to disable the _restrictCursor() call, which is abit unfortunate. This needs further investigation and is prolly related to our weird way of handling pending wraps. Turns out that xterm allows the last cell to be deleted if reverse wrap-around is set, otherwise not. Fixed.

Furthermore this PR revealed another bug - the last char before EOL is not shown under the "sticky" cursor, prolly the renderer does not take the char into account under the cursor in that position (data is correct in buffer).

Another bug: we currently dont clear cells to the right when early wraparound happens. Fixed.

TODO:

Closes #2716.

@jerch jerch self-assigned this Feb 16, 2020
@jerch jerch added area/parser type/enhancement Features or improvements to existing features labels Feb 16, 2020
@jerch
Copy link
Member Author

jerch commented Feb 17, 2020

Update: Eww, reverse wrap-around does some weird things on xterm - any cursor movement sequence does not respect grid borders anymore, instead the cursor wraps as well. Not sure why it was made like this, it leads to a totally different behavior for all of those sequences. DECAWM does not do this, from a "rule of least surprise" i'd call this behavior flawed. Ofc this is a bold statement since it seems to be an xterm feature originally. Still it changes the way the terminal content gets addressed, I think we should not follow that path.

Suggestion, up for discussion:

  • limit reverse wrap-around to soft NLs (can only happen in a line, that was wrapped beforehand)
  • always stop at hard NLs
  • within a line BS should act as it would normally w'o reverse wrap-around set
  • cursor movement sequences do not change anything:
    • they are bound to top/bottom/left/right and cannot pass these borders
    • a following BS would be eval'ed within the new position and apply the rules above
    • cursor jumps into an empty line "realize" that line up to the new cursor position, line itself is treated as not wrapped (cursor cannot pass into prev line)
  • scrollborders should work/respected as with DECAWM

This is more in line how DECAWM works and makes reverse wrap-around kinda the opposite/undo action.

FYI: @Tyriar, @egmontkob

@egmontkob
Copy link

limit reverse wrap-around to soft NLs

This is what tmux does, and is probably the most reasonable behavior.

@jerch
Copy link
Member Author

jerch commented Feb 18, 2020

@egmontkob Thx for your feedback. Yes I think so too, seems to be much more reasonable than altering the behavior of 50% of the common terminal sequences. Though I wonder why xterm did it this way in the first place (pros/cons compared to a stricter "DECAWM reverse") and whether there is some significant usage in the wild with that odd behavior. Not sure if it is worth to be brought up in terminal-wg...

FYI: @textshell

@jerch
Copy link
Member Author

jerch commented Feb 21, 2020

@Tyriar Done with the implementation and tests. Up for review.

Btw, you can test the difference with the following:

  • enable reverse wrap with echo -e "\x1b[?45h"
  • run cat in terminal
  • input some longish stuff over several lines w'o pressing enter
  • use BS to delete chars from the end:
    • before: would always stop at cursor.x == 0
    • this PR: soft wraps can be deleted into the previous line

@jerch jerch marked this pull request as ready for review February 21, 2020 17:38
backspace added a commit to hashicorp/nomad that referenced this pull request Mar 10, 2020
Excitingly enough, @jerch has made this PR in response to
my feature request for reverse-wraparound mode, which
obviates me having to add mediocre implementation of it:
xtermjs/xterm.js#2724
backspace added a commit to hashicorp/nomad that referenced this pull request Mar 10, 2020
Excitingly enough, @jerch has made this PR in response to
my feature request for reverse-wraparound mode, which
obviates me having to add mediocre implementation of it:
xtermjs/xterm.js#2724
@Tyriar
Copy link
Member

Tyriar commented Apr 10, 2020

Btw, you can test the difference with the following:

@jerch I don't see any difference with this branch and master when doing this? 😕

@jerch
Copy link
Member Author

jerch commented Apr 11, 2020

@jerch I don't see any difference with this branch and master when doing this?

Oh thats weird. Maybe you are "holding it wrong" 😸 Here are the exact steps to repro the difference:

  • switch on reverse-wrap with echo -e "\x1b[?45h"
  • open cat in demo
  • hold down some character key until it fills more than one line (thus wrapped at least once)
  • dont press Enter
  • hold down <--:
    • before: deleting chars would always stop at the beginning of the current cursor line
    • this PR: deleting wraps back into prev line up to last '\n' or top-left of the viewport

@Tyriar
Copy link
Member

Tyriar commented Apr 11, 2020

@jerch oh I ran cat README.md 😅, I see it now

src/InputHandler.ts Outdated Show resolved Hide resolved
src/InputHandler.ts Outdated Show resolved Hide resolved
* reverse wrap-around:
* Our implementation deviates from xterm on purpose. Details:
* - only previous soft NLs can be reversed (isWrapped=true)
* - only works within scrollborders (top/bottom, left/right not yet supported)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet supported? Do we need to note this in vt features?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think so, we dont support left/right scroll margins at all atm, it is still on the TODO list of missing vt features. The comment is more a reminder to cover it here as well once we implement it (which is abit more involved, as it needs to be respected in several vt commands, nothing to deal with here).

src/InputHandler.ts Outdated Show resolved Hide resolved
src/InputHandler.ts Outdated Show resolved Hide resolved
assert.equal(bufferService.buffer.x, 0);
});
/*
it.only('should not reverse outside of scroll margins', () => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Tyriar I cannot get this test working anymore without TestTerminal, seems the scrollback is not respected at all. Any clue why?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, move it over here:

describe('Terminal InputHandler integration', () => {
function getLines(term: TestTerminal, limit: number = term.rows): string[] {
const res: string[] = [];
for (let i = 0; i < limit; ++i) {
res.push(term.buffer.lines.get(i)!.translateToString(true));
}
return res;
}
// This suite cannot live in InputHandler unless Terminal.scroll moved into IBufferService

Terminal still owns scroll, scroll should probably live into BufferService and then Terminal reacts to it via an event. Created #2881 for this

@Tyriar
Copy link
Member

Tyriar commented Apr 27, 2020

I'll give this another review and hopefully merge next week 😃

@Tyriar Tyriar added this to the 4.6.0 milestone Apr 27, 2020
Copy link
Member

@Tyriar Tyriar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works great and well tested 👌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/parser type/enhancement Features or improvements to existing features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support reverse-wraparound mode?
3 participants