else
set_option (OPTIMAPLSUB);
- mutt_ungetch (0, OP_CHECK_NEW);
+ mutt_unget_event (0, OP_CHECK_NEW);
break;
case OP_CREATE_MAILBOX:
mutt_set_flag (Context, cur, M_READ, 1);
if (r != -1 && option (OPTPROMPTAFTER))
{
- mutt_ungetch (mutt_any_key_to_continue _("Command: "), 0);
+ mutt_unget_event (mutt_any_key_to_continue _("Command: "), 0);
rc = km_dokey (MENU_PAGER);
}
else
* is impossible to unget function keys in SLang, so roll our own input
* buffering routines.
*/
-size_t UngetCount = 0;
-static size_t UngetBufLen = 0;
-static event_t *KeyEvent;
+
+/* These are used for macros and exec/push commands.
+ * They can be temporarily ignored by setting OPTIGNOREMACROEVENTS
+ */
+static size_t MacroBufferCount = 0;
+static size_t MacroBufferLen = 0;
+static event_t *MacroEvents;
+
+/* These are used in all other "normal" situations, and are not
+ * ignored when setting OPTIGNOREMACROEVENTS
+ */
+static size_t UngetCount = 0;
+static size_t UngetLen = 0;
+static event_t *UngetKeyEvents;
void mutt_refresh (void)
{
event_t err = {-1, OP_NULL }, ret;
event_t timeout = {-2, OP_NULL};
- if (!option(OPTUNBUFFEREDINPUT) && UngetCount)
- return (KeyEvent[--UngetCount]);
+ if (UngetCount)
+ return (UngetKeyEvents[--UngetCount]);
+
+ if (!option(OPTIGNOREMACROEVENTS) && MacroBufferCount)
+ return (MacroEvents[--MacroBufferCount]);
SigInt = 0;
{
/* send ALT-x as ESC-x */
ch &= ~0x80;
- mutt_ungetch (ch, 0);
+ mutt_unget_event (ch, 0);
ret.ch = '\033';
ret.op = 0;
return ret;
{
int rc;
- set_option (OPTUNBUFFEREDINPUT);
+ set_option (OPTIGNOREMACROEVENTS);
rc = mutt_get_field (msg, buf, buflen, flags);
- unset_option (OPTUNBUFFEREDINPUT);
+ unset_option (OPTIGNOREMACROEVENTS);
return (rc);
}
char *pc = safe_malloc (mutt_strlen (prompt) + 3);
sprintf (pc, "%s: ", prompt); /* __SPRINTF_CHECKED__ */
- mutt_ungetch (ch.op ? 0 : ch.ch, ch.op ? ch.op : 0);
+ mutt_unget_event (ch.op ? 0 : ch.ch, ch.op ? ch.op : 0);
if (_mutt_get_field (pc, buf, blen, (buffy ? M_EFILE : M_FILE) | M_CLEAR, multiple, files, numfiles)
!= 0)
buf[0] = 0;
return 0;
}
-void mutt_ungetch (int ch, int op)
+void mutt_unget_event (int ch, int op)
+{
+ event_t tmp;
+
+ tmp.ch = ch;
+ tmp.op = op;
+
+ if (UngetCount >= UngetLen)
+ safe_realloc (&UngetKeyEvents, (UngetLen += 16) * sizeof(event_t));
+
+ UngetKeyEvents[UngetCount++] = tmp;
+}
+
+void mutt_unget_string (char *s)
+{
+ char *p = s + mutt_strlen (s) - 1;
+
+ while (p >= s)
+ {
+ mutt_unget_event ((unsigned char)*p--, 0);
+ }
+}
+
+/*
+ * Adds the ch/op to the macro buffer.
+ * This should be used for macros, push, and exec commands only.
+ */
+void mutt_push_macro_event (int ch, int op)
{
event_t tmp;
tmp.ch = ch;
tmp.op = op;
- if (UngetCount >= UngetBufLen)
- safe_realloc (&KeyEvent, (UngetBufLen += 128) * sizeof(event_t));
+ if (MacroBufferCount >= MacroBufferLen)
+ safe_realloc (&MacroEvents, (MacroBufferLen += 128) * sizeof(event_t));
+
+ MacroEvents[MacroBufferCount++] = tmp;
+}
- KeyEvent[UngetCount++] = tmp;
+void mutt_flush_macro_to_endcond (void)
+{
+ UngetCount = 0;
+ while (MacroBufferCount > 0)
+ {
+ if (MacroEvents[--MacroBufferCount].op == OP_END_COND)
+ return;
+ }
}
void mutt_flushinp (void)
{
UngetCount = 0;
+ MacroBufferCount = 0;
flushinp ();
}
#define OLDHDR Context->hdrs[Context->v2r[menu->oldcurrent]]
#define UNREAD(h) mutt_thread_contains_unread (Context, h)
-extern size_t UngetCount;
-
/* de facto standard escapes for tsl/fsl */
static char *tsl = "\033]0;";
static char *fsl = "\007";
if (!Context->tagged)
{
- event_t tmp;
- while(UngetCount>0)
- {
- tmp=mutt_getch();
- if(tmp.op==OP_END_COND)break;
- }
+ mutt_flush_macro_to_endcond ();
mutt_message _("Nothing to do.");
continue;
}
CHECK_MSGCOUNT;
CHECK_VISIBLE;
- if (isdigit (LastKey)) mutt_ungetch (LastKey, 0);
+ if (isdigit (LastKey)) mutt_unget_event (LastKey, 0);
buf[0] = 0;
if (mutt_get_field (_("Jump to message: "), buf, sizeof (buf), 0) != 0
|| !buf[0])
return NULL;
}
-static void push_string (char *s)
+/* Parses s for <function> syntax and adds the whole sequence to
+ * the macro buffer.
+ *
+ * This should be used for macros, push, and exec commands only.
+ */
+static void tokenize_push_macro_string (char *s)
{
char *pp, *p = s + mutt_strlen (s) - 1;
size_t l;
{
if ((i = parse_fkey (pp)) > 0)
{
- mutt_ungetch (KEY_F (i), 0);
+ mutt_push_macro_event (KEY_F (i), 0);
p = pp - 1;
continue;
}
if (KeyNames[i].name)
{
/* found a match */
- mutt_ungetch (KeyNames[i].value, 0);
+ mutt_push_macro_event (KeyNames[i].value, 0);
p = pp - 1;
continue;
}
if (op != OP_NULL)
{
- mutt_ungetch (0, op);
+ mutt_push_macro_event (0, op);
p = pp - 1;
continue;
}
}
}
- mutt_ungetch ((unsigned char)*p--, 0); /* independent 8 bits chars */
+ mutt_push_macro_event ((unsigned char)*p--, 0); /* independent 8 bits chars */
}
}
if (menu != MENU_EDITOR && menu != MENU_GENERIC && menu != MENU_PAGER)
{
if (lastkey)
- mutt_ungetch (lastkey, 0);
+ mutt_unget_event (lastkey, 0);
for (; keyslen; keyslen--)
- mutt_ungetch (keys[keyslen - 1], 0);
+ mutt_unget_event (keys[keyslen - 1], 0);
return (km_dokey (MENU_GENERIC));
}
if (menu != MENU_EDITOR)
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);
+ mutt_unget_event ('>', 0);
+ mutt_unget_string (func);
+ mutt_unget_event ('<', 0);
break;
}
}
if (map->op != OP_MACRO)
return map->op;
+ if (option (OPTIGNOREMACROEVENTS))
+ {
+ mutt_error _("Macros are currently disabled.");
+ return -1;
+ }
+
if (n++ == 10)
{
mutt_flushinp ();
return -1;
}
- push_string (map->macro);
+ tokenize_push_macro_string (map->macro);
map = Keymaps[menu];
pos = 0;
}
}
/* make sure the key is really the help key in this menu */
- push_string (buf);
+ mutt_unget_string (buf);
if (km_dokey (menu) != OP_HELP)
{
mutt_error _("Key is not bound.");
r = -1;
}
else
- push_string (buf->data);
+ tokenize_push_macro_string (buf->data);
return (r);
}
while(MoreArgs(s) && nops < sizeof(ops)/sizeof(ops[0]));
while(nops)
- mutt_ungetch(0, ops[--nops]);
+ mutt_push_macro_event (0, ops[--nops]);
return 0;
}
#include "mutt_menu.h"
#include "mbyte.h"
-extern size_t UngetCount;
-
char* SearchBuffers[MENU_MAX];
static void print_enriched_string (int attr, unsigned char *s, int do_color)
if (menu->max)
{
- mutt_ungetch (LastKey, 0);
+ mutt_unget_event (LastKey, 0);
buf[0] = 0;
if (mutt_get_field (_("Jump to: "), buf, sizeof (buf), 0) == 0 && buf[0])
{
}
else
{
- mutt_ungetch (ch.op ? 0 : ch.ch, ch.op ? ch.op : 0);
+ mutt_unget_event (ch.op ? 0 : ch.ch, ch.op ? ch.op : 0);
return -1;
}
}
}
else /* None tagged, OP_TAG_PREFIX_COND */
{
- event_t tmp;
- while(UngetCount>0)
- {
- tmp=mutt_getch();
- if(tmp.op==OP_END_COND)break;
- }
+ mutt_flush_macro_to_endcond ();
mutt_message _("Nothing to do.");
i = -1;
}
#define M_TOKEN_COMMENT (1<<5) /* don't reap comments */
#define M_TOKEN_SEMICOLON (1<<6) /* don't treat ; as special */
-/* flags for km_dokey() */
-#define M_KM_UNBUFFERED 1 /* don't read from the key buffer */
-
typedef struct
{
char *data; /* pointer to data */
OPTREDRAWTREE, /* (pseudo) redraw the thread tree */
OPTPGPCHECKTRUST, /* (pseudo) used by pgp_select_key () */
OPTDONTHANDLEPGPKEYS, /* (pseudo) used to extract PGP keys */
- OPTUNBUFFEREDINPUT, /* (pseudo) don't use key buffer */
+ OPTIGNOREMACROEVENTS, /* (pseudo) don't process macro/push/exec events while set */
OPTMAX
};
void mutt_flushinp (void);
void mutt_refresh (void);
void mutt_resize_screen (void);
-void mutt_ungetch (int, int);
+void mutt_unget_event (int, int);
+void mutt_unget_string (char *);
+void mutt_push_macro_event (int, int);
+void mutt_flush_macro_to_endcond (void);
void mutt_need_hard_redraw (void);
/* ----------------------------------------------------------------------------
menu->help = helpstr;
done = 0;
- set_option(OPTUNBUFFEREDINPUT);
+ set_option(OPTIGNOREMACROEVENTS);
while (!done)
{
switch (mutt_menuLoop (menu))
break;
}
}
- unset_option(OPTUNBUFFEREDINPUT);
+ unset_option(OPTIGNOREMACROEVENTS);
mutt_menuDestroy (&menu);
dprint (2, (debugfile, "ssl interactive_check_cert: done=%d\n", done));
return (done == 2);
menu->help = helpstr;
done = 0;
- set_option (OPTUNBUFFEREDINPUT);
+ set_option (OPTIGNOREMACROEVENTS);
while (!done)
{
switch (mutt_menuLoop (menu))
break;
}
}
- unset_option (OPTUNBUFFEREDINPUT);
+ unset_option (OPTIGNOREMACROEVENTS);
mutt_menuDestroy (&menu);
gnutls_x509_crt_deinit (cert);