New keybindings code and backend. New structs subnfunc for menu functions

and toggles and sc for shortcut keys, old 'shortcut' and 'toggles' structs are
gone.  The current implementation has a bunch of broken stuff (some of which is
documented in BUGS).  Updated nanorc.5 with some mostly complete documentation
on configuring.


git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4215 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
Chris Allegretta 2008-03-05 07:34:01 +00:00
parent 200f0c8c2c
commit 79a33bb38d
12 changed files with 1418 additions and 1306 deletions

View File

@ -64,9 +64,9 @@ char *do_browser(char *path, DIR *dir)
curs_set(0);
blank_statusbar();
#if !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE)
currshortcut = browser_list;
currmenu = MBROWSER;
#endif
bottombars(browser_list);
bottombars(MBROWSER);
wnoutrefresh(bottomwin);
UNSET(CONST_UPDATE);
@ -213,17 +213,17 @@ char *do_browser(char *path, DIR *dir)
#ifndef DISABLE_TABCOMP
FALSE,
#endif
gotodir_list, ans,
MGOTODIR, ans,
#ifndef NANO_TINY
NULL,
#endif
browser_refresh, _("Go To Directory"));
browser_refresh, N_("Go To Directory"));
curs_set(0);
#if !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE)
currshortcut = browser_list;
currmenu = MBROWSER;
#endif
bottombars(browser_list);
bottombars(MBROWSER);
/* If the directory begins with a newline (i.e. an
* encoded null), treat it as though it's blank. */
@ -552,7 +552,7 @@ void browser_init(const char *path, DIR *dir)
* shortcut keys. */
void parse_browser_input(int *kbinput, bool *meta_key, bool *func_key)
{
get_shortcut(browser_list, kbinput, meta_key, func_key);
get_shortcut(MBROWSER, kbinput, meta_key, func_key);
/* Pico compatibility. */
if (!*meta_key) {
@ -796,7 +796,7 @@ int filesearch_init(void)
#ifndef DISABLE_TABCOMP
TRUE,
#endif
whereis_file_list, backupstring,
MWHEREISFILE, backupstring,
#ifndef NANO_TINY
&search_history,
#endif
@ -955,8 +955,8 @@ void findnextfile_wrap_reset(void)
* search, if any. */
void filesearch_abort(void)
{
currshortcut = browser_list;
bottombars(browser_list);
currmenu = MBROWSER;
bottombars(MBROWSER);
#ifdef HAVE_REGEX_H
regexp_cleanup();
#endif

View File

@ -731,9 +731,9 @@ void do_insertfile(
TRUE,
#endif
#ifndef NANO_TINY
execute ? extcmd_list :
execute ? MEXTCMD :
#endif
insertfile_list, ans,
MINSERTFILE, ans,
#ifndef NANO_TINY
NULL,
#endif
@ -1814,7 +1814,7 @@ bool do_writeout(bool exiting)
#endif
bool retval = FALSE;
currshortcut = writefile_list;
currmenu = MWRITEFILE;
if (exiting && openfile->filename[0] != '\0' && ISSET(TEMP_FILE)) {
retval = write_file(openfile->filename, NULL, FALSE, OVERWRITE,
@ -1865,7 +1865,7 @@ bool do_writeout(bool exiting)
#ifndef DISABLE_TABCOMP
TRUE,
#endif
writefile_list, ans,
MWRITEFILE, ans,
#ifndef NANO_TINY
NULL,
#endif

File diff suppressed because it is too large Load Diff

View File

@ -47,13 +47,15 @@ void do_help(void (*refresh_func)(void))
/* The line number in help_text of the last help line. This
* variable is zero-based. */
#ifndef DISABLE_MOUSE
const shortcut *oldshortcut = currshortcut;
/* The current shortcut list. */
int oldmenu = currmenu;
#endif
const char *ptr;
/* The current line of the help text. */
size_t old_line = (size_t)-1;
/* The line we were on before the current line. */
const sc *s;
const subnfunc *f;
curs_set(0);
blank_edit();
@ -66,9 +68,9 @@ void do_help(void (*refresh_func)(void))
assert(help_text != NULL);
#ifndef DISABLE_MOUSE
/* Set currshortcut to allow clicking on the help screen's shortcut
/* Set currmenu to allow clicking on the help screen's shortcut
* list, after help_init() is called. */
currshortcut = help_list;
currmenu = MHELP;
#endif
if (ISSET(NO_HELP)) {
@ -78,7 +80,7 @@ void do_help(void (*refresh_func)(void))
window_init();
}
bottombars(help_list);
bottombars(MHELP);
wnoutrefresh(bottomwin);
/* Get the last line of the help text. */
@ -127,57 +129,57 @@ void do_help(void (*refresh_func)(void))
kbinput = get_kbinput(edit, &meta_key, &func_key);
parse_help_input(&kbinput, &meta_key, &func_key);
switch (kbinput) {
s = get_shortcut(MMAIN, &kbinput, &meta_key, &func_key);
if (!s)
continue;
f = sctofunc(s);
if (!f)
continue;
if (f->scfunc == (void *) do_mouse) {
#ifndef DISABLE_MOUSE
case KEY_MOUSE:
{
int mouse_x, mouse_y;
get_mouseinput(&mouse_x, &mouse_y, TRUE);
}
break;
#endif
/* Redraw the screen. */
case NANO_REFRESH_KEY:
} else if (f->scfunc == total_refresh) {
total_redraw();
break;
case NANO_PREVPAGE_KEY:
} else if (f->scfunc == do_page_up) {
if (line > editwinrows - 2)
line -= editwinrows - 2;
else
line = 0;
break;
case NANO_NEXTPAGE_KEY:
} else if (f->scfunc == do_page_down) {
if (line + (editwinrows - 1) < last_line)
line += editwinrows - 2;
break;
case NANO_PREVLINE_KEY:
} else if (f->scfunc == do_up_void) {
if (line > 0)
line--;
break;
case NANO_NEXTLINE_KEY:
} else if (f->scfunc == do_down_void) {
if (line + (editwinrows - 1) < last_line)
line++;
break;
case NANO_FIRSTLINE_METAKEY:
} else if (f->scfunc == do_first_line) {
if (meta_key)
line = 0;
break;
case NANO_LASTLINE_METAKEY:
} else if (f->scfunc == do_last_line) {
if (meta_key) {
if (line + (editwinrows - 1) < last_line)
line = last_line - (editwinrows - 1);
}
break;
/* Abort the help browser. */
case NANO_EXIT_KEY:
} else if (f->scfunc == do_exit) {
abort = TRUE;
break;
}
}
#ifndef DISABLE_MOUSE
currshortcut = oldshortcut;
currmenu = oldmenu;
#endif
if (old_no_help) {
@ -186,7 +188,7 @@ void do_help(void (*refresh_func)(void))
SET(NO_HELP);
window_init();
} else
bottombars(currshortcut);
bottombars(currmenu);
curs_set(1);
refresh_func();
@ -222,9 +224,11 @@ void help_init(void)
* full string is too long for the
* compiler to handle. */
char *ptr;
const shortcut *s;
const subnfunc *f;
const sc *s;
int scsfound = 0;
#ifndef NANO_TINY
const toggle *t;
#ifdef ENABLE_NANORC
bool old_whitespace = ISSET(WHITESPACE_DISPLAY);
@ -233,8 +237,7 @@ void help_init(void)
#endif
/* First, set up the initial help text for the current function. */
if (currshortcut == whereis_list || currshortcut == replace_list ||
currshortcut == replace_list_2) {
if (currmenu == MWHEREIS || currmenu == MREPLACE || currmenu == MREPLACE2) {
htx[0] = N_("Search Command Help Text\n\n "
"Enter the words or characters you would like to "
"search for, and then press Enter. If there is a "
@ -249,7 +252,7 @@ void help_init(void)
"will be replaced.\n\n The following function keys are "
"available in Search mode:\n\n");
htx[2] = NULL;
} else if (currshortcut == gotoline_list) {
} else if (currmenu == MGOTOLINE) {
htx[0] = N_("Go To Line Help Text\n\n "
"Enter the line number that you wish to go to and hit "
"Enter. If there are fewer lines of text than the "
@ -258,7 +261,7 @@ void help_init(void)
"available in Go To Line mode:\n\n");
htx[1] = NULL;
htx[2] = NULL;
} else if (currshortcut == insertfile_list) {
} else if (currmenu == MINSERTFILE) {
htx[0] = N_("Insert File Help Text\n\n "
"Type in the name of a file to be inserted into the "
"current file buffer at the current cursor "
@ -273,7 +276,7 @@ void help_init(void)
"the prompt and press Enter.\n\n The following "
"function keys are available in Insert File mode:\n\n");
htx[2] = NULL;
} else if (currshortcut == writefile_list) {
} else if (currmenu == MWRITEFILE) {
htx[0] = N_("Write File Help Text\n\n "
"Type the name that you wish to save the current file "
"as and press Enter to save the file.\n\n If you have "
@ -287,7 +290,7 @@ void help_init(void)
htx[2] = NULL;
}
#ifndef DISABLE_BROWSER
else if (currshortcut == browser_list) {
else if (currmenu == MBROWSER) {
htx[0] = N_("File Browser Help Text\n\n "
"The file browser is used to visually browse the "
"directory structure to select a file for reading "
@ -300,7 +303,7 @@ void help_init(void)
"in the file browser:\n\n");
htx[1] = NULL;
htx[2] = NULL;
} else if (currshortcut == whereis_file_list) {
} else if (currmenu == MWHEREISFILE) {
htx[0] = N_("Browser Search Command Help Text\n\n "
"Enter the words or characters you would like to "
"search for, and then press Enter. If there is a "
@ -313,7 +316,7 @@ void help_init(void)
htx[1] = N_(" The following function keys are available in "
"Browser Search mode:\n\n");
htx[2] = NULL;
} else if (currshortcut == gotodir_list) {
} else if (currmenu == MGOTODIR) {
htx[0] = N_("Browser Go To Directory Help Text\n\n "
"Enter the name of the directory you would like to "
"browse to.\n\n If tab completion has not been "
@ -326,7 +329,7 @@ void help_init(void)
}
#endif /* !DISABLE_BROWSER */
#ifndef DISABLE_SPELLER
else if (currshortcut == spell_list) {
else if (currmenu == MSPELL) {
htx[0] = N_("Spell Check Help Text\n\n "
"The spell checker checks the spelling of all text in "
"the current file. When an unknown word is "
@ -341,7 +344,7 @@ void help_init(void)
}
#endif /* !DISABLE_SPELLER */
#ifndef NANO_TINY
else if (currshortcut == extcmd_list) {
else if (currmenu == MEXTCMD) {
htx[0] = N_("Execute Command Help Text\n\n "
"This mode allows you to insert the output of a "
"command run by the shell into the current buffer (or "
@ -397,18 +400,21 @@ void help_init(void)
/* Count the shortcut help text. Each entry has up to three keys,
* which fill 24 columns, plus translated text, plus one or two
* \n's. */
for (s = currshortcut; s != NULL; s = s->next)
allocsize += (24 * mb_cur_max()) + strlen(s->help) + 2;
for (f = allfuncs; f != NULL; f = f->next)
if (f->menus & currmenu)
allocsize += (24 * mb_cur_max()) + strlen(f->help) + 2;
#ifndef NANO_TINY
/* If we're on the main list, we also count the toggle help text.
* Each entry has "M-%c\t\t\t", which fills 24 columns, plus a
* space, plus translated text, plus one or two '\n's. */
if (currshortcut == main_list) {
if (currmenu == MMAIN) {
size_t endis_len = strlen(_("enable/disable"));
for (t = toggles; t != NULL; t = t->next)
allocsize += strlen(t->desc) + endis_len + 9;
for (s = sclist; s != NULL; s = s->next)
if (s->scfunc == (void *) do_toggle)
allocsize += strlen(flagtostr(s->toggle)) + endis_len + 9;
}
#endif
@ -429,131 +435,55 @@ void help_init(void)
ptr = help_text + strlen(help_text);
/* Now add our shortcut info. Assume that each shortcut has, at the
* very least, an equivalent control key, an equivalent primary meta
* key sequence, or both. Also assume that the meta key values are
* not control characters. We can display a maximum of three
* shortcut entries. */
for (s = currshortcut; s != NULL; s = s->next) {
int entries = 0;
/* Now add our shortcut info. */
for (f = allfuncs; f != NULL; f = f->next) {
/* Control key. */
if (s->ctrlval != NANO_NO_KEY) {
entries++;
/* Yucky sentinel values that we can't handle a better
* way. */
if (s->ctrlval == NANO_CONTROL_SPACE) {
char *space_ptr = display_string(_("Space"), 0, 14,
FALSE);
if ((f->menus & currmenu) == 0)
continue;
if (s->funcval == NANO_NO_KEY && (s->metaval ==
NANO_NO_KEY || s->miscval == NANO_NO_KEY)) {
/* If we're here, we have at least two entries worth
* of blank space. If this entry takes up more than
* one entry's worth of space, use two to display
* it. */
if (mbstrlen(space_ptr) > 6)
entries++;
} else
/* Otherwise, truncate it so that it takes up only
* one entry's worth of space. */
space_ptr[6] = '\0';
if (!f->desc || !strcmp(f->desc, ""))
continue;
ptr += sprintf(ptr, "^%s", space_ptr);
/* Lets just try and use the first 3 shortcuts
from the new struct... */
for (s = sclist, scsfound = 0; s != NULL; s = s->next) {
free(space_ptr);
} else if (s->ctrlval == NANO_CONTROL_8)
ptr += sprintf(ptr, "^?");
/* Normal values. */
else
ptr += sprintf(ptr, "^%c", s->ctrlval + 64);
*(ptr++) = '\t';
}
if (scsfound == 3)
continue;
/* Function key. */
if (s->funcval != NANO_NO_KEY) {
entries++;
/* If this is the first entry, put it in the middle. */
if (entries == 1) {
entries++;
if ((s->menu & currmenu) == 0)
continue;
if (s->scfunc == f->scfunc) {
scsfound++;
if (scsfound == 1)
ptr += sprintf(ptr, "%s", s->keystr);
else
ptr += sprintf(ptr, "(%s)", s->keystr);
*(ptr++) = '\t';
}
ptr += sprintf(ptr, "(F%d)", s->funcval - KEY_F0);
*(ptr++) = '\t';
}
/* Primary meta key sequence. If it's the first entry, don't
* put parentheses around it. */
if (s->metaval != NANO_NO_KEY) {
entries++;
/* If this is the last entry, put it at the end. */
if (entries == 2 && s->miscval == NANO_NO_KEY) {
entries++;
*(ptr++) = '\t';
}
/* Yucky sentinel values that we can't handle a better
* way. */
if (s->metaval == NANO_META_SPACE && entries == 1) {
char *space_ptr = display_string(_("Space"), 0, 13,
FALSE);
/* If we're here, we have at least two entries worth of
* blank space. If this entry takes up more than one
* entry's worth of space, use two to display it. */
if (mbstrlen(space_ptr) > 5)
entries++;
ptr += sprintf(ptr, "M-%s", space_ptr);
free(space_ptr);
} else
/* Normal values. */
ptr += sprintf(ptr, (entries == 1) ? "M-%c" : "(M-%c)",
toupper(s->metaval));
/* Pad with tabs if we didnt find 3 */
for (; scsfound < 3; scsfound++) {
*(ptr++) = '\t';
}
/* Miscellaneous meta key sequence. */
if (entries < 3 && s->miscval != NANO_NO_KEY) {
entries++;
/* If this is the last entry, put it at the end. */
if (entries == 2) {
entries++;
*(ptr++) = '\t';
}
ptr += sprintf(ptr, "(M-%c)", toupper(s->miscval));
*(ptr++) = '\t';
}
/* If this entry isn't blank, make sure all the help text starts
* at the same place. */
if (s->ctrlval != NANO_NO_KEY || s->funcval != NANO_NO_KEY ||
s->metaval != NANO_NO_KEY || s->miscval !=
NANO_NO_KEY) {
while (entries < 3) {
entries++;
*(ptr++) = '\t';
}
}
/* The shortcut's help text. */
ptr += sprintf(ptr, "%s\n", s->help);
ptr += sprintf(ptr, "%s\n", f->help);
if (s->blank_after)
if (f->blank_after)
ptr += sprintf(ptr, "\n");
}
#ifndef NANO_TINY
/* And the toggles... */
if (currshortcut == main_list) {
for (t = toggles; t != NULL; t = t->next) {
ptr += sprintf(ptr, "M-%c\t\t\t%s %s\n",
toupper(t->val), t->desc, _("enable/disable"));
if (currmenu == MMAIN)
for (s = sclist; s != NULL; s = s->next)
if (s->scfunc == (void *) do_toggle)
ptr += sprintf(ptr, "(%s)\t\t\t%s %s\n",
s->keystr, flagtostr(s->toggle), _("enable/disable"));
if (t->blank_after)
ptr += sprintf(ptr, "\n");
}
}
#ifdef ENABLE_NANORC
if (old_whitespace)
@ -573,7 +503,7 @@ void help_init(void)
* shortcut keys. */
void parse_help_input(int *kbinput, bool *meta_key, bool *func_key)
{
get_shortcut(help_list, kbinput, meta_key, func_key);
get_shortcut(MHELP, kbinput, meta_key, func_key);
if (!*meta_key) {
switch (*kbinput) {

View File

@ -1174,7 +1174,7 @@ RETSIGTYPE handle_sigwinch(int signal)
/* Redraw the contents of the windows that need it. */
blank_statusbar();
wnoutrefresh(bottomwin);
currshortcut = main_list;
currmenu = MMAIN;
total_refresh();
/* Jump back to either main() or the unjustify routine in
@ -1196,52 +1196,54 @@ void allow_pending_sigwinch(bool allow)
#ifndef NANO_TINY
/* Handle the global toggle specified in which. */
void do_toggle(const toggle *which)
void do_toggle(int flag)
{
bool enabled;
char *desc;
TOGGLE(which->flag);
TOGGLE(flag);
switch (which->val) {
switch (flag) {
#ifndef DISABLE_MOUSE
case TOGGLE_MOUSE_KEY:
case USE_MOUSE:
mouse_init();
break;
#endif
case TOGGLE_MORESPACE_KEY:
case TOGGLE_NOHELP_KEY:
case MORE_SPACE:
case NO_HELP:
window_init();
total_refresh();
break;
case TOGGLE_SUSPEND_KEY:
case SUSPEND:
signal_init();
break;
#ifdef ENABLE_NANORC
case TOGGLE_WHITESPACE_KEY:
case WHITESPACE_DISPLAY:
titlebar(NULL);
edit_refresh();
break;
#endif
#ifdef ENABLE_COLOR
case TOGGLE_SYNTAX_KEY:
case NO_COLOR_SYNTAX:
edit_refresh();
break;
#endif
}
enabled = ISSET(which->flag);
enabled = ISSET(flag);
if (which->val == TOGGLE_NOHELP_KEY
if (flag == NO_HELP
#ifndef DISABLE_WRAPPING
|| which->val == TOGGLE_WRAP_KEY
|| flag == NO_WRAP
#endif
#ifdef ENABLE_COLOR
|| which->val == TOGGLE_SYNTAX_KEY
|| flag == NO_COLOR_SYNTAX
#endif
)
enabled = !enabled;
statusbar("%s %s", which->desc, enabled ? _("enabled") :
desc = flagtostr(flag);
statusbar("%s %s", desc, enabled ? _("enabled") :
_("disabled"));
}
#endif /* !NANO_TINY */
@ -1368,12 +1370,8 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
/* The length of the input buffer. */
bool cut_copy = FALSE;
/* Are we cutting or copying text? */
const shortcut *s;
const sc *s;
bool have_shortcut;
#ifndef NANO_TINY
const toggle *t;
bool have_toggle;
#endif
*s_or_t = FALSE;
*ran_func = FALSE;
@ -1399,32 +1397,15 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
#endif
/* Check for a shortcut in the main list. */
s = get_shortcut(main_list, &input, meta_key, func_key);
s = get_shortcut(MMAIN, &input, meta_key, func_key);
/* If we got a shortcut from the main list, or a "universal"
* edit window shortcut, set have_shortcut to TRUE. */
have_shortcut = (s != NULL || input == NANO_XON_KEY ||
input == NANO_XOFF_KEY || input == NANO_SUSPEND_KEY);
#ifndef NANO_TINY
/* Check for a toggle in the main list. */
t = get_toggle(input, *meta_key);
/* If we got a toggle from the main list, set have_toggle to
* TRUE. */
have_toggle = (t != NULL);
#endif
/* Set s_or_t to TRUE if we got a shortcut or toggle. */
*s_or_t = (have_shortcut
#ifndef NANO_TINY
|| have_toggle
#endif
);
have_shortcut = (s != NULL || input == NANO_SUSPEND_KEY);
/* If we got a non-high-bit control key, a meta key sequence, or a
* function key, and it's not a shortcut or toggle, throw it out. */
if (!*s_or_t) {
if (!have_shortcut) {
if (is_ascii_cntrl_char(input) || *meta_key || *func_key) {
statusbar(_("Unknown Command"));
beep();
@ -1439,7 +1420,7 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
* it's a normal text character. Display the warning if we're
* in view mode, or add the character to the input buffer if
* we're not. */
if (input != ERR && !*s_or_t) {
if (input != ERR && !have_shortcut) {
if (ISSET(VIEW_MODE))
print_view_warning();
else {
@ -1455,12 +1436,12 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
* output all the characters in the input buffer if it isn't
* empty. Note that it should be empty if we're in view
* mode. */
if (*s_or_t || get_key_buffer_len() == 0) {
if (have_shortcut || get_key_buffer_len() == 0) {
#ifndef DISABLE_WRAPPING
/* If we got a shortcut or toggle, and it's not the shortcut
* for verbatim input, turn off prepending of wrapped
* text. */
if (*s_or_t && (!have_shortcut || s == NULL || s->func !=
if (have_shortcut && (!have_shortcut || s == NULL || s->scfunc !=
do_verbatim_input))
wrap_reset();
#endif
@ -1489,12 +1470,6 @@ 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. */
case NANO_XON_KEY:
statusbar(_("XON ignored, mumble mumble"));
break;
case NANO_XOFF_KEY:
statusbar(_("XOFF ignored, mumble mumble"));
break;
case NANO_SUSPEND_KEY:
if (ISSET(SUSPEND))
do_suspend(0);
@ -1507,32 +1482,31 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
default:
/* If the function associated with this shortcut is
* cutting or copying text, indicate this. */
if (s->func == do_cut_text_void
if (s->scfunc == do_cut_text_void
#ifndef NANO_TINY
|| s->func == do_copy_text || s->func ==
|| s->scfunc == do_copy_text || s->scfunc ==
do_cut_till_end
#endif
)
cut_copy = TRUE;
if (s->func != NULL) {
if (s->scfunc != NULL) {
const subnfunc *f = sctofunc((sc *) s);
*ran_func = TRUE;
if (ISSET(VIEW_MODE) && !s->viewok)
if (ISSET(VIEW_MODE) && f && !f->viewok)
print_view_warning();
else
s->func();
#ifndef NANO_TINY
if (s->scfunc == (void *) do_toggle)
do_toggle(s->toggle);
else
#endif
s->scfunc();
}
*finished = TRUE;
break;
}
}
#ifndef NANO_TINY
else if (have_toggle) {
/* Toggle the flag associated with this shortcut. */
if (allow_funcs)
do_toggle(t);
}
#endif
}
/* If we aren't cutting or copying text, blow away the text in the
@ -1543,6 +1517,17 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
return input;
}
void xon_complaint(void)
{
statusbar(_("XON ignored, mumble mumble"));
}
void xoff_complaint(void)
{
statusbar(_("XOFF ignored, mumble mumble"));
}
#ifndef DISABLE_MOUSE
/* Handle a mouse click on the edit window or the shortcut list. */
int do_mouse(void)
@ -1991,6 +1976,11 @@ int main(int argc, char **argv)
#endif
}
/* Set up the shortcut lists.
Need to do this before the rcfile */
shortcut_init(FALSE);
/* We've read through the command line options. Now back up the flags
* and values that are set, and read the rcfile(s). If the values
* haven't changed afterward, restore the backed-up values. */
@ -2029,6 +2019,11 @@ int main(int argc, char **argv)
do_rcfile();
#ifdef DEBUG
fprintf(stderr, "After rebinding keys...\n");
print_sclist();
#endif
#ifndef DISABLE_OPERATINGDIR
if (operating_dir_cpy != NULL) {
free(operating_dir);
@ -2191,9 +2186,6 @@ int main(int argc, char **argv)
/* Set up the signal handlers. */
signal_init();
/* Set up the shortcut lists. */
shortcut_init(FALSE);
#ifndef DISABLE_MOUSE
/* Initialize mouse support. */
mouse_init();
@ -2302,7 +2294,7 @@ int main(int argc, char **argv)
if (ISSET(CONST_UPDATE) && get_key_buffer_len() == 0)
do_cursorpos(TRUE);
currshortcut = main_list;
currmenu = MMAIN;
/* Read in and interpret characters. */
do_input(&meta_key, &func_key, &s_or_t, &ran_func, &finished,

View File

@ -165,6 +165,10 @@ typedef enum {
CENTER, NONE
} update_type;
typedef enum {
CONTROL, META, FKEY, RAW
} function_type;
/* Structure types. */
typedef struct filestruct {
char *data;
@ -340,8 +344,52 @@ typedef struct rcoption {
long flag;
/* The flag associated with it, if any. */
} rcoption;
#endif
typedef struct sc {
char *keystr;
/* The shortcut key for a function, ASCII version */
function_type type;
/* What kind of function key is it for convenience later */
int seq;
/* The actual sequence to check on the the type is determined */
int menu;
/* What list does this apply to */
void (*scfunc)(void);
/* The function we're going to run */
int toggle;
/* If a toggle, what we're toggling */
bool execute;
/* Whether to execute the function in question or just return
so the sequence can be caught by the calling code */
struct sc *next;
/* Next in the list */
} sc;
typedef struct subnfunc {
void (*scfunc)(void);
/* What function is this */
int menus;
/* In what menus does this function applu */
const char *desc;
/* The function's description, e.g. "Page Up". */
#ifndef DISABLE_HELP
const char *help;
/* The help file entry text for this function. */
bool blank_after;
/* Whether there should be a blank line after the help entry
* text for this function. */
#endif
bool viewok;
/* Is this function allowed when in view mode? */
long toggle;
/* If this is a toggle, if nonzero what toggle to set */
struct subnfunc *next;
/* next item in the list */
} subnfunc;
/* Bitwise flags so that we can save space (or, more correctly, not
* waste it). */
#define CASE_SENSITIVE (1<<0)
@ -376,6 +424,23 @@ typedef struct rcoption {
#define NO_NEWLINES (1<<29)
#define BOLD_TEXT (1<<30)
/* Flags for which menus in which a given function should be present */
#define MMAIN (1<<0)
#define MWHEREIS (1<<1)
#define MREPLACE (1<<2)
#define MREPLACE2 (1<<3)
#define MGOTOLINE (1<<4)
#define MWRITEFILE (1<<5)
#define MINSERTFILE (1<<6)
#define MEXTCMD (1<<7)
#define MHELP (1<<8)
#define MSPELL (1<<9)
#define MBROWSER (1<<10)
#define MWHEREISFILE (1<<11)
#define MGOTODIR (1<<12)
/* This really isnt all but close enough */
#define MALL (MMAIN|MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE|MWRITEFILE|MINSERTFILE|MEXTCMD|MSPELL|MBROWSER|MWHEREISFILE|MGOTODIR|MHELP)
/* Control key sequences. Changing these would be very, very bad. */
#define NANO_CONTROL_SPACE 0
#define NANO_CONTROL_A 1

View File

@ -61,7 +61,8 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
/* The input buffer. */
static size_t kbinput_len = 0;
/* The length of the input buffer. */
const shortcut *s;
const sc *s;
const subnfunc *f;
bool have_shortcut;
*s_or_t = FALSE;
@ -88,7 +89,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
#endif
/* Check for a shortcut in the current list. */
s = get_shortcut(currshortcut, &input, meta_key, func_key);
s = get_shortcut(currmenu, &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. */
@ -131,7 +132,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
* and we're at the "Write File" prompt, disable text
* input. */
if (!ISSET(RESTRICTED) || openfile->filename[0] == '\0' ||
currshortcut != writefile_list) {
currmenu != MWRITEFILE) {
kbinput_len++;
kbinput = (int *)nrealloc(kbinput, kbinput_len *
sizeof(int));
@ -181,7 +182,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
* isn't blank, and we're at the "Write File"
* prompt, disable Cut. */
if (!ISSET(RESTRICTED) || openfile->filename[0] ==
'\0' || currshortcut != writefile_list)
'\0' || currmenu != MWRITEFILE)
do_statusbar_cut_text();
break;
case NANO_FORWARD_KEY:
@ -218,7 +219,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
* prompt, disable verbatim input. */
if (!ISSET(RESTRICTED) ||
openfile->filename[0] == '\0' ||
currshortcut != writefile_list) {
currmenu != MWRITEFILE) {
bool got_enter;
/* Whether we got the Enter key. */
@ -241,7 +242,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
* isn't blank, and we're at the "Write File"
* prompt, disable Delete. */
if (!ISSET(RESTRICTED) || openfile->filename[0] ==
'\0' || currshortcut != writefile_list)
'\0' || currmenu != MWRITEFILE)
do_statusbar_delete();
break;
case NANO_BACKSPACE_KEY:
@ -249,7 +250,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
* isn't blank, and we're at the "Write File"
* prompt, disable Backspace. */
if (!ISSET(RESTRICTED) || openfile->filename[0] ==
'\0' || currshortcut != writefile_list)
'\0' || currmenu != MWRITEFILE)
do_statusbar_backspace();
break;
/* Handle the normal statusbar prompt shortcuts, setting
@ -258,10 +259,11 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
* that we're done after running or trying to run their
* associated functions. */
default:
if (s->func != NULL) {
f = sctofunc((sc *) s);
if (s->scfunc != NULL && s->execute == TRUE) {
*ran_func = TRUE;
if (!ISSET(VIEW_MODE) || s->viewok)
s->func();
if (!ISSET(VIEW_MODE) || f->viewok)
f->scfunc();
}
*finished = TRUE;
}
@ -933,7 +935,7 @@ int get_prompt_string(bool allow_tabs,
#ifndef NANO_TINY
filestruct **history_list,
#endif
void (*refresh_func)(void), const shortcut *s
void (*refresh_func)(void), int menu
#ifndef DISABLE_TABCOMP
, bool *list
#endif
@ -982,7 +984,11 @@ int get_prompt_string(bool allow_tabs,
statusbar_pww = statusbar_xplustabs();
}
currshortcut = s;
currmenu = menu;
#ifdef DEBUG
fprintf(stderr, "get_prompt_string: answer = \"%s\", statusbar_x = %d\n", answer, statusbar_x);
#endif
update_statusbar_line(answer, statusbar_x);
@ -1118,6 +1124,7 @@ int get_prompt_string(bool allow_tabs,
wnoutrefresh(bottomwin);
}
#ifndef NANO_TINY
/* Set the current position in the history list to the bottom and
* free magichistory, if we need to. */
@ -1129,6 +1136,7 @@ int get_prompt_string(bool allow_tabs,
}
#endif
/* We've finished putting in an answer or run a normal shortcut's
* associated function, so reset statusbar_x and statusbar_pww. If
* we've finished putting in an answer, reset the statusbar cursor
@ -1165,7 +1173,7 @@ int do_prompt(bool allow_tabs,
#ifndef DISABLE_TABCOMP
bool allow_files,
#endif
const shortcut *s, const char *curranswer,
int menu, const char *curranswer,
#ifndef NANO_TINY
filestruct **history_list,
#endif
@ -1184,7 +1192,7 @@ int do_prompt(bool allow_tabs,
prompt = charalloc(((COLS - 4) * mb_cur_max()) + 1);
bottombars(s);
bottombars(menu);
va_start(ap, msg);
vsnprintf(prompt, (COLS - 4) * mb_cur_max(), msg, ap);
@ -1199,7 +1207,7 @@ int do_prompt(bool allow_tabs,
#ifndef NANO_TINY
history_list,
#endif
refresh_func, s
refresh_func, menu
#ifndef DISABLE_TABCOMP
, &list
#endif
@ -1224,6 +1232,7 @@ int do_prompt(bool allow_tabs,
break;
}
blank_statusbar();
wnoutrefresh(bottomwin);

View File

@ -91,34 +91,15 @@ extern char *full_operating_dir;
extern char *alt_speller;
#endif
extern shortcut *main_list;
extern shortcut *whereis_list;
extern shortcut *replace_list;
extern shortcut *replace_list_2;
extern shortcut *gotoline_list;
extern shortcut *writefile_list;
extern shortcut *insertfile_list;
#ifndef NANO_TINY
extern shortcut *extcmd_list;
#endif
#ifndef DISABLE_HELP
extern shortcut *help_list;
#endif
#ifndef DISABLE_SPELLER
extern shortcut *spell_list;
#endif
#ifndef DISABLE_BROWSER
extern shortcut *browser_list;
extern shortcut *whereis_file_list;
extern shortcut *gotodir_list;
#endif
extern sc *sclist;
extern subnfunc *allfuncs;
#ifdef ENABLE_COLOR
extern syntaxtype *syntaxes;
extern char *syntaxstr;
#endif
extern const shortcut *currshortcut;
extern int currmenu;
#ifndef NANO_TINY
extern toggle *toggles;
#endif
@ -341,7 +322,7 @@ void save_history(void);
#endif
/* All functions in global.c. */
size_t length_of_list(const shortcut *s);
size_t length_of_list(int menu);
#ifndef NANO_TINY
void toggle_init_one(int val
#ifndef DISABLE_HELP
@ -472,7 +453,7 @@ RETSIGTYPE handle_sigwinch(int signal);
void allow_pending_sigwinch(bool allow);
#endif
#ifndef NANO_TINY
void do_toggle(const toggle *which);
void do_toggle(int flag);
#endif
void disable_extended_io(void);
#ifdef USE_SLANG
@ -531,7 +512,7 @@ int get_prompt_string(bool allow_tabs,
#ifndef NANO_TINY
filestruct **history_list,
#endif
void (*refresh_func)(void), const shortcut *s
void (*refresh_func)(void), int menu
#ifndef DISABLE_TABCOMP
, bool *list
#endif
@ -540,7 +521,7 @@ int do_prompt(bool allow_tabs,
#ifndef DISABLE_TABCOMP
bool allow_files,
#endif
const shortcut *s, const char *curranswer,
int menu, const char *curranswer,
#ifndef NANO_TINY
filestruct **history_list,
#endif
@ -753,8 +734,9 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *kbinput_len);
#ifndef DISABLE_MOUSE
int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts);
#endif
const shortcut *get_shortcut(const shortcut *s_list, int *kbinput, bool
const sc *get_shortcut(int menu, int *kbinput, bool
*meta_key, bool *func_key);
const sc *first_sc_for(int menu, void *func);
#ifndef NANO_TINY
const toggle *get_toggle(int kbinput, bool meta_key);
#endif
@ -770,7 +752,7 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
void titlebar(const char *path);
void set_modified(void);
void statusbar(const char *msg, ...);
void bottombars(const shortcut *s);
void bottombars(int menu);
void onekey(const char *keystroke, const char *desc, size_t len);
void reset_cursor(void);
void edit_draw(const filestruct *fileptr, const char *converted, int
@ -788,6 +770,30 @@ void display_main_list(void);
void do_cursorpos(bool constant);
void do_cursorpos_void(void);
void do_replace_highlight(bool highlight, const char *word);
char *flagtostr(int flag);
const subnfunc *sctofunc(sc *s);
void print_sclist(void);
sc *strtosc(int menu, char *input);
function_type strtokeytype(char *str);
int strtomenu(char *input);
void assign_keyinfo(sc *s);
void xon_complaint(void);
void xoff_complaint(void);
const char *cancel_msg;
#ifndef NANO_TINY
const char *case_sens_msg;
const char *backwards_msg;
#endif
const char *replace_msg;
const char *no_replace_msg;
const char *go_to_line_msg;
#ifdef HAVE_REGEX_H
const char *regexp_msg;
#endif
#ifdef NANO_EXTRA
void do_credits(void);
#endif

View File

@ -347,6 +347,95 @@ void parse_syntax(char *ptr)
}
}
void parse_keybinding(char *ptr)
{
char *keyptr = NULL, *keycopy = NULL, *funcptr = NULL, *menuptr = NULL;
sc *s, *newsc;
int i, menu;
assert(ptr != NULL);
if (*ptr == '\0') {
rcfile_error(N_("Missing key name"));
return;
}
keyptr = ptr;
ptr = parse_next_word(ptr);
keycopy = mallocstrcpy(NULL, keyptr);
for (i = 0; i < strlen(keycopy); i++)
keycopy[i] = toupper(keycopy[i]);
if (keycopy[0] != 'M' && keycopy[0] != '^' && keycopy[0] != 'F') {
rcfile_error(
N_("keybindings must begin with \"^\", \"M\", or \"F\"\n"));
return;
}
funcptr = ptr;
ptr = parse_next_word(ptr);
if (funcptr == NULL) {
rcfile_error(
N_("Must specify function to bind key to\n"));
return;
}
menuptr = ptr;
ptr = parse_next_word(ptr);
if (menuptr == NULL) {
rcfile_error(
/* Note to translators, do not translate the word "all"
in the sentence below, everything else is fine */
N_("Must specify menu bind key to (or \"all\")\n"));
return;
}
menu = strtomenu(menuptr);
if (menu < 1) {
rcfile_error(
N_("Could not map name \"%s\" to a menu\n"), menuptr);
return;
}
newsc = strtosc(menu, funcptr);
#ifdef DEBUG
fprintf(stderr, "newsc now address %d, menu func assigned = %d, menu = %d\n",
(int) newsc, (int) newsc->scfunc, menu);
#endif
if (newsc == NULL) {
rcfile_error(
N_("Could not map name \"%s\" to a function\n"), funcptr);
return;
}
newsc->keystr = keycopy;
newsc->menu = menu;
newsc->type = strtokeytype(newsc->keystr);
assign_keyinfo(newsc);
#ifdef DEBUG
fprintf(stderr, "s->keystr = \"%s\"\n", newsc->keystr);
fprintf(stderr, "s->seq = \"%d\"\n", newsc->seq);
#endif
/* now let's have some fun. Try and delete the other entries
we found for the same menu, then make this new new
beginning */
for (s = sclist; s != NULL; s = s->next) {
if (((s->menu & newsc->menu) || newsc->menu == MALL) &&
(s->seq == newsc->seq)) {
s->menu &= ~newsc->menu;
#ifdef DEBUG
fprintf(stderr, "replaced menu entry %d\n", s->menu);
#endif
}
}
newsc->next = sclist;
sclist = newsc;
}
/* Read and parse additional syntax files. */
void parse_include(char *ptr)
{
@ -674,6 +763,8 @@ void parse_rcfile(FILE *rcstream
parse_colors(ptr, FALSE);
else if (strcasecmp(keyword, "icolor") == 0)
parse_colors(ptr, TRUE);
else if (strcasecmp(keyword, "bind") == 0)
parse_keybinding(ptr);
#endif /* ENABLE_COLOR */
else
rcfile_error(N_("Command \"%s\" not understood"), keyword);

View File

@ -136,6 +136,8 @@ int search_init(bool replacing, bool use_answer)
{
int i = 0;
char *buf;
sc *s;
void *func = NULL;
static char *backupstring = NULL;
/* The search string we'll be using. */
@ -173,7 +175,7 @@ int search_init(bool replacing, bool use_answer)
#ifndef DISABLE_TABCOMP
TRUE,
#endif
replacing ? replace_list : whereis_list, backupstring,
replacing ? MREPLACE : MWHEREIS, backupstring,
#ifndef NANO_TINY
&search_history,
#endif
@ -201,6 +203,8 @@ int search_init(bool replacing, bool use_answer)
#endif
_(" (to replace)") : "", buf);
fflush(stderr);
/* Release buf now that we don't need it anymore. */
free(buf);
@ -213,9 +217,13 @@ int search_init(bool replacing, bool use_answer)
statusbar(_("Cancelled"));
return -1;
} else {
switch (i) {
case -2: /* It's an empty string. */
case 0: /* It's a new string. */
for (s = sclist; s != NULL; s = s->next)
if ((s->menu & currmenu) && i == s->seq) {
func = s->scfunc;
break;
}
if (i == -2 || i == 0 ) {
#ifdef HAVE_REGEX_H
/* Use last_search if answer is an empty string, or
* answer if it isn't. */
@ -223,33 +231,34 @@ int search_init(bool replacing, bool use_answer)
last_search : answer))
return -1;
#endif
break;
;
#ifndef NANO_TINY
case TOGGLE_CASE_KEY:
} else if (func == (void *) case_sens_msg) {
TOGGLE(CASE_SENSITIVE);
backupstring = mallocstrcpy(backupstring, answer);
return 1;
case TOGGLE_BACKWARDS_KEY:
} else if (func == (void *) backwards_msg) {
TOGGLE(BACKWARDS_SEARCH);
backupstring = mallocstrcpy(backupstring, answer);
return 1;
#endif
#ifdef HAVE_REGEX_H
case NANO_REGEXP_KEY:
} else if (func == (void *) regexp_msg) {
TOGGLE(USE_REGEXP);
backupstring = mallocstrcpy(backupstring, answer);
return 1;
#endif
case NANO_TOOTHERSEARCH_KEY:
} else if (func == (void *) do_replace ||
func == (void *) no_replace_msg) {
backupstring = mallocstrcpy(backupstring, answer);
return -2; /* Call the opposite search function. */
case NANO_TOGOTOLINE_KEY:
} else if (func == (void *) go_to_line_msg) {
do_gotolinecolumn(openfile->current->lineno,
openfile->placewewant + 1, TRUE, TRUE, FALSE,
TRUE);
/* Put answer up on the statusbar and
* fall through. */
default:
} else {
return -1;
}
}
@ -915,7 +924,7 @@ void do_replace(void)
#ifndef DISABLE_TABCOMP
TRUE,
#endif
replace_list_2, last_replace,
MREPLACE2, last_replace,
#ifndef NANO_TINY
&replace_history,
#endif
@ -983,7 +992,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
#ifndef DISABLE_TABCOMP
TRUE,
#endif
gotoline_list, use_answer ? ans : "",
MGOTOLINE, use_answer ? ans : "",
#ifndef NANO_TINY
NULL,
#endif

View File

@ -1854,7 +1854,7 @@ bool do_int_spell_fix(const char *word)
#ifndef DISABLE_TABCOMP
TRUE,
#endif
spell_list, word,
MSPELL, word,
#ifndef NANO_TINY
NULL,
#endif
@ -2337,7 +2337,7 @@ void do_spell(void)
unlink(temp);
free(temp);
currshortcut = main_list;
currmenu = MMAIN;
/* If the spell-checker printed any error messages onscreen, make
* sure that they're cleared off. */

View File

@ -1,3 +1,4 @@
/* $Id$ */
/**************************************************************************
* winio.c *
@ -328,6 +329,7 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
*meta_key = FALSE;
*func_key = FALSE;
const sc *s;
/* Read in a character. */
while ((kbinput = get_input(win, 1)) == NULL);
@ -492,49 +494,100 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
NANO_BACKSPACE_KEY;
break;
case KEY_DOWN:
retval = NANO_NEXTLINE_KEY;
#ifdef KEY_SDOWN
/* ncurses and Slang don't support KEY_SDOWN. */
case KEY_SDOWN:
#endif
s = first_sc_for(currmenu, (void *) do_down_void);
if (s)
retval = s->seq;
break;
case KEY_UP:
retval = NANO_PREVLINE_KEY;
#ifdef KEY_SUP
/* ncurses and Slang don't support KEY_SUP. */
case KEY_SUP:
#endif
s = first_sc_for(currmenu, (void *) do_up_void);
if (s)
retval = s->seq;
break;
case KEY_LEFT:
retval = NANO_BACK_KEY;
#ifdef KEY_SLEFT
/* Slang doesn't support KEY_SLEFT. */
case KEY_SLEFT:
#endif
s = first_sc_for(currmenu, (void *) do_up_void);
if (s)
retval = s->seq;
break;
case KEY_RIGHT:
retval = NANO_FORWARD_KEY;
#ifdef KEY_SRIGHT
/* Slang doesn't support KEY_SRIGHT. */
case KEY_SRIGHT:
#endif
s = first_sc_for(currmenu, (void *) do_right);
if (s)
retval = s->seq;
break;
#ifdef KEY_HOME
/* HP-UX 10-11 doesn't support KEY_HOME. */
case KEY_HOME:
retval = NANO_HOME_KEY;
break;
#endif
case KEY_BACKSPACE:
retval = NANO_BACKSPACE_KEY;
break;
case KEY_DC:
retval = ISSET(REBIND_DELETE) ? NANO_BACKSPACE_KEY :
NANO_DELETE_KEY;
break;
case KEY_IC:
retval = NANO_INSERTFILE_KEY;
break;
case KEY_NPAGE:
retval = NANO_NEXTPAGE_KEY;
break;
case KEY_PPAGE:
retval = NANO_PREVPAGE_KEY;
break;
case KEY_ENTER:
retval = NANO_ENTER_KEY;
break;
#ifdef KEY_SHOME
/* HP-UX 10-11 and Slang don't support KEY_SHOME. */
case KEY_SHOME:
#endif
case KEY_A1: /* Home (7) on numeric keypad with
* NumLock off. */
retval = NANO_HOME_KEY;
s = first_sc_for(currmenu, (void *) do_home);
if (s)
retval = s->seq;
break;
case KEY_BACKSPACE:
s = first_sc_for(currmenu, (void *) do_backspace);
if (s)
retval = s->seq;
break;
case KEY_DC:
#ifdef KEY_SDC
/* Slang doesn't support KEY_SDC. */
case KEY_SDC:
#endif
if (ISSET(REBIND_DELETE))
s = first_sc_for(currmenu, (void *) do_delete);
else
s = first_sc_for(currmenu, (void *) do_backspace);
if (s)
retval = s->seq;
break;
case KEY_IC:
#ifdef KEY_SIC
/* Slang doesn't support KEY_SIC. */
case KEY_SIC:
#endif
s = first_sc_for(currmenu, (void *) do_insertfile_void);
if (s)
retval = s->seq;
break;
case KEY_NPAGE:
case KEY_C3: /* PageDown (4) on numeric keypad with
* NumLock off. */
s = first_sc_for(currmenu, (void *) do_page_down);
if (s)
retval = s->seq;
break;
case KEY_PPAGE:
case KEY_A3: /* PageUp (9) on numeric keypad with
* NumLock off. */
retval = NANO_PREVPAGE_KEY;
s = first_sc_for(currmenu, (void *) do_page_up);
if (s)
retval = s->seq;
break;
case KEY_ENTER:
s = first_sc_for(currmenu, (void *) do_enter);
if (s)
retval = s->seq;
break;
case KEY_B2: /* Center (5) on numeric keypad with
* NumLock off. */
@ -542,11 +595,17 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
break;
case KEY_C1: /* End (1) on numeric keypad with
* NumLock off. */
retval = NANO_END_KEY;
break;
case KEY_C3: /* PageDown (4) on numeric keypad with
* NumLock off. */
retval = NANO_NEXTPAGE_KEY;
#ifdef KEY_END
/* HP-UX 10-11 doesn't support KEY_END. */
case KEY_END:
#endif
#ifdef KEY_SEND
/* HP-UX 10-11 and Slang don't support KEY_SEND. */
case KEY_SEND:
#endif
s = first_sc_for(currmenu, (void *) do_end);
if (s)
retval = s->seq;
break;
#ifdef KEY_BEG
/* Slang doesn't support KEY_BEG. */
@ -558,13 +617,11 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
#ifdef KEY_CANCEL
/* Slang doesn't support KEY_CANCEL. */
case KEY_CANCEL:
retval = NANO_CANCEL_KEY;
break;
#ifdef KEY_SCANCEL
/* Slang doesn't support KEY_SCANCEL. */
case KEY_SCANCEL:
#endif
#ifdef KEY_END
/* HP-UX 10-11 doesn't support KEY_END. */
case KEY_END:
retval = NANO_END_KEY;
retval = first_sc_for(currmenu, (void *) cancel_msg)->seq;
break;
#endif
#ifdef KEY_SBEG
@ -574,61 +631,6 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
retval = ERR;
break;
#endif
#ifdef KEY_SCANCEL
/* Slang doesn't support KEY_SCANCEL. */
case KEY_SCANCEL:
retval = NANO_CANCEL_KEY;
break;
#endif
#ifdef KEY_SDC
/* Slang doesn't support KEY_SDC. */
case KEY_SDC:
retval = ISSET(REBIND_DELETE) ? NANO_BACKSPACE_KEY :
NANO_DELETE_KEY;
break;
#endif
#ifdef KEY_SEND
/* HP-UX 10-11 and Slang don't support KEY_SEND. */
case KEY_SEND:
retval = NANO_END_KEY;
break;
#endif
#ifdef KEY_SHOME
/* HP-UX 10-11 and Slang don't support KEY_SHOME. */
case KEY_SHOME:
retval = NANO_HOME_KEY;
break;
#endif
#ifdef KEY_SIC
/* Slang doesn't support KEY_SIC. */
case KEY_SIC:
retval = NANO_INSERTFILE_KEY;
break;
#endif
#ifdef KEY_SDOWN
/* ncurses and Slang don't support KEY_SDOWN. */
case KEY_SDOWN:
retval = NANO_NEXTLINE_KEY;
break;
#endif
#ifdef KEY_SUP
/* ncurses and Slang don't support KEY_SUP. */
case KEY_SUP:
retval = NANO_PREVLINE_KEY;
break;
#endif
#ifdef KEY_SLEFT
/* Slang doesn't support KEY_SLEFT. */
case KEY_SLEFT:
retval = NANO_BACK_KEY;
break;
#endif
#ifdef KEY_SRIGHT
/* Slang doesn't support KEY_SRIGHT. */
case KEY_SRIGHT:
retval = NANO_FORWARD_KEY;
break;
#endif
#ifdef KEY_SSUSPEND
/* Slang doesn't support KEY_SSUSPEND. */
case KEY_SSUSPEND:
@ -1639,6 +1641,7 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
{
MEVENT mevent;
bool in_bottomwin;
subnfunc *f;
*mouse_x = -1;
*mouse_y = -1;
@ -1670,9 +1673,6 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
size_t currslen;
/* The number of shortcuts in the current shortcut
* list. */
const shortcut *s;
/* The actual shortcut we released on, starting at the
* first one in the current shortcut list. */
/* Translate the mouse event coordinates so that they're
* relative to bottomwin. */
@ -1694,10 +1694,10 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
j = *mouse_y - 1;
/* Get the shortcut lists' length. */
if (currshortcut == main_list)
if (currmenu == MMAIN)
currslen = MAIN_VISIBLE;
else {
currslen = length_of_list(currshortcut);
currslen = length_of_list(currmenu);
/* We don't show any more shortcuts than the main list
* does. */
@ -1730,20 +1730,16 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
/* Go through the shortcut list to determine which shortcut
* we released/clicked on. */
s = currshortcut;
f = allfuncs;
for (; j > 0; j--)
s = s->next;
while (f != NULL && (f->menus & currmenu) != 0)
f = f->next;
/* And put back the equivalent key. Assume that each
* shortcut has, at the very least, an equivalent control
* key, an equivalent primary meta key sequence, or both. */
if (s->ctrlval != NANO_NO_KEY) {
unget_kbinput(s->ctrlval, FALSE, FALSE);
return 1;
} else if (s->metaval != NANO_NO_KEY) {
unget_kbinput(s->metaval, TRUE, FALSE);
return 1;
/* And put back the equivalent key. */
if (f != NULL) {
const sc *s = first_sc_for(currmenu, (void *) f->scfunc);
unget_kbinput(s->seq, s->type == META, FALSE);
}
} else
/* Handle releases/clicks of the first mouse button that
@ -1795,53 +1791,29 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
* example, passing in a meta key sequence that corresponds to a
* function with a control key, a function key, and a meta key sequence
* will return the control key corresponding to that function. */
const shortcut *get_shortcut(const shortcut *s_list, int *kbinput, bool
const sc *get_shortcut(int menu, int *kbinput, bool
*meta_key, bool *func_key)
{
const shortcut *s = s_list;
size_t slen = length_of_list(s_list);
sc *s;
#ifdef DEBUG
fprintf(stderr, "get_shortcut(): kbinput = %d, meta_key = %s, func_key = %s\n", *kbinput, *meta_key ? "TRUE" : "FALSE", *func_key ? "TRUE" : "FALSE");
#endif
/* Check for shortcuts. */
for (; slen > 0; slen--) {
/* We've found a shortcut if:
*
* 1. The key exists.
* 2. The key is a control key in the shortcut list.
* 3. meta_key is TRUE and the key is the primary or
* miscellaneous meta sequence in the shortcut list.
* 4. func_key is TRUE and the key is a function key in the
* shortcut list. */
if (*kbinput != NANO_NO_KEY && (*kbinput == s->ctrlval ||
(*meta_key && (*kbinput == s->metaval || *kbinput ==
s->miscval)) || (*func_key && *kbinput ==
s->funcval))) {
break;
}
s = s->next;
}
/* Translate the shortcut to either its control key or its meta key
* equivalent. Assume that the shortcut has an equivalent control
* key, an equivalent primary meta key sequence, or both. */
if (slen > 0) {
if (s->ctrlval != NANO_NO_KEY) {
*meta_key = FALSE;
*func_key = FALSE;
*kbinput = s->ctrlval;
return s;
} else if (s->metaval != NANO_NO_KEY) {
*meta_key = TRUE;
*func_key = FALSE;
*kbinput = s->metaval;
for (s = sclist; s != NULL; s = s->next) {
if ((menu & s->menu)
&& ((s->type == META && *meta_key == TRUE && *kbinput == s->seq)
|| (s->type != META && *kbinput == s->seq))) {
#ifdef DEBUG
fprintf (stderr, "matched seq \"%s\" and btw meta was %d (menus %d = %d)\n", s->keystr, *meta_key, menu, s->menu);
#endif
return s;
}
}
#ifdef DEBUG
fprintf (stderr, "matched nothing btw meta was %d\n", *meta_key);
#endif
return NULL;
}
@ -2375,19 +2347,21 @@ void statusbar(const char *msg, ...)
/* Display the shortcut list in s on the last two rows of the bottom
* portion of the window. */
void bottombars(const shortcut *s)
void bottombars(int menu)
{
size_t i, colwidth, slen;
subnfunc *f;
const sc *s;
if (ISSET(NO_HELP))
return;
if (s == main_list) {
if (menu == MMAIN) {
slen = MAIN_VISIBLE;
assert(slen <= length_of_list(s));
assert(slen <= length_of_list(menu));
} else {
slen = length_of_list(s);
slen = length_of_list(menu);
/* Don't show any more shortcuts than the main list does. */
if (slen > MAIN_VISIBLE)
@ -2402,26 +2376,34 @@ void bottombars(const shortcut *s)
blank_bottombars();
for (i = 0; i < slen; i++, s = s->next) {
const char *keystr;
char foo[4] = "";
#ifdef DEBUG
fprintf(stderr, "In bottombars, and slen == \"%d\"\n", (int) slen);
#endif
/* Yucky sentinel values that we can't handle a better way. */
if (s->ctrlval == NANO_CONTROL_SPACE)
strcpy(foo, "^ ");
else if (s->ctrlval == NANO_CONTROL_8)
strcpy(foo, "^?");
/* Normal values. Assume that the shortcut has an equivalent
* control key, meta key sequence, or both. */
else if (s->ctrlval != NANO_NO_KEY)
sprintf(foo, "^%c", s->ctrlval + 64);
else if (s->metaval != NANO_NO_KEY)
sprintf(foo, "M-%c", toupper(s->metaval));
for (f = allfuncs, i = 0; i < slen && f != NULL; f = f->next) {
keystr = foo;
#ifdef DEBUG
fprintf(stderr, "Checking menu items....");
#endif
if ((f->menus & menu) == 0)
continue;
#ifdef DEBUG
fprintf(stderr, "found one! f->menus = %d\n", f->menus);
#endif
s = first_sc_for(menu, f->scfunc);
if (s == NULL) {
#ifdef DEBUG
fprintf(stderr, "Whoops, guess not, no shortcut key found for func!\n");
#endif
continue;
}
wmove(bottomwin, 1 + i % 2, (i / 2) * colwidth);
onekey(keystr, s->desc, colwidth + (COLS % colwidth));
#ifdef DEBUG
fprintf(stderr, "Calling onekey with keystr \"%s\" and desc \"%s\"\n", s->keystr, f->desc);
#endif
onekey(s->keystr, f->desc, colwidth + (COLS % colwidth));
i++;
}
wnoutrefresh(bottomwin);
@ -3184,14 +3166,14 @@ void total_refresh(void)
total_redraw();
titlebar(NULL);
edit_refresh();
bottombars(currshortcut);
bottombars(currmenu);
}
/* Display the main shortcut list on the last two rows of the bottom
* portion of the window. */
void display_main_list(void)
{
bottombars(main_list);
bottombars(MMAIN);
}
/* If constant is TRUE, we display the current cursor position only if