NeoMutt  2022-04-29-145-g9b6a0e
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/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "keymap.h"
#include "color/lib.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 MenuFuncOp *funcs, const char *start, size_t len)
 Get the function by its name. More...
 
const char * mutt_get_func (const struct MenuFuncOp *funcs, 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 struct KeyEvent retry_generic (enum MenuType mtype, keycode_t *keys, int keyslen, int lastkey)
 Try to find the key in the generic menu bindings. More...
 
struct KeyEvent km_dokey_event (enum MenuType mtype)
 Determine what a keypress should do. More...
 
int km_dokey (enum MenuType mtype)
 Determine what a keypress should do. More...
 
static void create_bindings (const struct MenuOpSeq *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 MenuFuncOp *funcs, struct Buffer *err)
 Try to make a key binding. More...
 
const struct MenuFuncOpkm_get_table (enum MenuType mtype)
 Lookup a Menu's functions. 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...
 
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 177 of file keymap.c.

178 {
179  if (!km || !*km)
180  return;
181 
182  FREE(&(*km)->macro);
183  FREE(&(*km)->desc);
184  FREE(&(*km)->keys);
185  FREE(km);
186 }
#define FREE(x)
Definition: memory.h:43
+ 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 192 of file keymap.c.

193 {
194  struct Keymap *np = NULL, *tmp = NULL;
195  STAILQ_FOREACH_SAFE(np, km_list, entries, tmp)
196  {
197  STAILQ_REMOVE(km_list, np, Keymap, entries);
198  mutt_keymap_free(&np);
199  }
200 }
static void mutt_keymap_free(struct Keymap **km)
Free a Keymap.
Definition: keymap.c:177
#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 208 of file keymap.c.

209 {
210  struct Keymap *p = mutt_mem_calloc(1, sizeof(struct Keymap));
211  p->len = len;
212  p->keys = mutt_mem_calloc(len, sizeof(keycode_t));
213  memcpy(p->keys, keys, len * sizeof(keycode_t));
214  return p;
215 }
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 224 of file keymap.c.

225 {
226  char *t = NULL;
227  int n = 0;
228 
229  if ((s[0] != '<') || (tolower(s[1]) != 'f'))
230  return -1;
231 
232  for (t = s + 2; *t && isdigit((unsigned char) *t); t++)
233  {
234  n *= 10;
235  n += *t - '0';
236  }
237 
238  if (*t != '>')
239  return -1;
240  return n;
241 }
+ 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 251 of file keymap.c.

252 {
253  char *end_char = NULL;
254  long int result = strtol(s + 1, &end_char, 8);
255  /* allow trailing whitespace, eg. < 1001 > */
256  while (IS_SPACE(*end_char))
257  end_char++;
258  /* negative keycodes don't make sense, also detect overflow */
259  if ((*end_char != '>') || (result < 0) || (result == LONG_MAX))
260  {
261  return -1;
262  }
263 
264  return result;
265 }
#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 274 of file keymap.c.

275 {
276  int n;
277  size_t len = max;
278  char buf[128];
279  char c;
280  char *t = NULL;
281 
282  mutt_str_copy(buf, str, sizeof(buf));
283  char *s = buf;
284 
285  while (*s && len)
286  {
287  *d = '\0';
288  if ((*s == '<') && (t = strchr(s, '>')))
289  {
290  t++;
291  c = *t;
292  *t = '\0';
293 
295  if (n != -1)
296  {
297  s = t;
298  *d = n;
299  }
300  else if ((n = parse_fkey(s)) > 0)
301  {
302  s = t;
303  *d = KEY_F(n);
304  }
305  else if ((n = parse_keycode(s)) > 0)
306  {
307  s = t;
308  *d = n;
309  }
310 
311  *t = c;
312  }
313 
314  if (!*d)
315  {
316  *d = (unsigned char) *s;
317  s++;
318  }
319  d++;
320  len--;
321  }
322 
323  return max - len;
324 }
static int parse_keycode(const char *s)
Parse a numeric keycode.
Definition: keymap.c:251
static struct Mapping KeyNames[]
Key name lookup table.
Definition: keymap.c:62
static int parse_fkey(char *s)
Parse a function key string.
Definition: keymap.c:224
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:629
+ 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 333 of file keymap.c.

334 {
335  while (*pos < k1->len && *pos < k2->len)
336  {
337  if (k1->keys[*pos] < k2->keys[*pos])
338  return k2;
339  else if (k1->keys[*pos] > k2->keys[*pos])
340  return k1;
341  else
342  *pos = *pos + 1;
343  }
344 
345  return NULL;
346 }

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

363 {
365  struct Keymap *last = NULL, *np = NULL, *compare = NULL;
366  keycode_t buf[MAX_SEQ];
367  size_t pos = 0, lastpos = 0;
368 
369  size_t len = parsekeys(s, buf, MAX_SEQ);
370 
371  struct Keymap *map = alloc_keys(len, buf);
372  map->op = op;
373  map->macro = mutt_str_dup(macro);
374  map->desc = mutt_str_dup(desc);
375 
376  /* find position to place new keymap */
377  STAILQ_FOREACH(np, &Keymaps[mtype], entries)
378  {
379  compare = km_compare_keys(map, np, &pos);
380 
381  if (compare == map) /* map's keycode is bigger */
382  {
383  last = np;
384  lastpos = pos;
385  if (pos > np->eq)
386  pos = np->eq;
387  }
388  else if (compare == np) /* np's keycode is bigger, found insert location */
389  {
390  map->eq = pos;
391  break;
392  }
393  else /* equal keycodes */
394  {
395  /* Don't warn on overwriting a 'noop' binding */
396  if ((np->len != len) && (np->op != OP_NULL))
397  {
398  /* Overwrite with the different lengths, warn */
399  /* TODO: MAX_SEQ here is wrong */
400  char old_binding[MAX_SEQ];
401  char new_binding[MAX_SEQ];
402  km_expand_key(old_binding, MAX_SEQ, map);
403  km_expand_key(new_binding, MAX_SEQ, np);
404  char *err_msg = _("Binding '%s' will alias '%s' Before, try: 'bind %s %s noop' https://neomutt.org/guide/configuration.html#bind-warnings");
405  if (err)
406  {
407  /* err was passed, put the string there */
408  snprintf(err->data, err->dsize, err_msg, old_binding, new_binding,
409  mutt_map_get_name(mtype, MenuNames), new_binding);
410  }
411  else
412  {
413  mutt_error(err_msg, old_binding, new_binding,
414  mutt_map_get_name(mtype, MenuNames), new_binding);
415  }
416  rc = MUTT_CMD_WARNING;
417  }
418 
419  map->eq = np->eq;
420  STAILQ_REMOVE(&Keymaps[mtype], np, Keymap, entries);
421  mutt_keymap_free(&np);
422  break;
423  }
424  }
425 
426  if (map->op == OP_NULL)
427  {
428  mutt_keymap_free(&map);
429  }
430  else
431  {
432  if (last) /* if queue has at least one entry */
433  {
434  if (STAILQ_NEXT(last, entries))
435  STAILQ_INSERT_AFTER(&Keymaps[mtype], last, map, entries);
436  else /* last entry in the queue */
437  STAILQ_INSERT_TAIL(&Keymaps[mtype], map, entries);
438  last->eq = lastpos;
439  }
440  else /* queue is empty, so insert from head */
441  {
442  STAILQ_INSERT_HEAD(&Keymaps[mtype], map, entries);
443  }
444  }
445 
446  return rc;
447 }
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:208
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:333
struct KeymapList Keymaps[MENU_MAX]
Array of Keymap keybindings, one for each Menu.
Definition: keymap.c:126
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:926
static size_t parsekeys(const char *str, keycode_t *d, size_t max)
Parse a key string into key codes.
Definition: keymap.c:274
#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:250
#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 333 of file keymap.c.

459 {
460  return km_bind_err(s, mtype, op, macro, desc, NULL);
461 }
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:361
+ 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 333 of file keymap.c.

473 {
474  return km_bind_err(s, mtype, op, NULL, NULL, err);
475 }

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

485 {
486  return km_bindkey_err(s, mtype, op, NULL);
487 }
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:471
+ Here is the caller graph for this function:

◆ get_op()

static int get_op ( const struct MenuFuncOp funcs,
const char *  start,
size_t  len 
)
static

Get the function by its name.

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

Definition at line 496 of file keymap.c.

497 {
498  for (int i = 0; funcs[i].name; i++)
499  {
500  if (mutt_istrn_equal(start, funcs[i].name, len) && (mutt_str_len(funcs[i].name) == len))
501  {
502  return funcs[i].op;
503  }
504  }
505 
506  return OP_NULL;
507 }
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:544
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:501
const char * name
Name of the function.
Definition: keymap.h:93
int op
Operation, e.g. OP_DELETE.
Definition: keymap.h:94
+ 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 MenuFuncOp funcs,
int  op 
)

