mirror of git://git.sv.gnu.org/nano.git
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
This commit is contained in:
parent
3e81914b82
commit
c13b7f0699
32
ChangeLog
32
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
|
||||
|
|
|
@ -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;
|
||||
|
|
14
src/global.c
14
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);
|
||||
|
|
30
src/nano.c
30
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);
|
||||
}
|
||||
|
|
19
src/proto.h
19
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);
|
||||
|
|
513
src/winio.c
513
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 we have a shortcut with an associated function, break out
|
||||
* if we're finished after running the function. */
|
||||
if (finished)
|
||||
break;
|
||||
|
||||
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
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue