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.
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
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;
/* 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);
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;
break;
case NANO_NEXTPAGE_KEY:
case NANO_NEXTPAGE_FKEY:
- case KEY_NPAGE:
case ' ':
selected += (editwinrows - lineno % editwinrows) * width;
if (selected >= numents)
case NANO_HELP_FKEY:
do_help();
break;
- case KEY_ENTER:
case NANO_ENTER_KEY:
case 's': /* More Pico compatibility */
case 'S':
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
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;
}
}
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);
/* 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);
void mouse_init(void)
{
if (ISSET(USE_MOUSE)) {
- keypad_on(edit, 1);
- keypad_on(bottomwin, 1);
-
mousemask(BUTTON1_RELEASED, NULL);
mouseinterval(50);
} else
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"));
#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
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;
{"historylog", 0, 0, 'H'},
{"ignorercfiles", 0, 0, 'I'},
#endif
- {"keypad", 0, 0, 'K'},
#ifndef DISABLE_JUSTIFY
{"quotestr", 1, 0, 'Q'},
#endif
{"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'},
#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) {
SET(NO_RCFILE);
break;
#endif
- case 'K':
- SET(ALT_KEYPAD);
- break;
#ifndef NANO_SMALL
case 'M':
SET(MAC_FILE);
case 'c':
SET(CONSTUPDATE);
break;
+ case 'd':
+ SET(REBIND_DELETE);
+ break;
#ifndef NANO_SMALL
case 'i':
SET(AUTOINDENT);
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");
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:
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 */
#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;
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
#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 */
#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)
#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'
#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);
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
#ifndef DISABLE_WRAPJUSTIFY
{"fill", 0},
#endif
- {"keypad", ALT_KEYPAD},
#if !defined(DISABLE_MOUSE) && defined(NCURSES_MOUSE_VERSION)
{"mouse", USE_MOUSE},
#endif
{"operatingdir", 0},
#endif
{"preserve", PRESERVE},
+ {"rebinddelete", REBIND_DELETE},
#ifndef DISABLE_JUSTIFY
{"quotestr", 0},
#endif
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;
)
{
int kbinput;
+ int meta;
static int x = -1;
/* the cursor position in 'answer' */
int xend;
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);
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);
}
}
#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
}
#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
}
#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) {
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);
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;
currshortcut = help_list;
- kp = keypad_on(edit, 1);
-
if (ISSET(NO_HELP)) {
/* Well, if we're going to do this, we should at least
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++;
break;
case NANO_PREVPAGE_KEY:
case NANO_PREVPAGE_FKEY:
- case KEY_PPAGE:
- do_pageupkey:
if (page > 0) {
no_more = 0;
blank_edit();
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;
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. */
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)
{