diff --git a/src/TerminalDisplay.cpp b/src/TerminalDisplay.cpp --- a/src/TerminalDisplay.cpp +++ b/src/TerminalDisplay.cpp @@ -673,6 +673,9 @@ void TerminalDisplay::setKeyboardCursorShape(Enum::CursorShapeEnum shape) { _cursorShape = shape; + // not updateCursor() as that does not actually update the cursor in some + // cases (i.e. vim with `set showmode`). + update(); } Enum::CursorShapeEnum TerminalDisplay::keyboardCursorShape() const { diff --git a/src/Vt102Emulation.cpp b/src/Vt102Emulation.cpp --- a/src/Vt102Emulation.cpp +++ b/src/Vt102Emulation.cpp @@ -37,6 +37,9 @@ // Konsole #include "KeyboardTranslator.h" +#include "Session.h" +#include "SessionController.h" +#include "SessionManager.h" #include "TerminalDisplay.h" using Konsole::Vt102Emulation; @@ -148,6 +151,7 @@ - ESC_DE - Escape codes of the form C - CSI_PN - Escape codes of the form '[' {Pn} ';' {Pn} C - CSI_PS - Escape codes of the form '[' {Pn} ';' ... C + - CSI_DBL - Escape codes of the form '[' {Pn} ';' ... C C - CSI_PR - Escape codes of the form '[' '?' {Pn} ';' ... C - CSI_PE - Escape codes of the form '[' '!' {Pn} ';' ... C - VT52 - VT52 escape codes @@ -180,6 +184,8 @@ #define TY_CSI_PG(A) TY_CONSTRUCT(9,A,0) #define TY_CSI_PE(A) TY_CONSTRUCT(10,A,0) +#define TY_CSI_DBL(A,B) TY_CONSTRUCT(11,A,B) + const int MAX_ARGUMENT = 4096; // Tokenizer --------------------------------------------------------------- -- @@ -226,6 +232,7 @@ const int SCS = 16; // Select Character Set const int GRP = 32; // TODO: Document me const int CPS = 64; // Character which indicates end of window resize +const int CSIDBLF = 128; // characters which can come first in a 2 character CSI command void Vt102Emulation::initTokenizer() { @@ -256,6 +263,9 @@ for (s = (quint8 *)"()+*#[]%"; *s != 0u; ++s) { charClass[*s] |= GRP; } + for (s = (quint8 *)" '$\""; *s != 0u; ++s) { + charClass[*s] |= CSIDBLF; + } resetTokenizer(); } @@ -292,6 +302,8 @@ #define Xte (Xpe && (cc == 7 || cc == 27)) #define ces(C) (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte) #define dcs (p >= 2 && s[0] == ESC && s[1] == 'P') +#define csi( ) (p >= 2 && s[0] == ESC && s[1] == '[') +#define csidbl( ) (p >= 4 && csi() && (charClass[s[p-2]] & CSIDBLF) == CSIDBLF) #define CNTL(c) ((c)-'@') const int ESC = 27; @@ -351,12 +363,15 @@ if (epe( )) { processToken( TY_CSI_PE(cc), 0, 0); resetTokenizer(); return; } if (ees(DIG)) { addDigit(cc-'0'); return; } if (eec(';')) { addArgument(); return; } + if (csi() && ees(CSIDBLF)) { return; } // possible first char of a 2 char CSI command for (int i = 0; i <= argc; i++) { if (epp()) processToken(TY_CSI_PR(cc,argv[i]), 0, 0); else if (egt()) processToken(TY_CSI_PG(cc), 0, 0); // spec. case for ESC]>0c or ESC]>c + else if (csidbl()) + processToken(TY_CSI_DBL(cc, s[p-2]), argv[i], 0); else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2) { // ESC[ ... 48;2;;; ... m -or- ESC[ ... 38;2;;; ... m @@ -849,6 +864,41 @@ case TY_CSI_PG('c' ) : reportSecondaryAttributes( ); break; //VT100 + case TY_CSI_DBL('q', ' ') : // DECSCUSR, VT510/VT520 + { + auto scusr = [this](bool blink, Enum::CursorShapeEnum shape) { + _currentScreen->currentTerminalDisplay()->setBlinkingCursorEnabled(blink); + _currentScreen->currentTerminalDisplay()->setKeyboardCursorShape(shape); + }; + switch (p) + { + case 0 : + { // xterm treats 0 as case 1 (blinking block), vte reverts to 'default'. The + // latter seems sensible, revert cursor to how it is set in the profile. + auto session = _currentScreen->currentTerminalDisplay()->sessionController()->session(); + auto profile = SessionManager::instance()->sessionProfile(session.data()); + bool blink = profile->blinkingCursorEnabled(); + auto shape = profile->property(Profile::CursorShape); + if (shape == Enum::BlockCursor) { + scusr(blink, Enum::BlockCursor); + } else if (shape == Enum::IBeamCursor) { + scusr(blink, Enum::IBeamCursor); + } else if (shape == Enum::UnderlineCursor) { + scusr(blink, Enum::UnderlineCursor); + } + break; + } + case 1 : scusr(true, Enum::BlockCursor); break; + case 2 : scusr(false, Enum::BlockCursor); break; + case 3 : scusr(true, Enum::UnderlineCursor); break; + case 4 : scusr(false, Enum::UnderlineCursor); break; + case 5 : scusr(true, Enum::IBeamCursor); break; + case 6 : scusr(false, Enum::IBeamCursor); break; + default: break; + } + break; + } + default: reportDecodingError(); break;