nano

nano with my custom patches
git clone git://bsandro.tech/nano
Log | Files | Refs | README | LICENSE

commit 555a9878447d68b26ed4d505b56d6ba8bf228d71
parent c1df6dfd05a633fa9f18b5d517ee4c46bedf55d3
Author: Benno Schulenberg <bensberg@telfort.nl>
Date:   Thu, 27 Feb 2025 12:01:58 +0100

input: wait a bit for "~" when bracketed-paste sequence is incomplete

When pasting something into nano over OpenSSH_for_Windows, the final
tilde of the end-of-paste sequence can lag some 29 ms behind the rest
of the sequence, causing ncurses to split it off into a next batch of
bytes.  Accommodate for this by noticing the missing tilde and then
waiting at most one second for it to arrive.  This prevents the tilde
from appearing spuriously in the buffer after the paste.

This addresses https://savannah.gnu.org/bugs/?66858.
Reported-by: Doug Smythies <dsmythies@telus.net>

Diffstat:
Msrc/winio.c | 30++++++++++++++++++++++--------
1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/src/winio.c b/src/winio.c @@ -724,10 +724,30 @@ int convert_CSI_sequence(const int *seq, size_t length, int *consumed) /* Esc [ 2 n ; 2 ~ == F21...F24 on some terminals. */ *consumed = 5; #ifndef NANO_TINY - else if (length > 3 && seq[1] == '0' && seq[3] == '~') { + else { /* Esc [ 2 0 0 ~ == start of a bracketed paste, * Esc [ 2 0 1 ~ == end of a bracketed paste. */ - *consumed = 4; + int trailer = 0; + + if (length > 3 && seq[1] == '0' && seq[3] == '~') { + trailer = '~'; + *consumed = 4; + } else if (length == 3 && seq[1] == '0') { + /* Wait at most one second for the missing '~' character. */ + halfdelay(10); + disable_kb_interrupt(); + trailer = getch(); + *consumed = 3; + raw(); + } + + if (trailer != '~') { + /* Broken -- assume a truncated end-of-paste sequence. */ + bracketed_paste = FALSE; + *consumed = length; + return ERR; + } + if (seq[2] == '0') { bracketed_paste = TRUE; return BRACKETED_PASTE_MARKER; @@ -735,12 +755,6 @@ int convert_CSI_sequence(const int *seq, size_t length, int *consumed) bracketed_paste = FALSE; return BRACKETED_PASTE_MARKER; } - } else { - /* When invalid, assume it's a truncated end-of-paste sequence, - * in order to avoid a hang -- https://sv.gnu.org/bugs/?64996. */ - bracketed_paste = FALSE; - *consumed = length; - return ERR; } #endif break;