summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKurt Hindenburg <[email protected]>2018-02-04 14:09:28 -0500
committerKurt Hindenburg <[email protected]>2018-02-04 14:09:28 -0500
commitb8a2f0cfd0d0f894687953c3f50f2fb163e8690d (patch)
treef0ff825349149fd2beacbe3a44bf927020a78c46
parente2184aef3d7ed3f588b2981dfde652becaa1f60e (diff)
Add support for ECMA-48 REP: repeating previous character
Patch by btown using lxde/[email protected]60221da by @yan12125 ECMA-48 8.3.103 describes the sequence CSI Pn b for repeating the previous character in the data stream. This sequence has been present in XTerm since January 1997 and has been added to the latest terminfo entry for xterm-new and derived entries such as xterm-256color. https://phabricator.kde.org/D10064
-rw-r--r--src/Screen.cpp23
-rw-r--r--src/Screen.h8
-rw-r--r--src/Vt102Emulation.cpp3
3 files changed, 32 insertions, 2 deletions
diff --git a/src/Screen.cpp b/src/Screen.cpp
index 5642df8..a58e6dd 100644
--- a/src/Screen.cpp
+++ b/src/Screen.cpp
@@ -73,7 +73,8 @@ Screen::Screen(int lines, int columns):
_effectiveForeground(CharacterColor()),
_effectiveBackground(CharacterColor()),
_effectiveRendition(DEFAULT_RENDITION),
- _lastPos(-1)
+ _lastPos(-1),
+ _lastDrawnChar(0)
{
_lineProperties.resize(_lines + 1);
for (int i = 0; i < _lines + 1; i++) {
@@ -248,6 +249,24 @@ void Screen::insertChars(int n)
}
}
+void Screen::repeatChars(int n)
+{
+ if (n == 0) {
+ n = 1; // Default
+ }
+
+ // From ECMA-48 version 5, section 8.3.103:
+ // "If the character preceding REP is a control function or part of a
+ // control function, the effect of REP is not defined by this Standard."
+ //
+ // So, a "normal" program should always use REP immediately after a visible
+ // character (those other than escape sequences). So, _lastDrawnChar can be
+ // safely used.
+ for (int i = 0; i < n; i++) {
+ displayCharacter(_lastDrawnChar);
+ }
+}
+
void Screen::deleteLines(int n)
{
if (n == 0) {
@@ -751,6 +770,8 @@ void Screen::displayCharacter(unsigned short c)
currentChar.rendition = _effectiveRendition;
currentChar.isRealCharacter = true;
+ _lastDrawnChar = c;
+
int i = 0;
const int newCursorX = _cuX + w--;
while (w != 0) {
diff --git a/src/Screen.h b/src/Screen.h
index 868508f..3aedf4f 100644
--- a/src/Screen.h
+++ b/src/Screen.h
@@ -221,6 +221,11 @@ public:
*/
void insertChars(int n);
/**
+ * Repeat the preceeding graphic character @n times, including SPACE.
+ * If @n is 0 then the character is repeated once.
+ */
+ void repeatChars(int n);
+ /**
* Removes @p n lines beginning from the current cursor position.
* The position of the cursor is not altered.
* If @p n is 0 then one line is removed.
@@ -717,6 +722,9 @@ private:
// last position where we added a character
int _lastPos;
+
+ // used in REP (repeating char)
+ unsigned short _lastDrawnChar;
};
}
diff --git a/src/Vt102Emulation.cpp b/src/Vt102Emulation.cpp
index a75e03b..b07fb07 100644
--- a/src/Vt102Emulation.cpp
+++ b/src/Vt102Emulation.cpp
@@ -240,7 +240,7 @@ void Vt102Emulation::initTokenizer()
for (i = 32; i < 256; ++i) {
charClass[i] |= CHR;
}
- for (s = (quint8 *)"@ABCDGHILMPSTXZcdfry"; *s != 0u; ++s) {
+ for (s = (quint8 *)"@ABCDGHILMPSTXZbcdfry"; *s != 0u; ++s) {
charClass[*s] |= CPN;
}
// resize = \e[8;<row>;<col>t
@@ -684,6 +684,7 @@ void Vt102Emulation::processToken(int token, int p, int q)
case TY_CSI_PN('T' ) : _currentScreen->scrollDown (p ); break;
case TY_CSI_PN('X' ) : _currentScreen->eraseChars (p ); break;
case TY_CSI_PN('Z' ) : _currentScreen->backtab (p ); break;
+ case TY_CSI_PN('b' ) : _currentScreen->repeatChars (p ); break;
case TY_CSI_PN('c' ) : reportTerminalType ( ); break; //VT100
case TY_CSI_PN('d' ) : _currentScreen->setCursorY (p ); break; //LINUX
case TY_CSI_PN('f' ) : _currentScreen->setCursorYX (p, q); break; //VT100