NeoMutt  2021-10-29-225-gb9986f
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 "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "keymap.h"
#include "menu/lib.h"
#include "ncrypt/lib.h"
#include "functions.h"
#include "init.h"
#include "mutt_globals.h"
#include "mutt_logging.h"
#include "opcodes.h"
#include "options.h"
#include "imap/lib.h"
#include "monitor.h"
+ Include dependency graph for keymap.c:

Go to the source code of this file.

Data Structures

struct  Extkey
 Map key names from NeoMutt's style to Curses style. More...
 

Functions

static void mutt_keymap_free (struct Keymap **km)
 Free a Keymap. More...
 
static void mutt_keymaplist_free (struct KeymapList *km_list)
 Free a List of Keymaps. More...
 
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 struct Keymapkm_compare_keys (struct Keymap *k1, struct Keymap *k2, size_t *pos)
 Compare two keymaps' keyscodes and return the bigger one. More...
 
static enum CommandResult km_bind_err (const char *s, enum MenuType mtype, int op, char *macro, char *desc, struct Buffer *err)
 Set up a key binding. More...
 
enum CommandResult km_bind (char *s, enum MenuType mtype, int op, char *macro, char *desc)
 Bind a key to a macro. More...
 
static enum CommandResult km_bindkey_err (const char *s, enum MenuType mtype, int op, struct Buffer *err)
 Bind a key in a Menu to an operation (with error message) More...
 
static enum CommandResult km_bindkey (const char *s, enum MenuType mtype, 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...
 
const char * mutt_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 (enum MenuType mtype, keycode_t *keys, int keyslen, int lastkey)
 Try to find the key in the generic menu bindings. More...
 
int km_dokey (enum MenuType mtype)
 Determine what a keypress should do. More...
 
static void create_bindings (const struct Binding *map, enum MenuType mtype)
 Attach a set of keybindings to a Menu. More...
 
static const char * km_keyname (int c)
 Get the human name for a key. More...
 
void mutt_init_abort_key (void)
 Parse the abort_key config string. More...
 
int main_config_observer (struct NotifyCallback *nc)
 Notification that a Config Variable has changed - Implements observer_t -. More...
 
static int km_expand_key_string (char *str, char *buf, size_t buflen)
 Get a human-readable key string. 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 (enum MenuType mtype, int func)
 Find a function's mapping in a Menu. More...
 
static const char * find_ext_name (const char *key)
 Find the curses name for a key. 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 (enum MenuType mtype)
 Handle an unbound key sequence. More...
 
enum CommandResult mutt_parse_push (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'push' command - Implements Command::parse() -. More...
 
static char * parse_keymap (enum MenuType *mtypes, struct Buffer *s, int max_menus, int *num_menus, struct Buffer *err, bool bind)
 Parse a user-config key binding. More...
 
static enum CommandResult try_bind (char *key, enum MenuType mtype, char *func, const struct Binding *bindings, struct Buffer *err)
 Try to make a key binding. More...
 
const struct Bindingkm_get_table (enum MenuType mtype)
 Lookup a menu's keybindings. More...
 
enum CommandResult mutt_parse_bind (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'bind' command - Implements Command::parse() -. More...
 
static void * parse_menu (bool *menus, char *s, struct Buffer *err)
 Parse menu-names into an array. More...
 
static void km_unbind_all (struct KeymapList *km_list, unsigned long mode)
 Free all the keys in the supplied Keymap. More...
 
enum CommandResult mutt_parse_unbind (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unbind' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_macro (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'macro' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_exec (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'exec' command - Implements Command::parse() -. More...
 
void mutt_what_key (void)
 Ask the user to press a key. More...
 
void mutt_keys_free (void)
 Free the key maps. More...
 

Variables

static struct Mapping KeyNames []
 Key name lookup table. More...
 
int LastKey
 contains the last key the user pressed More...
 
keycode_t AbortKey
 code of key to abort prompts, normally Ctrl-G More...
 
struct KeymapList Keymaps [MENU_MAX]
 Array of Keymap keybindings, one for each Menu. More...
 
static const struct Extkey ExtKeys []
 

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

◆ mutt_keymap_free()

static void mutt_keymap_free ( struct Keymap **  km)
static

Free a Keymap.

Parameters
kmKeymap to free

Definition at line 171 of file keymap.c.

172 {
173  if (!km || !*km)
174  return;
175 
176  FREE(&(*km)->macro);
177  FREE(&(*km)->desc);
178  FREE(&(*km)->keys);
179  FREE(km);
180 }
#define FREE(x)
Definition: memory.h:40
+ Here is the caller graph for this function:

◆ mutt_keymaplist_free()

static void mutt_keymaplist_free ( struct KeymapList *  km_list)
static

Free a List of Keymaps.

Parameters
km_listList of Keymaps to free

Definition at line 186 of file keymap.c.

187 {
188  struct Keymap *np = NULL, *tmp = NULL;
189  STAILQ_FOREACH_SAFE(np, km_list, entries, tmp)
190  {
191  STAILQ_REMOVE(km_list, np, Keymap, entries);
192  mutt_keymap_free(&np);
193  }
194 }
static void mutt_keymap_free(struct Keymap **km)
Free a Keymap.
Definition: keymap.c:171
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:402
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
A keyboard mapping.
Definition: keymap.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ alloc_keys()

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 202 of file keymap.c.

203 {
204  struct Keymap *p = mutt_mem_calloc(1, sizeof(struct Keymap));
205  p->len = len;
206  p->keys = mutt_mem_calloc(len, sizeof(keycode_t));
207  memcpy(p->keys, keys, len * sizeof(keycode_t));
208  return p;
209 }
short keycode_t
Type for key storage, the rest of neomutt works fine with int type.
Definition: keymap.h:39
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
keycode_t * keys
key sequence
Definition: keymap.h:55
short len
length of key sequence (unit: sizeof (keycode_t))
Definition: keymap.h:54
+ Here is the call graph for this function:

◆ parse_fkey()

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 218 of file keymap.c.

219 {
220  char *t = NULL;
221  int n = 0;
222 
223  if ((s[0] != '<') || (tolower(s[1]) != 'f'))
224  return -1;
225 
226  for (t = s + 2; *t && isdigit((unsigned char) *t); t++)
227  {
228  n *= 10;
229  n += *t - '0';
230  }
231 
232  if (*t != '>')
233  return -1;
234  return n;
235 }
+ Here is the caller graph for this function:

◆ parse_keycode()

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 245 of file keymap.c.

246 {
247  char *end_char = NULL;
248  long int result = strtol(s + 1, &end_char, 8);
249  /* allow trailing whitespace, eg. < 1001 > */
250  while (IS_SPACE(*end_char))
251  end_char++;
252  /* negative keycodes don't make sense, also detect overflow */
253  if ((*end_char != '>') || (result < 0) || (result == LONG_MAX))
254  {
255  return -1;
256  }
257 
258  return result;
259 }
#define IS_SPACE(ch)
Definition: string2.h:38
+ Here is the caller graph for this function:

◆ parsekeys()

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 268 of file keymap.c.

269 {
270  int n;
271  size_t len = max;
272  char buf[128];
273  char c;
274  char *t = NULL;
275 
276  mutt_str_copy(buf, str, sizeof(buf));
277  char *s = buf;
278 
279  while (*s && len)
280  {
281  *d = '\0';
282  if ((*s == '<') && (t = strchr(s, '>')))
283  {
284  t++;
285  c = *t;
286  *t = '\0';
287 
289  if (n != -1)
290  {
291  s = t;
292  *d = n;
293  }
294  else if ((n = parse_fkey(s)) > 0)
295  {
296  s = t;
297  *d = KEY_F(n);
298  }
299  else if ((n = parse_keycode(s)) > 0)
300  {
301  s = t;
302  *d = n;
303  }
304 
305  *t = c;
306  }
307 
308  if (!*d)
309  {
310  *d = (unsigned char) *s;
311  s++;
312  }
313  d++;
314  len--;
315  }
316 
317  return max - len;
318 }
static int parse_keycode(const char *s)
Parse a numeric keycode.
Definition: keymap.c:245
static struct Mapping KeyNames[]
Key name lookup table.
Definition: keymap.c:60
static int parse_fkey(char *s)
Parse a function key string.
Definition: keymap.c:218
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition: mapping.c:85
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:560
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ km_compare_keys()

static struct Keymap* km_compare_keys ( struct Keymap k1,
struct Keymap k2,
size_t *  pos 
)
static

Compare two keymaps' keyscodes and return the bigger one.

Parameters
k1first keymap to compare
k2second keymap to compare
posposition where the two keycodes differ
Return values
ptrKeymap with a bigger ASCII keycode

Definition at line 327 of file keymap.c.

328 {
329  while (*pos < k1->len && *pos < k2->len)
330  {
331  if (k1->keys[*pos] < k2->keys[*pos])
332  return k2;
333  else if (k1->keys[*pos] > k2->keys[*pos])
334  return k1;
335  else
336  *pos = *pos + 1;
337  }
338 
339  return NULL;
340 }

◆ km_bind_err()

static enum CommandResult km_bind_err ( const char *  s,
enum MenuType  mtype,
int  op,
char *  macro,
char *  desc,
struct Buffer err 
)
static

Set up a key binding.

Parameters
sKey string
mtypeMenu type, e.g. MENU_EDITOR
opOperation, e.g. OP_DELETE
macroMacro string
descDescription of macro (OPTIONAL)
errBuffer for error message
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

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

Definition at line 327 of file keymap.c.

357 {
359  struct Keymap *last = NULL, *np = NULL, *compare = NULL;
360  keycode_t buf[MAX_SEQ];
361  size_t pos = 0, lastpos = 0;
362 
363  size_t len = parsekeys(s, buf, MAX_SEQ);
364 
365  struct Keymap *map = alloc_keys(len, buf);
366  map->op = op;
367  map->macro = mutt_str_dup(macro);
368  map->desc = mutt_str_dup(desc);
369 
370  /* find position to place new keymap */
371  STAILQ_FOREACH(np, &Keymaps[mtype], entries)
372  {
373  compare = km_compare_keys(map, np, &pos);
374 
375  if (compare == map) /* map's keycode is bigger */
376  {
377  last = np;
378  lastpos = pos;
379  if (pos > np->eq)
380  pos = np->eq;
381  }
382  else if (compare == np) /* np's keycode is bigger, found insert location */
383  {
384  map->eq = pos;
385  break;
386  }
387  else /* equal keycodes */
388  {
389  /* Don't warn on overwriting a 'noop' binding */
390  if ((np->len != len) && (np->op != OP_NULL))
391  {
392  /* Overwrite with the different lengths, warn */
393  /* TODO: MAX_SEQ here is wrong */
394  char old_binding[MAX_SEQ];
395  char new_binding[MAX_SEQ];
396  km_expand_key(old_binding, MAX_SEQ, map);
397  km_expand_key(new_binding, MAX_SEQ, np);
398  char *err_msg =
399  _("Binding '%s' will alias '%s' Before, try: 'bind %s %s noop' "
400  "https://neomutt.org/guide/configuration.html#bind-warnings");
401  if (err)
402  {
403  /* err was passed, put the string there */
404  snprintf(err->data, err->dsize, err_msg, old_binding, new_binding,
405  mutt_map_get_name(mtype, MenuNames), new_binding);
406  }
407  else
408  {
409  mutt_error(err_msg, old_binding, new_binding,
410  mutt_map_get_name(mtype, MenuNames), new_binding);
411  }
412  rc = MUTT_CMD_WARNING;
413  }
414 
415  map->eq = np->eq;
416  STAILQ_REMOVE(&Keymaps[mtype], np, Keymap, entries);
417  mutt_keymap_free(&np);
418  break;
419  }
420  }
421 
422  if (last) /* if queue has at least one entry */
423  {
424  if (STAILQ_NEXT(last, entries))
425  STAILQ_INSERT_AFTER(&Keymaps[mtype], last, map, entries);
426  else /* last entry in the queue */
427  STAILQ_INSERT_TAIL(&Keymaps[mtype], map, entries);
428  last->eq = lastpos;
429  }
430  else /* queue is empty, so insert from head */
431  {
432  STAILQ_INSERT_HEAD(&Keymaps[mtype], map, entries);
433  }
434 
435  return rc;
436 }
CommandResult
Error codes for command_t parse functions.
Definition: command.h:34
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:37
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition: command.h:36
#define mutt_error(...)
Definition: logging.h:87
static struct Keymap * alloc_keys(size_t len, keycode_t *keys)
Allocate space for a sequence of keys.
Definition: keymap.c:202
static struct Keymap * km_compare_keys(struct Keymap *k1, struct Keymap *k2, size_t *pos)
Compare two keymaps' keyscodes and return the bigger one.
Definition: keymap.c:327
struct KeymapList Keymaps[MENU_MAX]
Array of Keymap keybindings, one for each Menu.
Definition: keymap.c:120
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:910
static size_t parsekeys(const char *str, keycode_t *d, size_t max)
Parse a key string into key codes.
Definition: keymap.c:268
#define MAX_SEQ
Definition: keymap.h:36
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
#define _(a)
Definition: message.h:28
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:181
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:389
#define STAILQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:383
#define STAILQ_NEXT(elm, field)
Definition: queue.h:400
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field)
Definition: queue.h:377
size_t dsize
Length of data.
Definition: buffer.h:37
char * data
Pointer to data.
Definition: buffer.h:35
char * macro
macro expansion (op == OP_MACRO)
Definition: keymap.h:50
short eq
number of leading keys equal to next entry
Definition: keymap.h:53
char * desc
description of a macro for the help menu
Definition: keymap.h:51
short op
operation to perform
Definition: keymap.h:52
const struct Mapping MenuNames[]
Menu name lookup table.
Definition: type.c:31

◆ km_bind()

enum CommandResult km_bind ( char *  s,
enum MenuType  mtype,
int  op,
char *  macro,
char *  desc 
)

Bind a key to a macro.

Parameters
sKey string
mtypeMenu type, e.g. MENU_EDITOR
opOperation, e.g. OP_DELETE
macroMacro string
descDescription of macro (OPTIONAL)
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Definition at line 327 of file keymap.c.

448 {
449  return km_bind_err(s, mtype, op, macro, desc, NULL);
450 }
static enum CommandResult km_bind_err(const char *s, enum MenuType mtype, int op, char *macro, char *desc, struct Buffer *err)
Set up a key binding.
Definition: keymap.c:355
+ Here is the caller graph for this function:

◆ km_bindkey_err()

static enum CommandResult km_bindkey_err ( const char *  s,
enum MenuType  mtype,
int  op,
struct Buffer err 
)
static

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

Parameters
sKey string
mtypeMenu type, e.g. MENU_PAGER
opOperation, e.g. OP_DELETE
errBuffer for error message
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Definition at line 327 of file keymap.c.

462 {
463  return km_bind_err(s, mtype, op, NULL, NULL, err);
464 }

◆ km_bindkey()

static enum CommandResult km_bindkey ( const char *  s,
enum MenuType  mtype,
int  op 
)
static

Bind a key in a Menu to an operation.

Parameters
sKey string
mtypeMenu type, e.g. MENU_PAGER
opOperation, e.g. OP_DELETE
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Definition at line 327 of file keymap.c.

474 {
475  return km_bindkey_err(s, mtype, op, NULL);
476 }
static enum CommandResult km_bindkey_err(const char *s, enum MenuType mtype, int op, struct Buffer *err)
Bind a key in a Menu to an operation (with error message)
Definition: keymap.c:460
+ Here is the caller graph for this function:

◆ get_op()

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 485 of file keymap.c.

486 {
487  for (int i = 0; bindings[i].name; i++)
488  {
489  if (mutt_istrn_equal(start, bindings[i].name, len) &&
490  (mutt_str_len(bindings[i].name) == len))
491  {
492  return bindings[i].op;
493  }
494  }
495 
496  return OP_NULL;
497 }
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:475
bool mutt_istrn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings ignoring case (to a maximum), safely.
Definition: string.c:432
int op
function id number
Definition: keymap.h:94
const char * name
name of the function
Definition: keymap.h:93
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_get_func()

const char* mutt_get_func ( const struct Binding bindings,
int  op 
)

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 508 of file keymap.c.

509 {
510  for (int i = 0; bindings[i].name; i++)
511  {
512  if (bindings[i].op == op)
513  return bindings[i].name;
514  }
515 
516  return NULL;
517 }
+ Here is the caller graph for this function:

◆ generic_tokenize_push_string()

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 528 of file keymap.c.

529 {
530  char *pp = NULL;
531  char *p = s + mutt_str_len(s) - 1;
532  size_t l;
533  int i, op = OP_NULL;
534 
535  while (p >= s)
536  {
537  /* if we see something like "<PageUp>", look to see if it is a real
538  * function name and return the corresponding value */
539  if (*p == '>')
540  {
541  for (pp = p - 1; pp >= s && *pp != '<'; pp--)
542  ; // do nothing
543 
544  if (pp >= s)
545  {
546  i = parse_fkey(pp);
547  if (i > 0)
548  {
549  generic_push(KEY_F(i), 0);
550  p = pp - 1;
551  continue;
552  }
553 
554  l = p - pp + 1;
555  for (i = 0; KeyNames[i].name; i++)
556  {
557  if (mutt_istrn_equal(pp, KeyNames[i].name, l))
558  break;
559  }
560  if (KeyNames[i].name)
561  {
562  /* found a match */
563  generic_push(KeyNames[i].value, 0);
564  p = pp - 1;
565  continue;
566  }
567 
568  /* See if it is a valid command
569  * skip the '<' and the '>' when comparing */
570  for (enum MenuType j = 0; MenuNames[j].name; j++)
571  {
572  const struct Binding *binding = km_get_table(MenuNames[j].value);
573  if (binding)
574  {
575  op = get_op(binding, pp + 1, l - 2);
576  if (op != OP_NULL)
577  break;
578  }
579  }
580 
581  if (op != OP_NULL)
582  {
583  generic_push(0, op);
584  p = pp - 1;
585  continue;
586  }
587  }
588  }
589  generic_push((unsigned char) *p--, 0); /* independent 8 bits chars */
590  }
591 }
static int get_op(const struct Binding *bindings, const char *start, size_t len)
Get the function by its name.
Definition: keymap.c:485
const struct Binding * km_get_table(enum MenuType mtype)
Lookup a menu's keybindings.
Definition: keymap.c:1301
Mapping between a user key and a function.
Definition: keymap.h:92
const char * name
String value.
Definition: mapping.h:33
MenuType
Types of GUI selections.
Definition: type.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ retry_generic()

static int retry_generic ( enum MenuType  mtype,
keycode_t keys,
int  keyslen,
int  lastkey 
)
static

Try to find the key in the generic menu bindings.

Parameters
mtypeMenu type, 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 601 of file keymap.c.

602 {
603  if ((mtype != MENU_EDITOR) && (mtype != MENU_GENERIC) && (mtype != MENU_PAGER))
604  {
605  if (lastkey)
606  mutt_unget_event(lastkey, 0);
607  for (; keyslen; keyslen--)
608  mutt_unget_event(keys[keyslen - 1], 0);
609  return km_dokey(MENU_GENERIC);
610  }
611  if (mtype != MENU_EDITOR)
612  {
613  /* probably a good idea to flush input here so we can abort macros */
614  mutt_flushinp();
615  }
616  return OP_NULL;
617 }
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:645
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:560
int km_dokey(enum MenuType mtype)
Determine what a keypress should do.
Definition: keymap.c:627
@ MENU_GENERIC
Generic selection list.
Definition: type.h:45
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:54
@ MENU_EDITOR
Text entry area.
Definition: type.h:43
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ km_dokey()

int km_dokey ( enum MenuType  mtype)

Determine what a keypress should do.

Parameters
mtypeMenu type, 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 627 of file keymap.c.

628 {
629  struct KeyEvent tmp;
630  struct Keymap *map = STAILQ_FIRST(&Keymaps[mtype]);
631  int pos = 0;
632  int n = 0;
633 
634  if (!map && (mtype != MENU_EDITOR))
635  return retry_generic(mtype, NULL, 0, 0);
636 
637 #ifdef USE_IMAP
638  const short c_imap_keepalive =
639  cs_subset_number(NeoMutt->sub, "imap_keepalive");
640 #endif
641 
642  while (true)
643  {
644  const short c_timeout = cs_subset_number(NeoMutt->sub, "timeout");
645  int i = (c_timeout > 0) ? c_timeout : 60;
646 #ifdef USE_IMAP
647  /* keepalive may need to run more frequently than `$timeout` allows */
648  if (c_imap_keepalive)
649  {
650  if (c_imap_keepalive >= i)
651  imap_keepalive();
652  else
653  {
654  while (c_imap_keepalive && (c_imap_keepalive < i))
655  {
656  mutt_getch_timeout(c_imap_keepalive * 1000);
657  tmp = mutt_getch();
658  mutt_getch_timeout(-1);
659  /* If a timeout was not received, or the window was resized, exit the
660  * loop now. Otherwise, continue to loop until reaching a total of
661  * $timeout seconds. */
662  if ((tmp.ch != -2) || SigWinch)
663  goto gotkey;
664 #ifdef USE_INOTIFY
666  goto gotkey;
667 #endif
668  i -= c_imap_keepalive;
669  imap_keepalive();
670  }
671  }
672  }
673 #endif
674 
675  mutt_getch_timeout(i * 1000);
676  tmp = mutt_getch();
677  mutt_getch_timeout(-1);
678 
679 #ifdef USE_IMAP
680  gotkey:
681 #endif
682  /* hide timeouts, but not window resizes, from the line editor. */
683  if ((mtype == MENU_EDITOR) && (tmp.ch == -2) && !SigWinch)
684  continue;
685 
686  LastKey = tmp.ch;
687  if (LastKey < 0)
688  return LastKey;
689 
690  /* do we have an op already? */
691  if (tmp.op)
692  {
693  const char *func = NULL;
694  const struct Binding *bindings = NULL;
695 
696  /* is this a valid op for this menu type? */
697  if ((bindings = km_get_table(mtype)) && (func = mutt_get_func(bindings, tmp.op)))
698  return tmp.op;
699 
700  if ((mtype == MENU_EDITOR) && mutt_get_func(OpEditor, tmp.op))
701  return tmp.op;
702 
703  if ((mtype != MENU_EDITOR) && (mtype != MENU_PAGER))
704  {
705  /* check generic menu type */
706  bindings = OpGeneric;
707  func = mutt_get_func(bindings, tmp.op);
708  if (func)
709  return tmp.op;
710  }
711 
712  /* Sigh. Valid function but not in this context.
713  * Find the literal string and push it back */
714  for (i = 0; MenuNames[i].name; i++)
715  {
716  bindings = km_get_table(MenuNames[i].value);
717  if (bindings)
718  {
719  func = mutt_get_func(bindings, tmp.op);
720  if (func)
721  {
722  mutt_unget_event('>', 0);
723  mutt_unget_string(func);
724  mutt_unget_event('<', 0);
725  break;
726  }
727  }
728  }
729  /* continue to chew */
730  if (func)
731  continue;
732  }
733 
734  if (!map)
735  return tmp.op;
736 
737  /* Nope. Business as usual */
738  while (LastKey > map->keys[pos])
739  {
740  if ((pos > map->eq) || !STAILQ_NEXT(map, entries))
741  return retry_generic(mtype, map->keys, pos, LastKey);
742  map = STAILQ_NEXT(map, entries);
743  }
744 
745  if (LastKey != map->keys[pos])
746  return retry_generic(mtype, map->keys, pos, LastKey);
747 
748  if (++pos == map->len)
749  {
750  if (map->op != OP_MACRO)
751  return map->op;
752 
753  /* OptIgnoreMacroEvents turns off processing the MacroEvents buffer
754  * in mutt_getch(). Generating new macro events during that time would
755  * result in undesired behavior once the option is turned off.
756  *
757  * Originally this returned -1, however that results in an unbuffered
758  * username or password prompt being aborted. Returning OP_NULL allows
759  * mutt_enter_string_full() to display the keybinding pressed instead.
760  *
761  * It may be unexpected for a macro's keybinding to be returned,
762  * but less so than aborting the prompt. */
764  {
765  return OP_NULL;
766  }
767 
768  if (n++ == 10)
769  {
770  mutt_flushinp();
771  mutt_error(_("Macro loop detected"));
772  return -1;
773  }
774 
776  map = STAILQ_FIRST(&Keymaps[mtype]);
777  pos = 0;
778  }
779  }
780 
781  /* not reached */
782 }
void mutt_getch_timeout(int delay)
Set the getch() timeout.
Definition: curs_lib.c:152
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:195
void mutt_unget_string(const char *s)
Return a string to the input buffer.
Definition: curs_lib.c:579
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition: curs_lib.c:597
const struct Binding OpGeneric[]
Key bindings for the generic menu.
Definition: functions.c:53
const struct Binding OpEditor[]
Key bindings for the editor menu.
Definition: functions.c:622
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
void imap_keepalive(void)
Poll the current folder to keep the connection alive.
Definition: util.c:948
static int retry_generic(enum MenuType mtype, keycode_t *keys, int keyslen, int lastkey)
Try to find the key in the generic menu bindings.
Definition: keymap.c:601
static void generic_tokenize_push_string(char *s, void(*generic_push)(int, int))
Parse and queue a 'push' command.
Definition: keymap.c:528
int LastKey
contains the last key the user pressed
Definition: keymap.c:117
const char * mutt_get_func(const struct Binding *bindings, int op)
Get the name of a function.
Definition: keymap.c:508
bool MonitorFilesChanged
true after a monitored file has changed
Definition: monitor.c:52
SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: mutt_globals.h:72
bool OptIgnoreMacroEvents
(pseudo) don't process macro/push/exec events while set
Definition: options.h:43
#define STAILQ_FIRST(head)
Definition: queue.h:350
An event such as a keypress.
Definition: keymap.h:65
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ create_bindings()

static void create_bindings ( const struct Binding map,
enum MenuType  mtype 
)
static

Attach a set of keybindings to a Menu.

Parameters
mapKey bindings
mtypeMenu type, e.g. MENU_PAGER

Definition at line 789 of file keymap.c.

790 {
791  STAILQ_INIT(&Keymaps[mtype]);
792 
793  for (int i = 0; map[i].name; i++)
794  if (map[i].seq)
795  km_bindkey(map[i].seq, mtype, map[i].op);
796 }
static enum CommandResult km_bindkey(const char *s, enum MenuType mtype, int op)
Bind a key in a Menu to an operation.
Definition: keymap.c:473
#define STAILQ_INIT(head)
Definition: queue.h:372
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ km_keyname()

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 805 of file keymap.c.

806 {
807  static char buf[35];
808 
809  const char *p = mutt_map_get_name(c, KeyNames);
810  if (p)
811  return p;
812 
813  if ((c < 256) && (c > -128) && iscntrl((unsigned char) c))
814  {
815  if (c < 0)
816  c += 256;
817 
818  if (c < 128)
819  {
820  buf[0] = '^';
821  buf[1] = (c + '@') & 0x7f;
822  buf[2] = '\0';
823  }
824  else
825  snprintf(buf, sizeof(buf), "\\%d%d%d", c >> 6, (c >> 3) & 7, c & 7);
826  }
827  else if ((c >= KEY_F0) && (c < KEY_F(256))) /* this maximum is just a guess */
828  sprintf(buf, "<F%d>", c - KEY_F0);
829  else if (IsPrint(c))
830  snprintf(buf, sizeof(buf), "%c", (unsigned char) c);
831  else
832  snprintf(buf, sizeof(buf), "\\x%hx", (unsigned short) c);
833  return buf;
834 }
#define IsPrint(ch)
Definition: mbyte.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_init_abort_key()

void mutt_init_abort_key ( void  )

Parse the abort_key config string.

Parse the string into $abort_key and put the keycode into AbortKey.

Definition at line 841 of file keymap.c.

842 {
843  keycode_t buf[2];
844  const char *const c_abort_key = cs_subset_string(NeoMutt->sub, "abort_key");
845  size_t len = parsekeys(c_abort_key, buf, mutt_array_size(buf));
846  if (len == 0)
847  {
848  mutt_error(_("Abort key is not set, defaulting to Ctrl-G"));
849  AbortKey = ctrl('G');
850  return;
851  }
852  if (len > 1)
853  {
854  mutt_warning(
855  _("Specified abort key sequence (%s) will be truncated to first key"), c_abort_key);
856  }
857  AbortKey = buf[0];
858 }
#define mutt_warning(...)
Definition: logging.h:85
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
keycode_t AbortKey
code of key to abort prompts, normally Ctrl-G
Definition: keymap.c:118
#define mutt_array_size(x)
Definition: memory.h:33
#define ctrl(ch)
Definition: mutt_curses.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ km_expand_key_string()

static int km_expand_key_string ( char *  str,
char *  buf,
size_t  buflen 
)
static

Get a human-readable key string.

Parameters
strRaw key string
bufBuffer for the key string
buflenLength of buffer
Return values
numLength of string

Definition at line 885 of file keymap.c.

886 {
887  size_t len = 0;
888  for (; *str; str++)
889  {
890  const char *key = km_keyname(*str);
891  size_t keylen = mutt_str_len(key);
892 
893  mutt_str_copy(buf, key, buflen);
894  buf += keylen;
895  buflen -= keylen;
896  len += keylen;
897  }
898 
899  return len;
900 }
static const char * km_keyname(int c)
Get the human name for a key.
Definition: keymap.c:805
+ Here is the call graph for this function:

◆ km_expand_key()

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 910 of file keymap.c.

911 {
912  if (!map)
913  return 0;
914 
915  int p = 0;
916 
917  while (true)
918  {
919  mutt_str_copy(s, km_keyname(map->keys[p]), len);
920  const size_t l = mutt_str_len(s);
921  len -= l;
922 
923  if ((++p >= map->len) || !len)
924  return 1;
925 
926  s += l;
927  }
928 
929  /* not reached */
930 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ km_find_func()

struct Keymap* km_find_func ( enum MenuType  mtype,
int  func 
)

Find a function's mapping in a Menu.

Parameters
mtypeMenu type, e.g. MENU_PAGER
funcFunction, e.g. OP_DELETE
Return values
ptrKeymap for the function

Definition at line 938 of file keymap.c.

939 {
940  struct Keymap *np = NULL;
941  STAILQ_FOREACH(np, &Keymaps[mtype], entries)
942  {
943  if (np->op == func)
944  break;
945  }
946  return np;
947 }
+ Here is the caller graph for this function:

◆ find_ext_name()

static const char* find_ext_name ( const char *  key)
static

Find the curses name for a key.

Parameters
keyKey name
Return values
ptrCurses name

Look up NeoMutt's name for a key and find the ncurses extended name for it.

Note
This returns a static string.

Definition at line 958 of file keymap.c.

959 {
960  for (int j = 0; ExtKeys[j].name; j++)
961  {
962  if (strcasecmp(key, ExtKeys[j].name) == 0)
963  return ExtKeys[j].sym;
964  }
965  return 0;
966 }
static const struct Extkey ExtKeys[]
Definition: keymap.c:131
const char * sym
Curses key name.
Definition: keymap.c:128
const char * name
NeoMutt key name.
Definition: keymap.c:127
+ Here is the caller graph for this function:

◆ init_extended_keys()

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 978 of file keymap.c.

979 {
980  use_extended_names(true);
981 
982  for (int j = 0; KeyNames[j].name; j++)
983  {
984  if (KeyNames[j].value == -1)
985  {
986  const char *keyname = find_ext_name(KeyNames[j].name);
987 
988  if (keyname)
989  {
990  char *s = tigetstr((char *) keyname);
991  if (s && ((long) (s) != -1))
992  {
993  int code = key_defined(s);
994  if (code > 0)
995  KeyNames[j].value = code;
996  }
997  }
998  }
999  }
1000 }
static const char * find_ext_name(const char *key)
Find the curses name for a key.
Definition: keymap.c:958
int value
Integer value.
Definition: mapping.h:34
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ km_init()

void km_init ( void  )

Initialise all the menu keybindings.

Definition at line 1005 of file keymap.c.

1006 {
1007  memset(Keymaps, 0, sizeof(struct KeymapList) * MENU_MAX);
1008 
1017 
1020 
1023 
1024 #ifdef CRYPT_BACKEND_GPGME
1027 #endif
1028 
1029 #ifdef MIXMASTER
1031 
1032  km_bindkey("<space>", MENU_MIX, OP_GENERIC_SELECT_ENTRY);
1033  km_bindkey("h", MENU_MIX, OP_MIX_CHAIN_PREV);
1034  km_bindkey("l", MENU_MIX, OP_MIX_CHAIN_NEXT);
1035 #endif
1036 
1037 #ifdef USE_AUTOCRYPT
1039 #endif
1040 
1041  /* bindings for the line editor */
1043 
1044  km_bindkey("<up>", MENU_EDITOR, OP_EDITOR_HISTORY_UP);
1045  km_bindkey("<down>", MENU_EDITOR, OP_EDITOR_HISTORY_DOWN);
1046  km_bindkey("<left>", MENU_EDITOR, OP_EDITOR_BACKWARD_CHAR);
1047  km_bindkey("<right>", MENU_EDITOR, OP_EDITOR_FORWARD_CHAR);
1048  km_bindkey("<home>", MENU_EDITOR, OP_EDITOR_BOL);
1049  km_bindkey("<end>", MENU_EDITOR, OP_EDITOR_EOL);
1050  km_bindkey("<backspace>", MENU_EDITOR, OP_EDITOR_BACKSPACE);
1051  km_bindkey("<delete>", MENU_EDITOR, OP_EDITOR_DELETE_CHAR);
1052  km_bindkey("\177", MENU_EDITOR, OP_EDITOR_BACKSPACE);
1053 
1054  /* generic menu keymap */
1056 
1057  km_bindkey("<home>", MENU_GENERIC, OP_FIRST_ENTRY);
1058  km_bindkey("<end>", MENU_GENERIC, OP_LAST_ENTRY);
1059  km_bindkey("<pagedown>", MENU_GENERIC, OP_NEXT_PAGE);
1060  km_bindkey("<pageup>", MENU_GENERIC, OP_PREV_PAGE);
1061  km_bindkey("<right>", MENU_GENERIC, OP_NEXT_PAGE);
1062  km_bindkey("<left>", MENU_GENERIC, OP_PREV_PAGE);
1063  km_bindkey("<up>", MENU_GENERIC, OP_PREV_ENTRY);
1064  km_bindkey("<down>", MENU_GENERIC, OP_NEXT_ENTRY);
1065  km_bindkey("1", MENU_GENERIC, OP_JUMP);
1066  km_bindkey("2", MENU_GENERIC, OP_JUMP);
1067  km_bindkey("3", MENU_GENERIC, OP_JUMP);
1068  km_bindkey("4", MENU_GENERIC, OP_JUMP);
1069  km_bindkey("5", MENU_GENERIC, OP_JUMP);
1070  km_bindkey("6", MENU_GENERIC, OP_JUMP);
1071  km_bindkey("7", MENU_GENERIC, OP_JUMP);
1072  km_bindkey("8", MENU_GENERIC, OP_JUMP);
1073  km_bindkey("9", MENU_GENERIC, OP_JUMP);
1074 
1075  km_bindkey("<return>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY);
1076  km_bindkey("<enter>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY);
1077 
1078  /* Miscellaneous extra bindings */
1079 
1080  km_bindkey(" ", MENU_MAIN, OP_DISPLAY_MESSAGE);
1081  km_bindkey("<up>", MENU_MAIN, OP_MAIN_PREV_UNDELETED);
1082  km_bindkey("<down>", MENU_MAIN, OP_MAIN_NEXT_UNDELETED);
1083  km_bindkey("J", MENU_MAIN, OP_NEXT_ENTRY);
1084  km_bindkey("K", MENU_MAIN, OP_PREV_ENTRY);
1085  km_bindkey("x", MENU_MAIN, OP_EXIT);
1086 
1087  km_bindkey("<return>", MENU_MAIN, OP_DISPLAY_MESSAGE);
1088  km_bindkey("<enter>", MENU_MAIN, OP_DISPLAY_MESSAGE);
1089 
1090  km_bindkey("x", MENU_PAGER, OP_EXIT);
1091  km_bindkey("i", MENU_PAGER, OP_EXIT);
1092  km_bindkey("<backspace>", MENU_PAGER, OP_PREV_LINE);
1093  km_bindkey("<pagedown>", MENU_PAGER, OP_NEXT_PAGE);
1094  km_bindkey("<pageup>", MENU_PAGER, OP_PREV_PAGE);
1095  km_bindkey("<up>", MENU_PAGER, OP_MAIN_PREV_UNDELETED);
1096  km_bindkey("<right>", MENU_PAGER, OP_MAIN_NEXT_UNDELETED);
1097  km_bindkey("<down>", MENU_PAGER, OP_MAIN_NEXT_UNDELETED);
1098  km_bindkey("<left>", MENU_PAGER, OP_MAIN_PREV_UNDELETED);
1099  km_bindkey("<home>", MENU_PAGER, OP_PAGER_TOP);
1100  km_bindkey("<end>", MENU_PAGER, OP_PAGER_BOTTOM);
1101  km_bindkey("1", MENU_PAGER, OP_JUMP);
1102  km_bindkey("2", MENU_PAGER, OP_JUMP);
1103  km_bindkey("3", MENU_PAGER, OP_JUMP);
1104  km_bindkey("4", MENU_PAGER, OP_JUMP);
1105  km_bindkey("5", MENU_PAGER, OP_JUMP);
1106  km_bindkey("6", MENU_PAGER, OP_JUMP);
1107  km_bindkey("7", MENU_PAGER, OP_JUMP);
1108  km_bindkey("8", MENU_PAGER, OP_JUMP);
1109  km_bindkey("9", MENU_PAGER, OP_JUMP);
1110 
1111  km_bindkey("<return>", MENU_PAGER, OP_NEXT_LINE);
1112  km_bindkey("<enter>", MENU_PAGER, OP_NEXT_LINE);
1113 
1114  km_bindkey("<return>", MENU_ALIAS, OP_GENERIC_SELECT_ENTRY);
1115  km_bindkey("<enter>", MENU_ALIAS, OP_GENERIC_SELECT_ENTRY);
1116  km_bindkey("<space>", MENU_ALIAS, OP_TAG);
1117 
1118  km_bindkey("<return>", MENU_ATTACH, OP_VIEW_ATTACH);
1119  km_bindkey("<enter>", MENU_ATTACH, OP_VIEW_ATTACH);
1120  km_bindkey("<return>", MENU_COMPOSE, OP_VIEW_ATTACH);
1121  km_bindkey("<enter>", MENU_COMPOSE, OP_VIEW_ATTACH);
1122 
1123  /* edit-to (default "t") hides generic tag-entry in Compose menu
1124  * This will bind tag-entry to "T" in the Compose menu */
1125  km_bindkey("T", MENU_COMPOSE, OP_TAG);
1126 }
const struct Binding OpPager[]
Key bindings for the pager menu.
Definition: functions.c:265
const struct Binding OpSmime[]
Key bindings for the smime menu.
Definition: functions.c:663
const struct Binding OpAlias[]
Key bindings for the alias menu.
Definition: functions.c:543
const struct Binding OpPgp[]
Key bindings for the pgp menu.
Definition: functions.c:654
const struct Binding OpPost[]
Key bindings for the postpone menu.
Definition: functions.c:534
const struct Binding OpBrowser[]
Key bindings for the file browser menu.
Definition: functions.c:555
const struct Binding OpAttach[]
Key bindings for the attachment menu.
Definition: functions.c:424
const struct Binding OpCompose[]
Key bindings for the compose menu.
Definition: functions.c:463
const struct Binding OpMix[]
Key bindings for the mixmaster menu.
Definition: functions.c:675
const struct Binding OpQuery[]
Key bindings for the external query menu.
Definition: functions.c:608
const struct Binding OpMain[]
Key bindings for the index menu.
Definition: functions.c:102
const struct Binding OpAutocryptAcct[]
Key bindings for the autocrypt account.
Definition: functions.c:691
static void create_bindings(const struct Binding *map, enum MenuType mtype)
Attach a set of keybindings to a Menu.
Definition: keymap.c:789
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:87
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:88
#define WithCrypto
Definition: lib.h:113
@ MENU_KEY_SELECT_PGP
Select a PGP key.
Definition: type.h:47
@ MENU_MAIN
Index panel (list of emails)
Definition: type.h:50
@ MENU_KEY_SELECT_SMIME
Select a SMIME key.
Definition: type.h:48
@ MENU_ATTACH
Select an attachment.
Definition: type.h:38
@ MENU_QUERY
Select from results of external query.
Definition: type.h:57
@ MENU_COMPOSE
Compose an email.
Definition: type.h:42
@ MENU_MIX
Create/edit a Mixmaster chain.
Definition: type.h:52
@ MENU_PGP
PGP encryption menu.
Definition: type.h:55
@ MENU_SMIME
SMIME encryption menu.
Definition: type.h:58
@ MENU_MAX
Definition: type.h:59
@ MENU_POSTPONE
Select a postponed email.
Definition: type.h:56
@ MENU_ALIAS
Select an email address by its alias.
Definition: type.h:37
@ MENU_FOLDER
General file/mailbox browser.
Definition: type.h:44
@ MENU_AUTOCRYPT_ACCT
Autocrypt Account menu.
Definition: type.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ km_error_key()

void km_error_key ( enum MenuType  mtype)

Handle an unbound key sequence.

Parameters
mtypeMenu type, e.g. MENU_PAGER

Definition at line 1132 of file keymap.c.

1133 {
1134  char buf[128];
1135  int p, op;
1136 
1137  struct Keymap *key = km_find_func(mtype, OP_HELP);
1138  if (!key && (mtype != MENU_EDITOR) && (mtype != MENU_PAGER))
1139  key = km_find_func(MENU_GENERIC, OP_HELP);
1140  if (!key)
1141  {
1142  mutt_error(_("Key is not bound"));
1143  return;
1144  }
1145 
1146  /* Make sure the key is really the help key in this menu.
1147  *
1148  * OP_END_COND is used as a barrier to ensure nothing extra
1149  * is left in the unget buffer.
1150  *
1151  * Note that km_expand_key() + tokenize_unget_string() should
1152  * not be used here: control sequences are expanded to a form
1153  * (e.g. "^H") not recognized by km_dokey(). */
1154  mutt_unget_event(0, OP_END_COND);
1155  p = key->len;
1156  while (p--)
1157  mutt_unget_event(key->keys[p], 0);
1158 
1159  /* Note, e.g. for the index menu:
1160  * bind generic ? noop
1161  * bind generic ,a help
1162  * bind index ,ab quit
1163  * The index keybinding shadows the generic binding.
1164  * OP_END_COND will be read and returned as the op.
1165  *
1166  * bind generic ? noop
1167  * bind generic dq help
1168  * bind index d delete-message
1169  * OP_DELETE will be returned as the op, leaving "q" + OP_END_COND
1170  * in the unget buffer.
1171  */
1172  op = km_dokey(mtype);
1173  if (op != OP_END_COND)
1175  if (op != OP_HELP)
1176  {
1177  mutt_error(_("Key is not bound"));
1178  return;
1179  }
1180 
1181  km_expand_key(buf, sizeof(buf), key);
1182  mutt_error(_("Key is not bound. Press '%s' for help."), buf);
1183 }
void mutt_flush_unget_to_endcond(void)
Clear entries from UngetKeyEvents.
Definition: curs_lib.c:633
struct Keymap * km_find_func(enum MenuType mtype, int func)
Find a function's mapping in a Menu.
Definition: keymap.c:938
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_keymap()

static char* parse_keymap ( enum MenuType mtypes,
struct Buffer s,
int  max_menus,
int *  num_menus,
struct Buffer err,
bool  bind 
)
static

Parse a user-config key binding.

Parameters
mtypesArray for results
sBuffer containing config string
max_menusTotal number of menus
num_menusNumber 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 1216 of file keymap.c.

1218 {
1219  struct Buffer buf;
1220  int i = 0;
1221  char *q = NULL;
1222 
1223  mutt_buffer_init(&buf);
1224 
1225  /* menu name */
1227  char *p = buf.data;
1228  if (MoreArgs(s))
1229  {
1230  while (i < max_menus)
1231  {
1232  q = strchr(p, ',');
1233  if (q)
1234  *q = '\0';
1235 
1236  int val = mutt_map_get_value(p, MenuNames);
1237  if (val == -1)
1238  {
1239  mutt_buffer_printf(err, _("%s: no such menu"), p);
1240  goto error;
1241  }
1242  mtypes[i] = val;
1243  i++;
1244  if (q)
1245  p = q + 1;
1246  else
1247  break;
1248  }
1249  *num_menus = i;
1250  /* key sequence */
1252 
1253  if (buf.data[0] == '\0')
1254  {
1255  mutt_buffer_printf(err, _("%s: null key sequence"), bind ? "bind" : "macro");
1256  }
1257  else if (MoreArgs(s))
1258  return buf.data;
1259  }
1260  else
1261  {
1262  mutt_buffer_printf(err, _("%s: too few arguments"), bind ? "bind" : "macro");
1263  }
1264 error:
1265  FREE(&buf.data);
1266  return NULL;
1267 }
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
#define MoreArgs(buf)
Definition: buffer.h:40
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:399
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:66
String manipulation buffer.
Definition: buffer.h:34
+ Here is the call graph for this function:

◆ try_bind()

static enum CommandResult try_bind ( char *  key,
enum MenuType  mtype,
char *  func,
const struct Binding bindings,
struct Buffer err 
)
static

Try to make a key binding.

Parameters
keyKey name
mtypeMenu type, e.g. MENU_PAGER
funcFunction name
bindingsKey bindings table
errBuffer for error message
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Definition at line 1216 of file keymap.c.

1280 {
1281  for (int i = 0; bindings[i].name; i++)
1282  {
1283  if (mutt_str_equal(func, bindings[i].name))
1284  {
1285  return km_bindkey_err(key, mtype, bindings[i].op, err);
1286  }
1287  }
1288  if (err)
1289  {
1290  mutt_buffer_printf(err, _("Function '%s' not available for menu '%s'"),
1291  func, mutt_map_get_name(mtype, MenuNames));
1292  }
1293  return MUTT_CMD_ERROR; /* Couldn't find an existing function with this name */
1294 }
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:35
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:715

◆ km_get_table()

const struct Binding* km_get_table ( enum MenuType  mtype)

Lookup a menu's keybindings.

Parameters
mtypeMenu type, e.g. MENU_EDITOR
Return values
ptrArray of keybindings

Definition at line 1301 of file keymap.c.

1302 {
1303  switch (mtype)
1304  {
1305  case MENU_ALIAS:
1306  return OpAlias;
1307  case MENU_ATTACH:
1308  return OpAttach;
1309 #ifdef USE_AUTOCRYPT
1310  case MENU_AUTOCRYPT_ACCT:
1311  return OpAutocryptAcct;
1312 #endif
1313  case MENU_COMPOSE:
1314  return OpCompose;
1315  case MENU_EDITOR:
1316  return OpEditor;
1317  case MENU_FOLDER:
1318  return OpBrowser;
1319  case MENU_GENERIC:
1320  return OpGeneric;
1321 #ifdef CRYPT_BACKEND_GPGME
1322  case MENU_KEY_SELECT_PGP:
1323  return OpPgp;
1324  case MENU_KEY_SELECT_SMIME:
1325  return OpSmime;
1326 #endif
1327  case MENU_MAIN:
1328  return OpMain;
1329 #ifdef MIXMASTER
1330  case MENU_MIX:
1331  return OpMix;
1332 #endif
1333  case MENU_PAGER:
1334  return OpPager;
1335  case MENU_PGP:
1336  return (WithCrypto & APPLICATION_PGP) ? OpPgp : NULL;
1337  case MENU_POSTPONE:
1338  return OpPost;
1339  case MENU_QUERY:
1340  return OpQuery;
1341  default:
1342  return NULL;
1343  }
1344 }
+ Here is the caller graph for this function:

◆ parse_menu()

static void* parse_menu ( bool *  menus,
char *  s,
struct Buffer err 
)
static

Parse menu-names into an array.

Parameters
menusArray for results
sString containing menu-names
errBuffer for error messages
Return values
NULLAlways

Expects to see: <menu-string>[,<menu-string>]

Definition at line 1448 of file keymap.c.

1449 {
1450  char *menu_names_dup = mutt_str_dup(s);
1451  char *marker = menu_names_dup;
1452  char *menu_name = NULL;
1453 
1454  while ((menu_name = strsep(&marker, ",")))
1455  {
1456  int value = mutt_map_get_value(menu_name, MenuNames);
1457  if (value == -1)
1458  {
1459  mutt_buffer_printf(err, _("%s: no such menu"), menu_name);
1460  break;
1461  }
1462  else
1463  menus[value] = true;
1464  }
1465 
1466  FREE(&menu_names_dup);
1467  return NULL;
1468 }
+ Here is the call graph for this function:

◆ km_unbind_all()

static void km_unbind_all ( struct KeymapList *  km_list,
unsigned long  mode 
)
static

Free all the keys in the supplied Keymap.

Parameters
km_listKeymap mapping
modeUndo bind or macro, e.g. MUTT_UNBIND, MUTT_UNMACRO

Iterate through Keymap and free keys defined either by "macro" or "bind".

Definition at line 1477 of file keymap.c.

1478 {
1479  struct Keymap *np = NULL, *tmp = NULL;
1480 
1481  STAILQ_FOREACH_SAFE(np, km_list, entries, tmp)
1482  {
1483  if (((mode & MUTT_UNBIND) && !np->macro) || ((mode & MUTT_UNMACRO) && np->macro))
1484  {
1485  STAILQ_REMOVE(km_list, np, Keymap, entries);
1486  mutt_keymap_free(&np);
1487  }
1488  }
1489 }
#define MUTT_UNBIND
Definition: keymap.h:33
#define MUTT_UNMACRO
Definition: keymap.h:34
+ Here is the call graph for this function:

◆ mutt_what_key()

void mutt_what_key ( void  )

Ask the user to press a key.

Displays the octal value back to the user.

Definition at line 1707 of file keymap.c.

1708 {
1709  int ch;
1710 
1711  struct MuttWindow *win = msgwin_get_window();
1712  if (!win)
1713  return;
1714 
1715  mutt_window_mvprintw(win, 0, 0, _("Enter keys (%s to abort): "), km_keyname(AbortKey));
1716  do
1717  {
1718  ch = getch();
1719  if ((ch != ERR) && (ch != AbortKey))
1720  {
1721  mutt_message(_("Char = %s, Octal = %o, Decimal = %d"), km_keyname(ch), ch, ch);
1722  }
1723  } while (ch != ERR && ch != AbortKey);
1724 
1725  mutt_flushinp();
1726  mutt_clear_error();
1727 }
#define mutt_message(...)
Definition: logging.h:86
struct MuttWindow * msgwin_get_window(void)
Get the Message Window pointer.
Definition: msgwin.c:251
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
int mutt_window_mvprintw(struct MuttWindow *win, int col, int row, const char *fmt,...)
Move the cursor and write a formatted string to a Window.
Definition: mutt_window.c:321
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_keys_free()

void mutt_keys_free ( void  )

Free the key maps.

Definition at line 1732 of file keymap.c.

1733 {
1734  for (int i = 0; i < MENU_MAX; i++)
1735  {
1737  }
1738 }
static void mutt_keymaplist_free(struct KeymapList *km_list)
Free a List of Keymaps.
Definition: keymap.c:186
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ KeyNames

struct Mapping KeyNames[]
static

Key name lookup table.

Definition at line 1 of file keymap.c.

◆ LastKey

int LastKey

contains the last key the user pressed

Last real key pressed, recorded by dokey()

Definition at line 117 of file keymap.c.

◆ AbortKey

keycode_t AbortKey

code of key to abort prompts, normally Ctrl-G

key to abort edits etc, normally Ctrl-G

Definition at line 118 of file keymap.c.

◆ Keymaps

struct KeymapList Keymaps[MENU_MAX]

Array of Keymap keybindings, one for each Menu.

Definition at line 118 of file keymap.c.

◆ ExtKeys

const struct Extkey ExtKeys[]
static

Definition at line 118 of file keymap.c.