From 8082bcd2ef822fbbe06ca8716633f44fd20c0cb4 Mon Sep 17 00:00:00 2001 From: Kurt Hindenburg Date: Sat, 11 Jan 2014 12:28:46 -0500 Subject: [PATCH] Add xterm's bracketed paste mode Allow xterm's bracketed paste mode to work When enabled by '\e[?2004h', pasted data is surrounded by \e[200~ and \e[201~. This is mainly for text editors to temporarily switch off autoindent and line wrapping. http://invisible-island.net/xterm/ctlseqs/ctlseqs.html This page have a .vimrc that will trigger this https://bugzilla.gnome.org/show_bug.cgi?id=605299 Thanks to Egmont Koblinger for patch BUG: 324946 FEATURE: 4.13 --- src/Emulation.cpp | 13 +++++++++++++ src/Emulation.h | 7 +++++++ src/Session.cpp | 5 +++++ src/TerminalDisplay.cpp | 14 ++++++++++++++ src/TerminalDisplay.h | 4 ++++ src/Vt102Emulation.cpp | 14 ++++++++++++++ src/Vt102Emulation.h | 3 ++- 7 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/Emulation.cpp b/src/Emulation.cpp index 02ed4be4..80d93baa 100644 --- a/src/Emulation.cpp +++ b/src/Emulation.cpp @@ -39,6 +39,7 @@ Emulation::Emulation() : _decoder(0), _keyTranslator(0), _usesMouse(false), + _bracketedPasteMode(false), _imageSizeInitialized(false) { // create screens with a default size @@ -52,6 +53,8 @@ Emulation::Emulation() : // listen for mouse status changes connect(this , SIGNAL(programUsesMouseChanged(bool)) , SLOT(usesMouseChanged(bool))); + connect(this , SIGNAL(programBracketedPasteModeChanged(bool)) , + SLOT(bracketedPasteModeChanged(bool))); } bool Emulation::programUsesMouse() const @@ -64,6 +67,16 @@ void Emulation::usesMouseChanged(bool usesMouse) _usesMouse = usesMouse; } +bool Emulation::programBracketedPasteMode() const +{ + return _bracketedPasteMode; +} + +void Emulation::bracketedPasteModeChanged(bool bracketedPasteMode) +{ + _bracketedPasteMode = bracketedPasteMode; +} + ScreenWindow* Emulation::createWindow() { ScreenWindow* window = new ScreenWindow(); diff --git a/src/Emulation.h b/src/Emulation.h index 92a0ea7d..52a34b4e 100644 --- a/src/Emulation.h +++ b/src/Emulation.h @@ -215,6 +215,8 @@ public: */ bool programUsesMouse() const; + bool programBracketedPasteMode() const; + public slots: /** Change the size of the emulation's image */ @@ -314,6 +316,8 @@ signals: */ void programUsesMouseChanged(bool usesMouse); + void programBracketedPasteModeChanged(bool bracketedPasteMode); + /** * Emitted when the contents of the screen image change. * The emulation buffers the updates from successive image changes, @@ -474,8 +478,11 @@ private slots: void usesMouseChanged(bool usesMouse); + void bracketedPasteModeChanged(bool bracketedPasteMode); + private: bool _usesMouse; + bool _bracketedPasteMode; QTimer _bulkTimer1; QTimer _bulkTimer2; bool _imageSizeInitialized; diff --git a/src/Session.cpp b/src/Session.cpp index 21d82272..fbe85daa 100644 --- a/src/Session.cpp +++ b/src/Session.cpp @@ -326,6 +326,11 @@ void Session::addView(TerminalDisplay* widget) widget->setUsesMouse(_emulation->programUsesMouse()); + connect(_emulation, SIGNAL(programBracketedPasteModeChanged(bool)), + widget, SLOT(setBracketedPasteMode(bool))); + + widget->setBracketedPasteMode(_emulation->programBracketedPasteMode()); + widget->setScreenWindow(_emulation->createWindow()); //connect view signals and slots diff --git a/src/TerminalDisplay.cpp b/src/TerminalDisplay.cpp index 2235047f..061b5c31 100644 --- a/src/TerminalDisplay.cpp +++ b/src/TerminalDisplay.cpp @@ -377,6 +377,7 @@ TerminalDisplay::TerminalDisplay(QWidget* parent) setMouseTracking(true); setUsesMouse(true); + setBracketedPasteMode(false); setColorTable(ColorScheme::defaultTable); @@ -2673,6 +2674,15 @@ bool TerminalDisplay::usesMouse() const return _mouseMarks; } +void TerminalDisplay::setBracketedPasteMode(bool on) +{ + _bracketedPasteMode = on; +} +bool TerminalDisplay::bracketedPasteMode() const +{ + return _bracketedPasteMode; +} + /* ------------------------------------------------------------------------- */ /* */ /* Clipboard */ @@ -2701,6 +2711,10 @@ void TerminalDisplay::doPaste(QString text, bool appendReturn) if (!text.isEmpty()) { text.replace('\n', '\r'); + if (bracketedPasteMode()) { + text.prepend("\e[200~"); + text.append("\e[201~"); + } // perform paste by simulating keypress events QKeyEvent e(QEvent::KeyPress, 0, Qt::NoModifier, text); emit keyPressedSignal(&e); diff --git a/src/TerminalDisplay.h b/src/TerminalDisplay.h index fb040a76..289a0b16 100644 --- a/src/TerminalDisplay.h +++ b/src/TerminalDisplay.h @@ -534,6 +534,9 @@ public slots: /** See setUsesMouse() */ bool usesMouse() const; + void setBracketedPasteMode(bool bracketedPasteMode); + bool bracketedPasteMode() const; + /** * Shows a notification that a bell event has occurred in the terminal. * TODO: More documentation here @@ -808,6 +811,7 @@ private: bool _showTerminalSizeHint; bool _bidiEnabled; bool _mouseMarks; + bool _bracketedPasteMode; QPoint _iPntSel; // initial selection point QPoint _pntSel; // current selection point diff --git a/src/Vt102Emulation.cpp b/src/Vt102Emulation.cpp index 0b6d2ed2..bdcabdd8 100644 --- a/src/Vt102Emulation.cpp +++ b/src/Vt102Emulation.cpp @@ -789,6 +789,11 @@ void Vt102Emulation::processToken(int token, int p, int q) case TY_CSI_PR('h', 1049) : saveCursor(); _screen[1]->clearEntireScreen(); setMode(MODE_AppScreen); break; //XTERM case TY_CSI_PR('l', 1049) : resetMode(MODE_AppScreen); restoreCursor(); break; //XTERM + case TY_CSI_PR('h', 2004) : setMode (MODE_BracketedPaste); break; //XTERM + case TY_CSI_PR('l', 2004) : resetMode (MODE_BracketedPaste); break; //XTERM + case TY_CSI_PR('s', 2004) : saveMode (MODE_BracketedPaste); break; //XTERM + case TY_CSI_PR('r', 2004) : restoreMode (MODE_BracketedPaste); break; //XTERM + //FIXME: weird DEC reset sequence case TY_CSI_PE('p' ) : /* IGNORED: reset ( ) */ break; @@ -1196,6 +1201,7 @@ void Vt102Emulation::resetModes() resetMode(MODE_Mouse1005); saveMode(MODE_Mouse1005); resetMode(MODE_Mouse1006); saveMode(MODE_Mouse1006); resetMode(MODE_Mouse1015); saveMode(MODE_Mouse1015); + resetMode(MODE_BracketedPaste); saveMode(MODE_BracketedPaste); resetMode(MODE_AppScreen); saveMode(MODE_AppScreen); resetMode(MODE_AppCuKeys); saveMode(MODE_AppCuKeys); @@ -1221,6 +1227,10 @@ void Vt102Emulation::setMode(int m) emit programUsesMouseChanged(false); break; + case MODE_BracketedPaste: + emit programBracketedPasteModeChanged(true); + break; + case MODE_AppScreen : _screen[1]->clearSelection(); setScreen(1); @@ -1249,6 +1259,10 @@ void Vt102Emulation::resetMode(int m) emit programUsesMouseChanged(true); break; + case MODE_BracketedPaste: + emit programBracketedPasteModeChanged(false); + break; + case MODE_AppScreen : _screen[0]->clearSelection(); setScreen(0); diff --git a/src/Vt102Emulation.h b/src/Vt102Emulation.h index c15f6ea6..8d678e00 100644 --- a/src/Vt102Emulation.h +++ b/src/Vt102Emulation.h @@ -46,7 +46,8 @@ class QKeyEvent; #define MODE_Ansi (MODES_SCREEN+10) // Use US Ascii for character sets G0-G3 (DECANM) #define MODE_132Columns (MODES_SCREEN+11) // 80 <-> 132 column mode switch (DECCOLM) #define MODE_Allow132Columns (MODES_SCREEN+12) // Allow DECCOLM mode -#define MODE_total (MODES_SCREEN+13) +#define MODE_BracketedPaste (MODES_SCREEN+13) // Xterm-style bracketed paste mode +#define MODE_total (MODES_SCREEN+14) namespace Konsole {