NeoMutt  2018-07-16 +952-a2da0a
Teaching an old dog new tricks
DOXYGEN
keymap.c File Reference

Manage keymappings. More...

#include "config.h"
#include <ctype.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "mutt/mutt.h"
#include "mutt.h"
#include "keymap.h"
#include "curs_lib.h"
#include "functions.h"
#include "globals.h"
#include "mutt_curses.h"
#include "mutt_logging.h"
#include "mutt_window.h"
#include "ncrypt/ncrypt.h"
#include "opcodes.h"
#include "options.h"
#include "imap/imap.h"
+ Include dependency graph for keymap.c:

Go to the source code of this file.

Functions

static struct Keymapalloc_keys (size_t len, keycode_t *keys)
 Allocate space for a sequence of keys. More...
 
static int parse_fkey (char *s)
 Parse a function key string. More...
 
static int parse_keycode (const char *s)
 Parse a numeric keycode. More...
 
static size_t parsekeys (const char *str, keycode_t *d, size_t max)
 Parse a key string into key codes. More...
 
static int km_bind_err (const char *s, int menu, int op, char *macro, char *desc, struct Buffer *err)
 Set up a key binding. More...
 
int km_bind (char *s, int menu, int op, char *macro, char *desc)
 Bind a key to a macro. More...
 
static int km_bindkey_err (const char *s, int menu, int op, struct Buffer *err)
 Bind a key in a Menu to an operation (with error message) More...
 
static int km_bindkey (const char *s, int menu, int op)
 Bind a key in a Menu to an operation. More...
 
static int get_op (const struct Binding *bindings, const char *start, size_t len)
 Get the function by its name. More...
 
static const char * get_func (const struct Binding *bindings, int op)
 Get the name of a function. More...
 
static void generic_tokenize_push_string (char *s, void(*generic_push)(int, int))
 Parse and queue a 'push' command. More...
 
static int retry_generic (int menu, keycode_t *keys, int keyslen, int lastkey)
 Try to find the key in the generic menu bindings. More...
 
int km_dokey (int menu)
 Determine what a keypress should do. More...
 
static void create_bindings (const struct Binding *map, int menu)
 Attach a set of keybindings to a Menu. More...
 
static const char * km_keyname (int c)
 Get the human name for a key. More...
 
int km_expand_key (char *s, size_t len, struct Keymap *map)
 Get the key string bound to a Keymap. More...
 
struct Keymapkm_find_func (int menu, int func)
 Find a function's mapping in a Menu. More...
 
void init_extended_keys (void)
 Initialise map of ncurses extended keys. More...
 
void km_init (void)
 Initialise all the menu keybindings. More...
 
void km_error_key (int menu)
 Handle an unbound key sequence. More...
 
int mutt_parse_push (struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err)
 Parse the 'push' command - Implements command_t. More...
 
static char * parse_keymap (int *menu, struct Buffer *s, int maxmenus, int *nummenus, struct Buffer *err, bool bind)
 Parse a user-config key binding. More...
 
static int try_bind (char *key, int menu, char *func, const struct Binding *bindings, struct Buffer *err)
 Try to make a key binding. More...
 
const struct Bindingkm_get_table (int menu)
 Lookup a menu's keybindings. More...
 
int mutt_parse_bind (struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err)
 Parse the 'bind' command - Implements command_t. More...
 
int mutt_parse_macro (struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err)
 Parse the 'macro' command - Implements command_t. More...
 
int mutt_parse_exec (struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err)
 Parse the 'exec' command - Implements command_t. More...
 
void mutt_what_key (void)
 Ask the user to press a key. More...
 
void mutt_free_keys (void)
 Free the key maps. More...
 

Variables

const struct Mapping Menus []
 Menu name lookup table. More...
 
static struct Mapping KeyNames []
 Key name lookup table. More...
 
int LastKey
 contains the last key the user pressed More...
 
struct KeymapKeymaps [MENU_MAX]
 Array of Keymap keybindings, one for each Menu. More...
 

Detailed Description

Manage keymappings.

Authors
  • Michael R. Elkins

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file keymap.c.

Function Documentation

static struct Keymap* alloc_keys ( size_t  len,
keycode_t keys 
)
static

Allocate space for a sequence of keys.

Parameters
lenNumber of keys
keysArray of keys
Return values
ptrSequence of keys

Definition at line 154 of file keymap.c.

