Hi -

When bracketed paste is on, pasting leaves the commandline in movement
mode, with a 200 prefix.

This is the issue mentioned e.g. in
https://www.reddit.com/r/bash/comments/5pelmy/whats_going_on_with_bracketed_paste_vi_mode/

Trivial patch attached.

Details:

## To reproduce

In a suitable terminal (e.g. xterm):

$ set -o vi
$ bind 'set enable-bracketed-paste on'

Select the word "anything", middle-click, display is:
(arg: 200) anything

Expected display:
$ anything


## Root cause:

The delivered sequence is \033[200~anything\033[201~

The leader \033[200~ correctly triggers the bracketed paste: kill.c:698,
rl_bracketed_paste_begin()

That function consumes input up to and including the trailer, and returns
the (net) number of characters pasted, which is >=0.

*** Possible fix 1: Return zero here.


The initial \033 sets "got_subseq" to true for the entire prefix, so the
positive return gets interpreted by _rl_subseq_result (readline.c:1017) as
"no match", in ll. 1072:
    else if (r && got_subseq)
      {
        /* OK, back up the chain. */

This backtracking should not happen.

*** Possible fix 2: Change the two "if (r && ...)" conditions in
_rl_subseq_result function to explicitly test for r == -1


Emacs mode is not impacted, because there is no matching prefix
subsequence, so "got_subseq" is zero.

For completeness: The "arg: 200" is the result of interpreting \033 as
movement mode, skipping the bracket as unbound, parsing the 2 and following
"0" digits from vi_arg_digit and grabbing the two zeroes.
The tilde that completed the sequence does not get returned to the input
buffer; it is read into "newkey" when the second zero has been read
(readline.c:977ff):
        newkey = _rl_subseq_getchar (key);
        if (newkey < 0)
          {
            _rl_abort_internal ();
            return -1;
          }

        r = _rl_dispatch_subseq (newkey, _rl_dispatching_keymap, got_subseq
|| map[ANYOTHERKEY].function);
        return _rl_subseq_result (r, map, key, got_subseq);

This is the correct behaviour, the problem requires one of the above two
fixes. Patch implements option 1.


Gabe
-- 
Do not think by infection, catching an opinion like a cold.
From 5097f1eada2282e112c0fb97ce0c1a40a5a92c46 Mon Sep 17 00:00:00 2001
From: Gabe Krabbe <kra...@google.com>
Date: Wed, 21 Mar 2018 19:42:55 +0000
Subject: [PATCH] Fix bracketed paste for vi mode.

---
 lib/readline/kill.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/readline/kill.c b/lib/readline/kill.c
index 696f1938..8ed9dab9 100644
--- a/lib/readline/kill.c
+++ b/lib/readline/kill.c
@@ -702,7 +702,7 @@ rl_bracketed_paste_begin (count, key)
   size_t len, cap;
   char *buf;
 
-  retval = 1;
+  retval = -1;
   len = 0;
   buf = xmalloc (cap = 64);
 
@@ -733,7 +733,7 @@ rl_bracketed_paste_begin (count, key)
       if (len == cap)
 	buf = xrealloc (buf, cap + 1);
       buf[len] = '\0';
-      retval = rl_insert_text (buf);
+      retval = rl_insert_text (buf) ? 0 : -1;
     }
 
   xfree (buf);
-- 
2.17.0.rc0.231.g781580f067-goog

Reply via email to