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
master
David Lawrence Ramsey 2005-01-01 07:28:15 +00:00
parent 3e81914b82
commit c13b7f0699
6 changed files with 380 additions and 234 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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();
/* If we have a shortcut with an associated function, break out
* if we're finished after running the function. */
if (finished)
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
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;