155 {
156  struct Keymap *p = mutt_mem_calloc(1, sizeof(struct Keymap));
157  p->len = len;
158  p->keys = mutt_mem_malloc(len * sizeof(keycode_t));
159  memcpy(p->keys, keys, len * sizeof(keycode_t));
160  return p;
161 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
keycode_t * keys
key sequence
Definition: keymap.h:53
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:99
short keycode_t
Definition: keymap.h:33
A keyboard mapping.
Definition: keymap.h:45
short len
length of key sequence (unit: sizeof (keycode_t))
Definition: keymap.h:52

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int parse_fkey ( char *  s)
static

Parse a function key string.

Parameters
sString to parse
Return values
numNumber of the key

Given "<f8>", it will return 8.

Definition at line 170 of file keymap.c.

171 {
172  char *t = NULL;
173  int n = 0;
174 
175  if (s[0] != '<' || tolower(s[1]) != 'f')
176  return -1;
177 
178  for (t = s + 2; *t && isdigit((unsigned char) *t); t++)
179  {
180  n *= 10;
181  n += *t - '0';
182  }
183 
184  if (*t != '>')
185  return -1;
186  else
187  return n;
188 }

+ Here is the caller graph for this function:

static int parse_keycode ( const char *  s)
static

Parse a numeric keycode.

Parameters
sString to parse
Return values
numNumber of the key

This function parses the string <NNN> and uses the octal value as the key to bind.

Definition at line 198 of file keymap.c.

199 {
200  char *end_char = NULL;
201  long int result = strtol(s + 1, &end_char, 8);
202  /* allow trailing whitespace, eg. < 1001 > */
203  while (ISSPACE(*end_char))
204  end_char++;
205  /* negative keycodes don't make sense, also detect overflow */
206  if (*end_char != '>' || result < 0 || result == LONG_MAX)
207  {
208  return -1;
209  }
210 
211  return result;
212 }
#define ISSPACE(c)
Definition: string2.h:40

+ Here is the caller graph for this function:

static size_t parsekeys ( const char *  str,
keycode_t d,
size_t  max 
)
static

Parse a key string into key codes.

Parameters
strKey string
dArray for key codes
maxMaximum length of key sequence
Return values
numLength of key sequence

Definition at line 221 of file keymap.c.

222 {
223  int n;
224  size_t len = max;
225  char buf[SHORT_STRING];
226  char c;
227  char *t = NULL;
228 
229  mutt_str_strfcpy(buf, str, sizeof(buf));
230  char *s = buf;
231 
232  while (*s && len)
233  {
234  *d = '\0';
235  if (*s == '<' && (t = strchr(s, '>')))
236  {
237  t++;
238  c = *t;
239  *t = '\0';
240 
242  if (n != -1)
243  {
244  s = t;
245  *d = n;
246  }
247  else if ((n = parse_fkey(s)) > 0)
248  {
249  s = t;
250  *d = KEY_F(n);
251  }
252  else if ((n = parse_keycode(s)) > 0)
253  {
254  s = t;
255  *d = n;
256  }
257 
258  *t = c;
259  }
260 
261  if (!*d)
262  {
263  *d = (unsigned char) *s;
264  s++;
265  }
266  d++;
267  len--;
268  }
269 
270  return max - len;
271 }
#define SHORT_STRING
Definition: string2.h:34
static int parse_keycode(const char *s)
Parse a numeric keycode.
Definition: keymap.c:198
static struct Mapping KeyNames[]
Key name lookup table.
Definition: keymap.c:85
static int parse_fkey(char *s)
Parse a function key string.
Definition: keymap.c:170
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:742
short len
length of key sequence (unit: sizeof (keycode_t))
Definition: keymap.h:52
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition: mapping.c:61

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int km_bind_err ( const char *  s,
int  menu,
int  op,
char *  macro,
char *  desc,
struct Buffer err 
)
static

Set up a key binding.

Parameters
sKey string
menuMenu id, e.g. MENU_EDITOR
opOperation, e.g. OP_DELETE
macroMacro string
descDescription of macro (OPTIONAL)
errBuffer for error message
Return values
0Success
-2Error

Insert a key sequence into the specified map. The map is sorted by ASCII value (lowest to highest)

Definition at line 287 of file keymap.c.

289 {
290  int retval = 0;
291  struct Keymap *last = NULL, *next = NULL;
292  keycode_t buf[MAX_SEQ];
293  size_t pos = 0, lastpos = 0;
294 
295  size_t len = parsekeys(s, buf, MAX_SEQ);
296 
297  struct Keymap *map = alloc_keys(len, buf);
298  map->op = op;
299  map->macro = mutt_str_strdup(macro);
300  map->desc = mutt_str_strdup(desc);
301 
302  struct Keymap *tmp = Keymaps[menu];
303 
304  while (tmp)
305  {
306  if (pos >= len || pos >= tmp->len)
307  {
308  /* map and tmp match so overwrite */
309  do
310  {
311  /* Don't warn on overwriting a 'noop' binding */
312  if (tmp->len != len && tmp->op != OP_NULL)
313  {
314  /* Overwrite with the different lengths, warn */
315  /* TODO: MAX_SEQ here is wrong */
316  char old_binding[MAX_SEQ];
317  char new_binding[MAX_SEQ];
318  km_expand_key(old_binding, MAX_SEQ, map);
319  km_expand_key(new_binding, MAX_SEQ, tmp);
320  if (err)
321  {
322  /* err was passed, put the string there */
323  snprintf(
324  err->data, err->dsize,
325  _("Binding '%s' will alias '%s' Before, try: 'bind %s %s "
326  "noop' "
327  "https://neomutt.org/guide/configuration.html#bind-warnings"),
328  old_binding, new_binding, mutt_map_get_name(menu, Menus), new_binding);
329  }
330  else
331  {
332  mutt_error(
333  _("Binding '%s' will alias '%s' Before, try: 'bind %s %s "
334  "noop' "
335  "https://neomutt.org/guide/configuration.html#bind-warnings"),
336  old_binding, new_binding, mutt_map_get_name(menu, Menus), new_binding);
337  }
338  retval = -2;
339  }
340  len = tmp->eq;
341  next = tmp->next;
342  FREE(&tmp->macro);
343  FREE(&tmp->keys);
344  FREE(&tmp->desc);
345  FREE(&tmp);
346  tmp = next;
347  } while (tmp && len >= pos);
348  map->eq = len;
349  break;
350  }
351  else if (buf[pos] == tmp->keys[pos])
352  pos++;
353  else if (buf[pos] < tmp->keys[pos])
354  {
355  /* found location to insert between last and tmp */
356  map->eq = pos;
357  break;
358  }
359  else /* buf[pos] > tmp->keys[pos] */
360  {
361  last = tmp;
362  lastpos = pos;
363  if (pos > tmp->eq)
364  pos = tmp->eq;
365  tmp = tmp->next;
366  }
367  }
368 
369  map->next = tmp;
370  if (last)
371  {
372  last->next = map;
373  last->eq = lastpos;
374  }
375  else
376  {
377  Keymaps[menu] = map;
378  }
379 
380  return retval;
381 }
short eq
number of leading keys equal to next entry
Definition: keymap.h:51
struct Keymap * Keymaps[MENU_MAX]
Array of Keymap keybindings, one for each Menu.
Definition: keymap.c:146
keycode_t * keys
key sequence
Definition: keymap.h:53
#define _(a)
Definition: message.h:28
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
size_t dsize
length of data
Definition: buffer.h:37
static size_t parsekeys(const char *str, keycode_t *d, size_t max)
Parse a key string into key codes.
Definition: keymap.c:221
short op
operation to perform
Definition: keymap.h:50
const struct Mapping Menus[]
Menu name lookup table.
Definition: keymap.c:59
struct Keymap * next
next key in map
Definition: keymap.h:49
static struct Keymap * alloc_keys(size_t len, keycode_t *keys)
Allocate space for a sequence of keys.
Definition: keymap.c:154
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:770
char * macro
macro expansion (op == OP_MACRO)
Definition: keymap.h:47
char * data
pointer to data
Definition: buffer.h:35
short keycode_t
Definition: keymap.h:33
char * desc
description of a macro for the help menu
Definition: keymap.h:48
A keyboard mapping.
Definition: keymap.h:45
short len
length of key sequence (unit: sizeof (keycode_t))
Definition: keymap.h:52
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:384
#define mutt_error(...)
Definition: logging.h:88
#define FREE(x)
Definition: memory.h:46
#define MAX_SEQ
Definition: keymap.h:30

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int km_bind ( char *  s,
int  menu,
int  op,
char *  macro,
char *  desc 
)

Bind a key to a macro.

Parameters
sKey string
menuMenu id, e.g. MENU_EDITOR
opOperation, e.g. OP_DELETE
macroMacro string
descDescription of macro (OPTIONAL)
Return values
0Success
-2Error

Definition at line 393 of file keymap.c.

394 {
395  return km_bind_err(s, menu, op, macro, desc, NULL);
396 }
short op
operation to perform
Definition: keymap.h:50
char * macro
macro expansion (op == OP_MACRO)
Definition: keymap.h:47
char * desc
description of a macro for the help menu
Definition: keymap.h:48
static int km_bind_err(const char *s, int menu, int op, char *macro, char *desc, struct Buffer *err)
Set up a key binding.
Definition: keymap.c:287

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int km_bindkey_err ( const char *  s,
int  menu,
int  op,
struct Buffer err 
)
static

Bind a key in a Menu to an operation (with error message)

Parameters
sKey string
menuMenu id, e.g. MENU_PAGER
opOperation, e.g. OP_DELETE
errBuffer for error message
Return values
0Success
-2Error

Definition at line 407 of file keymap.c.

408 {
409  return km_bind_err(s, menu, op, NULL, NULL, err);
410 }
short op
operation to perform
Definition: keymap.h:50
static int km_bind_err(const char *s, int menu, int op, char *macro, char *desc, struct Buffer *err)
Set up a key binding.
Definition: keymap.c:287

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int km_bindkey ( const char *  s,
int  menu,
int  op 
)
static

Bind a key in a Menu to an operation.

Parameters
sKey string
menuMenu id, e.g. MENU_PAGER
opOperation, e.g. OP_DELETE
Return values
0Success
-2Error

Definition at line 420 of file keymap.c.

421 {
422  return km_bindkey_err(s, menu, op, NULL);
423 }
static int km_bindkey_err(const char *s, int menu, int op, struct Buffer *err)
Bind a key in a Menu to an operation (with error message)
Definition: keymap.c:407
short op
operation to perform
Definition: keymap.h:50

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int get_op ( const struct Binding bindings,
const char *  start,
size_t  len 
)
static

Get the function by its name.

Parameters
bindingsKey bindings table
startName of function to find
lenLength of string to match
Return values
numOperation, e.g. OP_DELETE

Definition at line 432 of file keymap.c.

433 {
434  for (int i = 0; bindings[i].name; i++)
435  {
436  if ((mutt_str_strncasecmp(start, bindings[i].name, len) == 0) &&
437  mutt_str_strlen(bindings[i].name) == len)
438  {
439  return bindings[i].op;
440  }
441  }
442 
443  return OP_NULL;
444 }
int op
function id number
Definition: keymap.h:101
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:663
const char * name
Definition: pgpmicalg.c:42
const char * name
name of the function
Definition: keymap.h:100
int mutt_str_strncasecmp(const char *a, const char *b, size_t l)
Compare two strings ignoring case (to a maximum), safely.
Definition: string.c:653
short len
length of key sequence (unit: sizeof (keycode_t))
Definition: keymap.h:52

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static const char* get_func ( const struct Binding bindings,
int  op 
)
static

Get the name of a function.

Parameters
bindingsKey bindings table
opOperation, e.g. OP_DELETE
Return values
ptrName of function
NULLOperation not found
Note
This returns a static string.

Definition at line 455 of file keymap.c.

456 {
457  for (int i = 0; bindings[i].name; i++)
458  {
459  if (bindings[i].op == op)
460  return bindings[i].name;
461  }
462 
463  return NULL;
464 }
const char * name
name of the function
Definition: keymap.h:100
short op
operation to perform
Definition: keymap.h:50

+ Here is the caller graph for this function:

static void generic_tokenize_push_string ( char *  s,
void(*)(int, int)  generic_push 
)
static

Parse and queue a 'push' command.

Parameters
sString to push into the key queue
generic_pushCallback function to add events to macro queue

Parses s for <function> syntax and adds the whole sequence to either the macro or unget buffer. This function is invoked by the next two defines below.

Definition at line 475 of file keymap.c.

476 {
477  char *pp = NULL, *p = s + mutt_str_strlen(s) - 1;
478  size_t l;
479  int i, op = OP_NULL;
480 
481  while (p >= s)
482  {
483  /* if we see something like "<PageUp>", look to see if it is a real
484  function name and return the corresponding value */
485  if (*p == '>')
486  {
487  for (pp = p - 1; pp >= s && *pp != '<'; pp--)
488  ;
489  if (pp >= s)
490  {
491  i = parse_fkey(pp);
492  if (i > 0)
493  {
494  generic_push(KEY_F(i), 0);
495  p = pp - 1;
496  continue;
497  }
498 
499  l = p - pp + 1;
500  for (i = 0; KeyNames[i].name; i++)
501  {
502  if (mutt_str_strncasecmp(pp, KeyNames[i].name, l) == 0)
503  break;
504  }
505  if (KeyNames[i].name)
506  {
507  /* found a match */
508  generic_push(KeyNames[i].value, 0);
509  p = pp - 1;
510  continue;
511  }
512 
513  /* See if it is a valid command
514  * skip the '<' and the '>' when comparing */
515  for (i = 0; Menus[i].name; i++)
516  {
517  const struct Binding *binding = km_get_table(Menus[i].value);
518  if (binding)
519  {
520  op = get_op(binding, pp + 1, l - 2);
521  if (op != OP_NULL)
522  break;
523  }
524  }
525 
526  if (op != OP_NULL)
527  {
528  generic_push(0, op);
529  p = pp - 1;
530  continue;
531  }
532  }
533  }
534  generic_push((unsigned char) *p--, 0); /* independent 8 bits chars */
535  }
536 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:663
const char * name
Definition: pgpmicalg.c:42
short op
operation to perform
Definition: keymap.h:50
static struct Mapping KeyNames[]
Key name lookup table.
Definition: keymap.c:85
const struct Mapping Menus[]
Menu name lookup table.
Definition: keymap.c:59
static int parse_fkey(char *s)
Parse a function key string.
Definition: keymap.c:170
int mutt_str_strncasecmp(const char *a, const char *b, size_t l)
Compare two strings ignoring case (to a maximum), safely.
Definition: string.c:653
const struct Binding * km_get_table(int menu)
Lookup a menu&#39;s keybindings.
Definition: keymap.c:1209
const char * name
Definition: mapping.h:31
static int get_op(const struct Binding *bindings, const char *start, size_t len)
Get the function by its name.
Definition: keymap.c:432
Mapping between a user key and a function.
Definition: keymap.h:98

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int retry_generic ( int  menu,
keycode_t keys,
int  keyslen,
int  lastkey 
)
static

Try to find the key in the generic menu bindings.

Parameters
menuMenu id, e.g. MENU_PAGER
keysArray of keys to return to the input queue
keyslenNumber of keys in the array
lastkeyLast key pressed (to return to input queue)
Return values
numOperation, e.g. OP_DELETE

Definition at line 546 of file keymap.c.

547 {
548  if (menu != MENU_EDITOR && menu != MENU_GENERIC && menu != MENU_PAGER)
549  {
550  if (lastkey)
551  mutt_unget_event(lastkey, 0);
552  for (; keyslen; keyslen--)
553  mutt_unget_event(keys[keyslen - 1], 0);
554  return km_dokey(MENU_GENERIC);
555  }
556  if (menu != MENU_EDITOR)
557  {
558  /* probably a good idea to flush input here so we can abort macros */
559  mutt_flushinp();
560  }
561  return OP_NULL;
562 }
int km_dokey(int menu)
Determine what a keypress should do.
Definition: keymap.c:572
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:753
Generic selection list.
Definition: keymap.h:72
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:668
Text entry area.
Definition: keymap.h:70
Pager pager (email viewer)
Definition: keymap.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int km_dokey ( int  menu)

Determine what a keypress should do.

Parameters
menuMenu ID, e.g. MENU_EDITOR
Return values
>0Function to execute
OP_NULLNo function bound to key sequence
-1Error occurred while reading input
-2A timeout or sigwinch occurred

Definition at line 572 of file keymap.c.

573 {
574  struct Event tmp;
575  struct Keymap *map = Keymaps[menu];
576  int pos = 0;
577  int n = 0;
578 
579  if (!map)
580  return retry_generic(menu, NULL, 0, 0);
581 
582  while (true)
583  {
584  int i = Timeout > 0 ? Timeout : 60;
585 #ifdef USE_IMAP
586  /* keepalive may need to run more frequently than Timeout allows */
587  if (ImapKeepalive)
588  {
589  if (ImapKeepalive >= i)
590  imap_keepalive();
591  else
592  {
593  while (ImapKeepalive && ImapKeepalive < i)
594  {
596  tmp = mutt_getch();
597  mutt_getch_timeout(-1);
598  /* If a timeout was not received, or the window was resized, exit the
599  * loop now. Otherwise, continue to loop until reaching a total of
600  * $timeout seconds.
601  */
602 #ifdef USE_INOTIFY
603  if (tmp.ch != -2 || SigWinch || MonitorFilesChanged)
604 #else
605  if (tmp.ch != -2 || SigWinch)
606 #endif
607  goto gotkey;
608  i -= ImapKeepalive;
609  imap_keepalive();
610  }
611  }
612  }
613 #endif
614 
615  mutt_getch_timeout(i * 1000);
616  tmp = mutt_getch();
617  mutt_getch_timeout(-1);
618 
619 #ifdef USE_IMAP
620  gotkey:
621 #endif
622  /* hide timeouts, but not window resizes, from the line editor. */
623  if (menu == MENU_EDITOR && tmp.ch == -2 && !SigWinch)
624  continue;
625 
626  LastKey = tmp.ch;
627  if (LastKey < 0)
628  return LastKey;
629 
630  /* do we have an op already? */
631  if (tmp.op)
632  {
633  const char *func = NULL;
634  const struct Binding *bindings = NULL;
635 
636  /* is this a valid op for this menu? */
637  if ((bindings = km_get_table(menu)) && (func = get_func(bindings, tmp.op)))
638  return tmp.op;
639 
640  if (menu == MENU_EDITOR && get_func(OpEditor, tmp.op))
641  return tmp.op;
642 
643  if (menu != MENU_EDITOR && menu != MENU_PAGER)
644  {
645  /* check generic menu */
646  bindings = OpGeneric;
647  func = get_func(bindings, tmp.op);
648  if (func)
649  return tmp.op;
650  }
651 
652  /* Sigh. Valid function but not in this context.
653  * Find the literal string and push it back */
654  for (i = 0; Menus[i].name; i++)
655  {
656  bindings = km_get_table(Menus[i].value);
657  if (bindings)
658  {
659  func = get_func(bindings, tmp.op);
660  if (func)
661  {
662  mutt_unget_event('>', 0);
663  mutt_unget_string(func);
664  mutt_unget_event('<', 0);
665  break;
666  }
667  }
668  }
669  /* continue to chew */
670  if (func)
671  continue;
672  }
673 
674  /* Nope. Business as usual */
675  while (LastKey > map->keys[pos])
676  {
677  if (pos > map->eq || !map->next)
678  return retry_generic(menu, map->keys, pos, LastKey);
679  map = map->next;
680  }
681 
682  if (LastKey != map->keys[pos])
683  return retry_generic(menu, map->keys, pos, LastKey);
684 
685  if (++pos == map->len)
686  {
687  if (map->op != OP_MACRO)
688  return map->op;
689 
691  {
692  mutt_error(_("Macros are currently disabled"));
693  return -1;
694  }
695 
696  if (n++ == 10)
697  {
698  mutt_flushinp();
699  mutt_error(_("Macro loop detected"));
700  return -1;
701  }
702 
704  map = Keymaps[menu];
705  pos = 0;
706  }
707  }
708 
709  /* not reached */
710 }
short eq
number of leading keys equal to next entry
Definition: keymap.h:51
static const char * get_func(const struct Binding *bindings, int op)
Get the name of a function.
Definition: keymap.c:455
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition: curs_lib.c:705
int op
function id number
Definition: keymap.h:101
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:753
struct Keymap * Keymaps[MENU_MAX]
Array of Keymap keybindings, one for each Menu.
Definition: keymap.c:146
keycode_t * keys
key sequence
Definition: keymap.h:53
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:668
#define _(a)
Definition: message.h:28
WHERE bool OptIgnoreMacroEvents
(pseudo) don&#39;t process macro/push/exec events while set
Definition: options.h:35
An event such as a keypress.
Definition: mutt_curses.h:107
int LastKey
contains the last key the user pressed
Definition: keymap.c:144
short op
operation to perform
Definition: keymap.h:50
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: globals.h:91
int MonitorFilesChanged
true after a monitored file has changed
Definition: monitor.c:49
const struct Mapping Menus[]
Menu name lookup table.
Definition: keymap.c:59
struct Event mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:180
struct Keymap * next
next key in map
Definition: keymap.h:49
const struct Binding * km_get_table(int menu)
Lookup a menu&#39;s keybindings.
Definition: keymap.c:1209
const struct Binding OpGeneric[]
Key bindings for the generic menu.
Definition: functions.h:52
char * macro
macro expansion (op == OP_MACRO)
Definition: keymap.h:47
static void generic_tokenize_push_string(char *s, void(*generic_push)(int, int))
Parse and queue a &#39;push&#39; command.
Definition: keymap.c:475
Text entry area.
Definition: keymap.h:70
A keyboard mapping.
Definition: keymap.h:45
short len
length of key sequence (unit: sizeof (keycode_t))
Definition: keymap.h:52
#define mutt_error(...)
Definition: logging.h:88
WHERE short ImapKeepalive
Config: (imap) Time to wait before polling an open IMAP connection.
Definition: globals.h:163
void mutt_getch_timeout(int delay)
Set the getch() timeout.
Definition: curs_lib.c:137
void mutt_unget_string(const char *s)
Return a string to the input buffer.
Definition: curs_lib.c:687
const struct Binding OpEditor[]
Key bindings for the editor menu.
Definition: functions.h:588
const char * name
Definition: mapping.h:31
void imap_keepalive(void)
poll the current folder to keep the connection alive
Definition: util.c:1063
Mapping between a user key and a function.
Definition: keymap.h:98
Pager pager (email viewer)
Definition: keymap.h:74
static int retry_generic(int menu, keycode_t *keys, int keyslen, int lastkey)
Try to find the key in the generic menu bindings.
Definition: keymap.c:546
WHERE short Timeout
Config: Time to wait for user input in menus.
Definition: globals.h:155

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void create_bindings ( const struct Binding map,
int  menu 
)
static

Attach a set of keybindings to a Menu.

Parameters
mapKey bindings
menuMenu id, e.g. MENU_PAGER

Definition at line 717 of file keymap.c.

718 {
719  for (int i = 0; map[i].name; i++)
720  if (map[i].seq)
721  km_bindkey(map[i].seq, menu, map[i].op);
722 }
int op
function id number
Definition: keymap.h:101
const char * name
name of the function
Definition: keymap.h:100
static int km_bindkey(const char *s, int menu, int op)
Bind a key in a Menu to an operation.
Definition: keymap.c:420
const char * seq
default key binding
Definition: keymap.h:102

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static const char* km_keyname ( int  c)
static

Get the human name for a key.

Parameters
cKey code
Return values
ptrName of the key
Note
This returns a pointer to a static buffer.

Definition at line 731 of file keymap.c.

732 {
733  static char buf[10];
734 
735  const char *p = mutt_map_get_name(c, KeyNames);
736  if (p)
737  return p;
738 
739  if (c < 256 && c > -128 && iscntrl((unsigned char) c))
740  {
741  if (c < 0)
742  c += 256;
743 
744  if (c < 128)
745  {
746  buf[0] = '^';
747  buf[1] = (c + '@') & 0x7f;
748  buf[2] = '\0';
749  }
750  else
751  snprintf(buf, sizeof(buf), "\\%d%d%d", c >> 6, (c >> 3) & 7, c & 7);
752  }
753  else if (c >= KEY_F0 && c < KEY_F(256)) /* this maximum is just a guess */
754  sprintf(buf, "<F%d>", c - KEY_F0);
755  else if (IsPrint(c))
756  snprintf(buf, sizeof(buf), "%c", (unsigned char) c);
757  else
758  snprintf(buf, sizeof(buf), "\\x%hx", (unsigned short) c);
759  return buf;
760 }
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
static struct Mapping KeyNames[]
Key name lookup table.
Definition: keymap.c:85
#define IsPrint(c)
Definition: mbyte.h:38

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int km_expand_key ( char *  s,
size_t  len,
struct Keymap map 
)

Get the key string bound to a Keymap.

Parameters
sBuffer for the key string
lenLength of buffer
mapKeybinding map
Return values
1Success
0Error

Definition at line 770 of file keymap.c.

771 {
772  int p = 0;
773 
774  if (!map)
775  return 0;
776 
777  while (true)
778  {
779  mutt_str_strfcpy(s, km_keyname(map->keys[p]), len);
780  const size_t l = mutt_str_strlen(s);
781  len -= l;
782 
783  if (++p >= map->len || !len)
784  return 1;
785 
786  s += l;
787  }
788 
789  /* not reached */
790 }
static const char * km_keyname(int c)
Get the human name for a key.
Definition: keymap.c:731
keycode_t * keys
key sequence
Definition: keymap.h:53
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:663
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:742
short len
length of key sequence (unit: sizeof (keycode_t))
Definition: keymap.h:52

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

struct Keymap* km_find_func ( int  menu,
int  func 
)

Find a function's mapping in a Menu.

Parameters
menuMenu id, e.g. MENU_PAGER
funcFunction, e.g. OP_DELETE
Return values
ptrKeymap for the function

Definition at line 798 of file keymap.c.

799 {
800  struct Keymap *map = Keymaps[menu];
801 
802  for (; map; map = map->next)
803  if (map->op == func)
804  break;
805  return map;
806 }
struct Keymap * Keymaps[MENU_MAX]
Array of Keymap keybindings, one for each Menu.
Definition: keymap.c:146
short op
operation to perform
Definition: keymap.h:50
struct Keymap * next
next key in map
Definition: keymap.h:49
A keyboard mapping.
Definition: keymap.h:45

+ Here is the caller graph for this function:

void init_extended_keys ( void  )

Initialise map of ncurses extended keys.

Determine the keycodes for ncurses extended keys and fill in the KeyNames array.

This function must be called after initscr(), or tigetstr() returns -1. This creates a bit of a chicken-and-egg problem because km_init() is called prior to start_curses(). This means that the default keybindings can't include any of the extended keys because they won't be defined until later.

Definition at line 884 of file keymap.c.

885 {
886 #ifdef NCURSES_VERSION
887 
888  use_extended_names(true);
889 
890  for (int j = 0; KeyNames[j].name; ++j)
891  {
892  if (KeyNames[j].value == -1)
893  {
894  const char *keyname = find_ext_name(KeyNames[j].name);
895 
896  if (keyname)
897  {
898  char *s = tigetstr((char *) keyname);
899  if (s && (long) (s) != -1)
900  {
901  int code = key_defined(s);
902  if (code > 0)
903  KeyNames[j].value = code;
904  }
905  }
906  }
907  }
908 #endif
909 }
int value
Definition: mapping.h:32
const char * name
Definition: pgpmicalg.c:42
static struct Mapping KeyNames[]
Key name lookup table.
Definition: keymap.c:85
const char * name
Definition: mapping.h:31

+ Here is the caller graph for this function:

void km_init ( void  )

Initialise all the menu keybindings.

Definition at line 914 of file keymap.c.

915 {
916  memset(Keymaps, 0, sizeof(struct Keymap *) * MENU_MAX);
917 
926 
929 
932 
933 #ifdef CRYPT_BACKEND_GPGME
934  create_bindings(OpPgp, MENU_KEY_SELECT_PGP);
935  create_bindings(OpSmime, MENU_KEY_SELECT_SMIME);
936 #endif
937 
938 #ifdef MIXMASTER
939  create_bindings(OpMix, MENU_MIX);
940 
941  km_bindkey("<space>", MENU_MIX, OP_GENERIC_SELECT_ENTRY);
942  km_bindkey("h", MENU_MIX, OP_MIX_CHAIN_PREV);
943  km_bindkey("l", MENU_MIX, OP_MIX_CHAIN_NEXT);
944 #endif
945 
946  /* bindings for the line editor */
948 
949  km_bindkey("<up>", MENU_EDITOR, OP_EDITOR_HISTORY_UP);
950  km_bindkey("<down>", MENU_EDITOR, OP_EDITOR_HISTORY_DOWN);
951  km_bindkey("<left>", MENU_EDITOR, OP_EDITOR_BACKWARD_CHAR);
952  km_bindkey("<right>", MENU_EDITOR, OP_EDITOR_FORWARD_CHAR);
953  km_bindkey("<home>", MENU_EDITOR, OP_EDITOR_BOL);
954  km_bindkey("<end>", MENU_EDITOR, OP_EDITOR_EOL);
955  km_bindkey("<backspace>", MENU_EDITOR, OP_EDITOR_BACKSPACE);
956  km_bindkey("<delete>", MENU_EDITOR, OP_EDITOR_DELETE_CHAR);
957  km_bindkey("\177", MENU_EDITOR, OP_EDITOR_BACKSPACE);
958 
959  /* generic menu keymap */
961 
962  km_bindkey("<home>", MENU_GENERIC, OP_FIRST_ENTRY);
963  km_bindkey("<end>", MENU_GENERIC, OP_LAST_ENTRY);
964  km_bindkey("<pagedown>", MENU_GENERIC, OP_NEXT_PAGE);
965  km_bindkey("<pageup>", MENU_GENERIC, OP_PREV_PAGE);
966  km_bindkey("<right>", MENU_GENERIC, OP_NEXT_PAGE);
967  km_bindkey("<left>", MENU_GENERIC, OP_PREV_PAGE);
968  km_bindkey("<up>", MENU_GENERIC, OP_PREV_ENTRY);
969  km_bindkey("<down>", MENU_GENERIC, OP_NEXT_ENTRY);
970  km_bindkey("1", MENU_GENERIC, OP_JUMP);
971  km_bindkey("2", MENU_GENERIC, OP_JUMP);
972  km_bindkey("3", MENU_GENERIC, OP_JUMP);
973  km_bindkey("4", MENU_GENERIC, OP_JUMP);
974  km_bindkey("5", MENU_GENERIC, OP_JUMP);
975  km_bindkey("6", MENU_GENERIC, OP_JUMP);
976  km_bindkey("7", MENU_GENERIC, OP_JUMP);
977  km_bindkey("8", MENU_GENERIC, OP_JUMP);
978  km_bindkey("9", MENU_GENERIC, OP_JUMP);
979 
980  km_bindkey("<return>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY);
981  km_bindkey("<enter>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY);
982 
983  /* Miscellaneous extra bindings */
984 
985  km_bindkey(" ", MENU_MAIN, OP_DISPLAY_MESSAGE);
986  km_bindkey("<up>", MENU_MAIN, OP_MAIN_PREV_UNDELETED);
987  km_bindkey("<down>", MENU_MAIN, OP_MAIN_NEXT_UNDELETED);
988  km_bindkey("J", MENU_MAIN, OP_NEXT_ENTRY);
989  km_bindkey("K", MENU_MAIN, OP_PREV_ENTRY);
990  km_bindkey("x", MENU_MAIN, OP_EXIT);
991 
992  km_bindkey("<return>", MENU_MAIN, OP_DISPLAY_MESSAGE);
993  km_bindkey("<enter>", MENU_MAIN, OP_DISPLAY_MESSAGE);
994 
995  km_bindkey("x", MENU_PAGER, OP_EXIT);
996  km_bindkey("i", MENU_PAGER, OP_EXIT);
997  km_bindkey("<backspace>", MENU_PAGER, OP_PREV_LINE);
998  km_bindkey("<pagedown>", MENU_PAGER, OP_NEXT_PAGE);
999  km_bindkey("<pageup>", MENU_PAGER, OP_PREV_PAGE);
1000  km_bindkey("<up>", MENU_PAGER, OP_MAIN_PREV_UNDELETED);
1001  km_bindkey("<right>", MENU_PAGER, OP_MAIN_NEXT_UNDELETED);
1002  km_bindkey("<down>", MENU_PAGER, OP_MAIN_NEXT_UNDELETED);
1003  km_bindkey("<left>", MENU_PAGER, OP_MAIN_PREV_UNDELETED);
1004  km_bindkey("<home>", MENU_PAGER, OP_PAGER_TOP);
1005  km_bindkey("<end>", MENU_PAGER, OP_PAGER_BOTTOM);
1006  km_bindkey("1", MENU_PAGER, OP_JUMP);
1007  km_bindkey("2", MENU_PAGER, OP_JUMP);
1008  km_bindkey("3", MENU_PAGER, OP_JUMP);
1009  km_bindkey("4", MENU_PAGER, OP_JUMP);
1010  km_bindkey("5", MENU_PAGER, OP_JUMP);
1011  km_bindkey("6", MENU_PAGER, OP_JUMP);
1012  km_bindkey("7", MENU_PAGER, OP_JUMP);
1013  km_bindkey("8", MENU_PAGER, OP_JUMP);
1014  km_bindkey("9", MENU_PAGER, OP_JUMP);
1015 
1016  km_bindkey("<return>", MENU_PAGER, OP_NEXT_LINE);
1017  km_bindkey("<enter>", MENU_PAGER, OP_NEXT_LINE);
1018 
1019  km_bindkey("<return>", MENU_ALIAS, OP_GENERIC_SELECT_ENTRY);
1020  km_bindkey("<enter>", MENU_ALIAS, OP_GENERIC_SELECT_ENTRY);
1021  km_bindkey("<space>", MENU_ALIAS, OP_TAG);
1022 
1023  km_bindkey("<return>", MENU_ATTACH, OP_VIEW_ATTACH);
1024  km_bindkey("<enter>", MENU_ATTACH, OP_VIEW_ATTACH);
1025  km_bindkey("<return>", MENU_COMPOSE, OP_VIEW_ATTACH);
1026  km_bindkey("<enter>", MENU_COMPOSE, OP_VIEW_ATTACH);
1027 
1028  /* edit-to (default "t") hides generic tag-entry in Compose menu
1029  This will bind tag-entry to "T" in the Compose menu */
1030  km_bindkey("T", MENU_COMPOSE, OP_TAG);
1031 }
Select from results of external query.
Definition: keymap.h:76
struct Keymap * Keymaps[MENU_MAX]
Array of Keymap keybindings, one for each Menu.
Definition: keymap.c:146
SMIME encryption menu.
Definition: keymap.h:78
PGP encryption menu.
Definition: keymap.h:77
Generic selection list.
Definition: keymap.h:72
General file/mailbox browser.
Definition: keymap.h:71
Select an email address by its alias.
Definition: keymap.h:67
const struct Binding OpPager[]
Key bindings for the pager menu.
Definition: functions.h:254
const struct Binding OpMain[]
Key bindings for the index menu.
Definition: functions.h:101
Select an attachment.
Definition: keymap.h:68
const struct Binding OpPgp[]
Key bindings for the pgp menu.
Definition: functions.h:620
const struct Binding OpAlias[]
Key bindings for the alias menu.
Definition: functions.h:516
const struct Binding OpSmime[]
Key bindings for the smime menu.
Definition: functions.h:629
const struct Binding OpGeneric[]
Key bindings for the generic menu.
Definition: functions.h:52
const struct Binding OpPost[]
Key bindings for the postpone menu.
Definition: functions.h:507
Text entry area.
Definition: keymap.h:70
Select a postponed email.
Definition: keymap.h:75
A keyboard mapping.
Definition: keymap.h:45
#define APPLICATION_PGP
Definition: ncrypt.h:129
static void create_bindings(const struct Binding *map, int menu)
Attach a set of keybindings to a Menu.
Definition: keymap.c:717
Compose an email.
Definition: keymap.h:69
static int km_bindkey(const char *s, int menu, int op)
Bind a key in a Menu to an operation.
Definition: keymap.c:420
const struct Binding OpBrowser[]
Key bindings for the file browser menu.
Definition: functions.h:525
const struct Binding OpCompose[]
Key bindings for the compose menu.
Definition: functions.h:440
const struct Binding OpAttach[]
Key bindings for the attachment menu.
Definition: functions.h:405
const struct Binding OpEditor[]
Key bindings for the editor menu.
Definition: functions.h:588
#define WithCrypto
Definition: ncrypt.h:154
Pager pager (email viewer)
Definition: keymap.h:74
Index panel (list of emails)
Definition: keymap.h:73
#define APPLICATION_SMIME
Definition: ncrypt.h:130
const struct Binding OpQuery[]
Key bindings for the external query menu.
Definition: functions.h:577

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void km_error_key ( int  menu)

Handle an unbound key sequence.

Parameters
menuMenu id, e.g. MENU_PAGER

Definition at line 1037 of file keymap.c.

1038 {
1039  char buf[SHORT_STRING];
1040  int p, op;
1041 
1042  struct Keymap *key = km_find_func(menu, OP_HELP);
1043  if (!key && (menu != MENU_EDITOR) && (menu != MENU_PAGER))
1044  key = km_find_func(MENU_GENERIC, OP_HELP);
1045  if (!key)
1046  {
1047  mutt_error(_("Key is not bound"));
1048  return;
1049  }
1050 
1051  /* Make sure the key is really the help key in this menu.
1052  *
1053  * OP_END_COND is used as a barrier to ensure nothing extra
1054  * is left in the unget buffer.
1055  *
1056  * Note that km_expand_key() + tokenize_unget_string() should
1057  * not be used here: control sequences are expanded to a form
1058  * (e.g. "^H") not recognized by km_dokey(). */
1059  mutt_unget_event(0, OP_END_COND);
1060  p = key->len;
1061  while (p--)
1062  mutt_unget_event(key->keys[p], 0);
1063 
1064  /* Note, e.g. for the index menu:
1065  * bind generic ? noop
1066  * bind generic ,a help
1067  * bind index ,ab quit
1068  * The index keybinding shadows the generic binding.
1069  * OP_END_COND will be read and returned as the op.
1070  *
1071  * bind generic ? noop
1072  * bind generic dq help
1073  * bind index d delete-message
1074  * OP_DELETE will be returned as the op, leaving "q" + OP_END_COND
1075  * in the unget buffer.
1076  */
1077  op = km_dokey(menu);
1078  if (op != OP_END_COND)
1080  if (op != OP_HELP)
1081  {
1082  mutt_error(_("Key is not bound"));
1083  return;
1084  }
1085 
1086  km_expand_key(buf, sizeof(buf), key);
1087  mutt_error(_("Key is not bound. Press '%s' for help."), buf);
1088 }
#define SHORT_STRING
Definition: string2.h:34
int km_dokey(int menu)
Determine what a keypress should do.
Definition: keymap.c:572
keycode_t * keys
key sequence
Definition: keymap.h:53
Generic selection list.
Definition: keymap.h:72
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:668
#define _(a)
Definition: message.h:28
struct Keymap * km_find_func(int menu, int func)
Find a function&#39;s mapping in a Menu.
Definition: keymap.c:798
short op
operation to perform
Definition: keymap.h:50
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:770
Text entry area.
Definition: keymap.h:70
A keyboard mapping.
Definition: keymap.h:45
short len
length of key sequence (unit: sizeof (keycode_t))
Definition: keymap.h:52
#define mutt_error(...)
Definition: logging.h:88
void mutt_flush_unget_to_endcond(void)
Clear entries from UngetKeyEvents.
Definition: curs_lib.c:741
Pager pager (email viewer)
Definition: keymap.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_parse_push ( struct Buffer buf,
struct Buffer s,
unsigned long  data,
struct Buffer err 
)

Parse the 'push' command - Implements command_t.

Definition at line 1093 of file keymap.c.

1095 {
1096  int r = 0;
1097 
1099  if (MoreArgs(s))
1100  {
1101  mutt_buffer_printf(err, _("%s: too many arguments"), "push");
1102  r = -1;
1103  }
1104  else
1106  return r;
1107 }
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition: curs_lib.c:705
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:200
#define MoreArgs(buf)
Definition: buffer.h:44
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, int flags)
Extract one token from a string.
Definition: init.c:2520
#define MUTT_TOKEN_CONDENSE
^(char) to control chars (macros)
Definition: mutt.h:72
char * data
pointer to data
Definition: buffer.h:35
static void generic_tokenize_push_string(char *s, void(*generic_push)(int, int))
Parse and queue a &#39;push&#39; command.
Definition: keymap.c:475

+ Here is the call graph for this function:

static char* parse_keymap ( int *  menu,
struct Buffer s,
int  maxmenus,
int *  nummenus,
struct Buffer err,
bool  bind 
)
static

Parse a user-config key binding.

Parameters
menuArray for results
sBuffer containing config string
maxmenusTotal number of menus
nummenusNumber of menus this config applies to
errBuffer for error messages
bindIf true 'bind', otherwise 'macro'
Return values
ptrKey string for the binding

Expects to see: <menu-string>,<menu-string>,... <key-string>

Note
Caller needs to free the returned string

Definition at line 1123 of file keymap.c.

1125 {
1126  struct Buffer buf;
1127  int i = 0;
1128  char *q = NULL;
1129 
1130  mutt_buffer_init(&buf);
1131 
1132  /* menu name */
1133  mutt_extract_token(&buf, s, 0);
1134  char *p = buf.data;
1135  if (MoreArgs(s))
1136  {
1137  while (i < maxmenus)
1138  {
1139  q = strchr(p, ',');
1140  if (q)
1141  *q = '\0';
1142 
1143  menu[i] = mutt_map_get_value(p, Menus);
1144  if (menu[i] == -1)
1145  {
1146  mutt_buffer_printf(err, _("%s: no such menu"), p);
1147  goto error;
1148  }
1149  i++;
1150  if (q)
1151  p = q + 1;
1152  else
1153  break;
1154  }
1155  *nummenus = i;
1156  /* key sequence */
1157  mutt_extract_token(&buf, s, 0);
1158 
1159  if (!*buf.data)
1160  {
1161  mutt_buffer_printf(err, _("%s: null key sequence"), bind ? "bind" : "macro");
1162  }
1163  else if (MoreArgs(s))
1164  return buf.data;
1165  }
1166  else
1167  {
1168  mutt_buffer_printf(err, _("%s: too few arguments"), bind ? "bind" : "macro");
1169  }
1170 error:
1171  FREE(&buf.data);
1172  return NULL;
1173 }
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:200
#define MoreArgs(buf)
Definition: buffer.h:44
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, int flags)
Extract one token from a string.
Definition: init.c:2520
const struct Mapping Menus[]
Menu name lookup table.
Definition: keymap.c:59
#define FREE(x)
Definition: memory.h:46
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:66
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition: mapping.c:61

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int try_bind ( char *  key,
int  menu,
char *  func,
const struct Binding bindings,
struct Buffer err 
)
static

Try to make a key binding.

Parameters
keyKey name
menuMenu id, e.g. MENU_PAGER
funcFunction name
bindingsKey bindings table
errBuffer for error message
Return values
0Success
-1Unknown function
-2Error

Definition at line 1186 of file keymap.c.

1188 {
1189  for (int i = 0; bindings[i].name; i++)
1190  {
1191  if (mutt_str_strcmp(func, bindings[i].name) == 0)
1192  {
1193  return km_bindkey_err(key, menu, bindings[i].op, err);
1194  }
1195  }
1196  if (err)
1197  {
1198  mutt_buffer_printf(err, _("Function '%s' not available for menu '%s'"),
1199  func, mutt_map_get_name(menu, Menus));
1200  }
1201  return -1; /* Couldn't find an existing function with this name */
1202 }
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:200
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
static int km_bindkey_err(const char *s, int menu, int op, struct Buffer *err)
Bind a key in a Menu to an operation (with error message)
Definition: keymap.c:407
const char * name
Definition: pgpmicalg.c:42
const char * name
name of the function
Definition: keymap.h:100
const struct Mapping Menus[]
Menu name lookup table.
Definition: keymap.c:59
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:612

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const struct Binding* km_get_table ( int  menu)

Lookup a menu's keybindings.

Parameters
menuMenu id, e.g. MENU_EDITOR
Return values
ptrArray of keybindings

Definition at line 1209 of file keymap.c.

1210 {
1211  switch (menu)
1212  {
1213  case MENU_ALIAS:
1214  return OpAlias;
1215  case MENU_ATTACH:
1216  return OpAttach;
1217  case MENU_COMPOSE:
1218  return OpCompose;
1219  case MENU_EDITOR:
1220  return OpEditor;
1221  case MENU_FOLDER:
1222  return OpBrowser;
1223  case MENU_GENERIC:
1224  return OpGeneric;
1225 #ifdef CRYPT_BACKEND_GPGME
1226  case MENU_KEY_SELECT_PGP:
1227  return OpPgp;
1228  case MENU_KEY_SELECT_SMIME:
1229  return OpSmime;
1230 #endif
1231  case MENU_MAIN:
1232  return OpMain;
1233 #ifdef MIXMASTER
1234  case MENU_MIX:
1235  return OpMix;
1236 #endif
1237  case MENU_PAGER:
1238  return OpPager;
1239  case MENU_PGP:
1240  return (WithCrypto & APPLICATION_PGP) ? OpPgp : NULL;
1241  case MENU_POST:
1242  return OpPost;
1243  case MENU_QUERY:
1244  return OpQuery;
1245  }
1246  return NULL;
1247 }
Select from results of external query.
Definition: keymap.h:76
PGP encryption menu.
Definition: keymap.h:77
Generic selection list.
Definition: keymap.h:72
General file/mailbox browser.
Definition: keymap.h:71
Select an email address by its alias.
Definition: keymap.h:67
const struct Binding OpPager[]
Key bindings for the pager menu.
Definition: functions.h:254
const struct Binding OpMain[]
Key bindings for the index menu.
Definition: functions.h:101
Select an attachment.
Definition: keymap.h:68
const struct Binding OpPgp[]
Key bindings for the pgp menu.
Definition: functions.h:620
const struct Binding OpAlias[]
Key bindings for the alias menu.
Definition: functions.h:516
const struct Binding OpSmime[]
Key bindings for the smime menu.
Definition: functions.h:629
const struct Binding OpGeneric[]
Key bindings for the generic menu.
Definition: functions.h:52
const struct Binding OpPost[]
Key bindings for the postpone menu.
Definition: functions.h:507
Text entry area.
Definition: keymap.h:70
Select a postponed email.
Definition: keymap.h:75
#define APPLICATION_PGP
Definition: ncrypt.h:129
Compose an email.
Definition: keymap.h:69
const struct Binding OpBrowser[]
Key bindings for the file browser menu.
Definition: functions.h:525
const struct Binding OpCompose[]
Key bindings for the compose menu.
Definition: functions.h:440
const struct Binding OpAttach[]
Key bindings for the attachment menu.
Definition: functions.h:405
const struct Binding OpEditor[]
Key bindings for the editor menu.
Definition: functions.h:588
#define WithCrypto
Definition: ncrypt.h:154
Pager pager (email viewer)
Definition: keymap.h:74
Index panel (list of emails)
Definition: keymap.h:73
const struct Binding OpQuery[]
Key bindings for the external query menu.
Definition: functions.h:577

+ Here is the caller graph for this function:

int mutt_parse_bind ( struct Buffer buf,
struct Buffer s,
unsigned long  data,
struct Buffer err 
)

Parse the 'bind' command - Implements command_t.

bind menu-name <key_sequence> function-name

Definition at line 1254 of file keymap.c.

1256 {
1257  const struct Binding *bindings = NULL;
1258  int menu[sizeof(Menus) / sizeof(struct Mapping) - 1], r = 0, nummenus;
1259 
1260  char *key = parse_keymap(menu, s, mutt_array_size(menu), &nummenus, err, true);
1261  if (!key)
1262  return -1;
1263 
1264  /* function to execute */
1265  mutt_extract_token(buf, s, 0);
1266  if (MoreArgs(s))
1267  {
1268  mutt_buffer_printf(err, _("%s: too many arguments"), "bind");
1269  r = -1;
1270  }
1271  else if (mutt_str_strcasecmp("noop", buf->data) == 0)
1272  {
1273  for (int i = 0; i < nummenus; ++i)
1274  {
1275  km_bindkey(key, menu[i], OP_NULL); /* the `unbind' command */
1276  }
1277  }
1278  else
1279  {
1280  for (int i = 0; i < nummenus; ++i)
1281  {
1282  /* The pager and editor menus don't use the generic map,
1283  * however for other menus try generic first. */
1284  if ((menu[i] != MENU_PAGER) && (menu[i] != MENU_EDITOR) && (menu[i] != MENU_GENERIC))
1285  {
1286  r = try_bind(key, menu[i], buf->data, OpGeneric, err);
1287  if (r == 0)
1288  continue;
1289  if (r == -2)
1290  break;
1291  }
1292 
1293  /* Clear any error message, we're going to try again */
1294  err->data[0] = '\0';
1295  bindings = km_get_table(menu[i]);
1296  if (bindings)
1297  {
1298  r = try_bind(key, menu[i], buf->data, bindings, err);
1299  }
1300  }
1301  }
1302  FREE(&key);
1303  return r;
1304 }
static char * parse_keymap(int *menu, struct Buffer *s, int maxmenus, int *nummenus, struct Buffer *err, bool bind)
Parse a user-config key binding.
Definition: keymap.c:1123
Generic selection list.
Definition: keymap.h:72
static int try_bind(char *key, int menu, char *func, const struct Binding *bindings, struct Buffer *err)
Try to make a key binding.
Definition: keymap.c:1186
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:200
#define mutt_array_size(x)
Definition: memory.h:33
#define MoreArgs(buf)
Definition: buffer.h:44
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, int flags)
Extract one token from a string.
Definition: init.c:2520
const struct Mapping Menus[]
Menu name lookup table.
Definition: keymap.c:59
const struct Binding * km_get_table(int menu)
Lookup a menu&#39;s keybindings.
Definition: keymap.c:1209
const struct Binding OpGeneric[]
Key bindings for the generic menu.
Definition: functions.h:52
char * data
pointer to data
Definition: buffer.h:35
Text entry area.
Definition: keymap.h:70
static int km_bindkey(const char *s, int menu, int op)
Bind a key in a Menu to an operation.
Definition: keymap.c:420
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:625
#define FREE(x)
Definition: memory.h:46
Mapping between user-readable string and a constant.
Definition: mapping.h:29
Mapping between a user key and a function.
Definition: keymap.h:98
Pager pager (email viewer)
Definition: keymap.h:74

+ Here is the call graph for this function:

int mutt_parse_macro ( struct Buffer buf,
struct Buffer s,
unsigned long  data,
struct Buffer err 
)

Parse the 'macro' command - Implements command_t.

macro <menu> <key> <macro> <description>

Definition at line 1311 of file keymap.c.

1313 {
1314  int menu[sizeof(Menus) / sizeof(struct Mapping) - 1], r = -1, nummenus;
1315  char *seq = NULL;
1316 
1317  char *key = parse_keymap(menu, s, mutt_array_size(menu), &nummenus, err, false);
1318  if (!key)
1319  return -1;
1320 
1322  /* make sure the macro sequence is not an empty string */
1323  if (!*buf->data)
1324  {
1325  mutt_buffer_strcpy(err, _("macro: empty key sequence"));
1326  }
1327  else
1328  {
1329  if (MoreArgs(s))
1330  {
1331  seq = mutt_str_strdup(buf->data);
1333 
1334  if (MoreArgs(s))
1335  {
1336  mutt_buffer_printf(err, _("%s: too many arguments"), "macro");
1337  }
1338  else
1339  {
1340  for (int i = 0; i < nummenus; ++i)
1341  {
1342  r = km_bind(key, menu[i], OP_MACRO, seq, buf->data);
1343  }
1344  }
1345 
1346  FREE(&seq);
1347  }
1348  else
1349  {
1350  for (int i = 0; i < nummenus; ++i)
1351  {
1352  r = km_bind(key, menu[i], OP_MACRO, buf->data, NULL);
1353  }
1354  }
1355  }
1356  FREE(&key);
1357  return r;
1358 }
static char * parse_keymap(int *menu, struct Buffer *s, int maxmenus, int *nummenus, struct Buffer *err, bool bind)
Parse a user-config key binding.
Definition: keymap.c:1123
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:200
#define mutt_array_size(x)
Definition: memory.h:33
#define MoreArgs(buf)
Definition: buffer.h:44
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, int flags)
Extract one token from a string.
Definition: init.c:2520
#define MUTT_TOKEN_CONDENSE
^(char) to control chars (macros)
Definition: mutt.h:72
const struct Mapping Menus[]
Menu name lookup table.
Definition: keymap.c:59
void mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:316
int km_bind(char *s, int menu, int op, char *macro, char *desc)
Bind a key to a macro.
Definition: keymap.c:393
char * data
pointer to data
Definition: buffer.h:35
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:384
const char * seq
default key binding
Definition: keymap.h:102
#define FREE(x)
Definition: memory.h:46
Mapping between user-readable string and a constant.
Definition: mapping.h:29

+ Here is the call graph for this function:

int mutt_parse_exec ( struct Buffer buf,
struct Buffer s,
unsigned long  data,
struct Buffer err 
)

Parse the 'exec' command - Implements command_t.

Definition at line 1363 of file keymap.c.

1365 {
1366  int ops[128];
1367  int nops = 0;
1368  const struct Binding *bindings = NULL;
1369  char *function = NULL;
1370 
1371  if (!MoreArgs(s))
1372  {
1373  mutt_buffer_strcpy(err, _("exec: no arguments"));
1374  return -1;
1375  }
1376 
1377  do
1378  {
1379  mutt_extract_token(buf, s, 0);
1380  function = buf->data;
1381 
1382  bindings = km_get_table(CurrentMenu);
1383  if (!bindings && (CurrentMenu != MENU_PAGER))
1384  bindings = OpGeneric;
1385 
1386  ops[nops] = get_op(bindings, function, mutt_str_strlen(function));
1387  if (ops[nops] == OP_NULL && CurrentMenu != MENU_PAGER)
1388  ops[nops] = get_op(OpGeneric, function, mutt_str_strlen(function));
1389 
1390  if (ops[nops] == OP_NULL)
1391  {
1392  mutt_flushinp();
1393  mutt_error(_("%s: no such function"), function);
1394  return -1;
1395  }
1396  nops++;
1397  } while (MoreArgs(s) && nops < mutt_array_size(ops));
1398 
1399  while (nops)
1400  mutt_push_macro_event(0, ops[--nops]);
1401 
1402  return 0;
1403 }
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition: curs_lib.c:705
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:753
#define _(a)
Definition: message.h:28
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:663
#define mutt_array_size(x)
Definition: memory.h:33
#define MoreArgs(buf)
Definition: buffer.h:44
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, int flags)
Extract one token from a string.
Definition: init.c:2520
void mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:316
const struct Binding * km_get_table(int menu)
Lookup a menu&#39;s keybindings.
Definition: keymap.c:1209
const struct Binding OpGeneric[]
Key bindings for the generic menu.
Definition: functions.h:52
char * data
pointer to data
Definition: buffer.h:35
#define mutt_error(...)
Definition: logging.h:88
WHERE int CurrentMenu
Current Menu, e.g. MENU_PAGER.
Definition: globals.h:93
static int get_op(const struct Binding *bindings, const char *start, size_t len)
Get the function by its name.
Definition: keymap.c:432
Mapping between a user key and a function.
Definition: keymap.h:98
Pager pager (email viewer)
Definition: keymap.h:74

+ Here is the call graph for this function:

void mutt_what_key ( void  )

Ask the user to press a key.

Displays the octal value back to the user.

Definition at line 1410 of file keymap.c.

1411 {
1412  int ch;
1413 
1414  mutt_window_mvprintw(MuttMessageWindow, 0, 0, _("Enter keys (^G to abort): "));
1415  do
1416  {
1417  ch = getch();
1418  if (ch != ERR && ch != ctrl('G'))
1419  {
1420  mutt_message(_("Char = %s, Octal = %o, Decimal = %d"), km_keyname(ch), ch, ch);
1421  }
1422  } while (ch != ERR && ch != ctrl('G'));
1423 
1424  mutt_flushinp();
1425  mutt_clear_error();
1426 }
static const char * km_keyname(int c)
Get the human name for a key.
Definition: keymap.c:731
#define mutt_message(...)
Definition: logging.h:87
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:753
#define _(a)
Definition: message.h:28
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:141
int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt,...)
Move the cursor and write a formatted string to a Window.
Definition: mutt_window.c:205
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:41
#define ctrl(c)
Definition: mutt_curses.h:96

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_free_keys ( void  )

Free the key maps.

Definition at line 1431 of file keymap.c.

1432 {
1433  struct Keymap *map = NULL;
1434  struct Keymap *next = NULL;
1435 
1436  for (int i = 0; i < MENU_MAX; i++)
1437  {
1438  for (map = Keymaps[i]; map; map = next)
1439  {
1440  next = map->next;
1441 
1442  FREE(&map->macro);
1443  FREE(&map->desc);
1444  FREE(&map->keys);
1445  FREE(&map);
1446  }
1447 
1448  Keymaps[i] = NULL;
1449  }
1450 }
struct Keymap * Keymaps[MENU_MAX]
Array of Keymap keybindings, one for each Menu.
Definition: keymap.c:146
keycode_t * keys
key sequence
Definition: keymap.h:53
struct Keymap * next
next key in map
Definition: keymap.h:49
char * macro
macro expansion (op == OP_MACRO)
Definition: keymap.h:47
char * desc
description of a macro for the help menu
Definition: keymap.h:48
A keyboard mapping.
Definition: keymap.h:45
#define FREE(x)
Definition: memory.h:46

+ Here is the caller graph for this function:

Variable Documentation

const struct Mapping Menus[]
Initial value:
= {
{ "alias", MENU_ALIAS },
{ "attach", MENU_ATTACH },
{ "browser", MENU_FOLDER },
{ "compose", MENU_COMPOSE },
{ "editor", MENU_EDITOR },
{ "index", MENU_MAIN },
{ "pager", MENU_PAGER },
{ "postpone", MENU_POST },
{ "pgp", MENU_PGP },
{ "smime", MENU_SMIME },
{ "query", MENU_QUERY },
{ "generic", MENU_GENERIC },
{ NULL, 0 },
}
Select from results of external query.
Definition: keymap.h:76
SMIME encryption menu.
Definition: keymap.h:78
PGP encryption menu.
Definition: keymap.h:77
Generic selection list.
Definition: keymap.h:72
General file/mailbox browser.
Definition: keymap.h:71
Select an email address by its alias.
Definition: keymap.h:67
Select an attachment.
Definition: keymap.h:68
Text entry area.
Definition: keymap.h:70
Select a postponed email.
Definition: keymap.h:75
Compose an email.
Definition: keymap.h:69
Pager pager (email viewer)
Definition: keymap.h:74
Index panel (list of emails)
Definition: keymap.h:73

Menu name lookup table.

Definition at line 59 of file keymap.c.

struct Mapping KeyNames[]
static

Key name lookup table.

Definition at line 85 of file keymap.c.

int LastKey

contains the last key the user pressed

Last real key pressed, recorded by dokey()

Definition at line 144 of file keymap.c.

struct Keymap* Keymaps[MENU_MAX]

Array of Keymap keybindings, one for each Menu.

Definition at line 146 of file keymap.c.