nano-devel
[Top][All Lists]
Advanced

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

[Nano-devel] [PATCH v2] moving: add functions to jump to previous or fol


From: Benno Schulenberg
Subject: [Nano-devel] [PATCH v2] moving: add functions to jump to previous or following block of text
Date: Sat, 2 Jul 2016 14:50:44 +0200

And hard-bind the keys Ctrl+Up and Ctrl+Down to these functions.

This fulfills https://savannah.gnu.org/bugs/?48291.
---
 src/global.c | 17 +++++++++++++++++
 src/move.c   | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/nano.c   | 11 ++++++++---
 src/nano.h   |  2 ++
 src/proto.h  |  5 +++++
 src/winio.c  | 18 +++++++++++++-----
 6 files changed, 87 insertions(+), 8 deletions(-)

diff --git a/src/global.c b/src/global.c
index fb8cce2..aea4899 100644
--- a/src/global.c
+++ b/src/global.c
@@ -44,6 +44,8 @@ message_type lastmessage = HUSH;
        /* Messages of type HUSH should not overwrite type MILD nor ALERT. */
 
 #ifndef NANO_TINY
+int controlup = CONTROL_UP;
+int controldown = CONTROL_DOWN;
 int controlleft = CONTROL_LEFT;
 int controlright = CONTROL_RIGHT;
 #endif
@@ -570,6 +572,10 @@ void shortcut_init(void)
     const char *nano_nextline_msg = N_("Go to next line");
     const char *nano_home_msg = N_("Go to beginning of current line");
     const char *nano_end_msg = N_("Go to end of current line");
+#ifndef NANO_TINY
+    const char *nano_prevblock_msg = N_("Go to previous block of text");
+    const char *nano_nextblock_msg = N_("Go to next block of text");
+#endif
 #ifndef DISABLE_JUSTIFY
     const char *nano_parabegin_msg =
        N_("Go to beginning of paragraph; then of previous paragraph");
@@ -869,6 +875,13 @@ void shortcut_init(void)
     add_to_funcs(do_down_void, MMAIN|MBROWSER,
        next_line_tag, IFSCHELP(nano_nextline_msg), BLANKAFTER, VIEW);
 
+#ifndef NANO_TINY
+    add_to_funcs(do_prev_block, MMAIN,
+       N_("Prev Block"), IFSCHELP(nano_prevblock_msg), TOGETHER, VIEW);
+    add_to_funcs(do_next_block, MMAIN,
+       N_("Next Block"), IFSCHELP(nano_nextblock_msg), TOGETHER, VIEW);
+#endif
+
 #ifndef DISABLE_JUSTIFY
     add_to_funcs(do_para_begin_void, MMAIN|MWHEREIS,
        N_("Beg of Par"), IFSCHELP(nano_parabegin_msg), TOGETHER, VIEW);
@@ -1130,6 +1143,10 @@ void shortcut_init(void)
     add_to_sclist(MMAIN|MHELP|MBROWSER, "Up", do_up_void, 0);
     add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", do_down_void, 0);
     add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", do_down_void, 0);
+#ifndef NANO_TINY
+    add_to_sclist(MMOST, "M-7", do_prev_block, 0);
+    add_to_sclist(MMOST, "M-8", do_next_block, 0);
+#endif
 #ifndef DISABLE_JUSTIFY
     add_to_sclist(MMAIN, "M-(", do_para_begin_void, 0);
     add_to_sclist(MMAIN, "M-9", do_para_begin_void, 0);
diff --git a/src/move.c b/src/move.c
index 2f234e5..d9a15f8 100644
--- a/src/move.c
+++ b/src/move.c
@@ -210,6 +210,48 @@ void do_para_end_void(void)
 #endif /* !DISABLE_JUSTIFY */
 
 #ifndef NANO_TINY
+/* Move to the preceding block of text in the file. */
+void do_prev_block(void)
+{
+    bool is_text = FALSE, seen_text = FALSE;
+
+    /* Skip backward until first blank line after some nonblank line(s). */
+    while (openfile->current->prev != NULL && (!seen_text || is_text)) {
+       openfile->current = openfile->current->prev;
+       is_text = !white_string(openfile->current->data);
+       seen_text = seen_text || is_text;
+    }
+
+    /* Step forward one line again if this one is blank. */
+    if (openfile->current->next != NULL &&
+               white_string(openfile->current->data))
+       openfile->current = openfile->current->next;
+
+    openfile->current_x = 0;
+    openfile->placewewant = 0;
+
+    edit_redraw(NULL);
+}
+
+/* Move to the next block of text in the file. */
+void do_next_block(void)
+{
+    bool is_white = white_string(openfile->current->data);
+    bool seen_white = is_white;
+
+    /* Skip forward until first nonblank line after some blank line(s). */
+    while (openfile->current->next != NULL && (!seen_white || is_white)) {
+       openfile->current = openfile->current->next;
+       is_white = white_string(openfile->current->data);
+       seen_white = seen_white || is_white;
+    }
+
+    openfile->current_x = 0;
+    openfile->placewewant = 0;
+
+    edit_redraw(NULL);
+}
+
 /* Move to the previous word in the file.  If allow_punct is TRUE, treat
  * punctuation as part of a word.  If allow_update is TRUE, update the
  * screen afterwards. */
diff --git a/src/nano.c b/src/nano.c
index 367d3f3..7588156 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -2518,13 +2518,18 @@ int main(int argc, char **argv)
 
 #if !defined(NANO_TINY) && defined(HAVE_KEY_DEFINED)
     const char *keyvalue;
