commit c13b7f069979db5543f7f74a18c1d9ad541f17a6
parent 3e81914b8275ab5cb5640dbfdbf191fda68e053c
Author: David Lawrence Ramsey <pooka109@gmail.com>
Date: Sat, 1 Jan 2005 07:28:15 +0000
overhaul the high-level input routines for the statusbar to make them
more flexible, among other things, and add UTF-8 support to them in the
process; also update the copyright years of the modified files
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2210 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
Diffstat:
6 files changed, 380 insertions(+), 234 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -45,19 +45,38 @@ CVS code -
do_mouse() and moved to nano.c), do_verbatim_input(),
do_tab(), main(), and get_ascii_kbinput() (renamed to
get_word_kbinput()). The wide version of ncurses is required
- in order for output to work properly. (DLR; buffered
- input/output based on ideas from mutt 1.4.2.1; double-Escape
- input of Unicode characters suggested by Michael Piefel)
+ in order for wide/multibyte input and output to work properly.
+ (DLR; buffered input/output based on ideas from mutt 1.4.2.1;
+ double-Escape input of Unicode characters suggested by Michael
+ Piefel)
- More steps toward wide character/multibyte character support.
Movement and cursor display in the edit window should now work
properly with files containing multibyte characters, and text
- display of such files should work properly some of the time.
- New functions control_rep(), parse_char(), move_left(),
+ display of such files should now work properly as well. New
+ functions control_rep(), parse_char(), move_left(),
move_right(), and display_string_len(); changes to do_left(),
do_right(), do_delete(), breakable(), break_line(),
do_output(), get_buffer(), unget_input(), actual_x(),
strnlenpt(), display_string(), titlebar(), statusbar(),
onekey(), and do_credits(). (David Benbennick and DLR)
+ - Overhaul the high-level input routines for the statusbar to
+ make them read the shortcut lists for functions instead of
+ manually running them, to make nanogetstr() less complex, and
+ to increase flexibility. Note that currshortcut is now used
+ regardless of #ifdefs. Changes to shortcut_init() and
+ nanogetstr(); new functions do_statusbar_input(),
+ do_statusbar_mouse(), do_statusbar_home(), do_statusbar_end(),
+ do_statusbar_right(), do_statusbar_left(),
+ do_statusbar_backspace(), do_statusbar_delete(),
+ do_statusbar_cut_text(), and do_statusbar_output(). (DLR)
+ - Even more steps toward wide character/multibyte character
+ support. Movement and (most) cursor display at the statusbar
+ prompt should now work properly with a string containing
+ multibyte characters, and text display of such strings should
+ now (mostly) work properly as well. Changes to
+ do_statusbar_right(), do_statusbar_left(),
+ do_statusbar_backspace(), and do_statusbar_delete(). (David
+ Benbennick and DLR)
- cut.c:
do_cut_text()
- If keep_cutbuffer is FALSE, only blow away the text in the
@@ -100,6 +119,9 @@ CVS code -
loop if there are no more paragraphs after the current one and
the paragraph search left us on the magicline, so as to avoid
a segfault. (DLR)
+ do_input()
+ - Add finished parameter, used to indicate when we run or try to
+ run a function associated with a shortcut. (DLR)
main()
- Try to automatically detect whether UTF-8 support is needed by
setting the NO_UTF8 flag if setlocale() returns a string that
diff --git a/src/files.c b/src/files.c
@@ -2,7 +2,7 @@
/**************************************************************************
* files.c *
* *
- * Copyright (C) 1999-2004 Chris Allegretta *
+ * Copyright (C) 1999-2005 Chris Allegretta *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2, or (at your option) *
@@ -1738,9 +1738,7 @@ int do_writeout(bool exiting)
static bool did_cred = FALSE;
#endif
-#if !defined(DISABLE_BROWSER) || !defined(DISABLE_MOUSE)
currshortcut = writefile_list;
-#endif
if (exiting && filename[0] != '\0' && ISSET(TEMP_FILE)) {
retval = write_file(filename, FALSE, 0, FALSE);
@@ -2541,9 +2539,7 @@ char *do_browser(const char *inpath)
check_statusblank();
-#if !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE)
currshortcut = browser_list;
-#endif
editline = 0;
col = 0;
diff --git a/src/global.c b/src/global.c
@@ -2,7 +2,7 @@
/**************************************************************************
* global.c *
* *
- * Copyright (C) 1999-2004 Chris Allegretta *
+ * Copyright (C) 1999-2005 Chris Allegretta *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2, or (at your option) *
@@ -159,9 +159,7 @@ syntaxtype *syntaxes = NULL;
char *syntaxstr = NULL;
#endif
-#if !defined(DISABLE_BROWSER) || !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE)
const shortcut *currshortcut; /* Current shortcut list we're using */
-#endif
#ifndef NANO_SMALL
toggle *toggles = NULL;
@@ -614,12 +612,12 @@ void shortcut_init(bool unjustify)
/* Translators: try to keep this string under 10 characters long */
sc_init_one(&whereis_list, NANO_TOOTHERSEARCH_KEY, replace_msg,
IFHELP(nano_replace_msg, NANO_NO_KEY), NANO_REPLACE_FKEY,
- NANO_NO_KEY, VIEW, do_replace);
+ NANO_NO_KEY, VIEW, 0);
/* Translators: try to keep this string under 10 characters long */
sc_init_one(&whereis_list, NANO_TOGOTOLINE_KEY, go_to_line_msg,
IFHELP(nano_gotoline_msg, NANO_NO_KEY), NANO_GOTOLINE_FKEY,
- NANO_NO_KEY, VIEW, do_gotoline_void);
+ NANO_NO_KEY, VIEW, 0);
#ifndef DISABLE_JUSTIFY
/* Translators: try to keep this string under 10 characters long */
@@ -691,11 +689,11 @@ void shortcut_init(bool unjustify)
/* Translators: try to keep this string under 12 characters long */
sc_init_one(&replace_list, NANO_TOOTHERSEARCH_KEY, N_("No Replace"),
IFHELP(nano_whereis_msg, NANO_NO_KEY), NANO_REPLACE_FKEY,
- NANO_NO_KEY, VIEW, do_search);
+ NANO_NO_KEY, VIEW, 0);
sc_init_one(&replace_list, NANO_TOGOTOLINE_KEY, go_to_line_msg,
IFHELP(nano_gotoline_msg, NANO_NO_KEY), NANO_GOTOLINE_FKEY,
- NANO_NO_KEY, VIEW, do_gotoline_void);
+ NANO_NO_KEY, VIEW, 0);
#ifndef NANO_SMALL
sc_init_one(&replace_list, NANO_NO_KEY, case_sens_msg,
@@ -773,7 +771,7 @@ void shortcut_init(bool unjustify)
sc_init_one(&gotoline_list, NANO_TOOTHERWHEREIS_KEY,
N_("Go To Text"), IFHELP(nano_whereis_msg, NANO_NO_KEY),
- NANO_NO_KEY, NANO_NO_KEY, VIEW, do_search);
+ NANO_NO_KEY, NANO_NO_KEY, VIEW, 0);
#ifndef DISABLE_HELP
free_shortcutage(&help_list);
diff --git a/src/nano.c b/src/nano.c
@@ -2,7 +2,7 @@
/**************************************************************************
* nano.c *
* *
- * Copyright (C) 1999-2004 Chris Allegretta *
+ * Copyright (C) 1999-2005 Chris Allegretta *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2, or (at your option) *
@@ -2718,7 +2718,7 @@ void do_justify(bool full_justify)
size_t mark_beginx_save = mark_beginx;
#endif
int kbinput;
- bool meta_key, func_key, s_or_t;
+ bool meta_key, func_key, s_or_t, finished;
/* If we're justifying the entire file, start at the beginning. */
if (full_justify)
@@ -2984,7 +2984,7 @@ void do_justify(bool full_justify)
/* Now get a keystroke and see if it's unjustify. If not, put back
* the keystroke and return. */
- kbinput = do_input(&meta_key, &func_key, &s_or_t, FALSE);
+ kbinput = do_input(&meta_key, &func_key, &s_or_t, &finished, FALSE);
if (!meta_key && !func_key && s_or_t &&
kbinput == NANO_UNJUSTIFY_KEY) {
@@ -3386,7 +3386,7 @@ void terminal_init(void)
}
int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
- allow_funcs)
+ *finished, bool allow_funcs)
{
int input;
/* The character we read in. */
@@ -3402,6 +3402,7 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
#endif
*s_or_t = FALSE;
+ *finished = FALSE;
/* Read in a character. */
input = get_kbinput(edit, meta_key, func_key);
@@ -3477,7 +3478,8 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
if (have_shortcut) {
switch (input) {
- /* Handle the "universal" edit window shortcuts. */
+ /* Handle the "universal" statusbar prompt shortcuts,
+ * setting ran_s_or_t to TRUE to indicate it. */
case NANO_XON_KEY:
statusbar(_("XON ignored, mumble mumble."));
break;
@@ -3490,21 +3492,23 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
do_suspend(0);
break;
#endif
- /* Handle the normal edit window shortcuts. */
+ /* Handle the normal edit window shortcuts, setting
+ * finished to TRUE to indicate that we're done after
+ * running or trying to run their associated
+ * functions. */
default:
/* Blow away the text in the cutbuffer if we aren't
* cutting text. */
if (s->func != do_cut_text)
cutbuffer_reset();
- /* Run the function associated with this shortcut,
- * if there is one. */
if (s->func != NULL) {
if (ISSET(VIEW_MODE) && !s->viewok)
print_view_warning();
else
s->func();
}
+ *finished = TRUE;
break;
}
}
@@ -3577,9 +3581,6 @@ bool do_mouse(void)
edit_refresh();
}
}
- /* FIXME: If we clicked on a location in the statusbar, the cursor
- * should move to the location we clicked on. This functionality
- * should be in do_statusbar_mouse() when it's written. */
return retval;
}
@@ -4225,6 +4226,9 @@ int main(int argc, char **argv)
/* Whether we got a function key. */
bool s_or_t;
/* Whether we got a shortcut or toggle. */
+ bool ran_s_or_t;
+ /* Whether we ran a function associated with a
+ * shortcut. */
/* Make sure the cursor is in the edit window. */
reset_cursor();
@@ -4234,12 +4238,10 @@ int main(int argc, char **argv)
if (ISSET(CONSTUPDATE))
do_cursorpos(TRUE);
-#if !defined(DISABLE_BROWSER) || !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE)
currshortcut = main_list;
-#endif
/* Read in and interpret characters. */
- do_input(&meta_key, &func_key, &s_or_t, TRUE);
+ do_input(&meta_key, &func_key, &s_or_t, &ran_s_or_t, TRUE);
}
assert(FALSE);
}
diff --git a/src/proto.h b/src/proto.h
@@ -2,7 +2,7 @@
/**************************************************************************
* proto.h *
* *
- * Copyright (C) 1999-2004 Chris Allegretta *
+ * Copyright (C) 1999-2005 Chris Allegretta *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2, or (at your option) *
@@ -122,9 +122,7 @@ extern shortcut *spell_list;
extern shortcut *browser_list, *gotodir_list;
#endif
-#if !defined(DISABLE_BROWSER) || !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE)
extern const shortcut *currshortcut;
-#endif
#ifdef HAVE_REGEX_H
extern regex_t search_regexp;
@@ -391,7 +389,7 @@ void disable_flow_control(void);
void enable_flow_control(void);
void terminal_init(void);
int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
- allow_funcs);
+ *finished, bool allow_funcs);
#ifndef DISABLE_MOUSE
bool do_mouse(void);
#endif
@@ -569,6 +567,19 @@ const shortcut *get_shortcut(const shortcut *s_list, int *kbinput, bool
#ifndef NANO_SMALL
const toggle *get_toggle(int kbinput, bool meta_key);
#endif
+int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
+ bool *finished, bool allow_funcs);
+#ifndef DISABLE_MOUSE
+bool do_statusbar_mouse(void);
+#endif
+void do_statusbar_home(void);
+void do_statusbar_end(void);
+void do_statusbar_right(void);
+void do_statusbar_left(void);
+void do_statusbar_backspace(void);
+void do_statusbar_delete(void);
+void do_statusbar_cut_text(void);
+void do_statusbar_output(int *kbinput, size_t kbinput_len);
size_t xplustabs(void);
size_t actual_x(const char *str, size_t xplus);
size_t strnlenpt(const char *buf, size_t size);
diff --git a/src/winio.c b/src/winio.c
@@ -2,7 +2,7 @@
/**************************************************************************
* winio.c *
* *
- * Copyright (C) 1999-2004 Chris Allegretta *
+ * Copyright (C) 1999-2005 Chris Allegretta *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2, or (at your option) *
@@ -46,6 +46,10 @@ static size_t key_buffer_len = 0;
static int statusblank = 0; /* The number of keystrokes left after
* we call statusbar(), before we
* actually blank the statusbar. */
+static size_t statusbar_x = (size_t)-1;
+ /* The cursor position in answer. */
+static size_t statusbar_xend = 0;
+ /* The length of answer. */
static bool resetstatuspos = FALSE;
/* Should we reset the cursor position
* at the statusbar prompt? */
@@ -1609,6 +1613,271 @@ const toggle *get_toggle(int kbinput, bool meta_key)
}
#endif /* !NANO_SMALL */
+int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
+ bool *finished, bool allow_funcs)
+{
+ int input;
+ /* The character we read in. */
+ static int *kbinput = NULL;
+ /* The input buffer. */
+ static size_t kbinput_len = 0;
+ /* The length of the input buffer. */
+ const shortcut *s;
+ bool have_shortcut;
+
+ *s_or_t = FALSE;
+ *finished = FALSE;
+
+ /* Read in a character. */
+ input = get_kbinput(bottomwin, meta_key, func_key);
+
+#ifndef DISABLE_MOUSE
+ /* If we got a mouse click and it was on a shortcut, read in the
+ * shortcut character. */
+ if (allow_funcs && func_key && input == KEY_MOUSE) {
+ if (do_mouse())
+ input = get_kbinput(bottomwin, meta_key, func_key);
+ else
+ input = ERR;
+ }
+#endif
+
+ /* Check for a shortcut in the current list. */
+ s = get_shortcut(currshortcut, &input, meta_key, func_key);
+
+ /* If we got a shortcut from the current list, or a "universal"
+ * statusbar prompt shortcut, set have_shortcut to TRUE. */
+ have_shortcut = (s != NULL || input == NANO_REFRESH_KEY ||
+ input == NANO_HOME_KEY || input == NANO_END_KEY ||
+ input == NANO_FORWARD_KEY || input == NANO_BACK_KEY ||
+ input == NANO_BACKSPACE_KEY || input == NANO_DELETE_KEY ||
+ input == NANO_CUT_KEY);
+
+ /* Set s_or_t to TRUE if we got a shortcut. */
+ *s_or_t = have_shortcut;
+
+ if (allow_funcs) {
+ if (input != ERR && *s_or_t == FALSE && !is_cntrl_char(input)) {
+ /* If we're using restricted mode, the filename isn't blank,
+ * and we're at the "Write File" prompt, disable text
+ * input. */
+ if (!ISSET(RESTRICTED) || filename[0] == '\0' ||
+ currshortcut != writefile_list) {
+ kbinput_len++;
+ kbinput = (int *)nrealloc(kbinput, kbinput_len *
+ sizeof(int));
+ kbinput[kbinput_len - 1] = input;
+ }
+ }
+
+ /* If we got a shortcut, or if there aren't any other characters
+ * waiting after the one we read in, we need to display all the
+ * characters in the input buffer if it isn't empty. */
+ if (*s_or_t == TRUE || get_buffer_len() == 0) {
+ if (kbinput != NULL) {
+ /* Display all the characters in the input buffer at
+ * once. */
+ do_statusbar_output(kbinput, kbinput_len);
+
+ /* Empty the input buffer. */
+ kbinput_len = 0;
+ free(kbinput);
+ kbinput = NULL;
+ }
+ }
+
+ if (have_shortcut) {
+ switch (input) {
+ /* Handle the "universal" statusbar prompt shortcuts. */
+ case NANO_REFRESH_KEY:
+ total_refresh();
+ break;
+ case NANO_HOME_KEY:
+ do_statusbar_home();
+ break;
+ case NANO_END_KEY:
+ do_statusbar_end();
+ break;
+ case NANO_FORWARD_KEY:
+ do_statusbar_right();
+ break;
+ case NANO_BACK_KEY:
+ do_statusbar_left();
+ break;
+ case NANO_BACKSPACE_KEY:
+ /* If we're using restricted mode, the filename
+ * isn't blank, and we're at the "Write File"
+ * prompt, disable Backspace. */
+ if (!ISSET(RESTRICTED) || filename[0] == '\0' ||
+ currshortcut != writefile_list)
+ do_statusbar_backspace();
+ break;
+ case NANO_DELETE_KEY:
+ /* If we're using restricted mode, the filename
+ * isn't blank, and we're at the "Write File"
+ * prompt, disable Delete. */
+ if (!ISSET(RESTRICTED) || filename[0] == '\0' ||
+ currshortcut != writefile_list)
+ do_statusbar_delete();
+ break;
+ case NANO_CUT_KEY:
+ /* If we're using restricted mode, the filename
+ * isn't blank, and we're at the "Write File"
+ * prompt, disable Cut. */
+ if (!ISSET(RESTRICTED) || filename[0] == '\0' ||
+ currshortcut != writefile_list)
+ do_statusbar_cut_text();
+ break;
+ /* Handle the normal statusbar prompt shortcuts, setting
+ * finished to TRUE to indicate that we're done after
+ * running or trying to run their associated
+ * functions. */
+ default:
+ if (s->func != NULL) {
+ if (ISSET(VIEW_MODE) && !s->viewok)
+ print_view_warning();
+ else
+ s->func();
+ }
+ *finished = TRUE;
+ }
+ }
+ }
+
+ return input;
+}
+
+#ifndef DISABLE_MOUSE
+bool do_statusbar_mouse(void)
+{
+ /* FIXME: If we clicked on a location in the statusbar, the cursor
+ * should move to the location we clicked on. This functionality
+ * should be in this function. */
+ int mouse_x, mouse_y;
+ return get_mouseinput(&mouse_x, &mouse_y, TRUE);
+}
+#endif
+
+void do_statusbar_home(void)
+{
+#ifndef NANO_SMALL
+ if (ISSET(SMART_HOME)) {
+ size_t statusbar_x_save = statusbar_x;
+ for (statusbar_x = 0; isblank(answer[statusbar_x]) &&
+ statusbar_x < statusbar_xend; statusbar_x++)
+ ;
+ if (statusbar_x == statusbar_x_save ||
+ statusbar_x == statusbar_xend)
+ statusbar_x = 0;
+ } else
+#endif
+ statusbar_x = 0;
+}
+
+void do_statusbar_end(void)
+{
+ statusbar_x = statusbar_xend;
+}
+
+void do_statusbar_right(void)
+{
+ if (statusbar_x < statusbar_xend)
+ statusbar_x = move_right(answer, statusbar_x);
+}
+
+void do_statusbar_left(void)
+{
+ if (statusbar_x > 0)
+ statusbar_x = move_left(answer, statusbar_x);
+}
+
+void do_statusbar_backspace(void)
+{
+ if (statusbar_x > 0) {
+ do_statusbar_left();
+ do_statusbar_delete();
+ }
+}
+
+void do_statusbar_delete(void)
+{
+ if (statusbar_x < statusbar_xend) {
+ int char_len = parse_char(answer + statusbar_x, NULL, NULL
+#ifdef NANO_WIDE
+ , NULL
+#endif
+ );
+
+ charmove(answer + statusbar_x, answer + statusbar_x + char_len,
+ statusbar_xend - statusbar_x - char_len + 1);
+ statusbar_xend -= char_len;
+ }
+}
+
+void do_statusbar_cut_text(void)
+{
+ null_at(&answer, 0);
+ statusbar_x = 0;
+ statusbar_xend = 0;
+}
+
+void do_statusbar_output(int *kbinput, size_t kbinput_len)
+{
+ size_t i;
+
+ char *key =
+#ifdef NANO_WIDE
+ !ISSET(NO_UTF8) ? charalloc(MB_CUR_MAX) :
+#endif
+ charalloc(1);
+
+ assert(answer != NULL);
+
+ for (i = 0; i < kbinput_len; i++) {
+ int key_len;
+
+ /* Null to newline, if needed. */
+ if (kbinput[i] == '\0')
+ kbinput[i] = '\n';
+ /* Newline to Enter, if needed. */
+ else if (kbinput[i] == '\n')
+ /* FIXME: We need to indicate when this happens, so that we
+ * can break out of the statusbar prompt properly. */
+ return;
+
+#ifdef NANO_WIDE
+ /* Change the wide character to its multibyte value. If it's
+ * invalid, go on to the next character. */
+ if (!ISSET(NO_UTF8)) {
+ key_len = wctomb(key, (wchar_t)kbinput[i]);
+
+ if (key_len == -1)
+ continue;
+ /* Interpret the character as a single-byte sequence. */
+ } else {
+#endif
+ key_len = 1;
+ key[0] = (unsigned char)kbinput[i];
+#ifdef NANO_WIDE
+ }
+#endif
+
+ /* More dangerousness fun =) */
+ answer = charealloc(answer, statusbar_xend + key_len + 1);
+
+ assert(statusbar_x <= statusbar_xend);
+
+ charmove(&answer[statusbar_x + key_len], &answer[statusbar_x],
+ statusbar_xend - statusbar_x + key_len);
+ charcpy(&answer[statusbar_x], key, key_len);
+ statusbar_xend += key_len;
+
+ do_statusbar_right();
+ }
+
+ free(key);
+}
+
/* Return the placewewant associated with current_x. That is, xplustabs
* is the zero-based column position of the cursor. Value is no smaller
* than current_x. */
@@ -2101,14 +2370,9 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *def,
)
{
int kbinput;
- bool meta_key, func_key;
- static size_t x = (size_t)-1;
- /* the cursor position in 'answer' */
- size_t xend;
- /* length of 'answer', the status bar text */
+ bool meta_key, func_key, s_or_t, finished;
bool tabbed = FALSE;
/* used by input_tab() */
- const shortcut *t;
#ifndef NANO_SMALL
/* for history */
@@ -2125,32 +2389,30 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *def,
answer or restored from answer to currentbuf. */
int use_cb = 0;
#endif
- xend = strlen(def);
+ statusbar_xend = strlen(def);
- /* Only put x at the end of the string if it's uninitialized, if it
- would be past the end of the string as it is, or if
- resetstatuspos is TRUE. Otherwise, leave it alone. This is so
- the cursor position stays at the same place if a prompt-changing
- toggle is pressed. */
- if (x == (size_t)-1 || x > xend || resetstatuspos)
- x = xend;
+ /* Only put statusbar_x at the end of the string if it's
+ * uninitialized, if it would be past the end of the string as it
+ * is, or if resetstatuspos is TRUE. Otherwise, leave it alone.
+ * This is so the cursor position stays at the same place if a
+ * prompt-changing toggle is pressed. */
+ if (statusbar_x == (size_t)-1 || statusbar_x > statusbar_xend ||
+ resetstatuspos)
+ statusbar_x = statusbar_xend;
- answer = charealloc(answer, xend + 1);
- if (xend > 0)
+ answer = charealloc(answer, statusbar_xend + 1);
+ if (statusbar_xend > 0)
strcpy(answer, def);
else
answer[0] = '\0';
-#if !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE)
currshortcut = s;
-#endif
/* Get the input! */
- nanoget_repaint(buf, answer, x);
+ nanoget_repaint(buf, answer, statusbar_x);
- /* Make sure any editor screen updates are displayed before getting
- input */
+ /* Refresh the edit window before getting input. */
wnoutrefresh(edit);
wrefresh(bottomwin);
@@ -2159,105 +2421,22 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *def,
* to files not specified on the command line. In this case,
* disable all keys that would change the text if the filename isn't
* blank and we're at the "Write File" prompt. */
- while ((kbinput = get_kbinput(bottomwin, &meta_key, &func_key)) !=
- NANO_CANCEL_KEY && kbinput != NANO_ENTER_KEY) {
- for (t = s; t != NULL; t = t->next) {
-#ifdef DEBUG
- fprintf(stderr, "Aha! \'%c\' (%d)\n", kbinput, kbinput);
-#endif
+ while ((kbinput = do_statusbar_input(&meta_key, &func_key,
+ &s_or_t, &finished, TRUE)) != NANO_CANCEL_KEY &&
+ kbinput != NANO_ENTER_KEY) {
- /* Temporary hack to interpret NANO_HELP_FKEY correctly. */
- if (kbinput == t->funcval)
- kbinput = t->ctrlval;
-
- if (kbinput == t->ctrlval && is_cntrl_char(kbinput)) {
-
-#ifndef DISABLE_HELP
- /* Have to do this here, it would be too late to do it
- in statusq() */
- if (kbinput == NANO_HELP_KEY) {
- do_help();
- break;
- }
-#endif
-#ifndef NANO_SMALL
- /* Have to handle these here too, for the time being */
- if (kbinput == NANO_PREVLINE_KEY || kbinput == NANO_NEXTLINE_KEY)
- break;
-#endif
+ /* If we have a shortcut with an associated function, break out
+ * if we're finished after running the function. */
+ if (finished)
+ break;
- return t->ctrlval;
- }
- }
- assert(x <= xend && xend == strlen(answer));
+ assert(statusbar_x <= statusbar_xend &&
+ statusbar_xend == strlen(answer));
if (kbinput != '\t')
tabbed = FALSE;
switch (kbinput) {
-#ifndef DISABLE_MOUSE
- case KEY_MOUSE:
- {
- int mouse_x, mouse_y;
- get_mouseinput(&mouse_x, &mouse_y, TRUE);
- }
- break;
-#endif
- case NANO_REFRESH_KEY:
- total_refresh();
- break;
- case NANO_HOME_KEY:
-#ifndef NANO_SMALL
- if (ISSET(SMART_HOME)) {
- size_t old_x = x;
-
- for (x = 0; isblank(answer[x]) && x < xend; x++)
- ;
-
- if (x == old_x || x == xend)
- x = 0;
- } else
-#endif
- x = 0;
- break;
- case NANO_END_KEY:
- x = xend;
- break;
- case NANO_FORWARD_KEY:
- if (x < xend)
- x++;
- break;
- case NANO_DELETE_KEY:
- /* If we're using restricted mode, the filename isn't blank,
- * and we're at the "Write File" prompt, disable Delete. */
- if (!ISSET(RESTRICTED) || filename[0] == '\0' || s != writefile_list) {
- if (x < xend) {
- charmove(answer + x, answer + x + 1, xend - x);
- xend--;
- }
- }
- break;
- case NANO_CUT_KEY:
- /* If we're using restricted mode, the filename isn't blank,
- * and we're at the "Write File" prompt, disable Cut. */
- if (!ISSET(RESTRICTED) || filename[0] == '\0' || s != writefile_list) {
- null_at(&answer, 0);
- xend = 0;
- x = 0;
- }
- break;
- case NANO_BACKSPACE_KEY:
- /* If we're using restricted mode, the filename isn't blank,
- * and we're at the "Write File" prompt, disable
- * Backspace. */
- if (!ISSET(RESTRICTED) || filename[0] == '\0' || s != writefile_list) {
- if (x > 0) {
- charmove(answer + x - 1, answer + x, xend - x + 1);
- x--;
- xend--;
- }
- }
- break;
case NANO_TAB_KEY:
#ifndef NANO_SMALL
/* tab history completion */
@@ -2269,8 +2448,8 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *def,
if (history_list->len > 0) {
complete = get_history_completion(history_list, answer);
- xend = strlen(complete);
- x = xend;
+ statusbar_x = strlen(complete);
+ statusbar_xend = statusbar_x;
answer = mallocstrcpy(answer, complete);
}
}
@@ -2282,18 +2461,15 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *def,
if (allow_tabs) {
int shift = 0;
- answer = input_tab(answer, x, &tabbed, &shift, list);
- xend = strlen(answer);
- x += shift;
- if (x > xend)
- x = xend;
+ answer = input_tab(answer, statusbar_x, &tabbed, &shift,
+ list);
+ statusbar_xend = strlen(answer);
+ statusbar_x += shift;
+ if (statusbar_x > statusbar_xend)
+ statusbar_x = statusbar_xend;
}
#endif
break;
- case NANO_BACK_KEY:
- if (x > 0)
- x--;
- break;
case NANO_PREVLINE_KEY:
#ifndef NANO_SMALL
if (history_list != NULL) {
@@ -2321,7 +2497,7 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *def,
answer = mallocstrcpy(answer, currentbuf);
free(currentbuf);
currentbuf = NULL;
- xend = strlen(answer);
+ statusbar_xend = strlen(answer);
use_cb = 0;
/* else get older search from the history list and save
@@ -2329,12 +2505,12 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *def,
answer */
} else if ((history = get_history_older(history_list)) != NULL) {
answer = mallocstrcpy(answer, history);
- xend = strlen(history);
+ statusbar_xend = strlen(history);
} else {
answer = mallocstrcpy(answer, "");
- xend = 0;
+ statusbar_xend = 0;
}
- x = xend;
+ statusbar_x = statusbar_xend;
}
#endif
break;
@@ -2346,7 +2522,7 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *def,
in answer */
if ((history = get_history_newer(history_list)) != NULL) {
answer = mallocstrcpy(answer, history);
- xend = strlen(history);
+ statusbar_xend = strlen(history);
/* if there is no newer search, we're here */
@@ -2360,7 +2536,7 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *def,
answer = mallocstrcpy(answer, currentbuf);
free(currentbuf);
currentbuf = NULL;
- xend = strlen(answer);
+ statusbar_xend = strlen(answer);
use_cb = 1;
/* otherwise, if currentbuf is NULL and use_cb isn't 2,
@@ -2374,53 +2550,24 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *def,
currentbuf = mallocstrcpy(currentbuf, answer);
answer = mallocstrcpy(answer, "");
}
- xend = 0;
+ statusbar_xend = 0;
use_cb = 2;
}
- x = xend;
+ statusbar_x = statusbar_xend;
}
#endif
break;
- default:
-
- for (t = s; t != NULL; t = t->next) {
-#ifdef DEBUG
- fprintf(stderr, "Aha! \'%c\' (%d)\n", kbinput,
- kbinput);
-#endif
- if (meta_key && (kbinput == t->metaval || kbinput == t->miscval))
- /* We hit a meta key. Do like above. We don't
- * just put back the letter and let it get
- * caught above cause that screws the
- * keypad... */
- return kbinput;
- }
-
- /* If we're using restricted mode, the filename isn't blank,
- * and we're at the "Write File" prompt, act as though the
- * unhandled character we got is a control character and
- * throw it away. */
- if (is_cntrl_char(kbinput) || (ISSET(RESTRICTED) && filename[0] != '\0' && s == writefile_list))
- break;
- answer = charealloc(answer, xend + 2);
- charmove(answer + x + 1, answer + x, xend - x + 1);
- xend++;
- answer[x] = kbinput;
- x++;
-
-#ifdef DEBUG
- fprintf(stderr, "input \'%c\' (%d)\n", kbinput, kbinput);
-#endif
- } /* switch (kbinput) */
+ }
#ifndef NANO_SMALL
last_kbinput = kbinput;
#endif
- nanoget_repaint(buf, answer, x);
+ nanoget_repaint(buf, answer, statusbar_x);
wrefresh(bottomwin);
- } /* while (kbinput ...) */
+ }
- /* We finished putting in an answer; reset x */
- x = (size_t)-1;
+ /* We finished putting in an answer, so reset statusbar_x. */
+ if (kbinput == NANO_CANCEL_KEY || kbinput == NANO_ENTER_KEY)
+ statusbar_x = (size_t)-1;
return kbinput;
}
@@ -2464,36 +2611,6 @@ int statusq(bool allow_tabs, const shortcut *s, const char *def,
resetstatuspos = FALSE;
switch (ret) {
- case NANO_FIRSTLINE_KEY:
- case NANO_FIRSTLINE_FKEY:
- do_first_line();
- resetstatuspos = TRUE;
- break;
- case NANO_LASTLINE_KEY:
- case NANO_LASTLINE_FKEY:
- do_last_line();
- resetstatuspos = TRUE;
- break;
-#ifndef DISABLE_JUSTIFY
- case NANO_PARABEGIN_KEY:
- case NANO_PARABEGIN_ALTKEY1:
- case NANO_PARABEGIN_ALTKEY2:
- do_para_begin();
- resetstatuspos = TRUE;
- break;
- case NANO_PARAEND_KEY:
- case NANO_PARAEND_ALTKEY1:
- case NANO_PARAEND_ALTKEY2:
- do_para_end();
- resetstatuspos = TRUE;
- break;
- case NANO_FULLJUSTIFY_KEY:
- case NANO_FULLJUSTIFY_ALTKEY:
- if (!ISSET(VIEW_MODE))
- do_full_justify();
- resetstatuspos = TRUE;
- break;
-#endif
case NANO_CANCEL_KEY:
ret = -1;
resetstatuspos = TRUE;