NeoMutt  2022-04-29-249-gaae397
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:
+ Here is the caller 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] = { 0 };
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:652
+ 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}
+ Here is the caller graph for this function:

◆ 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 361 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] = { 0 };
401 char new_binding[MAX_SEQ] = { 0 };
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 mutt_buffer_printf(err, 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}
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:168
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
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:928
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
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
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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 458 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 call graph for this function:
+ 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 471 of file keymap.c.

473{
474 return km_bind_err(s, mtype, op, NULL, NULL, err);
475}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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 484 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 call graph for this function:
+ 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:567
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:524
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:1230
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:
+ Here is the caller 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 611 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 */
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:592
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:521
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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 637 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)
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;
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 {
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:543
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition: curs_lib.c:561
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
static void generic_tokenize_push_string(char *s, void(*generic_push)(int, int))
Parse and queue a 'push' command.
Definition: keymap.c:538
const char * mutt_get_func(const struct MenuFuncOp *funcs, int op)
Get the name of a function.
Definition: keymap.c:518
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 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 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 903 of file keymap.c.

904{
905 size_t len = 0;
906 for (; *str; str++)
907 {
908 const char *key = km_keyname(*str);
909 size_t keylen = mutt_str_len(key);
910
911 mutt_str_copy(buf, key, buflen);
912 buf += keylen;
913 buflen -= keylen;
914 len += keylen;
915 }
916
917 return len;
918}
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:
+ Here is the caller 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 928 of file keymap.c.

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

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

977{
978 for (int j = 0; ExtKeys[j].name; j++)
979 {
980 if (strcasecmp(key, ExtKeys[j].name) == 0)
981 return ExtKeys[j].sym;
982 }
983 return 0;
984}
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 996 of file keymap.c.

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

1026{
1027 memset(Keymaps, 0, sizeof(struct KeymapList) * MENU_MAX);
1028
1031#ifdef USE_AUTOCRYPT
1033#endif
1039#ifdef MIXMASTER
1041#endif
1045
1050
1051#ifdef CRYPT_BACKEND_GPGME
1054#endif
1055}
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 1061 of file keymap.c.

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

1147{
1148 struct Buffer buf;
1149 int i = 0;
1150 char *q = NULL;
1151
1152 mutt_buffer_init(&buf);
1153
1154 /* menu name */
1156 char *p = buf.data;
1157 if (MoreArgs(s))
1158 {
1159 while (i < max_menus)
1160 {
1161 q = strchr(p, ',');
1162 if (q)
1163 *q = '\0';
1164
1165 int val = mutt_map_get_value(p, MenuNames);
1166 if (val == -1)
1167 {
1168 mutt_buffer_printf(err, _("%s: no such menu"), p);
1169 goto error;
1170 }
1171 mtypes[i] = val;
1172 i++;
1173 if (q)
1174 p = q + 1;
1175 else
1176 break;
1177 }
1178 *num_menus = i;
1179 /* key sequence */
1181
1182 if (buf.data[0] == '\0')
1183 {
1184 mutt_buffer_printf(err, _("%s: null key sequence"), bind ? "bind" : "macro");
1185 }
1186 else if (MoreArgs(s))
1187 return buf.data;
1188 }
1189 else
1190 {
1191 mutt_buffer_printf(err, _("%s: too few arguments"), bind ? "bind" : "macro");
1192 }
1193error:
1194 FREE(&buf.data);
1195 return NULL;
1196}
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:52
#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:
+ Here is the caller 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 1207 of file keymap.c.

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

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

1231{
1232 switch (mtype)
1233 {
1234 case MENU_ALIAS:
1235 return OpAlias;
1236 case MENU_ATTACH:
1237 return OpAttach;
1238#ifdef USE_AUTOCRYPT
1240 return OpAutocrypt;
1241#endif
1242 case MENU_COMPOSE:
1243 return OpCompose;
1244 case MENU_EDITOR:
1245 return OpEditor;
1246 case MENU_FOLDER:
1247 return OpBrowser;
1248 case MENU_GENERIC:
1249 return OpGeneric;
1250 case MENU_INDEX:
1251 return OpIndex;
1252#ifdef CRYPT_BACKEND_GPGME
1254 return OpPgp;
1256 return OpSmime;
1257#endif
1258#ifdef MIXMASTER
1259 case MENU_MIX:
1260 return OpMix;
1261#endif
1262 case MENU_PAGER:
1263 return OpPager;
1264 case MENU_PGP:
1265 return (WithCrypto & APPLICATION_PGP) ? OpPgp : NULL;
1266 case MENU_POSTPONE:
1267 return OpPostpone;
1268 case MENU_QUERY:
1269 return OpQuery;
1270 default:
1271 return NULL;
1272 }
1273}
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 1377 of file keymap.c.

1378{
1379 char *menu_names_dup = mutt_str_dup(s);
1380 char *marker = menu_names_dup;
1381 char *menu_name = NULL;
1382
1383 while ((menu_name = mutt_str_sep(&marker, ",")))
1384 {
1385 int value = mutt_map_get_value(menu_name, MenuNames);
1386 if (value == -1)
1387 {
1388 mutt_buffer_printf(err, _("%s: no such menu"), menu_name);
1389 break;
1390 }
1391 else
1392 menus[value] = true;
1393 }
1394
1395 FREE(&menu_names_dup);
1396 return NULL;
1397}
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:
+ Here is the caller 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 1406 of file keymap.c.

1407{
1408 struct Keymap *np = NULL, *tmp = NULL;
1409
1410 STAILQ_FOREACH_SAFE(np, km_list, entries, tmp)
1411 {
1412 if (((mode & MUTT_UNBIND) && !np->macro) || ((mode & MUTT_UNMACRO) && np->macro))
1413 {
1414 STAILQ_REMOVE(km_list, np, Keymap, entries);
1415 mutt_keymap_free(&np);
1416 }
1417 }
1418}
#define MUTT_UNBIND
Definition: keymap.h:33
#define MUTT_UNMACRO
Definition: keymap.h:34
+ Here is the call graph for this function:
+ Here is the caller 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 1638 of file keymap.c.

1639{
1640 int ch;
1641
1642 struct MuttWindow *win = msgwin_get_window();
1643 if (!win)
1644 return;
1645
1647 mutt_window_mvprintw(win, 0, 0, _("Enter keys (%s to abort): "), km_keyname(AbortKey));
1650 do
1651 {
1652 ch = getch();
1653 if ((ch != ERR) && (ch != AbortKey))
1654 {
1655 mutt_message(_("Char = %s, Octal = %o, Decimal = %d"), km_keyname(ch), ch, ch);
1656 mutt_window_move(win, 0, 0);
1657 }
1658 } while (ch != ERR && ch != AbortKey);
1659 mutt_curses_set_cursor(cursor);
1660
1661 mutt_flushinp();
1663}
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:54
@ MT_COLOR_PROMPT
Question/user input.
Definition: color.h:57
#define mutt_message(...)
Definition: logging.h:86
struct MuttWindow * msgwin_get_window(void)
Get the Message Window pointer.
Definition: msgwin.c:260
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:
+ Here is the caller graph for this function:

◆ mutt_keys_free()

void mutt_keys_free ( void  )

Free the key maps.

Definition at line 1668 of file keymap.c.

1669{
1670 for (int i = 0; i < MENU_MAX; i++)
1671 {
1673 }
1674}
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 62 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 126 of file keymap.c.

◆ ExtKeys

const struct Extkey ExtKeys[]
static

Definition at line 137 of file keymap.c.