-    /* Ask ncurses for the key codes for Control+Left and Control+Right. */
+    /* Ask ncurses for the key codes for Control+Left and Control+Right,
+     * and guess at those for Control+Up and Control+Down. */
     keyvalue = tigetstr("kLFT5");
-    if (keyvalue != 0 && keyvalue != (char *)-1)
+    if (keyvalue != 0 && keyvalue != (char *)-1) {
        controlleft = key_defined(keyvalue);
+       controlup = controlleft + 21;
+    }
     keyvalue = tigetstr("kRIT5");
-    if (keyvalue != 0 && keyvalue != (char *)-1)
+    if (keyvalue != 0 && keyvalue != (char *)-1) {
        controlright = key_defined(keyvalue);
+       controldown = controlright - 35;
+    }
 #endif
 
 #ifdef DEBUG
diff --git a/src/nano.h b/src/nano.h
index 98ec049..ef21460 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -564,6 +564,8 @@ enum
 #define NANO_CONTROL_8 127
 
 /* Codes for "modified" Arrow keys, beyond KEY_MAX of ncurses. */
+#define CONTROL_UP 0x407
+#define CONTROL_DOWN 0x408
 #define CONTROL_LEFT 0x401
 #define CONTROL_RIGHT 0x402
 
diff --git a/src/proto.h b/src/proto.h
index c3386af..dab7e23 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -37,6 +37,8 @@ extern bool focusing;
 extern message_type lastmessage;
 
 #ifndef NANO_TINY
+extern int controlup;
+extern int controldown;
 extern int controlleft;
 extern int controlright;
 #endif
@@ -394,6 +396,8 @@ void do_para_end(bool allow_update);
 void do_para_end_void(void);
 #endif
 #ifndef NANO_TINY
+void do_prev_block(void);
+void do_next_block(void);
 void do_prev_word(bool allow_punct, bool allow_update);
 void do_prev_word_void(void);
 bool do_next_word(bool allow_punct, bool allow_update);
@@ -644,6 +648,7 @@ void do_tab(void);
 void do_indent(ssize_t cols);
 void do_indent_void(void);
 void do_unindent(void);
+bool white_string(const char *s);
 void do_undo(void);
 void do_redo(void);
 #endif
diff --git a/src/winio.c b/src/winio.c
index b966c3f..744eb66 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -638,7 +638,11 @@ int parse_kbinput(WINDOW *win)
        }
 
 #ifndef NANO_TINY
-       if (retval == controlleft)
+       if (retval == controlup)
+           retval = sc_seq_or(do_prev_block, 0);
+       else if (retval == controldown)
+           retval = sc_seq_or(do_next_block, 0);
+       else if (retval == controlleft)
            retval = sc_seq_or(do_prev_word_void, 0);
        else if (retval == controlright)
            retval = sc_seq_or(do_next_word_void, 0);
@@ -703,8 +707,9 @@ int convert_sequence(const int *seq, size_t seq_len)
                if (seq_len >= 5) {
                    switch (seq[4]) {
                        case 'A': /* Esc O 1 ; 5 A == Ctrl-Up on Terminal. */
+                           return CONTROL_UP;
                        case 'B': /* Esc O 1 ; 5 B == Ctrl-Down on Terminal. */
-                           return arrow_from_abcd(seq[4]);
+                           return CONTROL_DOWN;
                        case 'C': /* Esc O 1 ; 5 C == Ctrl-Right on Terminal. */
                            return CONTROL_RIGHT;
                        case 'D': /* Esc O 1 ; 5 D == Ctrl-Left on Terminal. */
@@ -773,8 +778,9 @@ int convert_sequence(const int *seq, size_t seq_len)
                    case 'Y': /* Esc O Y == F10 on Mach console. */
                        return KEY_F(10);
                    case 'a': /* Esc O a == Ctrl-Up on rxvt. */
+                       return CONTROL_UP;
                    case 'b': /* Esc O b == Ctrl-Down on rxvt. */
-                       return arrow_from_abcd(seq[1]);
+                       return CONTROL_DOWN;
                    case 'c': /* Esc O c == Ctrl-Right on rxvt. */
                        return CONTROL_RIGHT;
                    case 'd': /* Esc O d == Ctrl-Left on rxvt. */
@@ -848,8 +854,9 @@ int convert_sequence(const int *seq, size_t seq_len)
            case 'o':
                switch (seq[1]) {
                    case 'a': /* Esc o a == Ctrl-Up on Eterm. */
+                       return CONTROL_UP;
                    case 'b': /* Esc o b == Ctrl-Down on Eterm. */
-                       return arrow_from_abcd(seq[1]);
+                       return CONTROL_DOWN;
                    case 'c': /* Esc o c == Ctrl-Right on Eterm. */
                        return CONTROL_RIGHT;
                    case 'd': /* Esc o d == Ctrl-Left on Eterm. */
@@ -902,8 +909,9 @@ int convert_sequence(const int *seq, size_t seq_len)
                if (seq_len >= 5) {
                    switch (seq[4]) {
                        case 'A': /* Esc [ 1 ; 5 A == Ctrl-Up on xterm. */
+                           return CONTROL_UP;
                        case 'B': /* Esc [ 1 ; 5 B == Ctrl-Down on xterm. */
-                           return arrow_from_abcd(seq[4]);
+                           return CONTROL_DOWN;
                        case 'C': /* Esc [ 1 ; 5 C == Ctrl-Right on xterm. */
                            return CONTROL_RIGHT;
                        case 'D': /* Esc [ 1 ; 5 D == Ctrl-Left on xterm. */
-- 
2.8.4




reply via email to

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