Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2325,10 +2325,10 @@ private void doCsi(int b) {
if (getArg0(0) == 0) mSession.write("\033[?64;1;2;4;6;9;15;18;21;22c");
break;
case 'd': // ESC [ Pn d - Vert Position Absolute
setCursorRow(Math.min(Math.max(1, getArg0(1)), mRows) - 1);
setCursorRowRespectingOriginMode(getArg0(1) - 1);
break;
case 'e': // Vertical Position Relative (VPR). From ISO-6429 (ECMA-48).
setCursorPosition(mCursorCol, mCursorRow + getArg0(1));
setCursorRowRespectingOriginMode(mCursorRow - (isDecsetInternalBitSet(DECSET_BIT_ORIGIN_MODE) ? mTopMargin : 0) + getArg0(1));
break;
// case 'f': "${CSI}${ROW};${COLUMN}f" - Horizontal and Vertical Position (HVP). Grouped with case 'H'.
case 'g': // Clear tab stop
Expand Down Expand Up @@ -3443,9 +3443,26 @@ private void setCursorCol(int col) {
mAboutToAutoWrap = false;
}

/** Set the cursor mode, but limit it to margins if {@link #DECSET_BIT_ORIGIN_MODE} is enabled. */
/**
* Set the cursor column, relative to the left margin and limited to the margins if
* {@link #DECSET_BIT_ORIGIN_MODE} is enabled. The cursor row is not changed.
*/
private void setCursorColRespectingOriginMode(int col) {
setCursorPosition(col, mCursorRow);
boolean originMode = isDecsetInternalBitSet(DECSET_BIT_ORIGIN_MODE);
int effectiveLeftMargin = originMode ? mLeftMargin : 0;
int effectiveRightMargin = originMode ? mRightMargin : mColumns;
setCursorCol(Math.max(effectiveLeftMargin, Math.min(effectiveLeftMargin + col, effectiveRightMargin - 1)));
}

/**
* Set the cursor row, relative to the top margin and limited to the margins if
* {@link #DECSET_BIT_ORIGIN_MODE} is enabled. The cursor column is not changed.
*/
private void setCursorRowRespectingOriginMode(int row) {
boolean originMode = isDecsetInternalBitSet(DECSET_BIT_ORIGIN_MODE);
int effectiveTopMargin = originMode ? mTopMargin : 0;
int effectiveBottomMargin = originMode ? mBottomMargin : mRows;
setCursorRow(Math.max(effectiveTopMargin, Math.min(effectiveTopMargin + row, effectiveBottomMargin - 1)));
}

/** TODO: Better name, distinguished from {@link #setCursorPosition(int, int)} by not regarding origin mode. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,19 @@ public void testCursorHorizontalPositionAbsolute() {
enterString("\033[?6h\033[`").assertCursorAt(0, 1).enterString("\033[22`").assertCursorAt(0, 2);
}

/** VPA, VPR and HPA with a top margin, with and without origin mode (http://www.vt100.net/docs/vt510-rm/DECOM). */
public void testCursorPositionWithOriginModeAndTopMargin() {
// Without origin mode, VPA and VPR are not limited by the scroll region:
withTerminalSized(4, 6).enterString("\033[3;5r\033[2d").assertCursorAt(1, 0).enterString("\033[9d").assertCursorAt(5, 0);
enterString("\033[1;1H\033[2e").assertCursorAt(2, 0).enterString("\033[9e").assertCursorAt(5, 0);
// With origin mode, VPA counts from the top margin and stops at the bottom margin:
enterString("\033[?6h\033[1d").assertCursorAt(2, 0).enterString("\033[2d").assertCursorAt(3, 0).enterString("\033[9d").assertCursorAt(4, 0);
// .. VPR moves down from the cursor and stops at the bottom margin:
enterString("\033[1;1H\033[1e").assertCursorAt(3, 0).enterString("\033[9e").assertCursorAt(4, 0);
// .. and HPA does not move the cursor to another row:
enterString("\033[1;1H\033[3`").assertCursorAt(2, 2);
}

public void testCursorForward() {
// "${CSI}${N:=1}C" moves cursor forward N columns:
withTerminalSized(6, 2).enterString("A\033[CB\033[2CC").assertLinesAre("A B C", " ");
Expand Down