Commit 79a33bb3 authored by Chris Allegretta's avatar Chris Allegretta
Browse files

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
parent 200f0c8c
Showing with 1409 additions and 1297 deletions
+1409 -1297
......@@ -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
......
......@@ -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
......
This diff is collapsed.
......@@ -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;
/* 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 (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';
ptr += sprintf(ptr, "^%s", space_ptr);
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';
}
/* Now add our shortcut info. */
for (f = allfuncs; f != NULL; f = f->next) {
/* Function key. */
if (s->funcval != NANO_NO_KEY) {
entries++;
/* If this is the first entry, put it in the middle. */
if (entries == 1) {
entries++;
*(ptr++) = '\t';
}
ptr += sprintf(ptr, "(F%d)", s->funcval - KEY_F0);
*(ptr++) = '\t';
}
if ((f->menus & currmenu) == 0)
continue;
/* 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));
*(ptr++) = '\t';
}
if (!f->desc || !strcmp(f->desc, ""))
continue;
/* 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';
}
/* Lets just try and use the first 3 shortcuts
from the new struct... */
for (s = sclist, scsfound = 0; s != NULL; s = s->next) {
/* 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++;
if (scsfound == 3)
continue;
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';
}
}
/* Pad with tabs if we didnt find 3 */
for (; scsfound < 3; scsfound++) {
*(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) {
......
......@@ -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,
......
......@@ -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,7 +344,51 @@ 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). */
......@@ -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
......
......@@ -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);
......
......@@ -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
......
......@@ -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);
......
......@@ -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
......
......@@ -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. */
......
/* $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
#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. */
s = first_sc_for(currmenu, (void *) do_home);
if (s)
retval = s->seq;
break;
case KEY_BACKSPACE:
retval = NANO_BACKSPACE_KEY;
s = first_sc_for(currmenu, (void *) do_backspace);
if (s)
retval = s->seq;
break;
case KEY_DC:
retval = ISSET(REBIND_DELETE) ? NANO_BACKSPACE_KEY :
NANO_DELETE_KEY;
#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:
retval = NANO_INSERTFILE_KEY;
#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:
retval = NANO_NEXTPAGE_KEY;
break;
case KEY_PPAGE:
retval = NANO_PREVPAGE_KEY;
break;
case KEY_ENTER:
retval = NANO_ENTER_KEY;
break;
case KEY_A1: /* Home (7) on numeric keypad with
case KEY_C3: /* PageDown (4) on numeric keypad with
* NumLock off. */
retval = NANO_HOME_KEY;
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;
/* 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;
while (f != NULL && (f->menus & currmenu) != 0)
f = f->next;
/* 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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment