]> git.wh0rd.org Git - nano.git/commitdiff
low-level input overhaul
authorDavid Lawrence Ramsey <pooka109@gmail.com>
Sun, 17 Aug 2003 02:48:43 +0000 (02:48 +0000)
committerDavid Lawrence Ramsey <pooka109@gmail.com>
Sun, 17 Aug 2003 02:48:43 +0000 (02:48 +0000)
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1523 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
configure.ac
files.c
nano.c
nano.h
proto.h
rcfile.c
winio.c

index ee70774da5b4c6290ab2672b6aae4216a60d648c..1cbd48325f92a1459a96c51c8d343ee44e854400 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,36 @@
 CVS code -
-
+- General:
+       - Complete overhaul and abstraction of the lowest level of
+         keyboard input, mostly rewritten but incorporating a few bits
+         from the old functions and adding support for Pico's Esc Esc
+         [three-digit decimal ASCII code] input method.  New functions
+         get_kbinput(), get_verbatim_kbinput(), get_ignored_kbinput(),
+         get_accepted_kbinput(), get_ascii_kbinput(),
+         get_escape_seq_kbinput(), and get_skip_tilde_kbinput().  These
+         should work properly on FreeBSD (due to code and input
+         provided by Lee Nelson and Wouter van Hemel, respectively).
+         (DLR)
+       - The -K/--keypad command line/rcfile option has been removed,
+         and keypad() is now always TRUE.  keypad_on() in winio.c and
+         the check for _use_keypad in configure.ac have both been
+         removed. (DLR)
+       - The -d/--rebinddelete command line/rcfile option, equivalent
+         to Pico's -d, has been added.  It is intended to work around
+         the problem with Backspace/Delete confusion on some terminals,
+         notably FreeBSD; if your Backspace key acts like Delete, this
+         option will fix that. (DLR)
+- files.c:
+  do_browser():
+       - Some of the Pico compatibility options in the file browser
+         that don't work properly for Pico 4.6 have been removed. 
+         Backspace, 'g', 'l', 'q', and 'u' are invalid, 'd' deletes the
+         highlighted file, and 'r' renames the highlighted file. (DLR)
+- nano.h:
+       - Define KEY_SUSPEND as -1 when slang is used, as slang has no
+         KEY_SUSPEND equivalent.  When nano is compiled with slang
+         support, pressing Ctrl-Z to suspend nano at the Linux console
+         with keypad(TRUE) generates Ctrl-Z instead of KEY_SUSPEND
+         (which is what ncurses generates then). (DLR)
 - AUTHORS
        - Updated to show 1.2/1.3 maintainers.
 
index c7302cb3ade4486341d1d31af698df901ee3d2a0..da0ef4140ac7f07a2d6cd8c5c4ea6083462ec626 100644 (file)
@@ -330,20 +330,6 @@ AC_CHECK_LIB([$CURSES_LIB_NAME], use_default_colors, AC_DEFINE(HAVE_USE_DEFAULT_
 if test x$slang_support != xyes; then
     AC_CHECK_LIB([$CURSES_LIB_NAME], wresize, AC_DEFINE(HAVE_WRESIZE, 1, [Define this if you have the wresize function in your ncurses-type library.]))
     AC_CHECK_LIB([$CURSES_LIB_NAME], resizeterm, AC_DEFINE(HAVE_RESIZETERM, 1, [Define this if you have the resizeterm function in your ncurses-type library.]))
-
-    # Taken from aumix (can't tell from the variable name?)
-    AC_CACHE_CHECK([for private member _use_keypad in WINDOW],
-    aumix_cv_struct_window_usekeypad,
-    [AC_TRY_COMPILE([#ifdef HAVE_NCURSES_H
-#include <ncurses.h>
-#else
-#include <curses.h>
-#endif], [WINDOW w; w._use_keypad;],
-    aumix_cv_struct_window_usekeypad=yes, aumix_cv_struct_window_usekeypad=no)])
-    
-    if test $aumix_cv_struct_window_usekeypad = yes; then
-       AC_DEFINE(HAVE_USEKEYPAD, 1, [Define this if your curses lib has the _use_keypad flag.])
-    fi
 fi
 
 dnl Parse any configure options
diff --git a/files.c b/files.c
index b70ed9461f01e3e155985f135f4d5ecb2c152d2d..4193a932756f26e0d25532373cb8c531f50fc2cf 100644 (file)
--- a/files.c
+++ b/files.c
@@ -2477,9 +2477,9 @@ char *do_browser(const char *inpath)
     struct stat st;
     char *foo, *retval = NULL;
     static char *path = NULL;
-    int numents = 0, i = 0, j = 0, kbinput = 0, longest = 0, abort = 0;
-    int col = 0, selected = 0, editline = 0, width = 0, filecols = 0;
-    int lineno = 0, kb;
+    int numents = 0, i = 0, j = 0, kbinput = -1, meta, longest = 0;
+    int abort = 0, col = 0, selected = 0, editline = 0, width = 0;
+    int filecols = 0, lineno = 0;
     char **filelist = (char **)NULL;
 #if !defined(DISABLE_MOUSE) && defined(NCURSES_MOUSE_VERSION)
     MEVENT mevent;
@@ -2505,7 +2505,6 @@ char *do_browser(const char *inpath)
     /* Sort the list by directory first, then alphabetically */
     qsort(filelist, numents, sizeof(char *), diralphasort);
 
-    kb = keypad_on(edit, 1);
     titlebar(path);
     bottombars(browser_list);
     curs_set(0);
@@ -2569,34 +2568,23 @@ char *do_browser(const char *inpath)
             break;
 #endif
        case NANO_UP_KEY:
-       case KEY_UP:
-       case 'u':
            if (selected - width >= 0)
                selected -= width;
            break;
        case NANO_BACK_KEY:
-       case KEY_LEFT:
-       case NANO_BACKSPACE_KEY:
-       case 127:
-       case 'l':
            if (selected > 0)
                selected--;
            break;
-       case KEY_DOWN:
        case NANO_DOWN_KEY:
-       case 'd':
            if (selected + width <= numents - 1)
                selected += width;
            break;
-       case KEY_RIGHT:
        case NANO_FORWARD_KEY:
-       case 'r':
            if (selected < numents - 1)
                selected++;
            break;
        case NANO_PREVPAGE_KEY:
        case NANO_PREVPAGE_FKEY:
-       case KEY_PPAGE:
        case '-':
            if (selected >= (editwinrows + lineno % editwinrows) * width)
                selected -= (editwinrows + lineno % editwinrows) * width; 
@@ -2605,7 +2593,6 @@ char *do_browser(const char *inpath)
            break;
        case NANO_NEXTPAGE_KEY:
        case NANO_NEXTPAGE_FKEY:
-       case KEY_NPAGE: 
        case ' ':
            selected += (editwinrows - lineno % editwinrows) * width;
            if (selected >= numents)
@@ -2615,7 +2602,6 @@ char *do_browser(const char *inpath)
        case NANO_HELP_FKEY:
             do_help();
             break;
-       case KEY_ENTER:
        case NANO_ENTER_KEY:
        case 's': /* More Pico compatibility */
        case 'S':
@@ -2678,10 +2664,8 @@ char *do_browser(const char *inpath)
            return do_browser(path);
 
        /* Goto a specific directory */
-       case 'g':       /* Pico compatibility */
-       case 'G':
        case NANO_GOTO_KEY:
-
+       case NANO_GOTO_FKEY:
            curs_set(1);
            j = statusq(0, gotodir_list, "",
 #ifndef NANO_SMALL
@@ -2726,11 +2710,10 @@ char *do_browser(const char *inpath)
            return do_browser(path);
 
        /* Stuff we want to abort the browser */
-       case 'q':
-       case 'Q':
        case 'e':       /* Pico compatibility, yeech */
        case 'E':
        case NANO_CANCEL_KEY:
+       case NANO_EXIT_KEY:
        case NANO_EXIT_FKEY:
            abort = 1;
            break;
@@ -2806,12 +2789,11 @@ char *do_browser(const char *inpath)
            }
        }
        wrefresh(edit);
-    } while ((kbinput = wgetch(edit)) != NANO_EXIT_KEY);
+    } while ((kbinput = get_kbinput(edit, &meta, ISSET(REBIND_DELETE))) != NANO_EXIT_KEY && kbinput != NANO_EXIT_FKEY);
     curs_set(1);
     blank_edit();
     titlebar(NULL);
     edit_refresh();
-    kb = keypad_on(edit, kb);
 
     /* cleanup */
     free_charptrarray(filelist, numents);
diff --git a/nano.c b/nano.c
index 1cb3aedc35591d9245a0a7e93905caad1480e6b1..c7bb5f528633d946c5fda5b36f7ca1ff96c0cf47 100644 (file)
--- a/nano.c
+++ b/nano.c
@@ -66,9 +66,6 @@ static sigjmp_buf jmpbuf;     /* Used to return to mainloop after SIGWINCH */
 /* What we do when we're all set to exit */
 RETSIGTYPE finish(int sigage)
 {
-    keypad(edit, TRUE);
-    keypad(bottomwin, TRUE);
-
     if (!ISSET(NO_HELP)) {
        mvwaddstr(bottomwin, 1, 0, hblank);
        mvwaddstr(bottomwin, 2, 0, hblank);
@@ -251,9 +248,6 @@ void window_init(void)
 void mouse_init(void)
 {
     if (ISSET(USE_MOUSE)) {
-       keypad_on(edit, 1);
-       keypad_on(bottomwin, 1);
-
        mousemask(BUTTON1_RELEASED, NULL);
        mouseinterval(50);
     } else
@@ -639,7 +633,6 @@ void usage(void)
     print1opt("-H", "--historylog", _("Log & read search/replace string history"));
     print1opt("-I", "--ignorercfiles", _("Don't look at nanorc files"));
 #endif
-    print1opt("-K", "--keypad", _("Use alternate keypad routines"));
 #ifndef NANO_SMALL
     print1opt("-M", "--mac", _("Write file in Mac format"));
     print1opt("-N", "--noconvert", _("Don't convert files from DOS/Mac format"));
@@ -660,6 +653,7 @@ void usage(void)
 #endif
     print1opt("-c", "--const", _("Constantly show cursor position"));
 #ifndef NANO_SMALL
+    print1opt("-d", "--rebinddelete", _("Fix Backspace if it acts like Delete"));
     print1opt("-i", "--autoindent", _("Automatically indent new lines"));
     print1opt("-k", "--cut", _("Let ^K cut from cursor to end of line"));
 #endif
@@ -3001,6 +2995,7 @@ int main(int argc, char *argv[])
     const shortcut *s;
     int keyhandled = 0;        /* Have we handled the keystroke yet? */
     int kbinput = -1;          /* Input from keyboard */
+    int meta;
 
 #ifndef NANO_SMALL
     const toggle *t;
@@ -3019,7 +3014,6 @@ int main(int argc, char *argv[])
        {"historylog", 0, 0, 'H'},
        {"ignorercfiles", 0, 0, 'I'},
 #endif
-       {"keypad", 0, 0, 'K'},
 #ifndef DISABLE_JUSTIFY
        {"quotestr", 1, 0, 'Q'},
 #endif
@@ -3032,6 +3026,7 @@ int main(int argc, char *argv[])
        {"syntax", 1, 0, 'Y'},
 #endif
        {"const", 0, 0, 'c'},
+       {"rebinddelete", 0, 0, 'd'},
        {"nofollow", 0, 0, 'l'},
 #if !defined(DISABLE_MOUSE) && defined(NCURSES_MOUSE_VERSION)
        {"mouse", 0, 0, 'm'},
@@ -3080,11 +3075,11 @@ int main(int argc, char *argv[])
 #endif
 
 #ifdef HAVE_GETOPT_LONG
-    while ((optchr = getopt_long(argc, argv, "h?BDFHIKMNQ:RST:VY:abcefgijklmo:pr:s:tvwxz",
+    while ((optchr = getopt_long(argc, argv, "h?BDFHIMNQ:RST:VY:abcdefgijklmo:pr:s:tvwxz",
                                 long_options, &option_index)) != -1) {
 #else
     while ((optchr =
-           getopt(argc, argv, "h?BDFHIKMNQ:RST:VY:abcefgijklmo:pr:s:tvwxz")) != -1) {
+           getopt(argc, argv, "h?BDFHIMNQ:RST:VY:abcdefgijklmo:pr:s:tvwxz")) != -1) {
 #endif
 
        switch (optchr) {
@@ -3118,9 +3113,6 @@ int main(int argc, char *argv[])
            SET(NO_RCFILE);
            break;
 #endif
-       case 'K':
-           SET(ALT_KEYPAD);
-           break;
 #ifndef NANO_SMALL
        case 'M':
            SET(MAC_FILE);
@@ -3173,6 +3165,9 @@ int main(int argc, char *argv[])
        case 'c':
            SET(CONSTUPDATE);
            break;
+       case 'd':
+           SET(REBIND_DELETE);
+           break;
 #ifndef NANO_SMALL
        case 'i':
            SET(AUTOINDENT);
@@ -3389,10 +3384,8 @@ int main(int argc, char *argv[])
     mouse_init();
 #endif
 
-    if (!ISSET(ALT_KEYPAD)) {
-       keypad(edit, TRUE);
-       keypad(bottomwin, TRUE);
-    }
+    keypad(edit, TRUE);
+    keypad(bottomwin, TRUE);
 
 #ifdef DEBUG
     fprintf(stderr, "Main: bottom win\n");
@@ -3456,160 +3449,12 @@ int main(int argc, char *argv[])
        raw();
 #endif
 
-       kbinput = wgetch(edit);
+       kbinput = get_kbinput(edit, &meta, ISSET(REBIND_DELETE));
 #ifdef DEBUG
        fprintf(stderr, "AHA!  %c (%d)\n", kbinput, kbinput);
 #endif
-       if (kbinput == 27) {    /* Grab Alt-key stuff first */
-           kbinput = wgetch(edit);
+       if (meta == 1) {
            switch (kbinput) {
-               /* Alt-O, suddenly very important ;) */
-           case 'O':
-               kbinput = wgetch(edit);
-               /* Shift or Ctrl + Arrows are Alt-O-[2,5,6]-[A,B,C,D] on some terms */
-               if (kbinput == '2' || kbinput == '5' || kbinput == '6')
-                   kbinput = wgetch(edit);
-               if ((kbinput <= 'D' && kbinput >= 'A') ||
-                       (kbinput <= 'd' && kbinput >= 'a'))
-                   kbinput = abcd(kbinput);
-               else if (kbinput <= 'z' && kbinput >= 'j')
-                   print_numlock_warning();
-               else if (kbinput <= 'S' && kbinput >= 'P')
-                   kbinput = KEY_F(kbinput - 79);
-#ifdef DEBUG
-               else {
-                   fprintf(stderr, "I got Alt-O-%c! (%d)\n",
-                           kbinput, kbinput);
-                   break;
-               }
-#endif
-               break;
-           case 27:
-               /* If we get Alt-Alt, the next keystroke should be the same as a
-                  control sequence */
-               modify_control_seq = 1;
-               keyhandled = 1;
-               break;
-           case '[':
-               kbinput = wgetch(edit);
-               switch (kbinput) {
-               case '1':       /* Alt-[-1-[0-5,7-9] = F1-F8 in X at least */
-                   kbinput = wgetch(edit);
-                   if (kbinput >= '1' && kbinput <= '5') {
-                       kbinput = KEY_F(kbinput - 48);
-                       wgetch(edit);
-                   } else if (kbinput >= '7' && kbinput <= '9') {
-                       kbinput = KEY_F(kbinput - 49);
-                       wgetch(edit);
-                   } else if (kbinput == '~')
-                       kbinput = KEY_HOME;
-#ifdef DEBUG
-                   else {
-                       fprintf(stderr, "I got Alt-[-1-%c! (%d)\n",
-                               kbinput, kbinput);
-                       break;
-                   }
-#endif
-                   break;
-               case '2':       /* Alt-[-2-[0,1,3,4] = F9-F12 in many terms */
-                   kbinput = wgetch(edit);
-                   switch (kbinput) {
-                   case '0':
-                       kbinput = KEY_F(9);
-                       wgetch(edit);
-                       break;
-                   case '1':
-                       kbinput = KEY_F(10);
-                       wgetch(edit);
-                       break;
-                   case '3':
-                       kbinput = KEY_F(11);
-                       wgetch(edit);
-                       break;
-                   case '4':
-                       kbinput = KEY_F(12);
-                       wgetch(edit);
-                       break;
-                   case '~':
-                       kbinput = NANO_INSERTFILE_KEY;
-                       break;
-#ifdef DEBUG
-                   default:
-                       fprintf(stderr, "I got Alt-[-2-%c! (%d)\n",
-                               kbinput, kbinput);
-                       break;
-#endif
-                   }
-                   break;
-               case '3':       /* Alt-[-3 = Delete? */
-                   kbinput = NANO_DELETE_KEY;
-                   wgetch(edit);
-                   break;
-               case '4':       /* Alt-[-4 = End? */
-                   kbinput = NANO_END_KEY;
-                   wgetch(edit);
-                   break;
-               case '5':       /* Alt-[-5 = Page Up */
-                   kbinput = KEY_PPAGE;
-                   wgetch(edit);
-                   break;
-               case 'V':       /* Alt-[-V = Page Up in Hurd Console */
-               case 'I':       /* Alt-[-I = Page Up - FreeBSD Console */
-                   kbinput = KEY_PPAGE;
-                   break;
-               case '6':       /* Alt-[-6 = Page Down */
-                   kbinput = KEY_NPAGE;
-                   wgetch(edit);
-                   break;
-               case 'U':       /* Alt-[-U = Page Down in Hurd Console */
-               case 'G':       /* Alt-[-G = Page Down - FreeBSD Console */
-                   kbinput = KEY_NPAGE;
-                   break;
-               case '7':
-                   kbinput = KEY_HOME;
-                   wgetch(edit);
-                   break;
-               case '8':
-                   kbinput = KEY_END;
-                   wgetch(edit);
-                   break;
-               case '9':       /* Alt-[-9 = Delete in Hurd Console */
-                   kbinput = KEY_DC;
-                   break;
-               case '@':       /* Alt-[-@ = Insert in Hurd Console */
-               case 'L':       /* Alt-[-L = Insert - FreeBSD Console */
-                   kbinput = NANO_INSERTFILE_KEY;
-                   break;
-               case '[':       /* Alt-[-[-[A-E], F1-F5 in Linux console */
-                   kbinput = wgetch(edit);
-                   if (kbinput >= 'A' && kbinput <= 'E')
-                       kbinput = KEY_F(kbinput - 64);
-                   break;
-               case 'A':
-               case 'B':
-               case 'C':
-               case 'D':
-               case 'a':
-               case 'b':
-               case 'c':
-               case 'd':
-                   kbinput = abcd(kbinput);
-                   break;
-               case 'H':
-                   kbinput = KEY_HOME;
-                   break;
-               case 'F':
-               case 'Y':               /* End Key in Hurd Console */
-                   kbinput = KEY_END;
-                   break;
-               default:
-#ifdef DEBUG
-                   fprintf(stderr, "I got Alt-[-%c! (%d)\n",
-                           kbinput, kbinput);
-#endif
-                   break;
-               }
-               break;
 #ifdef ENABLE_MULTIBUFFER
            case NANO_OPENPREV_KEY:
            case NANO_OPENPREV_ALTKEY:
@@ -3656,23 +3501,6 @@ int main(int argc, char *argv[])
                break;
            }
        }
-       /* Hack, make insert key do something useful, like insert file */
-       else if (kbinput == KEY_IC)
-           kbinput = NANO_INSERTFILE_KEY;
-
-       /* If modify_control_seq is set, we received an Alt-Alt
-          sequence before this, so we make this key a control sequence
-          by subtracting 32, 64, or 96, depending on its value. */
-       if (!keyhandled && modify_control_seq) {
-           if (kbinput == ' ')
-               kbinput -= 32;
-           else if (kbinput >= 'A' && kbinput < 'a')
-               kbinput -= 64;
-           else if (kbinput >= 'a' && kbinput <= 'z')
-               kbinput -= 96;
-
-           modify_control_seq = 0;
-       }
 
        /* Look through the main shortcut list to see if we've hit a
           shortcut key */
@@ -3707,19 +3535,18 @@ int main(int argc, char *argv[])
 
 #ifdef _POSIX_VDISABLE
        /* Don't even think about changing this string */
-       if (kbinput == 19)
-           statusbar(_("XOFF ignored, mumble mumble."));
-       if (kbinput == 17)
+       if (kbinput == NANO_CONTROL_Q)
            statusbar(_("XON ignored, mumble mumble."));
+       if (kbinput == NANO_CONTROL_S)
+           statusbar(_("XOFF ignored, mumble mumble."));
 #endif
        /* If we're in raw mode or using Alt-Alt-x, we have to catch
           Control-S and Control-Q */
-       if (kbinput == 17 || kbinput == 19)
+       if (kbinput == NANO_CONTROL_Q || kbinput == NANO_CONTROL_S)
            keyhandled = 1;
 
-       /* Catch ^Z by hand when triggered also
-          407 == ^Z in Linux console when keypad() is used? */
-       if (kbinput == 26 || kbinput == 407) {
+       /* Catch ^Z by hand when triggered also */
+       if (kbinput == NANO_SUSPEND_KEY) {
            if (ISSET(SUSPEND))
                do_suspend(0);
            keyhandled = 1;
@@ -3734,18 +3561,10 @@ int main(int argc, char *argv[])
                break;
 #endif
 
-           case -1:            /* Stuff that we don't want to do squat */
-           case 0:             /* Erg */
-           case 29:            /* Ctrl-] */
-           case 410:           /* Must ignore this, it's sent when we resize */
-#ifdef PDCURSES
-           case 541:           /* ???? */
-           case 542:           /* Control and alt in Windows *shrug* */
-           case 543:           /* Right ctrl key */
-           case 544:
-           case 545:           /* Right alt key */
-#endif
-
+           case NANO_CONTROL_3:        /* Ctrl-[ (Esc), which should
+                                        * have been handled before we
+                                        * got here */
+           case NANO_CONTROL_5:        /* Ctrl-] */
                break;
            default:
 #ifdef DEBUG
diff --git a/nano.h b/nano.h
index b442503b9677ce49b78bb710388feb112a6c3ab0..0444ab005a21bbdde2366154d83fcc34157f522b 100644 (file)
--- a/nano.h
+++ b/nano.h
@@ -48,6 +48,7 @@
 #include <slcurses.h>
 #define KEY_IC SL_KEY_IC
 #define KEY_DC SL_KEY_DELETE
+#define KEY_SUSPEND -1
 #elif defined(HAVE_NCURSES_H)
 #include <ncurses.h>
 #else /* Uh oh */
@@ -244,7 +245,7 @@ typedef struct historyheadtype {
 #define MAC_FILE               (1<<20)
 #define SMOOTHSCROLL           (1<<21)
 #define DISABLE_CURPOS         (1<<22) /* Damn, we still need it */
-#define ALT_KEYPAD             (1<<23)
+#define REBIND_DELETE          (1<<23)
 #define NO_CONVERT             (1<<24)
 #define BACKUP_FILE            (1<<25)
 #define NO_RCFILE              (1<<26)
@@ -283,11 +284,12 @@ typedef struct historyheadtype {
 #define NANO_CONTROL_X 24
 #define NANO_CONTROL_Y 25
 #define NANO_CONTROL_Z 26
-
+#define NANO_CONTROL_3 27
 #define NANO_CONTROL_4 28
 #define NANO_CONTROL_5 29
 #define NANO_CONTROL_6 30
 #define NANO_CONTROL_7 31
+#define NANO_CONTROL_8 127
 
 #define NANO_ALT_A 'a'
 #define NANO_ALT_B 'b'
diff --git a/proto.h b/proto.h
index 9ad6a42b14b0e2e099f3aa82640007a6ca583736..609d6c6eb3236fe57eabf7b4cfeb443f45bc1cc0 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -424,6 +424,14 @@ int check_wildcard_match(const char *text, const char *pattern);
 #endif
 
 /* Public functions in winio.c */
+int get_kbinput(WINDOW *win, int *meta, int rebind_delete);
+char *get_verbatim_kbinput(WINDOW *win, int *kbinput_len);
+int get_ignored_kbinput(WINDOW *win);
+int get_accepted_kbinput(WINDOW *win, int kbinput, int *meta,
+       int rebind_delete);
+int get_ascii_kbinput(WINDOW *win, int kbinput);
+int get_escape_seq_kbinput(WINDOW *win, int kbinput);
+int get_skip_tilde_kbinput(WINDOW *win, int errval, int retval);
 int do_first_line(void);
 int do_last_line(void);
 int xpt(const filestruct *fileptr, int index);
@@ -482,7 +490,6 @@ int do_cursorpos(int constant);
 int do_cursorpos_void(void);
 int line_len(const char *ptr);
 int do_help(void);
-int keypad_on(WINDOW *win, int newval);
 void do_replace_highlight(int highlight_flag, const char *word);
 void fix_editbot(void);
 #ifdef DEBUG
index cbdd52b68bb398b0886cca44de54f49bcaa290d5..071b7654bb0815ea08401a9c6f59709357e709f6 100644 (file)
--- a/rcfile.c
+++ b/rcfile.c
@@ -49,7 +49,6 @@ const static rcoption rcopts[] = {
 #ifndef DISABLE_WRAPJUSTIFY
     {"fill", 0},
 #endif
-    {"keypad", ALT_KEYPAD},
 #if !defined(DISABLE_MOUSE) && defined(NCURSES_MOUSE_VERSION)
     {"mouse", USE_MOUSE},
 #endif
@@ -68,6 +67,7 @@ const static rcoption rcopts[] = {
     {"operatingdir", 0},
 #endif
     {"preserve", PRESERVE},
+    {"rebinddelete", REBIND_DELETE},
 #ifndef DISABLE_JUSTIFY
     {"quotestr", 0},
 #endif
diff --git a/winio.c b/winio.c
index dd72bcc3c0258d550e7f615dbb8cb1205e4e5321..1a7590023c595b0663deda6df4c1bb91130aee18 100644 (file)
--- a/winio.c
+++ b/winio.c
@@ -34,6 +34,295 @@ static int statblank = 0;   /* Number of keystrokes left after
                                   we call statusbar(), before we
                                   actually blank the statusbar */
 
+/* Read in a single input character.  If it's ignored, swallow it and go
+ * on.  Otherwise, try to translate it from ASCII and extended (keypad)
+ * input.  Assume nodelay(win) is FALSE. */
+int get_kbinput(WINDOW *win, int *meta, int rebind_delete)
+{
+    int kbinput, retval;
+
+    kbinput = get_ignored_kbinput(win);
+    retval = get_accepted_kbinput(win, kbinput, meta, rebind_delete);
+
+    return retval;
+}
+
+/* Read in a string of input characters (e. g. an escape sequence)
+ * verbatim, and return the length of the string in kbinput_len.  Assume
+ * nodelay(win) is FALSE. */
+char *get_verbatim_kbinput(WINDOW *win, int *kbinput_len)
+{
+    char *verbatim_kbinput;
+    int kbinput = wgetch(win);
+
+    verbatim_kbinput = charalloc(1);
+    verbatim_kbinput[0] = kbinput;
+    *kbinput_len = 1;
+
+    if (kbinput >= '0' && kbinput <= '2')
+       /* Entering a three-digit decimal ASCII code from 000-255 in
+        * verbatim mode will produce the corresponding ASCII
+        * character. */
+       verbatim_kbinput[0] = (char)get_ascii_kbinput(win, kbinput);
+    else {
+       nodelay(win, TRUE);
+       while ((kbinput = wgetch(win)) != ERR) {
+           *kbinput_len++;
+           verbatim_kbinput = charealloc(verbatim_kbinput, *kbinput_len);
+           verbatim_kbinput[*kbinput_len - 1] = (char)kbinput;
+       }
+       nodelay(win, FALSE);
+    }
+
+#ifdef DEBUG
+    fprintf(stderr, "get_verbatim_kbinput(): verbatim_kbinput = %s\n", verbatim_kbinput);
+#endif
+    return verbatim_kbinput;
+}
+
+/* Swallow input characters that should be quietly ignored, and return
+ * the first input character that shouldn't be. */
+int get_ignored_kbinput(WINDOW *win)
+{
+    int kbinput;
+
+    while (1) {
+       kbinput = wgetch(win);
+       switch (kbinput) {
+           case ERR:
+           case KEY_RESIZE:
+#ifdef PDCURSES
+           case KEY_SHIFT_L:
+           case KEY_SHIFT_R:
+           case KEY_CONTROL_L:
+           case KEY_CONTROL_R:
+           case KEY_ALT_L:
+           case KEY_ALT_R:
+#endif
+#ifdef DEBUG
+               fprintf(stderr, "get_ignored_kbinput(): kbinput = %d\n", kbinput);
+#endif
+               break;
+           default:
+               return kbinput;
+       }
+    }
+}
+
+/* Translate acceptable ASCII and extended (keypad) input.  Set meta to
+ * 1 if we get a Meta sequence.  Assume nodelay(win) is FALSE. */
+int get_accepted_kbinput(WINDOW *win, int kbinput, int *meta,
+       int rebind_delete)
+{
+    *meta = 0;
+
+    switch (kbinput) {
+       case NANO_CONTROL_3: /* Escape */
+           switch (kbinput = wgetch(win)) {
+               case NANO_CONTROL_3: /* Escape */
+                   kbinput = wgetch(win);
+                   /* Esc Esc [three-digit decimal ASCII code from
+                    * 000-255] == [corresponding ASCII character];
+                      Esc Esc 2 obviously can't be Ctrl-2 here */
+                   if (kbinput >= '0' && kbinput <= '2')
+                       kbinput = get_ascii_kbinput(win, kbinput);
+                   /* Esc Esc [character] == Ctrl-[character];
+                    * Ctrl-Space (Ctrl-2) == Ctrl-@ == Ctrl-` */
+                   else if (kbinput == ' ' || kbinput == '@' || kbinput == '`')
+                       kbinput = NANO_CONTROL_SPACE;
+                   /* Ctrl-3 (Ctrl-[, Esc) to Ctrl-7 (Ctrl-_) */
+                   else if (kbinput >= '3' && kbinput <= '7')
+                       kbinput -= 24;
+                   /* Ctrl-8 (Ctrl-?) */
+                   else if (kbinput == '8' || kbinput == '?')
+                       kbinput = NANO_CONTROL_8;
+                   /* Ctrl-A to Ctrl-_ */
+                   else if (kbinput >= 'A' && kbinput <= '_')
+                       kbinput -= 64;
+                   /* Ctrl-A to Ctrl-Z */
+                   else if (kbinput >= 'a' && kbinput <= 'z')
+                       kbinput -= 96;
+                   break;
+               /* Terminal breakage, part 1: We shouldn't get an escape
+                * sequence here for terminals that support Delete, but
+                * we do sometimes on FreeBSD.  Thank you, Wouter van
+                * Hemel. */
+               case '[':
+                   nodelay(win, TRUE);
+                   kbinput = wgetch(win);
+                   switch (kbinput) {
+                       case ERR:
+                           kbinput = '[';
+                           *meta = 1;
+                           break;
+                       default:
+                           kbinput = get_escape_seq_kbinput(win, kbinput);
+                           break;
+                   }
+                   nodelay(win, FALSE);
+                   break;
+               case '`':
+                   /* Esc Space == Esc ` */
+                   kbinput = ' ';
+                   break;
+               default:
+                   /* Esc [character] == Meta-[character] */
+                   if (isupper(kbinput))
+                       kbinput = tolower(kbinput);
+                   *meta = 1;
+                   break;
+           }
+           break;
+       case KEY_DOWN:
+           kbinput = NANO_DOWN_KEY;
+           break;
+       case KEY_UP:
+           kbinput = NANO_UP_KEY;
+           break;
+       case KEY_LEFT:
+           kbinput = NANO_BACK_KEY;
+           break;
+       case KEY_RIGHT:
+           kbinput = NANO_FORWARD_KEY;
+           break;
+       case KEY_HOME:
+           kbinput = NANO_HOME_KEY;
+           break;
+       case KEY_BACKSPACE:
+           kbinput = NANO_BACKSPACE_KEY;
+           break;
+       case KEY_DC:
+           /* Terminal breakage, part 2: We should only get KEY_DC when
+            * hitting Delete, but we get it when hitting Backspace
+            * sometimes on FreeBSD.  Thank you, Lee Nelson. */
+           kbinput = (rebind_delete) ? NANO_BACKSPACE_KEY : NANO_DELETE_KEY;
+           break;
+       case KEY_IC:
+           kbinput = NANO_INSERTFILE_KEY;
+           break;
+       case KEY_NPAGE:
+           kbinput = NANO_NEXTPAGE_KEY;
+           break;
+       case KEY_PPAGE:
+           kbinput = NANO_PREVPAGE_KEY;
+           break;
+       case KEY_ENTER:
+           kbinput = NANO_ENTER_KEY;
+           break;
+       case KEY_END:
+           kbinput = NANO_END_KEY;
+           break;
+       case KEY_SUSPEND:
+           kbinput = NANO_SUSPEND_KEY;
+           break;
+       default:
+           break;
+    }
+#ifdef DEBUG
+    fprintf(stderr, "get_accepted_kbinput(): kbinput = %d, meta = %d\n", kbinput, *meta);
+#endif
+    return kbinput;
+}
+
+/* Translate a three-digit decimal ASCII code from 000-255 into the
+ * corresponding ASCII character. */
+int get_ascii_kbinput(WINDOW *win, int kbinput)
+{
+    int retval;
+
+    switch (kbinput) {
+       case '0':
+       case '1':
+       case '2':
+           retval = (kbinput - 48) * 100;
+           break;
+       default:
+           return kbinput;
+    }
+
+    kbinput = wgetch(win);
+    switch (kbinput) {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+           retval += (kbinput - 48) * 10;
+           break;
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+           if (retval < 200) {
+               retval += (kbinput - 48) * 10;
+               break;
+           }
+       default:
+           return kbinput;
+    }
+
+    kbinput = wgetch(win);
+    switch (kbinput) {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+           retval += kbinput - 48;
+           break;
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+           if (retval < 250) {
+               retval += kbinput - 48;
+               break;
+           }
+       default:
+           return kbinput;
+    }
+
+#ifdef DEBUG
+    fprintf(stderr, "get_ascii_kbinput(): kbinput = %d\n", kbinput);
+#endif
+    return retval;
+}
+
+/* Translate common escape sequences for some keys.  These are generated
+ * when the terminal doesn't support those keys.  Assume nodelay(win) is
+ * TRUE. */
+int get_escape_seq_kbinput(WINDOW *win, int kbinput)
+{
+    switch (kbinput) {
+       case '3':
+           /* Esc [ 3 ~ == kdch1 on many terminals. */
+           kbinput = get_skip_tilde_kbinput(win, kbinput, NANO_DELETE_KEY);
+           break;
+       default:
+           break;
+    }
+    return kbinput;
+}
+
+/* If there is no next character, return the passed-in error value.  If
+ * the next character's a tilde, eat it and return the passed-in
+ * return value.  Otherwise, return the next character.  Assume
+ * nodelay(win) is TRUE. */
+int get_skip_tilde_kbinput(WINDOW *win, int errval, int retval)
+{
+    int kbinput = wgetch(win);
+    switch (kbinput) {
+       case ERR:
+           return errval;
+       case '~':
+           return retval;
+       default:
+           return kbinput;
+    }
+}
+
 int do_first_line(void)
 {
     current = fileage;
@@ -197,6 +486,7 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
                )
 {
     int kbinput;
+    int meta;
     static int x = -1;
        /* the cursor position in 'answer' */
     int xend;
@@ -247,7 +537,7 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
        input */
     wrefresh(edit);
 
-    while ((kbinput = wgetch(bottomwin)) != 13) {
+    while ((kbinput = get_kbinput(bottomwin, &meta, ISSET(REBIND_DELETE))) != NANO_ENTER_KEY) {
        for (t = s; t != NULL; t = t->next) {
 #ifdef DEBUG
            fprintf(stderr, "Aha! \'%c\' (%d)\n", kbinput, kbinput);
@@ -273,64 +563,45 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
            tabbed = 0;
 
        switch (kbinput) {
-
-           /* Stuff we want to equate with <enter>, ASCII 13 */
-       case 343:
-           ungetch(13);        /* Enter on iris-ansi $TERM, sometimes */
-           break;
-           /* Stuff we want to ignore */
-#ifdef PDCURSES
-       case 541:
-       case 542:
-       case 543:               /* Right ctrl again */
-       case 544:
-       case 545:               /* Right alt again */
-           break;
-#endif
 #if !defined(DISABLE_MOUSE) && defined(NCURSES_MOUSE_VERSION)
        case KEY_MOUSE:
            do_mouse();
            break;
 #endif
        case NANO_HOME_KEY:
-       case KEY_HOME:
            x = 0;
            break;
        case NANO_END_KEY:
-       case KEY_END:
            x = xend;
            break;
-       case KEY_RIGHT:
        case NANO_FORWARD_KEY:
            if (x < xend)
                x++;
            break;
-       case NANO_CONTROL_D:
+       case NANO_DELETE_KEY:
            if (x < xend) {
                memmove(answer + x, answer + x + 1, xend - x);
                xend--;
            }
            break;
-       case NANO_CONTROL_K:
-       case NANO_CONTROL_U:
+       case NANO_CUT_KEY:
+       case NANO_UNCUT_KEY:
            null_at(&answer, 0);
            xend = 0;
            x = 0;
            break;
-       case KEY_BACKSPACE:
-       case 127:
-       case NANO_CONTROL_H:
+       case NANO_BACKSPACE_KEY:
            if (x > 0) {
                memmove(answer + x - 1, answer + x, xend - x + 1);
                x--;
                xend--;
            }
            break;
-       case NANO_CONTROL_I:
+       case NANO_TAB_KEY:
 #ifndef NANO_SMALL
            /* tab history completion */
            if (history_list != NULL) {
-               if (!complete || last_kbinput != NANO_CONTROL_I) {
+               if (!complete || last_kbinput != NANO_TAB_KEY) {
                    history_list->current = (historytype *)history_list;
                    history_list->len = strlen(answer);
                }
@@ -358,15 +629,12 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
            }
 #endif
            break;
-       case KEY_LEFT:
        case NANO_BACK_KEY:
            if (x > 0)
                x--;
            break;
-       case KEY_UP:
        case NANO_UP_KEY:
 #ifndef NANO_SMALL
-  do_upkey:
            if (history_list != NULL) {
 
                /* if currentbuf is NULL, or if use_cb is 1, currentbuf
@@ -407,10 +675,8 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
            }
 #endif
            break;
-       case KEY_DOWN:
        case NANO_DOWN_KEY:
 #ifndef NANO_SMALL
-  do_downkey:
            if (history_list != NULL) {
 
                /* get newer search from the history list and save it 
@@ -452,71 +718,6 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
            }
 #endif
            break;
-       case KEY_DC:
-           goto do_deletekey;
-       case 27:
-           switch (kbinput = wgetch(edit)) {
-           case 'O':
-               switch (kbinput = wgetch(edit)) {
-               case 'F':
-                   x = xend;
-                   break;
-               case 'H':
-                   x = 0;
-                   break;
-               }
-               break;
-           case '[':
-               switch (kbinput = wgetch(edit)) {
-               case 'A':
-#ifndef NANO_SMALL
-                   goto do_upkey;
-#else
-                   break;
-#endif
-               case 'B':
-#ifndef NANO_SMALL
-                   goto do_downkey;
-#else
-                   break;
-#endif
-               case 'C':
-                   if (x < xend)
-                       x++;
-                   break;
-               case 'D':
-                   if (x > 0)
-                       x--;
-                   break;
-               case 'F':
-                   x = xend;
-                   break;
-               case 'H':
-                   x = 0;
-                   break;
-               case '1':
-               case '7':
-                   x = 0;
-                   goto skip_tilde;
-               case '3':
-                 do_deletekey:
-                   if (x < xend) {
-                       memmove(answer + x, answer + x + 1, xend - x);
-                       xend--;
-                   }
-                   goto skip_tilde;
-               case '4':
-               case '8':
-                   x = xend;
-                 skip_tilde:
-                   nodelay(edit, TRUE);
-                   kbinput = wgetch(edit);
-                   if (kbinput == '~' || kbinput == ERR)
-                       kbinput = -1;
-                   nodelay(edit, FALSE);
-                   break;
-               }
-               break;
            default:
 
                for (t = s; t != NULL; t = t->next) {
@@ -524,17 +725,14 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
                    fprintf(stderr, "Aha! \'%c\' (%d)\n", kbinput,
                            kbinput);
 #endif
-                   if (kbinput == t->val || kbinput == t->val - 32)
+                   if (meta == 1 && (kbinput == t->val || kbinput == t->val - 32))
                        /* We hit an Alt key.  Do like above.  We don't
                           just ungetch() the letter and let it get
                           caught above cause that screws the
                           keypad... */
                        return t->val;
                }
-           }
-           break;
 
-       default:
            if (kbinput < 32)
                break;
            answer = charealloc(answer, xend + 2);
@@ -1546,7 +1744,7 @@ int line_len(const char *ptr)
 int do_help(void)
 {
 #ifndef DISABLE_HELP
-    int i, page = 0, kbinput = 0, no_more = 0, kp;
+    int i, page = 0, kbinput = -1, meta, no_more = 0;
     int no_help_flag = 0;
     const shortcut *oldshortcut;
 
@@ -1563,8 +1761,6 @@ int do_help(void)
 
     currshortcut = help_list;
 
-    kp = keypad_on(edit, 1);
-
     if (ISSET(NO_HELP)) {
 
        /* Well, if we're going to do this, we should at least
@@ -1586,32 +1782,8 @@ int do_help(void)
            do_mouse();
            break;
 #endif
-       case 27:
-           kbinput = wgetch(edit);
-           switch(kbinput) {
-           case '[':
-               kbinput = wgetch(edit);
-               switch(kbinput) {
-                   case '5':   /* Alt-[-5 = Page Up */
-                       wgetch(edit);
-                       goto do_pageupkey;
-                   case 'V':   /* Alt-[-V = Page Up in Hurd Console */
-                   case 'I':   /* Alt-[-I = Page Up - FreeBSD Console */
-                       goto do_pageupkey;
-                   case '6':   /* Alt-[-6 = Page Down */
-                       wgetch(edit);
-                       goto do_pagedownkey;
-                   case 'U':   /* Alt-[-U = Page Down in Hurd Console */
-                   case 'G':   /* Alt-[-G = Page Down - FreeBSD Console */
-                       goto do_pagedownkey;
-               }
-               break;
-           }
-           break;
        case NANO_NEXTPAGE_KEY:
        case NANO_NEXTPAGE_FKEY:
-       case KEY_NPAGE:
-         do_pagedownkey:
            if (!no_more) {
                blank_edit();
                page++;
@@ -1619,8 +1791,6 @@ int do_help(void)
            break;
        case NANO_PREVPAGE_KEY:
        case NANO_PREVPAGE_FKEY:
-       case KEY_PPAGE:
-         do_pageupkey:
            if (page > 0) {
                no_more = 0;
                blank_edit();
@@ -1649,8 +1819,7 @@ int do_help(void)
            no_more = 1;
            continue;
        }
-    } while ((kbinput = wgetch(edit)) != NANO_EXIT_KEY &&
-            kbinput != NANO_EXIT_FKEY);
+    } while ((kbinput = get_kbinput(edit, &meta, ISSET(REBIND_DELETE))) != NANO_EXIT_KEY && kbinput != NANO_EXIT_FKEY);
 
     currshortcut = oldshortcut;
 
@@ -1664,7 +1833,6 @@ int do_help(void)
 
     curs_set(1);
     edit_refresh();
-    kp = keypad_on(edit, kp);
 
     /* The help_init() at the beginning allocated help_text, which has
        now been written to screen. */
@@ -1678,19 +1846,6 @@ int do_help(void)
     return 1;
 }
 
-int keypad_on(WINDOW *win, int newval)
-{
-/* This is taken right from aumix.  Don't sue me. */
-#ifdef HAVE_USEKEYPAD
-    int old = win->_use_keypad;
-    keypad(win, newval);
-    return old;
-#else
-    keypad(win, newval);
-    return 1;
-#endif /* HAVE_USEKEYPAD */
-}
-
 /* Highlight the current word being replaced or spell checked. */
 void do_replace_highlight(int highlight_flag, const char *word)
 {