diff --git a/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java b/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java index a993d834..10c7321d 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java @@ -223,6 +223,7 @@ public final class TerminalEmulator { private byte mUtf8ToFollow, mUtf8Index; private final byte[] mUtf8InputBuffer = new byte[4]; + private int mLastEmittedCodePoint = -1; public final TerminalColors mColors = new TerminalColors(); @@ -1509,6 +1510,11 @@ public final class TerminalEmulator { case '`': // Horizontal position absolute (HPA - http://www.vt100.net/docs/vt510-rm/HPA). setCursorColRespectingOriginMode(getArg0(1) - 1); break; + case 'b': // Repeat the preceding graphic character Ps times (REP). + if (mLastEmittedCodePoint == -1) break; + final int numRepeat = getArg0(1); + for (int i = 0; i < numRepeat; i++) emitCodePoint(mLastEmittedCodePoint); + break; case 'c': // Primary Device Attributes (http://www.vt100.net/docs/vt510-rm/DA1) if argument is missing or zero. // The important part that may still be used by some (tmux stores this value but does not currently use it) // is the first response parameter identifying the terminal service class, where we send 64 for "vt420". @@ -1574,6 +1580,7 @@ public final class TerminalEmulator { // Also require that top + 2 <= bottom. mTopMargin = Math.max(0, Math.min(getArg0(1) - 1, mRows - 2)); mBottomMargin = Math.max(mTopMargin + 2, Math.min(getArg1(mRows), mRows)); + // DECSTBM moves the cursor to column 1, line 1 of the page respecting origin mode. setCursorPosition(0, 0); } @@ -2091,6 +2098,7 @@ public final class TerminalEmulator { * @param codePoint The code point of the character to display */ private void emitCodePoint(int codePoint) { + mLastEmittedCodePoint = codePoint; if (mUseLineDrawingUsesG0 ? mUseLineDrawingG0 : mUseLineDrawingG1) { // http://www.vt100.net/docs/vt102-ug/table5-15.html. switch (codePoint) { diff --git a/terminal-emulator/src/test/java/com/termux/terminal/ControlSequenceIntroducerTest.java b/terminal-emulator/src/test/java/com/termux/terminal/ControlSequenceIntroducerTest.java index 626075f8..b48243e5 100644 --- a/terminal-emulator/src/test/java/com/termux/terminal/ControlSequenceIntroducerTest.java +++ b/terminal-emulator/src/test/java/com/termux/terminal/ControlSequenceIntroducerTest.java @@ -35,4 +35,12 @@ public class ControlSequenceIntroducerTest extends TerminalTestCase { withTerminalSized(3, 2).enterString("\033[0;38;2;255;255;255;48;2;0;0;0;1;2;3;4;5;7;8;9mabc").assertLinesAre("abc", " "); } + /** CSI Ps b Repeat the preceding graphic character Ps times (REP). */ + public void testRepeat() { + withTerminalSized(3, 2).enterString("a\033[b").assertLinesAre("aa ", " "); + withTerminalSized(3, 2).enterString("a\033[2b").assertLinesAre("aaa", " "); + // When no char has been output we ignore REP: + withTerminalSized(3, 2).enterString("\033[b").assertLinesAre(" ", " "); + } + }