NeoMutt  2025-12-11-911-gd8d604
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
commands.h File Reference

Parse key binding commands. More...

#include "core/lib.h"
+ Include dependency graph for commands.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

enum CommandResult km_bind (struct MenuDefinition *md, const char *key_str, int op, char *macro, char *desc, struct Buffer *err)
 Set up a key binding.
 
char * parse_keymap (const struct Command *cmd, struct MenuDefinitionArray *mda, struct Buffer *line, struct Buffer *err)
 Parse a user-config key binding.
 
void parse_menu (struct MenuDefinitionArray *menus, const char *s, struct Buffer *err)
 Parse menu-names into an array.
 
enum CommandResult parse_bind (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'bind' command - Implements Command::parse() -.
 
enum CommandResult parse_exec (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'exec' command - Implements Command::parse() -.
 
enum CommandResult parse_macro (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'macro' command - Implements Command::parse() -.
 
enum CommandResult parse_push (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'push' command - Implements Command::parse() -.
 
enum CommandResult parse_unbind (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unbind' and 'unmacro' commands - Implements Command::parse() -.
 

Detailed Description

Parse key binding commands.

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

Function Documentation

◆ km_bind()

enum CommandResult km_bind ( struct MenuDefinition * md,
const char * key_str,
int op,
char * macro,
char * desc,
struct Buffer * err )

Set up a key binding.

Parameters
mdMenu Definition
key_strKey string
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 52 of file menu.c.

54{
55 if (!md || ARRAY_EMPTY(&md->submenus))
56 return MUTT_CMD_ERROR;
57
59 struct Keymap *last = NULL;
60 struct Keymap *np = NULL;
61 struct Keymap *compare = NULL;
62 keycode_t buf[KEY_SEQ_MAX_LEN] = { 0 };
63 size_t pos = 0;
64 size_t lastpos = 0;
65
66 struct SubMenu *sm = *ARRAY_FIRST(&md->submenus);
67 struct KeymapList *kml = &sm->keymaps;
68
69 size_t len = parse_keys(key_str, buf, KEY_SEQ_MAX_LEN);
70
71 struct Keymap *map = keymap_alloc(len, buf);
72 map->op = op;
73 map->macro = mutt_str_dup(macro);
74 map->desc = mutt_str_dup(desc);
75
76 /* find position to place new keymap */
77 STAILQ_FOREACH(np, kml, entries)
78 {
79 compare = keymap_compare(map, np, &pos);
80
81 if (compare == map) /* map's keycode is bigger */
82 {
83 last = np;
84 lastpos = pos;
85 if (pos > np->eq)
86 pos = np->eq;
87 }
88 else if (compare == np) /* np's keycode is bigger, found insert location */
89 {
90 map->eq = pos;
91 break;
92 }
93 else /* equal keycodes */
94 {
95 if (np->len < len)
96 {
97 // Prefix-compatible binding, continue looking for insertion point.
98 last = np;
99 lastpos = np->len;
100 if (pos > np->eq)
101 pos = np->eq;
102 continue;
103 }
104 else if (np->len > len)
105 {
106 // Prefix-compatible binding, insert before the longer sequence.
107 map->eq = len;
108 break;
109 }
110
111 // Exact same key sequence: replace existing mapping.
112 map->eq = np->eq;
113 STAILQ_REMOVE(kml, np, Keymap, entries);
114 keymap_free(&np);
115 break;
116 }
117 }
118
119 if (last) /* if queue has at least one entry */
120 {
121 if (STAILQ_NEXT(last, entries))
122 STAILQ_INSERT_AFTER(kml, last, map, entries);
123 else /* last entry in the queue */
124 STAILQ_INSERT_TAIL(kml, map, entries);
125 last->eq = lastpos;
126 }
127 else /* queue is empty, so insert from head */
128 {
129 STAILQ_INSERT_HEAD(kml, map, entries);
130 }
131
132 return rc;
133}
#define ARRAY_FIRST(head)
Convenience method to get the first element.
Definition array.h:136
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
CommandResult
Error codes for command_t parse functions.
Definition command.h:37
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition command.h:40
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition command.h:38
#define KEY_SEQ_MAX_LEN
Maximum number of keys in a key sequence, e.g. abc
Definition get.h:48
void keymap_free(struct Keymap **pptr)
Free a Keymap.
Definition keymap.c:146
struct Keymap * keymap_compare(struct Keymap *km1, struct Keymap *km2, size_t *pos)
Compare two keymaps' keyscodes and return the bigger one.
Definition keymap.c:181
size_t parse_keys(const char *str, keycode_t *d, size_t max)
Parse a key string into key codes.
Definition keymap.c:337
struct Keymap * keymap_alloc(size_t len, keycode_t *keys)
Allocate space for a sequence of keys.
Definition keymap.c:131
short keycode_t
Type for key storage, the rest of neomutt works fine with int type.
Definition keymap.h:31
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
#define STAILQ_REMOVE(head, elm, type, field)
Definition queue.h:441
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition queue.h:427
#define STAILQ_INSERT_HEAD(head, elm, field)
Definition queue.h:421
#define STAILQ_NEXT(elm, field)
Definition queue.h:439
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field)
Definition queue.h:415
A keyboard mapping.
Definition keymap.h:43
char * macro
Macro expansion (op == OP_MACRO)
Definition keymap.h:44
short eq
Number of leading keys equal to next entry.
Definition keymap.h:47
char * desc
Description of a macro for the help menu.
Definition keymap.h:45
short len
Length of key sequence (unit: sizeof (keycode_t))
Definition keymap.h:48
short op
Operation to perform.
Definition keymap.h:46
struct SubMenuPArray submenus
Parts making up the Menu.
Definition menu.h:80
Collection of related functions.
Definition menu.h:65
struct KeymapList keymaps
All keybindings.
Definition menu.h:68
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_keymap()

char * parse_keymap ( const struct Command * cmd,
struct MenuDefinitionArray * mda,
struct Buffer * line,
struct Buffer * err )

Parse a user-config key binding.

Parameters
cmdCommand being processed
mdaArray for results
lineBuffer containing config string
errBuffer for error messages
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 115 of file commands.c.

117{
118 struct Buffer *token = buf_pool_get();
119 char *q = NULL;
120 char *result = NULL;
121
122 /* menu name */
123 parse_extract_token(token, line, TOKEN_NONE);
124 char *p = token->data;
125 if (MoreArgs(line))
126 {
127 while (true)
128 {
129 q = strchr(p, ',');
130 if (q)
131 *q = '\0';
132
133 struct MenuDefinition *md = menu_find_by_name(p);
134 if (!md)
135 {
136 buf_printf(err, _("%s: no such menu"), p);
137 goto done;
138 }
139 ARRAY_ADD(mda, md);
140 if (q)
141 p = q + 1;
142 else
143 break;
144 }
145 /* key sequence */
146 parse_extract_token(token, line, TOKEN_NONE);
147
148 if (buf_at(token, 0) == '\0')
149 {
150 buf_printf(err, _("%s: null key sequence"), cmd->name);
151 }
152 else if (MoreArgs(line))
153 {
154 result = buf_strdup(token);
155 goto done;
156 }
157 }
158 else
159 {
160 buf_printf(err, _("%s: too few arguments"), cmd->name);
161 }
162done:
163 buf_pool_release(&token);
164 return result;
165}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
char buf_at(const struct Buffer *buf, size_t offset)
Return the character at the given offset.
Definition buffer.c:668
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:571
int parse_extract_token(struct Buffer *dest, struct Buffer *line, TokenFlags flags)
Extract one token from a string.
Definition extract.c:49
#define MoreArgs(buf)
Definition extract.h:31
@ TOKEN_NONE
No flags are set.
Definition extract.h:49
struct MenuDefinition * menu_find_by_name(const char *name)
Find a Menu Definition by its name.
Definition menu.c:251
#define _(a)
Definition message.h:28
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
char * data
Pointer to data.
Definition buffer.h:37
const char * name
Name of the Command.
Definition command.h:162
Functions for a Dialog or Window.
Definition menu.h:77
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_menu()

void parse_menu ( struct MenuDefinitionArray * menus,
const char * s,
struct Buffer * err )

Parse menu-names into an array.

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

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

Definition at line 175 of file commands.c.

176{
177 char *menu_names_dup = mutt_str_dup(s);
178 char *marker = menu_names_dup;
179 char *menu_name = NULL;
180
181 while ((menu_name = mutt_str_sep(&marker, ",")))
182 {
183 struct MenuDefinition *md = menu_find_by_name(menu_name);
184 if (!md)
185 {
186 buf_printf(err, _("%s: no such menu"), menu_name);
187 break;
188 }
189 else
190 {
191 ARRAY_ADD(menus, md);
192 }
193 }
194
195 FREE(&menu_names_dup);
196}
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
char * mutt_str_sep(char **stringp, const char *delim)
Find first occurrence of any of delim characters in *stringp.
Definition string.c:190
+ Here is the call graph for this function:
+ Here is the caller graph for this function: