1https://marc.info/?l=openbsd-tech&m=161737611015124&w=223diff -upr a/edit.c b/edit.c4--- a/edit.c 2021-05-01 11:37:53.000000000 +02005+++ b/edit.c 2021-09-04 15:22:54.365095598 +02006@@ -150,12 +150,28 @@ x_puts(const char *s)7 shf_putc(*s++, shl_out);8 }910+#ifdef EMACS11+static void12+x_paste_mode(bool onoff)13+{14+ if (!Flag(FBBRACKETPASTE))15+ return;16+17+ printf((onoff) ? BRPASTE_INT : BRPASTE_DEINT);18+ fflush(stdout);19+}20+#endif21+22 bool23 x_mode(bool onoff)24 {25 static bool x_cur_mode;26 bool prev;2728+#ifdef EMACS29+ x_paste_mode(onoff);30+#endif31+32 if (x_cur_mode == onoff)33 return x_cur_mode;34 prev = x_cur_mode;35diff -upr a/edit.h b/edit.h36--- a/edit.h 2021-05-01 11:37:53.000000000 +020037+++ b/edit.h 2021-09-04 15:22:27.475021303 +020038@@ -34,6 +34,12 @@ extern X_chars edchars;39 #define XCF_FULLPATH BIT(2) /* command completion: store full path */40 #define XCF_COMMAND_FILE (XCF_COMMAND|XCF_FILE)4142+/* https://www.xfree86.org/4.7.0/ctlseqs.html#Bracketed%20Paste%20Mode */43+#define BRPASTE_INT "\033[?2004h"44+#define BRPASTE_DEINT "\033[?2004l"45+#define BRPASTE_PRE kb_encode("^[[200~")46+#define BRPASTE_POST kb_encode("^[[201~")47+48 /* edit.c */49 int x_getc(void);50 void x_flush(void);51diff -upr a/emacs.c b/emacs.c52--- a/emacs.c 2021-05-01 11:37:53.000000000 +020053+++ b/emacs.c 2021-09-04 15:22:27.478354645 +020054@@ -118,6 +118,7 @@ static char *xmp; /* mark pointer */55 static char *killstack[KILLSIZE];56 static int killsp, killtp;57 static int x_literal_set;58+static int x_brack_paste;59 static int x_arg_set;60 static char *macro_args;61 static int prompt_skip;62@@ -203,6 +204,8 @@ static int x_fold_lower(int);63 static int x_fold_upper(int);64 static int x_set_arg(int);65 static int x_comment(int);66+static int x_brack_paste_start(int);67+static int x_brack_paste_end(int);68 #ifdef DEBUG69 static int x_debug_info(int);70 #endif71@@ -260,6 +263,8 @@ static const struct x_ftab x_ftab[] = {72 { x_fold_upper, "upcase-word", XF_ARG },73 { x_set_arg, "set-arg", XF_NOBIND },74 { x_comment, "comment", 0 },75+ { x_brack_paste_start, "bracketed-paste-start", 0 },76+ { x_brack_paste_end, "bracketed-paste-end", 0 },77 { 0, 0, 0 },78 #ifdef DEBUG79 { x_debug_info, "debug-info", 0 },80@@ -316,6 +321,8 @@ x_emacs(char *buf, size_t len)81 }8283 x_literal_set = 0;84+ x_brack_paste = 0;85+86 x_arg = -1;87 x_last_command = NULL;88 while (1) {89@@ -353,6 +360,13 @@ x_emacs(char *buf, size_t len)90 }91 }9293+ /* In bracketed paste mode only allow x_brack_paste_end,94+ * to quit this mode, for all other commands insert a literal. */95+ if (x_brack_paste && (submatch == 1 && kmatch)) {96+ if (kmatch->ftab->xf_func != x_brack_paste_end)97+ submatch = 0;98+ }99+100 if (submatch == 1 && kmatch) {101 if (kmatch->ftab->xf_func == x_ins_string &&102 kmatch->args && !macro_args) {103@@ -1479,6 +1493,10 @@ x_init_emacs(void)104105 TAILQ_INIT(&kblist);106107+ /* bracketed paste mode */108+ kb_add_string(x_brack_paste_start, NULL, BRPASTE_PRE);109+ kb_add_string(x_brack_paste_end, NULL, BRPASTE_POST);110+111 /* man page order */112 kb_add(x_abort, CTRL('G'), 0);113 kb_add(x_mv_back, CTRL('B'), 0);114@@ -1984,6 +2002,21 @@ x_comment(int c)115 return KSTD;116 }117118+int119+x_brack_paste_start(int c)120+{121+ if (Flag(FBBRACKETPASTE))122+ x_brack_paste = 1;123+ return KSTD;124+}125+126+int127+x_brack_paste_end(int c)128+{129+ if (Flag(FBBRACKETPASTE))130+ x_brack_paste = 0;131+ return KSTD;132+}133134 /* NAME:135 * x_prev_histword - recover word from prev command136diff -upr a/ksh.1 b/ksh.1137--- a/ksh.1 2021-05-01 11:37:53.000000000 +0200138+++ b/ksh.1 2021-09-04 15:23:21.358503517 +0200139@@ -3595,6 +3595,9 @@ during file name generation.140 Print commands and parameter assignments when they are executed, preceded by141 the value of142 .Ev PS4 .143+.It Ic bracket-paste144+Enables bracketed paste mode, requires the associated escape sequences to be145+supported by the utilized terminal emulator.146 .It Ic bgnice147 Background jobs are run with lower priority.148 .It Ic braceexpand149diff -upr a/misc.c b/misc.c150--- a/misc.c 2021-05-01 11:37:53.000000000 +0200151+++ b/misc.c 2021-09-04 15:22:27.478354645 +0200152@@ -123,6 +123,9 @@ const struct option sh_options[] = {153 */154 { "allexport", 'a', OF_ANY },155 { "braceexpand", 0, OF_ANY }, /* non-standard */156+#ifdef EMACS157+ { "bracket-paste", 0, OF_ANY }, /* non-standard */158+#endif159 { "bgnice", 0, OF_ANY },160 { NULL, 'c', OF_CMDLINE },161 { "csh-history", 0, OF_ANY }, /* non-standard */162diff -upr a/sh.h b/sh.h163--- a/sh.h 2021-05-01 11:37:53.000000000 +0200164+++ b/sh.h 2021-09-04 15:22:27.481687988 +0200165@@ -134,6 +134,9 @@ extern const struct option sh_options[];166 enum sh_flag {167 FEXPORT = 0, /* -a: export all */168 FBRACEEXPAND, /* enable {} globbing */169+#ifdef EMACS170+ FBBRACKETPASTE, /* bracketed paste mode */171+#endif172 FBGNICE, /* bgnice */173 FCOMMAND, /* -c: (invocation) execute specified command */174 FCSHHISTORY, /* csh-style history enabled */