diff --git a/src/conio/cterm.c b/src/conio/cterm.c index fe4a3f3f767f3b73c1b25c4537a8bf36a789c2eb..4386f0b735053a9d1128d2d818ac1fe7f1cc82d0 100644 --- a/src/conio/cterm.c +++ b/src/conio/cterm.c @@ -2527,6 +2527,9 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int * if (cterm->mouse_state_change) cterm->mouse_state_change(seq->param_int[i], 1, cterm->mouse_state_change_cbdata); break; + case 2004: + cterm->extattr |= CTERM_EXTATTR_BRACKETPASTE; + break; } } if (updfg || updbg) { @@ -2602,6 +2605,9 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int * if (cterm->mouse_state_change) cterm->mouse_state_change(seq->param_int[i], 0, cterm->mouse_state_change_cbdata); break; + case 2004: + cterm->extattr &= ~(CTERM_EXTATTR_BRACKETPASTE); + break; } } if (updfg || updbg) { diff --git a/src/conio/cterm.h b/src/conio/cterm.h index c5840fedde10a2ac80b6e26892cd7f5d9cafaa12..3b55d37610a7971f60d2aea87b6a78430e9c0c0c 100644 --- a/src/conio/cterm.h +++ b/src/conio/cterm.h @@ -122,6 +122,7 @@ struct cterminal { #define CTERM_EXTATTR_ORIGINMODE 0x0002 #define CTERM_EXTATTR_SXSCROLL 0x0004 #define CTERM_EXTATTR_DECLRMM 0x0008 +#define CTERM_EXTATTR_BRACKETPASTE 0x0016 int save_xpos; // Saved position (for later restore) int save_ypos; int sequence; // An escape sequence is being parsed diff --git a/src/conio/cterm.txt b/src/conio/cterm.txt index 439e8df646f98f9a101465e0dcb3c2646f105df3..1f95ae9880a59613ef0a1421e65d0d4a9180d5e5 100644 --- a/src/conio/cterm.txt +++ b/src/conio/cterm.txt @@ -901,6 +901,8 @@ CSI ? Ps... h (DECSET) 1015 - URXVT encoded extended coordinates (Not supported by SyncTERM) SOURCE: xterm + 2004 - Set bracketed paste mode + SOURCE: xterm (https://invisible-island.net/xterm/xterm-paste64.html) CSI Pn j (HPB) Character Position Backward @@ -996,6 +998,8 @@ CSI ? Ps... l (DECRST) 1015 - Disable URXVT encoded extended coordinates (Not supported by SyncTERM) SOURCE: xterm + 2004 - Disable bracketed paste mode + SOURCE: xterm (https://invisible-island.net/xterm/xterm-paste64.html) CSI Ps... m (SGR) Select Graphic Rendition diff --git a/src/syncterm/syncterm.c b/src/syncterm/syncterm.c index 734f07c1a3356bcef63dda51319ee0e4e370fcf1..8cf087fdf9f49af214d0577980be8a0074c4762f 100644 --- a/src/syncterm/syncterm.c +++ b/src/syncterm/syncterm.c @@ -1409,6 +1409,15 @@ main(int argc, char **argv) "\tsmglp=\\E[69h\\E[%{1}%p1%+%d;0s\\E[69l,smgrp=\\E[69h\\E[0;%{1}%p1%+%ds\\E[69l,\n" "\thts=\\E[H,ht=\t,setab=\\E[4%p1%dm,setaf=\\E[3%p1%dm,\n" "\tsmglr=\\E[?69h\\E[%i%p1%d;%p2%ds\\E?69l,smso=\\E[0;1;7m,rmso=\\E[m,\n" + // XTerm bracketed pasted: https://invisible-island.net/xterm/xterm-paste64.html + /* NOTE: From terminfo source: https://invisible-island.net/ncurses/terminfo.ti.html + * Bracketed paste was introduced by xterm patch #203 in May 2005, as part of a + * larger feature for manipulating the clipboard selection. Few terminals aside + * from xterm fully implement the clipboard feature, but several copy this + * detail. The names for the extended capabilities here were introduced by vim + * in January 2017, but used internally. In 2023, vim patch 9.0.1117 is needed + * to work with this change. */ + "\tBD=\\E[?2004l,BE=\\E[?2004h,PE=\\E[201~,PS=\\E[200~," "syncterm-bitmap|SyncTERM in Bitmap Mode,\n" "\tccc,\n" "\tcolors#256,pairs#65535,\n" diff --git a/src/syncterm/term.c b/src/syncterm/term.c index 5abd94123c44fbdfdc8dfc6645e42f67c4e0e2ae..3766e978f1c7ecb46f85aa8a8db77159cb717c2f 100644 --- a/src/syncterm/term.c +++ b/src/syncterm/term.c @@ -3572,16 +3572,28 @@ do_paste(void) setfont(oldfont, false, 1); free(p2); if (p != NULL) { + if (cterm->extattr & CTERM_EXTATTR_BRACKETPASTE) + conn_send("\x1b[200~", 6, 0); for (p2 = p; *p2; p2++) { if (*p2 == '\n') { /* If previous char was not \r, send a \r */ if ((p2 == p) || (*(p2 - 1) != '\r')) conn_send("\r", 1, 0); } + else if (*p2 == '\x1b') { + // If we're using bracked paste, strip paste end sequence + // TODO: Do we generally want to disable all ESC chars? + if (strcmp(p2, "\x1b[201~") == 0) + p2 += 5; + else + conn_send(p2, 1, 0); + } else { conn_send(p2, 1, 0); } } + if (cterm->extattr & CTERM_EXTATTR_BRACKETPASTE) + conn_send("\x1b[201~", 6, 0); free(p); } }