From: Thomas Roessler Date: Mon, 5 Oct 1998 18:24:42 +0000 (+0000) Subject: Vikas' macro_function patch. X-Git-Tag: mutt-0-94-13-rel~67 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f9fb45338e02ec7171f58b91ba89554f3ea57098;p=mutt Vikas' macro_function patch. --- diff --git a/aclocal.m4 b/aclocal.m4 index ce0848aa..2d233c87 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -182,11 +182,8 @@ AC_DEFUN(AM_WITH_NLS, if test "$gt_cv_func_gettext_libc" != "yes"; then AC_CHECK_LIB(intl, bindtextdomain, - [AC_CACHE_CHECK([for gettext in libintl], - gt_cv_func_gettext_libintl, - [AC_CHECK_LIB(intl, gettext, - gt_cv_func_gettext_libintl=yes, - gt_cv_func_gettext_libintl=no)], + [AC_CHECK_LIB(intl, gettext, + gt_cv_func_gettext_libintl=yes, gt_cv_func_gettext_libintl=no)]) fi diff --git a/addrbook.c b/addrbook.c index 6f494978..50bd030c 100644 --- a/addrbook.c +++ b/addrbook.c @@ -125,6 +125,7 @@ void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases) int t = -1; int i, done = 0; char helpstr[SHORT_STRING]; + int savedmenu = CurrentMenu; if (!aliases) { @@ -139,7 +140,7 @@ void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases) menu->make_entry = alias_entry; menu->search = alias_search; menu->tag = alias_tag; - menu->menu = MENU_ALIAS; + menu->menu = CurrentMenu = MENU_ALIAS; menu->title = _("Aliases"); menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_ALIAS, AliasHelp); @@ -188,5 +189,6 @@ void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases) rfc822_write_address (buf, buflen, AliasTable[t]->addr); mutt_menuDestroy (&menu); + CurrentMenu = savedmenu; safe_free ((void **) &AliasTable); } diff --git a/browser.c b/browser.c index 032d5d3f..62635d91 100644 --- a/browser.c +++ b/browser.c @@ -465,6 +465,7 @@ void mutt_select_file (char *f, size_t flen, int buffy) MUTTMENU *menu; struct stat st; int i, killPrefix = 0; + int savedmenu = CurrentMenu; memset (&state, 0, sizeof (struct browser_state)); @@ -515,7 +516,7 @@ void mutt_select_file (char *f, size_t flen, int buffy) return; menu = mutt_new_menu (); - menu->menu = MENU_FOLDER; + menu->menu = CurrentMenu = MENU_FOLDER; menu->make_entry = folder_entry; menu->search = select_file_search; menu->title = title; @@ -624,6 +625,7 @@ void mutt_select_file (char *f, size_t flen, int buffy) destroy_state (&state); mutt_menuDestroy (&menu); + CurrentMenu = savedmenu; return; case OP_BROWSER_TELL: @@ -662,6 +664,7 @@ void mutt_select_file (char *f, size_t flen, int buffy) mutt_error _("Error scanning directory."); destroy_state (&state); mutt_menuDestroy (&menu); + CurrentMenu = savedmenu; return; } } @@ -718,6 +721,7 @@ void mutt_select_file (char *f, size_t flen, int buffy) { mutt_error _("Error scanning directory."); mutt_menuDestroy (&menu); + CurrentMenu = savedmenu; return; } killPrefix = 0; @@ -736,6 +740,7 @@ void mutt_select_file (char *f, size_t flen, int buffy) { int reverse = 0; + event_t ch; move (LINES - 1, 0); if (i == OP_SORT_REVERSE) @@ -747,18 +752,21 @@ void mutt_select_file (char *f, size_t flen, int buffy) } clrtoeol (); - while ((i = mutt_getch ()) != EOF && i != 'a' && i != 'd' && i != 'z' - && i != 'n') + FOREVER { - if (i == ERR || CI_is_return (i)) + ch = mutt_getch(); + if (ch.ch == EOF || ch.ch == 'a' || ch.ch == 'd' || ch.ch == 'z' || ch.ch == 'n') + break; + + if (ch.ch == ERR || CI_is_return (ch.ch)) break; else BEEP (); } - if (i != EOF) + if (ch.ch != EOF) { - switch (i) + switch (ch.ch) { case 'a': BrowserSort = reverse | SORT_SUBJECT; @@ -805,6 +813,7 @@ void mutt_select_file (char *f, size_t flen, int buffy) strfcpy (f, buf, flen); destroy_state (&state); mutt_menuDestroy (&menu); + CurrentMenu = savedmenu; return; } MAYBE_REDRAW (menu->redraw); diff --git a/commands.c b/commands.c index bfaecf8f..c32539fb 100644 --- a/commands.c +++ b/commands.c @@ -221,7 +221,7 @@ int mutt_display_message (HEADER *cur) mutt_set_flag (Context, cur, M_READ, 1); if (option (OPTPROMPTAFTER)) { - mutt_ungetch (mutt_any_key_to_continue _("Command: ")); + mutt_ungetch (mutt_any_key_to_continue _("Command: "), 0); rc = km_dokey (MENU_PAGER); } else @@ -393,7 +393,7 @@ int mutt_pipe_message (HEADER *h) int mutt_select_sort (int reverse) { int method = Sort; /* save the current method in case of abort */ - int ch; + event_t ch; Sort = 0; while (!Sort) @@ -403,13 +403,13 @@ int mutt_select_sort (int reverse) _("Rev-Sort (d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/(u)nsort/si(z)e/s(c)ore?: ") : _("Sort (d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/(u)nsort/si(z)e/s(c)ore?: ")); ch = mutt_getch (); - if (ch == ERR || CI_is_return (ch)) + if (ch.ch == -1 || CI_is_return (ch.ch)) { Sort = method; CLEARLINE (LINES-1); return (-1); } - switch (ch) + switch (ch.ch) { case 'c': Sort = SORT_SCORE; diff --git a/compose.c b/compose.c index 21a829c2..40bb4927 100644 --- a/compose.c +++ b/compose.c @@ -435,11 +435,12 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */ /* Sort, SortAux could be changed in mutt_index_menu() */ int oldSort = Sort, oldSortAux = SortAux; struct stat st; + int savedmenu = CurrentMenu; idx = mutt_gen_attach_list (msg->content, idx, &idxlen, &idxmax, 0, 1); menu = mutt_new_menu (); - menu->menu = MENU_COMPOSE; + menu->menu = CurrentMenu = MENU_COMPOSE; menu->offset = HDR_ATTACH; menu->max = idxlen; menu->make_entry = snd_entry; @@ -1105,6 +1106,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */ } mutt_menuDestroy (&menu); + CurrentMenu = savedmenu; if (idxlen) { diff --git a/configure b/configure index eb3787e2..4df75ab3 100755 --- a/configure +++ b/configure @@ -817,7 +817,7 @@ fi -ALL_LINGUAS="de" +ALL_LINGUAS="de ru" # Make sure we can run config.sub. @@ -4324,13 +4324,8 @@ LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 - echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6 -echo "configure:4329: checking for gettext in libintl" >&5 -if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6 -echo "configure:4334: checking for gettext in -lintl" >&5 +echo "configure:4329: checking for gettext in -lintl" >&5 ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4338,7 +4333,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lintl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:4348: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4370,9 +4365,6 @@ else gt_cv_func_gettext_libintl=no fi -fi - -echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6 else echo "$ac_t""no" 1>&6 fi @@ -4388,7 +4380,7 @@ EOF # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4392: checking for $ac_word" >&5 +echo "configure:4384: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4422,12 +4414,12 @@ fi for ac_func in dcgettext do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4426: checking for $ac_func" >&5 +echo "configure:4418: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:4446: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4477,7 +4469,7 @@ done # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4481: checking for $ac_word" >&5 +echo "configure:4473: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4509,7 +4501,7 @@ fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4513: checking for $ac_word" >&5 +echo "configure:4505: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4541,7 +4533,7 @@ else fi cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:4545: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* CATOBJEXT=.gmo DATADIRNAME=share @@ -4572,7 +4564,7 @@ fi if test "$CATOBJEXT" = "NONE"; then echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6 -echo "configure:4576: checking whether catgets can be used" >&5 +echo "configure:4568: checking whether catgets can be used" >&5 # Check whether --with-catgets or --without-catgets was given. if test "${with_catgets+set}" = set; then withval="$with_catgets" @@ -4585,7 +4577,7 @@ fi if test "$nls_cv_use_catgets" = "yes"; then echo $ac_n "checking for main in -li""... $ac_c" 1>&6 -echo "configure:4589: checking for main in -li" >&5 +echo "configure:4581: checking for main in -li" >&5 ac_lib_var=`echo i'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4593,14 +4585,14 @@ else ac_save_LIBS="$LIBS" LIBS="-li $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:4596: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4628,12 +4620,12 @@ else fi echo $ac_n "checking for catgets""... $ac_c" 1>&6 -echo "configure:4632: checking for catgets" >&5 +echo "configure:4624: checking for catgets" >&5 if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:4652: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_catgets=yes" else @@ -4678,7 +4670,7 @@ EOF # Extract the first word of "gencat", so it can be a program name with args. set dummy gencat; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4682: checking for $ac_word" >&5 +echo "configure:4674: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4710,7 +4702,7 @@ fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4714: checking for $ac_word" >&5 +echo "configure:4706: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4743,7 +4735,7 @@ fi # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4747: checking for $ac_word" >&5 +echo "configure:4739: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4778,7 +4770,7 @@ fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4782: checking for $ac_word" >&5 +echo "configure:4774: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4836,7 +4828,7 @@ fi # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4840: checking for $ac_word" >&5 +echo "configure:4832: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4870,7 +4862,7 @@ fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4874: checking for $ac_word" >&5 +echo "configure:4866: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4902,7 +4894,7 @@ fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4906: checking for $ac_word" >&5 +echo "configure:4898: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4995,7 +4987,7 @@ fi LINGUAS= else echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 -echo "configure:4999: checking for catalogs to be installed" >&5 +echo "configure:4991: checking for catalogs to be installed" >&5 NEW_LINGUAS= for lang in ${LINGUAS=$ALL_LINGUAS}; do case "$ALL_LINGUAS" in @@ -5023,17 +5015,17 @@ echo "configure:4999: checking for catalogs to be installed" >&5 if test "$CATOBJEXT" = ".cat"; then ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6 -echo "configure:5027: checking for linux/version.h" >&5 +echo "configure:5019: checking for linux/version.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5037: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5029: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* diff --git a/configure.in b/configure.in index fe99a38d..72f9701a 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ AC_INIT(mutt.h) AM_CONFIG_HEADER(config.h) AM_INIT_AUTOMAKE(mutt, 0.94.10) -ALL_LINGUAS="de" +ALL_LINGUAS="de ru" AC_CANONICAL_HOST diff --git a/curs_lib.c b/curs_lib.c index 15482458..cc07bcc1 100644 --- a/curs_lib.c +++ b/curs_lib.c @@ -35,9 +35,8 @@ * buffering routines. */ static short UngetCount = 0; - #define UngetBufLen 128 -static int UngetBuf[UngetBufLen]; +static event_t KeyEvent[UngetBufLen] = { {0,0} }; void mutt_refresh (void) { @@ -46,12 +45,13 @@ void mutt_refresh (void) refresh (); } -int mutt_getch (void) +event_t mutt_getch (void) { int ch; + event_t err = {-1,0}, ret; if (UngetCount) - return (UngetBuf[--UngetCount]); + return (KeyEvent[--UngetCount]); Signals &= ~S_INTERRUPT; @@ -66,17 +66,21 @@ int mutt_getch (void) mutt_query_exit (); if(ch == -1) - return ch; + return err; if ((ch & 0x80) && option (OPTMETAKEY)) { /* send ALT-x as ESC-x */ ch &= ~0x80; - mutt_ungetch (ch); - return ('\033'); + mutt_ungetch (ch, 0); + ret.ch = '\033'; + ret.op = 0; + return ret; } - return (ch == ctrl ('G') ? ERR : ch); + ret.ch = ch; + ret.op = 0; + return (ch == ctrl ('G') ? err : ret); } int mutt_get_field (/* const */ char *field, char *buf, size_t buflen, int complete) @@ -126,7 +130,7 @@ void mutt_edit_file (const char *editor, const char *data) int mutt_yesorno (const char *msg, int def) { - int ch; + event_t ch; const char *yes = _("yes"); const char *no = _("no"); @@ -137,15 +141,15 @@ int mutt_yesorno (const char *msg, int def) { mutt_refresh (); ch = mutt_getch (); - if (ch == ERR) return(-1); - if (CI_is_return (ch)) + if (ch.ch == ERR) return(-1); + if (CI_is_return (ch.ch)) break; - else if (tolower(ch) == tolower(*yes)) + else if (tolower(ch.ch) == tolower(*yes)) { def = 1; break; } - else if (tolower(ch) == tolower(*no)) + else if (tolower(ch.ch) == tolower(*no)) { def = 0; break; @@ -297,7 +301,7 @@ int mutt_do_pager (const char *banner, int mutt_enter_fname (const char *prompt, char *buf, size_t blen, int *redraw, int buffy) { - int i; + event_t ch; mvaddstr (LINES-1, 0, (char *) prompt); addstr (_(" ('?' for list): ")); @@ -306,12 +310,13 @@ int mutt_enter_fname (const char *prompt, char *buf, size_t blen, int *redraw, i clrtoeol (); mutt_refresh (); - if ((i = mutt_getch ()) == ERR) + ch = mutt_getch(); + if (ch.ch == -1) { CLEARLINE (LINES-1); return (-1); } - else if (i == '?') + else if (ch.ch == '?') { mutt_refresh (); buf[0] = 0; @@ -323,7 +328,7 @@ int mutt_enter_fname (const char *prompt, char *buf, size_t blen, int *redraw, i char *pc = safe_malloc (strlen (prompt) + 3); sprintf (pc, "%s: ", prompt); - mutt_ungetch (i); + mutt_ungetch (ch.ch, 0); if (mutt_get_field (pc, buf, blen, (buffy ? M_EFILE : M_FILE) | M_CLEAR) != 0) buf[0] = 0; @@ -337,10 +342,15 @@ int mutt_enter_fname (const char *prompt, char *buf, size_t blen, int *redraw, i /* FOO - this could be made more efficient by allocating/deallocating memory * instead of using a fixed array */ -void mutt_ungetch (int ch) +void mutt_ungetch (int ch, int op) { + event_t tmp; + + tmp.ch = ch; + tmp.op = op; + if (UngetCount < UngetBufLen) /* make sure not to overflow */ - UngetBuf[UngetCount++] = ch; + KeyEvent[UngetCount++] = tmp; } void mutt_flushinp (void) diff --git a/curs_main.c b/curs_main.c index 78cbdd64..3175c432 100644 --- a/curs_main.c +++ b/curs_main.c @@ -241,7 +241,8 @@ struct mapping_t IndexHelp[] = { int mutt_index_menu (void) { char buf[LONG_STRING], helpstr[SHORT_STRING]; - int op = OP_NULL; /* function to execute */ + int op = OP_NULL; + event_t event = {OP_NULL, 0}; int done = 0; /* controls when to exit the "event" loop */ int i = 0, j; int tag = 0; /* has the tag-prefix command been pressed? */ @@ -254,9 +255,10 @@ int mutt_index_menu (void) int do_buffy_notify = 1; int close = 0; /* did we OP_QUIT or OP_EXIT out of this menu? */ int attach_msg = option(OPTATTACHMSG); + int savedmenu = CurrentMenu; menu = mutt_new_menu (); - menu->menu = MENU_MAIN; + menu->menu = CurrentMenu = MENU_MAIN; menu->offset = 1; menu->pagelen = LINES - 3; menu->make_entry = index_make_entry; @@ -474,25 +476,26 @@ int mutt_index_menu (void) if (Timeout > 0) { timeout (Timeout * 1000); /* milliseconds */ - op = mutt_getch (); + event = mutt_getch (); timeout (-1); /* restore blocking operation */ - if (op != -1) + if (event.ch != -1) { - mutt_ungetch (op); + mutt_ungetch (event.ch, event.op); op = km_dokey (MENU_MAIN); } } else op = km_dokey (MENU_MAIN); - mutt_curs_set (1); + mutt_curs_set (1); + #if defined (USE_SLANG_CURSES) || defined (HAVE_RESIZETERM) if (Signals & S_SIGWINCH) { mutt_flushinp (); mutt_resize_screen (); menu->redraw = REDRAW_FULL; - menu->menu = MENU_MAIN; + menu->menu = CurrentMenu = MENU_MAIN; Signals &= ~S_SIGWINCH; menu->top = 0; /* so we scroll the right amount */ continue; @@ -591,7 +594,7 @@ int mutt_index_menu (void) case OP_JUMP: CHECK_MSGCOUNT; - mutt_ungetch (LastKey); + mutt_ungetch (LastKey, 0); buf[0] = 0; if (mutt_get_field (_("Jump to message: "), buf, sizeof (buf), 0) != 0 || !buf[0]) @@ -957,7 +960,7 @@ int mutt_index_menu (void) menu->redraw = REDRAW_INDEX | REDRAW_STATUS; } - menu->menu = MENU_PAGER; + menu->menu = CurrentMenu = MENU_PAGER; menu->oldcurrent = menu->current; continue; @@ -1461,6 +1464,7 @@ int mutt_index_menu (void) case OP_ENTER_COMMAND: + CurrentMenu = MENU_MAIN; mutt_enter_command (); mutt_check_rescore (Context); if (option (OPTNEEDRESORT) && Context && Context->msgcount) @@ -1706,7 +1710,7 @@ int mutt_index_menu (void) if (menu->menu == MENU_PAGER) { - menu->menu = MENU_MAIN; + menu->menu = CurrentMenu = MENU_MAIN; menu->redraw = REDRAW_FULL; set_option (OPTWEED); /* turn header weeding back on. */ } @@ -1715,6 +1719,7 @@ int mutt_index_menu (void) } mutt_menuDestroy (&menu); + CurrentMenu = savedmenu; return (close); } diff --git a/enter.c b/enter.c index 334bf2ff..e45caf93 100644 --- a/enter.c +++ b/enter.c @@ -53,6 +53,7 @@ enum int mutt_enter_string (unsigned char *buf, size_t buflen, int y, int x, int flags) { + event_t event; int curpos = 0; /* the location of the cursor */ int lastchar = 0; /* offset of the last char in the string */ int begin = 0; /* first character displayed on the line */ @@ -122,7 +123,7 @@ int mutt_enter_string (unsigned char *buf, size_t buflen, int y, int x, return (-1); } - if (ch != 0) + if (ch != OP_NULL) { first = 0; /* make sure not to clear the buffer */ if (ch != OP_EDITOR_COMPLETE) @@ -414,7 +415,8 @@ int mutt_enter_string (unsigned char *buf, size_t buflen, int y, int x, case OP_EDITOR_QUOTE_CHAR: ADDCH (LastKey); - LastKey = mutt_getch (); + event = mutt_getch (); + LastKey = event.ch; move (y, x + curpos - begin); goto self_insert; @@ -436,7 +438,7 @@ self_insert: first = 0; if (IsPrint (ch)) { - mutt_ungetch (ch); + mutt_ungetch (ch, 0); buf[0] = 0; redraw = M_REDRAW_INIT; continue; diff --git a/flags.c b/flags.c index 02496ce4..b53f2c18 100644 --- a/flags.c +++ b/flags.c @@ -250,12 +250,14 @@ int mutt_thread_set_flag (HEADER *cur, int flag, int bf, int subthread) int mutt_change_flag (HEADER *h, int bf) { int i, flag; + event_t event; - mvprintw (LINES - 1, 0, "? (D/N/O/r/*/!): ", bf ? _("Set %s flag") : - _("Clear %s flag")); + mvprintw (LINES - 1, 0, "%s flag? (D/N/O/r/*/!): ", bf ? _("Set") : _("Clear")); clrtoeol (); - if ((i = mutt_getch ()) == ERR) + event = mutt_getch(); + i = event.ch; + if (i == -1) { CLEARLINE (LINES-1); return (-1); diff --git a/globals.h b/globals.h index 9854d0f8..9c328862 100644 --- a/globals.h +++ b/globals.h @@ -114,6 +114,8 @@ WHERE short WriteInc; /* vector to store received signals */ WHERE short Signals INITVAL (0); +WHERE int CurrentMenu; + WHERE ALIAS *Aliases INITVAL (0); WHERE LIST *UserHeader INITVAL (0); diff --git a/init.c b/init.c index 07e6eab7..3d37b177 100644 --- a/init.c +++ b/init.c @@ -21,6 +21,7 @@ #include "mutt_curses.h" #include "mutt_regex.h" #include "history.h" +#include "keymap.h" #ifdef _PGPPATH @@ -1306,6 +1307,52 @@ int mutt_command_complete (char *buffer, size_t len, int pos, int numtabs) strncpy (pt, Completed, buffer + len - pt - spaces); } + else if (!strncmp (buffer, "exec", 4)) + { + struct binding_t *menu = km_get_table (CurrentMenu); + + if (!menu && CurrentMenu != MENU_PAGER) + menu = OpGeneric; + + pt++; + /* first TAB. Collect all the matches */ + if (numtabs == 1) + { + Num_matched = 0; + strfcpy (User_typed, pt, sizeof (User_typed)); + memset (Matches, 0, sizeof (Matches)); + memset (Completed, 0, sizeof (Completed)); + for (num = 0; menu[num].name; num++) + candidate (Completed, User_typed, menu[num].name, sizeof (Completed)); + /* try the generic menu */ + if (Completed[0] == 0 && CurrentMenu != MENU_PAGER) + { + menu = OpGeneric; + for (num = 0; menu[num].name; num++) + candidate (Completed, User_typed, menu[num].name, sizeof (Completed)); + } + Matches[Num_matched++] = User_typed; + + /* All matches are stored. Longest non-ambiguous string is "" + * i.e. dont change 'buffer'. Fake successful return this time */ + if (User_typed[0] == 0) + return 1; + } + + if (Completed[0] == 0 && User_typed[0]) + return 0; + + /* Num_matched will _always_ be atleast 1 since the initial + * user-typed string is always stored */ + if (numtabs == 1 && Num_matched == 2) + snprintf(Completed, sizeof(Completed),"%s", Matches[0]); + else if (numtabs > 1 && Num_matched > 2) + /* cycle thru all the matches */ + snprintf(Completed, sizeof(Completed), "%s", + Matches[(numtabs - 2) % Num_matched]); + + strncpy (pt, Completed, buffer + len - pt - spaces); + } else return 0; @@ -1600,6 +1647,8 @@ void mutt_init (int skip_sys_rc, LIST *commands) for (i = 0; MuttVars[i].option; i++) mutt_restore_default (&MuttVars[i]); + CurrentMenu = MENU_MAIN; + #ifndef LOCALES_HACK /* Do we have a locale definition? */ if (((p = getenv ("LC_ALL")) != NULL && p[0]) || diff --git a/init.h b/init.h index ff429bce..e4204b41 100644 --- a/init.h +++ b/init.h @@ -332,6 +332,7 @@ struct command_t Commands[] = { { "color", mutt_parse_color, 0 }, { "uncolor", mutt_parse_uncolor, 0 }, #endif + { "exec", mutt_parse_exec, 0 }, { "fcc-hook", mutt_parse_hook, M_FCCHOOK }, { "fcc-save-hook", mutt_parse_hook, M_FCCHOOK | M_SAVEHOOK }, { "folder-hook", mutt_parse_hook, M_FOLDERHOOK }, diff --git a/keymap.c b/keymap.c index 7fd1223d..29fb1b0a 100644 --- a/keymap.c +++ b/keymap.c @@ -219,11 +219,37 @@ void km_bindkey (char *s, int menu, int op) km_bind (s, menu, op, NULL, NULL); } +static int get_op (struct binding_t *bindings, const char *start, size_t len) +{ + int i; + + for (i = 0; bindings[i].name; i++) + { + if (!strncasecmp (start, bindings[i].name, len)) + return bindings[i].op; + } + + return OP_NULL; +} + +static char *get_func (struct binding_t *bindings, int op) +{ + int i; + + for (i = 0; bindings[i].name; i++) + { + if (bindings[i].op == op) + return bindings[i].name; + } + + return NULL; +} + static void push_string (char *s) { char *pp, *p = s + strlen (s) - 1; size_t l; - int i; + int i, op = OP_NULL; while (p >= s) { @@ -244,13 +270,33 @@ static void push_string (char *s) if (KeyNames[i].name) { /* found a match */ - mutt_ungetch (KeyNames[i].value); + mutt_ungetch (KeyNames[i].value, 0); + p = pp - 1; + continue; + } + + /* See if it is a valid command + * skip the '<' and the '>' when comparing */ + for (i = 0; Menus[i].name; i++) + { + struct binding_t *binding = km_get_table (Menus[i].value); + if (binding) + { + op = get_op (binding, pp + 1, l - 2); + if (op != OP_NULL) + break; + } + } + + if (op != OP_NULL) + { + mutt_ungetch (0, op); p = pp - 1; continue; } } } - mutt_ungetch (*p--); + mutt_ungetch (*p--, 0); } } @@ -259,9 +305,9 @@ static int retry_generic (int menu, keycode_t *keys, int keyslen, int lastkey) if (menu != MENU_EDITOR && menu != MENU_GENERIC && menu != MENU_PAGER) { if (lastkey) - mutt_ungetch (lastkey); + mutt_ungetch (lastkey, 0); for (; keyslen; keyslen--) - mutt_ungetch (keys[keyslen - 1]); + mutt_ungetch (keys[keyslen - 1], 0); return (km_dokey (MENU_GENERIC)); } if (menu != MENU_EDITOR) @@ -279,18 +325,65 @@ static int retry_generic (int menu, keycode_t *keys, int keyslen, int lastkey) */ int km_dokey (int menu) { + event_t tmp; struct keymap_t *map = Keymaps[menu]; int pos = 0; int n = 0; + int i; if (!map) return (retry_generic (menu, NULL, 0, 0)); FOREVER { - if ((LastKey = mutt_getch ()) == ERR) - return (-1); + tmp = mutt_getch(); + LastKey = tmp.ch; + if (LastKey == -1) + return -1; + /* do we have an op already? */ + if (tmp.op) + { + char *func = NULL; + struct binding_t *bindings; + + /* is this a valid op for the current menu? */ + bindings = km_get_table (CurrentMenu); + if ((func = get_func (bindings, tmp.op))) + return tmp.op; + if (CurrentMenu != MENU_PAGER) + { + /* check generic menu */ + bindings = OpGeneric; + if ((func = get_func (bindings, tmp.op))) + return tmp.op; + } + + /* Sigh. Valid function but not in this context. + * Find the literal string and push it back */ + for (i = 0; Menus[i].name; i++) + { + bindings = km_get_table (Menus[i].value); + if (bindings) + { + func = get_func (bindings, tmp.op); + if (func) + { + /* careful not to feed the <..> as one token. otherwise + * push_string() will push the bogus op right back! */ + mutt_ungetch ('>', 0); + push_string (func); + mutt_ungetch ('<', 0); + break; + } + } + } + /* continue to chew */ + if (func) + continue; + } + + /* Nope. Business as usual */ while (LastKey > map->keys[pos]) { if (pos > map->eq || !map->next) @@ -303,14 +396,15 @@ int km_dokey (int menu) if (++pos == map->len) { + if (map->op != OP_MACRO) - return (map->op); + return map->op; if (n++ == 10) { mutt_flushinp (); mutt_error _("Macro loop detected."); - return (-1); + return -1; } push_string (map->macro); @@ -692,3 +786,45 @@ int mutt_parse_macro (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) FREE (&key); return (r); } + +/* exec command-name */ +int mutt_parse_exec (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) +{ + int op = OP_NULL; + char *command = NULL; + struct binding_t *bindings = NULL; + + if (!MoreArgs (s)) + { + strfcpy (err->data, _("exec: too few arguments"), err->dsize); + return (-1); + } + + mutt_extract_token (buf, s, 0); + command = safe_strdup (buf->data); + + if (MoreArgs (s)) + { + strfcpy (err->data, _("too many arguments"), err->dsize); + return (-1); + } + + if ((bindings = km_get_table (CurrentMenu)) == NULL) + bindings = OpGeneric; + + op = get_op (bindings, command, strlen(command)); + if (op == OP_NULL) + op = get_op (OpGeneric, command, strlen(command)); + + if (op == OP_NULL) + { + mutt_flushinp (); + mutt_error (_("%s: no such command"), command); + FREE (&command); + return (-1); + } + + mutt_ungetch (0, op); + FREE (&command); + return 0; +} diff --git a/menu.c b/menu.c index 8a16b704..192b8d28 100644 --- a/menu.c +++ b/menu.c @@ -292,7 +292,7 @@ void menu_jump (MUTTMENU *menu) if (menu->max) { - mutt_ungetch (LastKey); + mutt_ungetch (LastKey, 0); buf[0] = 0; if (mutt_get_field (_("Jump to: "), buf, sizeof (buf), 0) == 0 && buf[0]) { @@ -769,6 +769,7 @@ int mutt_menuLoop (MUTTMENU *menu) break; case OP_ENTER_COMMAND: + CurrentMenu = menu->menu; mutt_enter_command (); if (option (OPTFORCEREDRAWINDEX)) { diff --git a/mutt.h b/mutt.h index 918d218b..21d7ac65 100644 --- a/mutt.h +++ b/mutt.h @@ -109,6 +109,12 @@ typedef struct int destroy; /* destroy `data' when done? */ } BUFFER; +typedef struct +{ + int ch; /* raw key pressed */ + int op; /* function op */ +} event_t; + /* flags for _mutt_system() */ #define M_DETACH_PROCESS 1 /* detach subprocess from group */ diff --git a/mutt_curses.h b/mutt_curses.h index 2d5b7eaa..eb08e5ce 100644 --- a/mutt_curses.h +++ b/mutt_curses.h @@ -79,13 +79,13 @@ void mutt_curs_set (int); #define CI_is_return(c) ((c) == '\r' || (c) == '\n' || (c) == KEY_ENTER) -int mutt_getch (void); +event_t mutt_getch (void); void mutt_endwin (const char *); void mutt_flushinp (void); void mutt_refresh (void); void mutt_resize_screen (void); -void mutt_ungetch (int); +void mutt_ungetch (int, int); /* ---------------------------------------------------------------------------- * Support for color diff --git a/pager.c b/pager.c index 0919acb1..9cf333c6 100644 --- a/pager.c +++ b/pager.c @@ -2032,6 +2032,7 @@ mutt_pager (const char *banner, const char *fname, int do_color, pager_t *extra) old_markers = option (OPTMARKERS); old_PagerIndexLines = PagerIndexLines; + CurrentMenu = MENU_PAGER; mutt_enter_command (); if (option (OPTNEEDRESORT)) diff --git a/pgpkey.c b/pgpkey.c index 42e19e67..13448b4c 100644 --- a/pgpkey.c +++ b/pgpkey.c @@ -123,6 +123,7 @@ static KEYINFO *pgp_select_key (struct pgp_vinfo *pgp, FILE *fp, *devnull; pid_t thepid; KEYINFO *info; + int savedmenu = CurrentMenu; for (i = 0, l = keys; l; l = l->next) @@ -184,7 +185,7 @@ static KEYINFO *pgp_select_key (struct pgp_vinfo *pgp, menu->max = keymax; menu->make_entry = pgp_entry; menu->search = pgp_search; - menu->menu = MENU_PGP; + menu->menu = CurrentMenu = MENU_PGP; menu->help = helpstr; menu->data = KeyTable; @@ -282,6 +283,7 @@ static KEYINFO *pgp_select_key (struct pgp_vinfo *pgp, } mutt_menuDestroy (&menu); + CurrentMenu = savedmenu; safe_free ((void **) &KeyTable); return (info); diff --git a/postpone.c b/postpone.c index 4b8cfb72..027e2b05 100644 --- a/postpone.c +++ b/postpone.c @@ -103,10 +103,11 @@ static HEADER *select_msg (void) MUTTMENU *menu; int i, done=0, r=-1; char helpstr[SHORT_STRING]; + int savedmenu = CurrentMenu; menu = mutt_new_menu (); menu->make_entry = post_entry; - menu->menu = MENU_POST; + menu->menu = CurrentMenu = MENU_POST; menu->max = PostContext->msgcount; menu->title = _("Postponed Messages"); menu->data = PostContext; @@ -148,6 +149,7 @@ static HEADER *select_msg (void) } mutt_menuDestroy (&menu); + CurrentMenu = savedmenu; return (r > -1 ? PostContext->hdrs[r] : NULL); } diff --git a/protos.h b/protos.h index b6af9be3..5de94779 100644 --- a/protos.h +++ b/protos.h @@ -238,6 +238,7 @@ int mutt_is_valid_mailbox (const char *); int mutt_needs_mailcap (BODY *); int mutt_num_postponed (void); int mutt_parse_bind (BUFFER *, BUFFER *, unsigned long, BUFFER *); +int mutt_parse_exec (BUFFER *, BUFFER *, unsigned long, BUFFER *); int mutt_parse_color (BUFFER *, BUFFER *, unsigned long, BUFFER *); int mutt_parse_uncolor (BUFFER *, BUFFER *, unsigned long, BUFFER *); int mutt_parse_hook (BUFFER *, BUFFER *, unsigned long, BUFFER *); diff --git a/query.c b/query.c index 19a6be89..0ca596be 100644 --- a/query.c +++ b/query.c @@ -240,13 +240,15 @@ static void query_menu (char *buf, size_t buflen, QUERY *results, int retbuf) int op; char helpstr[SHORT_STRING]; char title[STRING]; + int savedmenu = CurrentMenu; + snprintf (title, sizeof (title), _("Query")); /* FIXME */ menu = mutt_new_menu (); menu->make_entry = query_entry; menu->search = query_search; menu->tag = query_tag; - menu->menu = MENU_QUERY; + menu->menu = CurrentMenu = MENU_QUERY; menu->title = title; menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_QUERY, QueryHelp); @@ -462,4 +464,5 @@ static void query_menu (char *buf, size_t buflen, QUERY *results, int retbuf) } mutt_menuDestroy (&menu); + CurrentMenu = savedmenu; } diff --git a/recvattach.c b/recvattach.c index a20fc611..91f6b537 100644 --- a/recvattach.c +++ b/recvattach.c @@ -809,6 +809,7 @@ void mutt_view_attachments (HEADER *hdr) short idxmax = 0; int flags = 0; int op; + int savedmenu = CurrentMenu; /* make sure we have parsed this message */ mutt_parse_mime_message (Context, hdr); @@ -847,7 +848,7 @@ void mutt_view_attachments (HEADER *hdr) menu->max = idxlen; menu->make_entry = attach_entry; menu->tag = mutt_tag_attach; - menu->menu = MENU_ATTACH; + menu->menu = CurrentMenu = MENU_ATTACH; menu->title = _("Attachments"); menu->data = idx; menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_ATTACH, AttachHelp); @@ -1043,6 +1044,7 @@ void mutt_view_attachments (HEADER *hdr) mutt_menuDestroy (&menu); + CurrentMenu = savedmenu; return; } }