RE: nano hangs when pasting five characters

"Doug Smythies" <[email protected]>
Newsgroups gmane.editors.nano.devel
Message-ID <[email protected]>
Hi Benno,

On 2025.02.28 02:29 Benno Schulenberg wrote:
> Op 27-02-2025 om 23:07 schreef Doug Smythies:
>> The issue is not keystroke based, but time based.
>> After the first one, 5 character pastes work fine if I paste repeatedly and rapidly.
>> 5 character pastes are always split if I paste repeatedly but very slowly.
>
> Yes, I suspected something like that when seeing, in your previous email,
> eight pastes in a row go fine.
>
>>                  key_buffer[waiting_codes++] = input;
>> +               napms(2);  /* rate limit the input */
>
> But when pasting, say, two thousand characters, it would take four seconds
> for the paste to complete.  That is not acceptable.  (One of the reasons
> for implementing bracketed pastes was to make large pastes go fast.  Going
> slow again is not an option.)

Agreed. It was just a test to help increase, at least my, understanding of what is going on.
It was never intended as a suggested solution, for exactly the reasons you mention.

>
> While trying to simulate your problem locally, I created this little script:
>
>    #!/bin/bash
>    sleep 5
>
>    xdotool key  --delay 0 Escape
>    xdotool type --delay 0 "[200~"
>
>    xdotool type --delay 0 "abcde"
>
>    xdotool key  --delay 0 Escape
>    xdotool type --delay 0 "[201~"
>
> Then I run this script in the background (./paste.sh &) and run a nano
> (src/nano -x_c README 2>TRAIL; grep hex TRAIL) and wait for the "ghost"
> to simulate a paste, and exit with ^X^Q.  Which gives me this:
>
> Sequence of hex codes:  1b  5b  32  30  30
> Sequence of hex codes:  7e
> Sequence of hex codes:  61
> Sequence of hex codes:  62
> Sequence of hex codes:  63
> Sequence of hex codes:  64
> Sequence of hex codes:  65
> Sequence of hex codes:  1b  5b  32  30  31
> Sequence of hex codes:  7e
> Sequence of hex codes:  18
> Sequence of hex codes:  11
>
> What?  Why is the "~" split from the rest?  Does Xorg buffer things
> by five bytes?  To check this, I made nano recognize also \e[41 and
> \e[42 as opening and closing sequences of a bracketed paste.  With
> an adjusted paste script, the first time I got this:
>
> Sequence of hex codes:  1b  5b  34
> Sequence of hex codes:  31
> Sequence of hex codes:  61  62  63  64  65
> Sequence of hex codes:  1b  5b  34
> Sequence of hex codes:  32
> Sequence of hex codes:  18
> Sequence of hex codes:  11
>
> Five subsequent times, I got this:
>
> Sequence of hex codes:  1b  5b  34
> Sequence of hex codes:  31
> Sequence of hex codes:  61
> Sequence of hex codes:  62
> Sequence of hex codes:  63
> Sequence of hex codes:  64
> Sequence of hex codes:  65
> Sequence of hex codes:  1b  5b  34
> Sequence of hex codes:  32
> Sequence of hex codes:  18
> Sequence of hex codes:  11
>
> Somehow something in the input pipeline seems to look at these codes
> and thinks to know how long escape sequences are, and cuts them off
> when a byte arrives that (it thinks) doesn't belong.
>
> Then I modified nano to recognize \e[31 and \e[32 instead, as escape
> sequences that start with \e[3 can be five bytes long.  Result:
>
> Sequence of hex codes:  1b  5b  33  31
> Sequence of hex codes:  61
> Sequence of hex codes:  62
> Sequence of hex codes:  63
> Sequence of hex codes:  64
> Sequence of hex codes:  65
> Sequence of hex codes:  1b  5b  33  32
> Sequence of hex codes:  18
> Sequence of hex codes:  11
>
> Indeed.  Something in the pipeline /thinks/ to know how long escape
> sequences that start with \e[x can be, and breaks them up when they
> are longer.  I begin to suspect ncurses.  It would mean that ncurses
> sometimes forgets about the existence of \e[200~ and \e[201~.
>
> Checked it for \e[58 and \e[59 too:
>
> Sequence of hex codes:  1b  5b  35  38
> Sequence of hex codes:  61
> Sequence of hex codes:  62  63  64  65
> Sequence of hex codes:  1b  5b  35  39
> Sequence of hex codes:  18
> Sequence of hex codes:  11

Thank you for your continued work on this.
I am struggling a bit with the timings of the different lines in relation to some of my previously reported testing.

In another branch of this thread, I mentioned that this:

diff --git a/src/winio.c b/src/winio.c
index 2fff0d9e..e13bceef 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -290,9 +290,12 @@ void read_keys_from(WINDOW *frame)
                input = wgetch(frame);

                /* If there aren't any more characters, stop reading. */
-               if (input == ERR)
-                       break;
-
+               if (input == ERR) {
+                       napms(20);  /* check for sender slower than here */
+                       input = wgetch(frame); /* check again */
+                               if (input == ERR)
+                                       break;
+               }
                /* When the keystroke buffer is full, extend it. */
                if (waiting_codes == capacity)
                        reserve_space_for(2 * capacity);

didn't work.
But it turns out that it works fine if the sleep is 29 mSec instead of 20.
28 mSec and below doesn't work. 29 mSec and above works.
I am not sure why that number is the threshold of working and have played with
other delays in an attempt to find a correlation without success.

... Doug
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.