Skip to content

Commit e33fdba

Browse files
committed
Move displaced line of top-anchored scroll region into scroll-back
Full-screen CLIs such as Codex in --no-alt-screen mode render through DECSTBM scroll regions anchored at the top of the screen and scroll by emitting newlines at the region bottom. VT100EmulatorBackend scrolled such a region in place and discarded the displaced top line, so no scroll-back history was created and the output could not be scrolled backwards. Like xterm and VTE, a newline at the bottom of a scroll region whose top margin is the top of the screen now moves the displaced top line into the scroll-back history, while the lines below the region keep their position on the screen. Scroll regions with a top margin below the top of the screen still scroll in place and discard the top line. The characterization test documenting the old behavior is flipped to assert that the history is created; the remaining scrolling guards are unchanged. #2680
1 parent c385363 commit e33fdba

2 files changed

Lines changed: 38 additions & 19 deletions

File tree

terminal/bundles/org.eclipse.terminal.control/src/org/eclipse/terminal/internal/emulator/VT100EmulatorBackend.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,11 @@ private int doLineWrap() {
354354
*/
355355
private void doNewline() {
356356
if (fCursorLine == fScrollRegion.getBottomLine()) {
357-
scrollUp(1);
357+
if (fScrollRegion.getTopLine() == 0) {
358+
scrollTopAnchoredRegionUpIntoHistory();
359+
} else {
360+
scrollUp(1);
361+
}
358362
} else if (fCursorLine + 1 >= fLines) {
359363
int h = fTerminal.getHeight();
360364
fTerminal.addLine();
@@ -366,6 +370,26 @@ private void doNewline() {
366370
}
367371
}
368372

373+
/**
374+
* Scrolls a scroll region whose top margin is the top of the screen: the displaced top line
375+
* is moved into the scroll-back history (like xterm/VTE) instead of being discarded.
376+
* MUST be called from a synchronized block!
377+
*/
378+
private void scrollTopAnchoredRegionUpIntoHistory() {
379+
// adding a line moves the whole screen window up by one line: the former top line of the
380+
// screen (and of the region) becomes the newest scroll-back line and the new bottom line of
381+
// the screen is blank
382+
fTerminal.addLine();
383+
int regionBottom = fScrollRegion.getBottomLine();
384+
if (regionBottom < fLines - 1) {
385+
// lines below the region must not move: shift them back down by one line, which also
386+
// vacates the new bottom line of the region
387+
fTerminal.scroll(toAbsoluteLine(regionBottom), fLines - regionBottom, 1);
388+
}
389+
// the absolute line of the cursor may have changed
390+
setCursorLine(fCursorLine);
391+
}
392+
369393
@Override
370394
public void processNewline() {
371395
synchronized (fTerminal) {

terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/emulator/VT100EmulatorBackendTest.java

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -979,12 +979,7 @@ public void testEraseCharacters() {
979979
}
980980

981981
// ---------------------------------------------------------------------------------------------
982-
// Characterization tests for the scrolling behavior.
983-
//
984-
// These lock the current behavior before any change to how scrolling interacts with the
985-
// scroll-back history. The regression guards below MUST keep passing through such a change; the
986-
// "currentlyDiscards" test documents the behavior that a future fix for top-anchored scroll
987-
// regions (eclipse.platform issue 2680) is expected to change.
982+
// Tests for how scrolling interacts with the scroll-back history.
988983
// ---------------------------------------------------------------------------------------------
989984

990985
/**
@@ -1061,14 +1056,11 @@ public void testReverseLineFeedAtTopOfRegionScrollsDown() {
10611056
}
10621057

10631058
/**
1064-
* Characterization of the <em>current</em> behavior for a scroll region anchored at the top of
1065-
* the screen: a newline at the region bottom scrolls in place and discards the top line, creating
1066-
* no history. This is the behavior the planned fix for eclipse.platform issue 2680 will change so
1067-
* that the discarded line is added to the scroll-back instead. Until then this documents the
1068-
* status quo.
1059+
* A newline at the bottom of a top-anchored scroll region moves the displaced top line into
1060+
* the scroll-back history instead of discarding it.
10691061
*/
10701062
@Test
1071-
public void testNewlineInTopAnchoredScrollRegionCurrentlyDiscardsTopLine() {
1063+
public void testNewlineInTopAnchoredScrollRegionMovesTopLineToHistory() {
10721064
ITerminalTextData term = makeITerminalTextData();
10731065
IVT100EmulatorBackend vt100 = makeBakend(term);
10741066
term.setMaxHeight(10);
@@ -1079,11 +1071,14 @@ public void testNewlineInTopAnchoredScrollRegionCurrentlyDiscardsTopLine() {
10791071
vt100.setCursorLine(3);
10801072
vt100.processNewline();
10811073

1082-
assertEquals(5, term.getHeight()); // currently no history is created
1083-
assertEquals("1111", new String(term.getChars(0))); // "0000" was discarded (lost)
1084-
assertEquals("2222", new String(term.getChars(1)));
1085-
assertEquals("3333", new String(term.getChars(2)));
1086-
assertNull(term.getChars(3));
1087-
assertEquals("4444", new String(term.getChars(4))); // footer below the region is untouched
1074+
assertEquals(6, term.getHeight()); // one line of history was created
1075+
assertEquals("0000", new String(term.getChars(0))); // ... holding the displaced top line
1076+
// the screen is now lines 1..5 of the model
1077+
assertEquals("1111", new String(term.getChars(1)));
1078+
assertEquals("2222", new String(term.getChars(2)));
1079+
assertEquals("3333", new String(term.getChars(3)));
1080+
assertNull(term.getChars(4)); // vacated line at the bottom of the region
1081+
assertEquals("4444", new String(term.getChars(5))); // footer below the region is untouched
1082+
assertEquals(3, vt100.getCursorLine()); // cursor stays at the bottom of the region
10881083
}
10891084
}

0 commit comments

Comments
 (0)