Get the name of a function.

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

Definition at line 518 of file keymap.c.

519 {
520  for (int i = 0; funcs[i].name; i++)
521  {
522  if (funcs[i].op == op)
523  return funcs[i].name;
524  }
525 
526  return NULL;
527 }
+ 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 538 of file keymap.c.

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

◆ retry_generic()

static struct KeyEvent 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 538 of file keymap.c.

613 {
614  if (lastkey)
615  mutt_unget_ch(lastkey);
616  for (; keyslen; keyslen--)
617  mutt_unget_ch(keys[keyslen - 1]);
618 
619  if ((mtype != MENU_EDITOR) && (mtype != MENU_GENERIC) && (mtype != MENU_PAGER))
620  {
622  }
623  if ((mtype != MENU_EDITOR) && (mtype != MENU_GENERIC))
624  {
625  /* probably a good idea to flush input here so we can abort macros */
626  mutt_flushinp();
627  }
628 
629  return (struct KeyEvent){ .ch = mutt_getch().ch, .op = OP_NULL };
630 }
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:593
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:242
void mutt_unget_ch(int ch)
Return a keystroke to the input buffer.
Definition: curs_lib.c:522
struct KeyEvent km_dokey_event(enum MenuType mtype)
Determine what a keypress should do.
Definition: keymap.c:637
An event such as a keypress.
Definition: keymap.h:65
int ch
Raw key pressed.
Definition: keymap.h:66
@ 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

◆ km_dokey_event()

struct KeyEvent km_dokey_event ( enum MenuType  mtype)

Determine what a keypress should do.

Parameters
mtypeMenu type, e.g. MENU_EDITOR
Return values
ptrEvent

Definition at line 538 of file keymap.c.

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

796 {
797  return km_dokey_event(mtype).op;
798 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ create_bindings()

static void create_bindings ( const struct MenuOpSeq 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 805 of file keymap.c.

806 {
807  STAILQ_INIT(&Keymaps[mtype]);
808 
809  for (int i = 0; map[i].op != 0; i++)
810  if (map[i].seq)
811  km_bindkey(map[i].seq, mtype, map[i].op);
812 }
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:484
#define STAILQ_INIT(head)
Definition: queue.h:372
int op
Operation, e.g. OP_DELETE.
Definition: keymap.h:102
+ 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 821 of file keymap.c.

822 {
823  static char buf[35];
824 
825  const char *p = mutt_map_get_name(c, KeyNames);
826  if (p)
827  return p;
828 
829  if ((c < 256) && (c > -128) && iscntrl((unsigned char) c))
830  {
831  if (c < 0)
832  c += 256;
833 
834  if (c < 128)
835  {
836  buf[0] = '^';
837  buf[1] = (c + '@') & 0x7f;
838  buf[2] = '\0';
839  }
840  else
841  snprintf(buf, sizeof(buf), "\\%d%d%d", c >> 6, (c >> 3) & 7, c & 7);
842  }
843  else if ((c >= KEY_F0) && (c < KEY_F(256))) /* this maximum is just a guess */
844  sprintf(buf, "<F%d>", c - KEY_F0);
845  else if (IsPrint(c))
846  snprintf(buf, sizeof(buf), "%c", (unsigned char) c);
847  else
848  snprintf(buf, sizeof(buf), "\\x%hx", (unsigned short) c);
849  return buf;
850 }
#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 857 of file keymap.c.

858 {
859  keycode_t buf[2];
860  const char *const c_abort_key = cs_subset_string(NeoMutt->sub, "abort_key");
861  size_t len = parsekeys(c_abort_key, buf, mutt_array_size(buf));
862  if (len == 0)
863  {
864  mutt_error(_("Abort key is not set, defaulting to Ctrl-G"));
865  AbortKey = ctrl('G');
866  return;
867  }
868  if (len > 1)
869  {
870  mutt_warning(_("Specified abort key sequence (%s) will be truncated to first key"),
871  c_abort_key);
872  }
873  AbortKey = buf[0];
874 }
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
#define mutt_warning(...)
Definition: logging.h:85
keycode_t AbortKey
code of key to abort prompts, normally Ctrl-G
Definition: keymap.c:124
#define mutt_array_size(x)
Definition: memory.h:36
#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 901 of file keymap.c.

902 {
903  size_t len = 0;
904  for (; *str; str++)
905  {
906  const char *key = km_keyname(*str);
907  size_t keylen = mutt_str_len(key);
908 
909  mutt_str_copy(buf, key, buflen);
910  buf += keylen;
911  buflen -= keylen;
912  len += keylen;
913  }
914 
915  return len;
916 }
static const char * km_keyname(int c)
Get the human name for a key.
Definition: keymap.c:821
+ 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 926 of file keymap.c.

927 {
928  if (!map)
929  return 0;
930 
931  int p = 0;
932 
933  while (true)
934  {
935  mutt_str_copy(s, km_keyname(map->keys[p]), len);
936  const size_t l = mutt_str_len(s);
937  len -= l;
938 
939  if ((++p >= map->len) || !len)
940  return 1;
941 
942  s += l;
943  }
944 
945  /* not reached */
946 }
+ 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 954 of file keymap.c.

955 {
956  struct Keymap *np = NULL;
957  STAILQ_FOREACH(np, &Keymaps[mtype], entries)
958  {
959  if (np->op == func)
960  break;
961  }
962  return np;
963 }
+ 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 974 of file keymap.c.

975 {
976  for (int j = 0; ExtKeys[j].name; j++)
977  {
978  if (strcasecmp(key, ExtKeys[j].name) == 0)
979  return ExtKeys[j].sym;
980  }
981  return 0;
982 }
static const struct Extkey ExtKeys[]
Definition: keymap.c:137
const char * sym
Curses key name.
Definition: keymap.c:134
const char * name
NeoMutt key name.
Definition: keymap.c:133
+ 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 994 of file keymap.c.

995 {
996 #ifdef HAVE_USE_EXTENDED_NAMES
997  use_extended_names(true);
998 
999  for (int j = 0; KeyNames[j].name; j++)
1000  {
1001  if (KeyNames[j].value == -1)
1002  {
1003  const char *keyname = find_ext_name(KeyNames[j].name);
1004 
1005  if (keyname)
1006  {
1007  char *s = tigetstr((char *) keyname);
1008  if (s && ((long) (s) != -1))
1009  {
1010  int code = key_defined(s);
1011  if (code > 0)
1012  KeyNames[j].value = code;
1013  }
1014  }
1015  }
1016  }
1017 #endif
1018 }
static const char * find_ext_name(const char *key)
Find the curses name for a key.
Definition: keymap.c:974
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 1023 of file keymap.c.

1024 {
1025  memset(Keymaps, 0, sizeof(struct KeymapList) * MENU_MAX);
1026 
1029 #ifdef USE_AUTOCRYPT
1031 #endif
1037 #ifdef MIXMASTER
1039 #endif
1043 
1048 
1049 #ifdef CRYPT_BACKEND_GPGME
1052 #endif
1053 }
const struct MenuOpSeq AutocryptAcctDefaultBindings[]
Key bindings for the Autocrypt Account.
Definition: functions.c:794
const struct MenuOpSeq PostDefaultBindings[]
Key bindings for the Postpone Menu.
Definition: functions.c:1224
const struct MenuOpSeq EditorDefaultBindings[]
Key bindings for the Editor Menu.
Definition: functions.c:907
const struct MenuOpSeq QueryDefaultBindings[]
Key bindings for the external Query Menu.
Definition: functions.c:1234
const struct MenuOpSeq BrowserDefaultBindings[]
Key bindings for the file Browser Menu.
Definition: functions.c:807
const struct MenuOpSeq AliasDefaultBindings[]
Key bindings for the Alias Menu.
Definition: functions.c:748
const struct MenuOpSeq PagerDefaultBindings[]
Key bindings for the Pager Menu.
Definition: functions.c:1110
const struct MenuOpSeq GenericDefaultBindings[]
Key bindings for the Generic Menu.
Definition: functions.c:945
const struct MenuOpSeq AttachDefaultBindings[]
Key bindings for the Attachment Menu.
Definition: functions.c:763
const struct MenuOpSeq IndexDefaultBindings[]
Key bindings for the Index Menu.
Definition: functions.c:994
const struct MenuOpSeq MixDefaultBindings[]
Key bindings for the Mixmaster Menu.
Definition: functions.c:1090
const struct MenuOpSeq PgpDefaultBindings[]
Key bindings for the Pgp Menu.
Definition: functions.c:1214
const struct MenuOpSeq ComposeDefaultBindings[]
Key bindings for the Compose Menu.
Definition: functions.c:844
const struct MenuOpSeq SmimeDefaultBindings[]
Key bindings for the Smime Menu.
Definition: functions.c:1249
static void create_bindings(const struct MenuOpSeq *map, enum MenuType mtype)
Attach a set of keybindings to a Menu.
Definition: keymap.c:805
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:91
#define WithCrypto
Definition: lib.h:116
@ MENU_KEY_SELECT_PGP
Select a PGP key.
Definition: type.h:47
@ MENU_INDEX
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 1059 of file keymap.c.

1060 {
1061  char buf[128];
1062  int p, op;
1063 
1064  struct Keymap *key = km_find_func(mtype, OP_HELP);
1065  if (!key && (mtype != MENU_EDITOR) && (mtype != MENU_PAGER))
1066  key = km_find_func(MENU_GENERIC, OP_HELP);
1067  if (!key)
1068  {
1069  mutt_error(_("Key is not bound"));
1070  return;
1071  }
1072 
1073  /* Make sure the key is really the help key in this menu.
1074  *
1075  * OP_END_COND is used as a barrier to ensure nothing extra
1076  * is left in the unget buffer.
1077  *
1078  * Note that km_expand_key() + tokenize_unget_string() should
1079  * not be used here: control sequences are expanded to a form
1080  * (e.g. "^H") not recognized by km_dokey(). */
1081  mutt_unget_op(OP_END_COND);
1082  p = key->len;
1083  while (p--)
1084  mutt_unget_ch(key->keys[p]);
1085 
1086  /* Note, e.g. for the index menu:
1087  * bind generic ? noop
1088  * bind generic ,a help
1089  * bind index ,ab quit
1090  * The index keybinding shadows the generic binding.
1091  * OP_END_COND will be read and returned as the op.
1092  *
1093  * bind generic ? noop
1094  * bind generic dq help
1095  * bind index d delete-message
1096  * OP_DELETE will be returned as the op, leaving "q" + OP_END_COND
1097  * in the unget buffer.
1098  */
1099  op = km_dokey(mtype);
1100  if (op != OP_END_COND)
1102  if (op != OP_HELP)
1103  {
1104  mutt_error(_("Key is not bound"));
1105  return;
1106  }
1107 
1108  km_expand_key(buf, sizeof(buf), key);
1109  mutt_error(_("Key is not bound. Press '%s' for help."), buf);
1110 }
void mutt_unget_op(int op)
Return an operation to the input buffer.
Definition: curs_lib.c:533
void mutt_flush_unget_to_endcond(void)
Clear entries from UngetKeyEvents.
Definition: curs_lib.c:585
struct Keymap * km_find_func(enum MenuType mtype, int func)
Find a function's mapping in a Menu.
Definition: keymap.c:954
int km_dokey(enum MenuType mtype)
Determine what a keypress should do.
Definition: keymap.c:795
+ 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 1143 of file keymap.c.

1145 {
1146  struct Buffer buf;
1147  int i = 0;
1148  char *q = NULL;
1149 
1150  mutt_buffer_init(&buf);
1151 
1152  /* menu name */
1154  char *p = buf.data;
1155  if (MoreArgs(s))
1156  {
1157  while (i < max_menus)
1158  {
1159  q = strchr(p, ',');
1160  if (q)
1161  *q = '\0';
1162 
1163  int val = mutt_map_get_value(p, MenuNames);
1164  if (val == -1)
1165  {
1166  mutt_buffer_printf(err, _("%s: no such menu"), p);
1167  goto error;
1168  }
1169  mtypes[i] = val;
1170  i++;
1171  if (q)
1172  p = q + 1;
1173  else
1174  break;
1175  }
1176  *num_menus = i;
1177  /* key sequence */
1179 
1180  if (buf.data[0] == '\0')
1181  {
1182  mutt_buffer_printf(err, _("%s: null key sequence"), bind ? "bind" : "macro");
1183  }
1184  else if (MoreArgs(s))
1185  return buf.data;
1186  }
1187  else
1188  {
1189  mutt_buffer_printf(err, _("%s: too few arguments"), bind ? "bind" : "macro");
1190  }
1191 error:
1192  FREE(&buf.data);
1193  return NULL;
1194 }
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:48
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:158
#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:273
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:67
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 MenuFuncOp funcs,
struct Buffer err 
)
static

Try to make a key binding.

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

Definition at line 1143 of file keymap.c.

1207 {
1208  for (int i = 0; funcs[i].name; i++)
1209  {
1210  if (mutt_str_equal(func, funcs[i].name))
1211  {
1212  return km_bindkey_err(key, mtype, funcs[i].op, err);
1213  }
1214  }
1215  if (err)
1216  {
1217  mutt_buffer_printf(err, _("Function '%s' not available for menu '%s'"),
1218  func, mutt_map_get_name(mtype, MenuNames));
1219  }
1220  return MUTT_CMD_ERROR; /* Couldn't find an existing function with this name */
1221 }
@ 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:784

◆ km_get_table()

const struct MenuFuncOp* km_get_table ( enum MenuType  mtype)

Lookup a Menu's functions.

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

Definition at line 1228 of file keymap.c.

1229 {
1230  switch (mtype)
1231  {
1232  case MENU_ALIAS:
1233  return OpAlias;
1234  case MENU_ATTACH:
1235  return OpAttach;
1236 #ifdef USE_AUTOCRYPT
1237  case MENU_AUTOCRYPT_ACCT:
1238  return OpAutocrypt;
1239 #endif
1240  case MENU_COMPOSE:
1241  return OpCompose;
1242  case MENU_EDITOR:
1243  return OpEditor;
1244  case MENU_FOLDER:
1245  return OpBrowser;
1246  case MENU_GENERIC:
1247  return OpGeneric;
1248  case MENU_INDEX:
1249  return OpIndex;
1250 #ifdef CRYPT_BACKEND_GPGME
1251  case MENU_KEY_SELECT_PGP:
1252  return OpPgp;
1253  case MENU_KEY_SELECT_SMIME:
1254  return OpSmime;
1255 #endif
1256 #ifdef MIXMASTER
1257  case MENU_MIX:
1258  return OpMix;
1259 #endif
1260  case MENU_PAGER:
1261  return OpPager;
1262  case MENU_PGP:
1263  return (WithCrypto & APPLICATION_PGP) ? OpPgp : NULL;
1264  case MENU_POSTPONE:
1265  return OpPostpone;
1266  case MENU_QUERY:
1267  return OpQuery;
1268  default:
1269  return NULL;
1270  }
1271 }
const struct MenuFuncOp OpQuery[]
Functions for the external Query Menu.
Definition: functions.c:721
const struct MenuFuncOp OpMix[]
Functions for the Mixmaster Menu.
Definition: functions.c:514
const struct MenuFuncOp OpAttach[]
Functions for the Attachment Menu.
Definition: functions.c:69
const struct MenuFuncOp OpIndex[]
Functions for the Index Menu.
Definition: functions.c:349
const struct MenuFuncOp OpCompose[]
Functions for the Compose Menu.
Definition: functions.c:177
const struct MenuFuncOp OpSmime[]
Functions for the Smime Menu.
Definition: functions.c:736
const struct MenuFuncOp OpBrowser[]
Functions for the file Browser Menu.
Definition: functions.c:123
const struct MenuFuncOp OpAutocrypt[]
Functions for the Autocrypt Account.
Definition: functions.c:110
const struct MenuFuncOp OpPager[]
Functions for the Pager Menu.
Definition: functions.c:529
const struct MenuFuncOp OpEditor[]
Functions for the Editor Menu.
Definition: functions.c:254
const struct MenuFuncOp OpPgp[]
Functions for the Pgp Menu.
Definition: functions.c:701
const struct MenuFuncOp OpPostpone[]
Functions for the Postpone Menu.
Definition: functions.c:711
const struct MenuFuncOp OpAlias[]
Functions for the Alias Menu.
Definition: functions.c:55
+ 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 1375 of file keymap.c.

1376 {
1377  char *menu_names_dup = mutt_str_dup(s);
1378  char *marker = menu_names_dup;
1379  char *menu_name = NULL;
1380 
1381  while ((menu_name = mutt_str_sep(&marker, ",")))
1382  {
1383  int value = mutt_map_get_value(menu_name, MenuNames);
1384  if (value == -1)
1385  {
1386  mutt_buffer_printf(err, _("%s: no such menu"), menu_name);
1387  break;
1388  }
1389  else
1390  menus[value] = true;
1391  }
1392 
1393  FREE(&menu_names_dup);
1394  return NULL;
1395 }
char * mutt_str_sep(char **stringp, const char *delim)
Find first occurance of any of delim characters in *stringp.
Definition: string.c:183
+ 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 1404 of file keymap.c.

1405 {
1406  struct Keymap *np = NULL, *tmp = NULL;
1407 
1408  STAILQ_FOREACH_SAFE(np, km_list, entries, tmp)
1409  {
1410  if (((mode & MUTT_UNBIND) && !np->macro) || ((mode & MUTT_UNMACRO) && np->macro))
1411  {
1412  STAILQ_REMOVE(km_list, np, Keymap, entries);
1413  mutt_keymap_free(&np);
1414  }
1415  }
1416 }
#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 1636 of file keymap.c.

1637 {
1638  int ch;
1639 
1640  struct MuttWindow *win = msgwin_get_window();
1641  if (!win)
1642  return;
1643 
1645  mutt_window_mvprintw(win, 0, 0, _("Enter keys (%s to abort): "), km_keyname(AbortKey));
1648  do
1649  {
1650  ch = getch();
1651  if ((ch != ERR) && (ch != AbortKey))
1652  {
1653  mutt_message(_("Char = %s, Octal = %o, Decimal = %d"), km_keyname(ch), ch, ch);
1654  mutt_window_move(win, 0, 0);
1655  }
1656  } while (ch != ERR && ch != AbortKey);
1657  mutt_curses_set_cursor(cursor);
1658 
1659  mutt_flushinp();
1660  mutt_clear_error();
1661 }
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:53
@ MT_COLOR_PROMPT
Question/user input.
Definition: color.h:56
#define mutt_message(...)
Definition: logging.h:86
struct MuttWindow * msgwin_get_window(void)
Get the Message Window pointer.
Definition: msgwin.c:258
enum MuttCursorState mutt_curses_set_cursor(enum MuttCursorState state)
Set the cursor state.
Definition: mutt_curses.c:96
struct AttrColor * mutt_curses_set_normal_backed_color_by_id(enum ColorId cid)
Set the colour and attributes by the colour id.
Definition: mutt_curses.c:65
struct AttrColor * mutt_curses_set_color_by_id(enum ColorId cid)
Set the colour and attributes by the colour id.
Definition: mutt_curses.c:81
MuttCursorState
Cursor states for mutt_curses_set_cursor()
Definition: mutt_curses.h:52
@ MUTT_CURSOR_VISIBLE
Display a normal cursor.
Definition: mutt_curses.h:54
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:74
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:293
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:322
+ Here is the call graph for this function:

◆ mutt_keys_free()

void mutt_keys_free ( void  )

Free the key maps.

Definition at line 1666 of file keymap.c.

1667 {
1668  for (int i = 0; i < MENU_MAX; i++)
1669  {
1671  }
1672 }
static void mutt_keymaplist_free(struct KeymapList *km_list)
Free a List of Keymaps.
Definition: keymap.c:192
+ 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.

◆ AbortKey

keycode_t AbortKey

code of key to abort prompts, normally Ctrl-G

key to abort edits etc, normally Ctrl-G

Definition at line 124 of file keymap.c.

◆ Keymaps

struct KeymapList Keymaps[MENU_MAX]

Array of Keymap keybindings, one for each Menu.

Definition at line 124 of file keymap.c.

◆ ExtKeys

const struct Extkey ExtKeys[]
static

Definition at line 124 of file keymap.c.