NeoMutt  2025-12-11-980-ge38c27
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
get.h File Reference

Get a key from the user. More...

#include <stdint.h>
#include "mutt/lib.h"
#include "menu/lib.h"
#include "keymap.h"
+ Include dependency graph for get.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  KeyEvent
 An event such as a keypress. More...
 
struct  KeymapMatch
 Result of Matching Keybinding. More...
 

Macros

#define KEY_COUNT_MAX_DIGITS   6
 Maximum number of digits in a key count prefix, e.g. 123j
 
#define KEY_SEQ_MAX_LEN   8
 Maximum number of keys in a key sequence, e.g. abc
 

Typedefs

typedef uint8_t GetChFlags
 
typedef uint8_t KeyGatherFlags
 
typedef uint8_t MenuFuncFlags
 

Enumerations

enum  GetChFlag { GETCH_NONE = 0 , GETCH_IGNORE_MACRO = 1U << 0 , GETCH_NO_COUNTER = 1U << 1 , GETCH_NO_FEEDBACK = 1U << 2 }
 Flags for mutt_getch(), e.g. More...
 
enum  KeyGatherFlag { KEY_GATHER_NO_MATCH = 0 , KEY_GATHER_MATCH = 1U << 0 , KEY_GATHER_LONGER = 1U << 1 }
 Flags for gather_functions(), e.g. More...
 
enum  MenuFuncFlag { MFF_NONE = 0 , MFF_DEPRECATED = 1U << 1 }
 Menu function property flags. More...
 

Functions

 ARRAY_HEAD (KeyEventArray, struct KeyEvent)
 
 ARRAY_HEAD (KeymapMatchArray, struct KeymapMatch)
 
void array_add (struct KeyEventArray *a, int ch, int op)
 Add an event to the end of the array.
 
struct KeyEventarray_pop (struct KeyEventArray *a)
 Remove an event from the array.
 
void array_to_endcond (struct KeyEventArray *a)
 Clear the array until an OP_END_COND.
 
KeyGatherFlags gather_functions (const struct MenuDefinition *md, const keycode_t *keys, int key_len, struct KeymapMatchArray *kma)
 Find functions whose keybindings match.
 
void generic_tokenize_push_string (char *s)
 Parse and queue a 'push' command.
 
struct KeyEvent km_dokey (const struct MenuDefinition *md, GetChFlags flags)
 Determine what a keypress should do.
 
void km_error_key (const struct MenuDefinition *md)
 Handle an unbound key sequence.
 
void mutt_flushinp (void)
 MacroEvents moved to KeyModuleData UngetKeyEvents moved to KeyModuleData.
 
void mutt_flush_macro_to_endcond (void)
 Drop a macro from the input buffer.
 
struct KeyEvent mutt_getch (GetChFlags flags)
 Read a character from the input buffer.
 
int mutt_monitor_getch (void)
 
void mutt_push_macro_event (int ch, int op)
 Add the character/operation to the macro buffer.
 
void mutt_push_macro_repeated (char *macro, int count)
 Push a macro string into the input queue, optionally repeated.
 
void mutt_unget_ch (int ch)
 Return a keystroke to the input buffer.
 
void mutt_unget_op (int op)
 Return an operation to the input buffer.
 

Detailed Description

Get a key from the user.

Authors
  • Richard Russon

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 get.h.

Macro Definition Documentation

◆ KEY_COUNT_MAX_DIGITS

#define KEY_COUNT_MAX_DIGITS   6

Maximum number of digits in a key count prefix, e.g. 123j

Definition at line 46 of file get.h.

◆ KEY_SEQ_MAX_LEN

#define KEY_SEQ_MAX_LEN   8

Maximum number of keys in a key sequence, e.g. abc

Definition at line 48 of file get.h.

Typedef Documentation

◆ GetChFlags

typedef uint8_t GetChFlags

Definition at line 43 of file get.h.

◆ KeyGatherFlags

typedef uint8_t KeyGatherFlags

Definition at line 59 of file get.h.

◆ MenuFuncFlags

typedef uint8_t MenuFuncFlags

Definition at line 69 of file get.h.

Enumeration Type Documentation

◆ GetChFlag

enum GetChFlag

Flags for mutt_getch(), e.g.

GETCH_NONE

Enumerator
GETCH_NONE 

No flags are set.

GETCH_IGNORE_MACRO 

Don't use MacroEvents.

GETCH_NO_COUNTER 

km_dokey(): disable numeric count prefix parsing

GETCH_NO_FEEDBACK 

km_dokey(): suppress key progress notifications

Definition at line 36 of file get.h.

37{
38 GETCH_NONE = 0,
39 GETCH_IGNORE_MACRO = 1U << 0,
40 GETCH_NO_COUNTER = 1U << 1,
41 GETCH_NO_FEEDBACK = 1U << 2,
42};
@ GETCH_NONE
No flags are set.
Definition get.h:38
@ GETCH_IGNORE_MACRO
Don't use MacroEvents.
Definition get.h:39
@ GETCH_NO_FEEDBACK
km_dokey(): suppress key progress notifications
Definition get.h:41
@ GETCH_NO_COUNTER
km_dokey(): disable numeric count prefix parsing
Definition get.h:40

◆ KeyGatherFlag

Flags for gather_functions(), e.g.

KEY_GATHER_NO_MATCH

Enumerator
KEY_GATHER_NO_MATCH 

No bindings match the search string.

KEY_GATHER_MATCH 

Binding matches the search string.

KEY_GATHER_LONGER 

No bindings match, but longer strings might.

Definition at line 53 of file get.h.

54{
56 KEY_GATHER_MATCH = 1U << 0,
57 KEY_GATHER_LONGER = 1U << 1,
58};
@ KEY_GATHER_NO_MATCH
No bindings match the search string.
Definition get.h:55
@ KEY_GATHER_LONGER
No bindings match, but longer strings might.
Definition get.h:57
@ KEY_GATHER_MATCH
Binding matches the search string.
Definition get.h:56

◆ MenuFuncFlag

Menu function property flags.

Enumerator
MFF_NONE 

No flags are set.

MFF_DEPRECATED 

Function is deprecated.

Definition at line 64 of file get.h.

65{
66 MFF_NONE = 0,
67 MFF_DEPRECATED = 1U << 1,
68};
@ MFF_DEPRECATED
Function is deprecated.
Definition get.h:67
@ MFF_NONE
No flags are set.
Definition get.h:66

Function Documentation

◆ ARRAY_HEAD() [1/2]

ARRAY_HEAD ( KeyEventArray ,
struct KeyEvent  )

◆ ARRAY_HEAD() [2/2]

ARRAY_HEAD ( KeymapMatchArray ,
struct KeymapMatch  )
+ Here is the call graph for this function:

◆ array_add()

void array_add ( struct KeyEventArray * a,
int ch,
int op )

Add an event to the end of the array.

Parameters
aArray
chCharacter
opOperation, e.g. OP_DELETE

Definition at line 120 of file get.c.

121{
122 struct KeyEvent event = { ch, op, 0 };
123 ARRAY_ADD(a, event);
124}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
An event such as a keypress.
Definition get.h:75
int op
Function opcode, e.g. OP_HELP.
Definition get.h:77
int ch
Raw key pressed.
Definition get.h:76
+ Here is the caller graph for this function:

◆ array_pop()

struct KeyEvent * array_pop ( struct KeyEventArray * a)

Remove an event from the array.

Parameters
aArray
Return values
ptrEvent

Definition at line 102 of file get.c.

103{
104 if (ARRAY_EMPTY(a))
105 {
106 return NULL;
107 }
108
109 struct KeyEvent *event = ARRAY_LAST(a);
110 ARRAY_SHRINK(a, 1);
111 return event;
112}
#define ARRAY_LAST(head)
Convenience method to get the last element.
Definition array.h:145
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
#define ARRAY_SHRINK(head, n)
Mark a number of slots at the end of the array as unused.
Definition array.h:174
+ Here is the caller graph for this function:

◆ array_to_endcond()

void array_to_endcond ( struct KeyEventArray * a)

Clear the array until an OP_END_COND.

Parameters
aArray

Definition at line 130 of file get.c.

131{
132 while (!ARRAY_EMPTY(a))
133 {
134 if (array_pop(a)->op == OP_END_COND)
135 {
136 return;
137 }
138 }
139}
struct KeyEvent * array_pop(struct KeyEventArray *a)
Remove an event from the array.
Definition get.c:102
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ gather_functions()

KeyGatherFlags gather_functions ( const struct MenuDefinition * md,
const keycode_t * keys,
int key_len,
struct KeymapMatchArray * kma )

Find functions whose keybindings match.

Parameters
[in]mdMenu Definition of all valid functions
[in]keysUser-entered key string to match
[in]key_lenLength of key string
[out]kmaArray for the results
Return values
flagsResults, e.g. KEY_GATHER_MATCH

Definition at line 428 of file get.c.

430{
431 if (!md || !keys || !kma)
432 return 0;
433
434 struct SubMenu **smp = NULL;
436
437 ARRAY_FOREACH(smp, &md->submenus)
438 {
439 struct Keymap *km = NULL;
440
441 STAILQ_FOREACH(km, &(*smp)->keymaps, entries)
442 {
443 if (key_len > km->len)
444 continue;
445
446 bool match = true;
447
448 for (int i = 0; i < key_len; i++)
449 {
450 if (keys[i] != km->keys[i])
451 {
452 match = false;
453 break;
454 }
455 }
456
457 if (match)
458 {
460 if (km->len == key_len)
461 fmatch = KEY_GATHER_MATCH;
462 else
463 fmatch = KEY_GATHER_LONGER;
464
465 flags |= fmatch;
466
467 struct KeymapMatch kmatch = { md->id, fmatch, km };
468 ARRAY_ADD(kma, kmatch);
469 }
470 }
471 }
472
473 return flags;
474}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
uint8_t KeyGatherFlags
Definition get.h:59
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
Result of Matching Keybinding.
Definition get.h:88
KeyGatherFlags flags
Flags, e.g. KEY_GATHER_MATCH.
Definition get.h:90
A keyboard mapping.
Definition keymap.h:43
keycode_t * keys
Key sequence.
Definition keymap.h:49
short len
Length of key sequence (unit: sizeof (keycode_t))
Definition keymap.h:48
struct SubMenuArray submenus
Parts making up the Menu.
Definition menudef.h:47
int id
Menu ID, e.g. MENU_ALIAS.
Definition menudef.h:45
Collection of related functions.
Definition menudef.h:33
+ Here is the caller graph for this function:

◆ generic_tokenize_push_string()

void generic_tokenize_push_string ( char * s)

Parse and queue a 'push' command.

Parameters
sString to push into the key queue

Parses s for <function> syntax and adds the whole sequence the macro buffer.

Definition at line 352 of file get.c.

353{
355 char *pp = NULL;
356 char *p = s + mutt_str_len(s) - 1;
357 size_t l;
358 int i;
359 int op = OP_NULL;
360
361 while (p >= s)
362 {
363 /* if we see something like "<PageUp>", look to see if it is a real
364 * function name and return the corresponding value */
365 if (*p == '>')
366 {
367 for (pp = p - 1; pp >= s && *pp != '<'; pp--)
368 ; // do nothing
369
370 if (pp >= s)
371 {
372 i = parse_fkey(pp);
373 if (i > 0)
374 {
375 mutt_push_macro_event(KEY_F(i), 0);
376 p = pp - 1;
377 continue;
378 }
379
380 l = p - pp + 1;
381 for (i = 0; mod_data->key_names[i].name; i++)
382 {
383 if (mutt_istrn_equal(pp, mod_data->key_names[i].name, l))
384 break;
385 }
386 if (mod_data->key_names[i].name)
387 {
388 /* found a match */
389 mutt_push_macro_event(mod_data->key_names[i].value, 0);
390 p = pp - 1;
391 continue;
392 }
393
394 /* See if it is a valid command
395 * skip the '<' and the '>' when comparing */
396 struct Buffer *buf = buf_pool_get();
397 buf_strcpy_n(buf, pp + 1, l - 2);
398
399 for (enum MenuType j = 0; j < MENU_MAX; j++)
400 {
401 op = km_get_op_menu(j, buf_string(buf));
402 if (op != OP_NULL)
403 break;
404 }
405
406 buf_pool_release(&buf);
407
408 if (op != OP_NULL)
409 {
411 p = pp - 1;
412 continue;
413 }
414 }
415 }
416 mutt_push_macro_event((unsigned char) *p--, 0); /* independent 8 bits chars */
417 }
418}
size_t buf_strcpy_n(struct Buffer *buf, const char *s, size_t len)
Copy a string into a Buffer.
Definition buffer.c:422
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition get.c:173
int parse_fkey(char *str)
Parse a function key string.
Definition keymap.c:284
int km_get_op_menu(int mtype, const char *func)
Get the OpCode for a Function from a Menu.
Definition menu.c:198
@ MODULE_ID_KEY
ModuleKey, Key mappings
Definition module_api.h:74
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:503
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:457
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:666
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
String manipulation buffer.
Definition buffer.h:36
Key private Module data.
Definition module_data.h:34
struct Mapping * key_names
Key name lookup table.
Definition module_data.h:41
int value
Integer value.
Definition mapping.h:35
const char * name
String value.
Definition mapping.h:34
Container for Accounts, Notifications.
Definition neomutt.h:41
MenuType
Types of GUI selections.
Definition type.h:33
@ MENU_MAX
Definition type.h:53
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ km_dokey()

struct KeyEvent km_dokey ( const struct MenuDefinition * md,
GetChFlags flags )

Determine what a keypress should do.

Parameters
mdMenu Definition
flagsFlags, e.g. GETCH_IGNORE_MACRO
Return values
ptrEvent

Definition at line 519 of file get.c.

520{
521 struct KeyEvent event = { 0, OP_NULL, 0 };
522 enum DokeyState state = DKS_START;
523 int count = 0;
524 int count_digits = 0;
525 int key_len = 0;
526 struct Keymap *pending_exact = NULL;
527 bool feedback_active = false;
529
530 const short c_key_timeout_idle = cs_subset_number(NeoMutt->sub, "key_timeout_idle");
531 const short c_key_timeout_progress = cs_subset_number(NeoMutt->sub, "key_timeout_partial");
532
533 if (!md)
534 return event;
535
536 for (int n = 0; n < MaxKeyLoop; n++)
537 {
538 const int timeout_ms = (state == DKS_START) ? c_key_timeout_idle : c_key_timeout_progress;
539 event = mutt_getch_timeout(flags, timeout_ms);
540
541 // abort, timeout, repaint
542 if (event.op < OP_NULL)
543 {
544 if (event.op == OP_TIMEOUT)
545 {
546 if ((state == DKS_NEED_MORE) && pending_exact)
547 {
548 if (pending_exact->op != OP_MACRO)
549 {
550 key_progress_notify(md, count, keys, key_len, flags);
551 key_progress_notify(md, 0, NULL, 0, flags);
552 return (struct KeyEvent) { 0, pending_exact->op, count };
553 }
554
555 if (flags & GETCH_IGNORE_MACRO)
556 {
557 key_progress_notify(md, 0, NULL, 0, flags);
558 return (struct KeyEvent) { 0, OP_NULL, 0 };
559 }
560
561 mutt_push_macro_repeated(pending_exact->macro, count_digits > 0 ? count : 0);
562 state = DKS_START;
563 count = 0;
564 count_digits = 0;
565 key_len = 0;
566 pending_exact = NULL;
567 memset(keys, 0, sizeof(keys));
568 feedback_active = false;
569 key_progress_notify(md, 0, NULL, 0, flags);
570 continue;
571 }
572 }
573
574 if (feedback_active || (state != DKS_START))
575 {
576 key_progress_notify(md, 0, NULL, 0, flags);
577 }
578 mutt_debug(LL_DEBUG3, "KEY: getch() %s\n", opcodes_get_name(event.op));
579 return event;
580 }
581
582 // macro op pushed into queue (e.g. from `exec`)
583 if (event.op > OP_NULL)
584 {
585 if (feedback_active || (state != DKS_START))
586 {
587 key_progress_notify(md, 0, NULL, 0, flags);
588 }
589 // Apply any count digits that arrived ahead of this op
590 // (e.g. "5<next-entry>" inside a macro body),
591 // preserving an explicit count already attached to the event.
592 if ((event.count == 0) && (count_digits > 0))
593 event.count = count;
594 return event;
595 }
596
597 mutt_debug(LL_DEBUG3, "KEY: getch() '%c'\n", isprint(event.ch) ? event.ch : '?');
598
599 // Check if digit keys have explicit bindings before using them as a counter
600 if (!(flags & GETCH_NO_COUNTER) && (state != DKS_NEED_MORE) &&
601 (event.ch >= '0') && (event.ch <= '9'))
602 {
603 keycode_t digit_key = event.ch;
604 struct KeymapMatchArray digit_kma = ARRAY_HEAD_INITIALIZER;
605 KeyGatherFlags digit_kgf = gather_functions(md, &digit_key, 1, &digit_kma);
606 bool digit_bound = (digit_kgf & KEY_GATHER_MATCH);
607 ARRAY_FREE(&digit_kma);
608
609 if (!digit_bound)
610 {
611 if (count_digits >= KEY_COUNT_MAX_DIGITS)
612 {
613 key_progress_notify(md, count, keys, key_len, flags);
614 key_progress_notify(md, 0, NULL, 0, flags);
615 return (struct KeyEvent) { event.ch, OP_NULL, 0 };
616 }
617
618 const int digit = event.ch - '0';
619 if ((count > (INT_MAX / 10)) ||
620 ((count == (INT_MAX / 10)) && (digit > (INT_MAX % 10))))
621 {
622 key_progress_notify(md, count, keys, key_len, flags);
623 key_progress_notify(md, 0, NULL, 0, flags);
624 return (struct KeyEvent) { event.ch, OP_NULL, 0 };
625 }
626
627 count = (count * 10) + digit;
628 count_digits++;
629 state = DKS_COUNTER;
630 feedback_active = true;
631 key_progress_notify(md, count, keys, key_len, flags);
632 continue;
633 }
634 }
635
636 if (key_len >= KEY_SEQ_MAX_LEN)
637 {
638 key_progress_notify(md, count, keys, key_len, flags);
639 key_progress_notify(md, 0, NULL, 0, flags);
640 return (struct KeyEvent) { event.ch, OP_NULL, 0 };
641 }
642
643 keys[key_len] = event.ch;
644 key_len++;
645
646 struct KeymapMatchArray kma = ARRAY_HEAD_INITIALIZER;
647 KeyGatherFlags kgf = gather_functions(md, keys, key_len, &kma);
648
649 mutt_debug(LL_DEBUG3, "KEY: flags = %x\n", kgf);
650
651 bool has_exact = false;
652 bool has_longer = false;
653 pending_exact = NULL;
654
655 struct KeymapMatch *kmatch = NULL;
656 ARRAY_FOREACH(kmatch, &kma)
657 {
658 if (kmatch->flags == KEY_GATHER_MATCH)
659 {
660 has_exact = true;
661 if (!pending_exact)
662 pending_exact = kmatch->keymap;
663 }
664 else if (kmatch->flags == KEY_GATHER_LONGER)
665 {
666 has_longer = true;
667 }
668 }
669
670 if (!has_exact && !has_longer)
671 {
672 key_progress_notify(md, count, keys, key_len, flags);
673 key_progress_notify(md, 0, NULL, 0, flags);
674 mutt_debug(LL_DEBUG3, "KEY: FAIL1: ('%c', %s)\n",
675 isprint(event.ch) ? event.ch : '?', opcodes_get_name(event.op));
676 ARRAY_FREE(&kma);
677 return event;
678 }
679
680 if (has_exact && has_longer)
681 {
682 state = DKS_NEED_MORE;
683 feedback_active = true;
684 key_progress_notify(md, count, keys, key_len, flags);
685 ARRAY_FREE(&kma);
686 continue;
687 }
688
689 if (!has_exact && has_longer)
690 {
691 state = DKS_NEED_MORE;
692 feedback_active = true;
693 key_progress_notify(md, count, keys, key_len, flags);
694 ARRAY_FREE(&kma);
695 continue;
696 }
697
698 if (has_exact && pending_exact)
699 {
700 struct Keymap *map = pending_exact;
701
702 if (map->op != OP_MACRO)
703 {
704 key_progress_notify(md, count, keys, key_len, flags);
705 key_progress_notify(md, 0, NULL, 0, flags);
706 mutt_debug(LL_DEBUG3, "KEY: SUCCESS: ('%c', %s)\n",
707 isprint(event.ch) ? event.ch : '?', opcodes_get_name(map->op));
708 ARRAY_FREE(&kma);
709 return (struct KeyEvent) { event.ch, map->op, count_digits > 0 ? count : 0 };
710 }
711
712 /* #GETCH_IGNORE_MACRO turns off processing the MacroEvents buffer
713 * in mutt_getch(). Generating new macro events during that time would
714 * result in undesired behavior once the option is turned off.
715 *
716 * Originally this returned -1, however that results in an unbuffered
717 * username or password prompt being aborted. Returning OP_NULL allows
718 * mw_get_field() to display the keybinding pressed instead.
719 *
720 * It may be unexpected for a macro's keybinding to be returned,
721 * but less so than aborting the prompt. */
722 if (flags & GETCH_IGNORE_MACRO)
723 {
724 key_progress_notify(md, 0, NULL, 0, flags);
725 ARRAY_FREE(&kma);
726 return (struct KeyEvent) { event.ch, OP_NULL, 0 };
727 }
728
729 mutt_push_macro_repeated(map->macro, count_digits > 0 ? count : 0);
730 state = DKS_START;
731 count = 0;
732 count_digits = 0;
733 key_len = 0;
734 pending_exact = NULL;
735 memset(keys, 0, sizeof(keys));
736 feedback_active = false;
737 key_progress_notify(md, 0, NULL, 0, flags);
738 ARRAY_FREE(&kma);
739 continue;
740 }
741
742 ARRAY_FREE(&kma);
743 }
744
745 key_progress_notify(md, 0, NULL, 0, flags);
747 mutt_error(_("Macro loop detected"));
748 return (struct KeyEvent) { '\0', OP_ABORT, 0 };
749}
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition array.h:58
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition helpers.c:143
int digit(const char *s)
KeyGatherFlags gather_functions(const struct MenuDefinition *md, const keycode_t *keys, int key_len, struct KeymapMatchArray *kma)
Find functions whose keybindings match.
Definition get.c:428
void mutt_push_macro_repeated(char *macro, int count)
Push a macro string into the input queue, optionally repeated.
Definition get.c:60
void mutt_flushinp(void)
MacroEvents moved to KeyModuleData UngetKeyEvents moved to KeyModuleData.
Definition get.c:81
static struct KeyEvent mutt_getch_timeout(GetChFlags flags, int timeout_ms)
Read a character from the input buffer with timeout.
Definition get.c:222
static const int MaxKeyLoop
XXX.
Definition get.c:51
DokeyState
Internal state for km_dokey()
Definition get.c:480
@ DKS_START
Initial state, no input received yet.
Definition get.c:481
@ DKS_COUNTER
Reading count prefix digits.
Definition get.c:482
@ DKS_NEED_MORE
Prefix matches an exact and/or longer keybinding.
Definition get.c:483
static void key_progress_notify(const struct MenuDefinition *md, int count, const keycode_t *keys, int key_len, GetChFlags flags)
Send key matching progress notification.
Definition get.c:494
#define KEY_COUNT_MAX_DIGITS
Maximum number of digits in a key count prefix, e.g. 123j
Definition get.h:46
#define KEY_SEQ_MAX_LEN
Maximum number of keys in a key sequence, e.g. abc
Definition get.h:48
#define mutt_error(...)
Definition logging2.h:94
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
short keycode_t
Type for key storage, the rest of neomutt works fine with int type.
Definition keymap.h:31
@ LL_DEBUG3
Log at debug level 3.
Definition logging2.h:47
#define _(a)
Definition message.h:28
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition opcodes.c:48
#define OP_TIMEOUT
1 second with no events
Definition opcodes.h:35
#define OP_ABORT
$abort_key pressed (Ctrl-G)
Definition opcodes.h:36
int count
Optional count prefix, e.g. 3 for 3j
Definition get.h:78
struct Keymap * keymap
Keymap defining bind or `macro.
Definition get.h:91
char * macro
Macro expansion (op == OP_MACRO)
Definition keymap.h:44
short op
Operation to perform.
Definition keymap.h:46
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ km_error_key()

void km_error_key ( const struct MenuDefinition * md)

Handle an unbound key sequence.

Parameters
mdMenu Definition

Definition at line 328 of file get.c.

329{
330 if (!md)
331 return;
332
333 struct Keymap *key = km_find_func(md, OP_HELP);
334 if (!key)
335 {
336 mutt_error(_("Key is not bound"));
337 return;
338 }
339
340 struct Buffer *buf = buf_pool_get();
341 keymap_expand_key(key, buf);
342 mutt_error(_("Key is not bound. Press '%s' for help."), buf_string(buf));
343 buf_pool_release(&buf);
344}
bool keymap_expand_key(struct Keymap *km, struct Buffer *buf)
Get the key string bound to a Keymap.
Definition keymap.c:247
struct Keymap * km_find_func(const struct MenuDefinition *md, int func)
Find a function's mapping in a Menu.
Definition menu.c:141
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_flushinp()

void mutt_flushinp ( void )

MacroEvents moved to KeyModuleData UngetKeyEvents moved to KeyModuleData.

Empty all the keyboard buffers

Definition at line 81 of file get.c.

82{
84 const size_t unget_count = ARRAY_SIZE(&mod_data->unget_key_events);
85 const size_t macro_count = ARRAY_SIZE(&mod_data->macro_events);
87 ARRAY_SHRINK(&mod_data->macro_events, ARRAY_SIZE(&mod_data->macro_events));
88
89 if ((unget_count + macro_count) > 0)
90 {
91 mutt_debug(LL_DEBUG1, "Flushed %zu queued key events (%zu unget, %zu macro)\n",
92 unget_count + macro_count, unget_count, macro_count);
93 }
94 flushinp();
95}
#define ARRAY_SIZE(head)
The number of elements stored.
Definition array.h:87
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
struct KeyEventArray macro_events
Macro event buffer.
Definition module_data.h:36
struct KeyEventArray unget_key_events
Unget key event buffer.
Definition module_data.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_flush_macro_to_endcond()

void mutt_flush_macro_to_endcond ( void )

Drop a macro from the input buffer.

All the macro text is deleted until an OP_END_COND command, or the buffer is empty.

Definition at line 185 of file get.c.

186{
188 array_to_endcond(&mod_data->macro_events);
189}
void array_to_endcond(struct KeyEventArray *a)
Clear the array until an OP_END_COND.
Definition get.c:130
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_getch()

struct KeyEvent mutt_getch ( GetChFlags flags)

Read a character from the input buffer.

Parameters
flagsFlags, e.g. GETCH_IGNORE_MACRO
Return values
objKeyEvent to process

The priority for reading events is:

  1. UngetKeyEvents buffer
  2. MacroEvents buffer
  3. Keyboard

This function can return:

  • Abort { 0, OP_ABORT, 0 }
  • Repaint { 0, OP_REPAINT, 0 }
  • Timeout { 0, OP_TIMEOUT, 0 }

Definition at line 319 of file get.c.

320{
321 return mutt_getch_timeout(flags, 1000);
322}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_monitor_getch()

int mutt_monitor_getch ( void )

◆ mutt_push_macro_event()

void mutt_push_macro_event ( int ch,
int op )

Add the character/operation to the macro buffer.

Parameters
chCharacter to add
opOperation to add

Adds the ch/op to the macro buffer. This should be used for macros, push, and exec commands only.

Definition at line 173 of file get.c.

174{
176 array_add(&mod_data->macro_events, ch, op);
177}
void array_add(struct KeyEventArray *a, int ch, int op)
Add an event to the end of the array.
Definition get.c:120
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_push_macro_repeated()

void mutt_push_macro_repeated ( char * macro,
int count )

Push a macro string into the input queue, optionally repeated.

Parameters
macroMacro string to expand
countNumber of times to repeat (0 or 1 means once)

The repeat count is clamped to $macro_repeat_max to bound queue growth.

Definition at line 60 of file get.c.

61{
62 int repeat = (count > 0) ? count : 1;
63
64 const short c_macro_repeat_max = cs_subset_number(NeoMutt->sub, "macro_repeat_max");
65 if ((c_macro_repeat_max > 0) && (repeat > c_macro_repeat_max))
66 repeat = c_macro_repeat_max;
67
68 for (int i = 0; i < repeat; i++)
70}
void generic_tokenize_push_string(char *s)
Parse and queue a 'push' command.
Definition get.c:352
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_unget_ch()

void mutt_unget_ch ( int ch)

Return a keystroke to the input buffer.

Parameters
chKey press

This puts events into the UngetKeyEvents buffer

Definition at line 147 of file get.c.

148{
150 array_add(&mod_data->unget_key_events, ch, OP_NULL);
151}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_unget_op()

void mutt_unget_op ( int op)

Return an operation to the input buffer.

Parameters
opOperation, e.g. OP_DELETE

This puts events into the UngetKeyEvents buffer

Definition at line 159 of file get.c.

160{
162 array_add(&mod_data->unget_key_events, 0, op);
163}
+ Here is the call graph for this function:
+ Here is the caller graph for this function: