nano-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/2] input: recognize the start and stop sequences of a bracketed


From: Benno Schulenberg
Subject: [PATCH 1/2] input: recognize the start and stop sequences of a bracketed paste
Date: Sun, 5 Jan 2020 16:32:06 +0100

From: Brand Huntsman <address@hidden>

Also, tell the terminal to switch on bracketed-paste mode, and toggle
a boolean when the start and stop sequences of such a paste are seen.
This boolean can later be used to suppress auto-indent and such.

Signed-off-by: Brand Huntsman <address@hidden>
---
 src/global.c | 20 ++++++++++++++++++++
 src/nano.c   | 21 +++++++++++++++++++++
 src/nano.h   |  3 +++
 src/prompt.c |  2 ++
 src/proto.h  |  2 ++
 src/winio.c  | 12 ++++++++++++
 6 files changed, 60 insertions(+)

diff --git a/src/global.c b/src/global.c
index 067d202d..b95dcf2b 100644
--- a/src/global.c
+++ b/src/global.c
@@ -38,6 +38,8 @@ bool meta_key;
                /* Whether the current keystroke is a Meta key. */
 bool shift_held;
                /* Whether Shift was being held together with a movement key. */
+bool bracketed_paste = FALSE;
+               /* Whether text is being pasted into nano from outside. */
 bool focusing = TRUE;
                /* Whether an update of the edit window should center the 
cursor. */
 
@@ -336,6 +338,11 @@ void do_cancel(void)
 {
 }
 
+/* Ignore the start and stop sequences of a bracketed paste. */
+void do_nothing(void)
+{
+}
+
 /* Add a function to the linked list of functions. */
 void add_to_funcs(void (*func)(void), int menus, const char *desc,
                                        const char *help, bool blank_after, 
bool viewok)
@@ -447,6 +454,16 @@ const keystruct *get_shortcut(int *kbinput)
                                                (*kbinput >= 0xA0 && *kbinput 
<= 0xFF)))
                return NULL;
 
+       if (bracketed_paste && *kbinput != BRACKETED_PASTE_MARKER) {
+               /* Beep and ignore all non-printable characters in prompts. */
+               if (currmenu != MMAIN)
+                       return NULL;
+
+               /* Beep and ignore most non-printable characters in buffer. */
+               if (*kbinput != 0x9 && *kbinput != 0xA && *kbinput != 0xD)
+                       return NULL;
+       }
+
        for (keystruct *s = sclist; s != NULL; s = s->next) {
                if ((s->menus & currmenu) && *kbinput == s->keycode &&
                                                                                
meta_key == s->meta)
@@ -1396,6 +1413,9 @@ void shortcut_init(void)
 #ifdef ENABLE_SPELLER
        add_to_sclist(MMAIN, "F12", 0, do_spell, 0);
 #endif
+
+       /* Catch and ignore bracketed paste marker keys. */
+       add_to_sclist(MMOST|MHELP|MBROWSER|MYESNO, "", BRACKETED_PASTE_MARKER, 
do_nothing, 0);
 }
 
 #ifndef NANO_TINY
diff --git a/src/nano.c b/src/nano.c
index 34eafe29..557a1903 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -482,6 +482,13 @@ void say_there_is_no_help(void)
 }
 #endif
 
+/* Tell the terminal to disable bracketed pastes. */
+void disable_bracketed_paste(void)
+{
+       printf("\e[?2004l");
+       fflush(stdout);
+}
+
 /* Exit normally: restore the terminal state and save history files. */
 void finish(void)
 {
@@ -501,6 +508,8 @@ void finish(void)
        curs_set(1);
        endwin();
 
+       disable_bracketed_paste();
+
        /* Restore the old terminal settings. */
        tcsetattr(0, TCSANOW, &original_state);
 
@@ -532,6 +541,8 @@ void die(const char *msg, ...)
        curs_set(1);
        endwin();
 
+       disable_bracketed_paste();
+
        /* Restore the old terminal settings. */
        tcsetattr(0, TCSANOW, &original_state);
 
@@ -1097,6 +1108,8 @@ bool scoop_stdin(void)
        endwin();
        tcsetattr(0, TCSANOW, &original_state);
 
+       disable_bracketed_paste();
+
        /* When input comes from a terminal, show a helpful message. */
        if (isatty(STANDARD_INPUT))
                fprintf(stderr, _("Reading data from keyboard; "
@@ -1216,6 +1229,8 @@ RETSIGTYPE do_suspend(int signal)
        curs_set(1);
        endwin();
 
+       disable_bracketed_paste();
+
        /* Display our helpful message. */
        printf(_("Use \"fg\" to return to nano.\n"));
        fflush(stdout);
@@ -1323,6 +1338,8 @@ void regenerate_screen(void)
        endwin();
        doupdate();
 
+       disable_bracketed_paste();
+
        /* Put the terminal in the desired state again, recreate the subwindows
         * with their (new) sizes, and redraw the contents of these windows. */
        terminal_init();
@@ -1481,6 +1498,10 @@ void terminal_init(void)
        } else
                tcsetattr(0, TCSANOW, &desired_state);
 #endif
+
+       /* Tell the terminal to enable bracketed pastes. */
+       printf("\e[?2004h");
+       fflush(stdout);
 }
 
 /* Ask ncurses for a keycode, or assign a default one. */
diff --git a/src/nano.h b/src/nano.h
index ba05501c..2011fcde 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -610,6 +610,9 @@ enum
 /* A special keycode for when <Tab> is pressed while the mark is on. */
 #define INDENT_KEY 0x4F1
 
+/* A special keycode to signal the beginning and end of a bracketed paste. */
+#define BRACKETED_PASTE_MARKER 0x4FB
+
 #ifdef USE_SLANG
 #ifdef ENABLE_UTF8
 #define KEY_BAD 0xFF  /* Clipped error code. */
diff --git a/src/prompt.c b/src/prompt.c
index d579f763..7f328394 100644
--- a/src/prompt.c
+++ b/src/prompt.c
@@ -486,6 +486,8 @@ functionptrtype acquire_an_answer(int *actual, bool 
allow_tabs,
 
                if (func == do_cancel || func == do_enter)
                        break;
+               if (func == do_nothing)
+                       finished = FALSE;
 
 #ifdef ENABLE_TABCOMP
                if (func != do_tab)
diff --git a/src/proto.h b/src/proto.h
index 682538b1..343499c4 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -30,6 +30,7 @@ extern bool on_a_vt;
 
 extern bool meta_key;
 extern bool shift_held;
+extern bool bracketed_paste;
 
 extern bool focusing;
 
@@ -695,3 +696,4 @@ void flip_newbuffer(void);
 #endif
 void discard_buffer(void);
 void do_cancel(void);
+void do_nothing(void);
diff --git a/src/winio.c b/src/winio.c
index 43925289..d7c9856c 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -1105,6 +1105,18 @@ int convert_sequence(const int *seq, size_t length, int 
*consumed)
                                                        /* Discard broken 
sequences that Slang produces. */
                                                        *consumed = 4;
 #endif
+                                               else if (length > 4 && seq[2] 
== '0' && seq[4] == '~') {
+                                                       /* Esc [ 2 0 0 ~ == 
start of a bracketed paste,
+                                                        * Esc [ 2 0 1 ~ == end 
of a bracketed paste. */
+                                                       *consumed = 5;
+                                                       if (seq[3] == '0') {
+                                                               bracketed_paste 
= TRUE;
+                                                               return 
BRACKETED_PASTE_MARKER;
+                                                       } else if (seq[3] == 
'1') {
+                                                               bracketed_paste 
= FALSE;
+                                                               return 
BRACKETED_PASTE_MARKER;
+                                                       }
+                                               }
                                                break;
                                        case '3': /* Esc [ 3 ~ == Delete on 
VT220/VT320/
                                                           * Linux 
console/xterm/Terminal. */
-- 
2.24.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]