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

Maniplate Menus and SubMenus. More...

#include "config.h"
#include <string.h>
#include "mutt/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "menu.h"
#include "get.h"
#include "keymap.h"
#include "module_data.h"
+ Include dependency graph for menu.c:

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.
 
struct Keymapkm_find_func (const struct MenuDefinition *md, int func)
 Find a function's mapping in a Menu.
 
int km_get_op (const char *func)
 Get the OpCode for a Function.
 
int km_get_op_menu (int mtype, const char *func)
 Get the OpCode for a Function from a Menu.
 
struct MenuDefinitionmenu_find (int menu)
 Find a Menu Definition by Menu type.
 
struct MenuDefinitionmenu_find_by_name (const char *name)
 Find a Menu Definition by its name.
 
bool is_bound (const struct MenuDefinition *md, int op)
 Does a function have a keybinding?
 

Detailed Description

Maniplate Menus and SubMenus.

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 menu.c.

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:

◆ km_find_func()

struct Keymap * km_find_func ( const struct MenuDefinition * md,
int func )

Find a function's mapping in a Menu.

Parameters
mdMenu Definition
funcFunction, e.g. OP_DELETE
Return values
ptrKeymap for the function

Definition at line 141 of file menu.c.

142{
143 if (!md)
144 return NULL;
145
146 struct SubMenu **smp = NULL;
147
148 ARRAY_FOREACH(smp, &md->submenus)
149 {
150 struct SubMenu *sm = *smp;
151
152 struct Keymap *map = NULL;
153 STAILQ_FOREACH(map, &sm->keymaps, entries)
154 {
155 if (map->op == func)
156 return map;
157 }
158 }
159
160 return NULL;
161}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
+ Here is the caller graph for this function:

◆ km_get_op()

int km_get_op ( const char * func)

Get the OpCode for a Function.

Parameters
funcFunction name, e.g. "exit"
Return values
numOpCode, e.g. OP_EXIT

Definition at line 168 of file menu.c.

169{
171 struct MenuDefinition **mdp = NULL;
172 ARRAY_FOREACH(mdp, &mod_data->menu_defs)
173 {
174 struct MenuDefinition *md = *mdp;
175 struct SubMenu **smp = NULL;
176
177 ARRAY_FOREACH(smp, &md->submenus)
178 {
179 struct SubMenu *sm = *smp;
180
181 for (int i = 0; sm->functions[i].name; i++)
182 {
183 if (mutt_str_equal(sm->functions[i].name, func))
184 return sm->functions[i].op;
185 }
186 }
187 }
188
189 return OP_NULL;
190}
@ MODULE_ID_KEY
ModuleKey, Key mappings
Definition module_api.h:73
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:665
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:663
Key private Module data.
Definition module_data.h:34
struct MenuDefinitionArray menu_defs
All registered Menus.
Definition module_data.h:39
Functions for a Dialog or Window.
Definition menu.h:77
const char * name
Name of the function.
Definition menu.h:36
int op
Operation, e.g. OP_DELETE.
Definition menu.h:37
Container for Accounts, Notifications.
Definition neomutt.h:41
const struct MenuFuncOp * functions
All available functions.
Definition menu.h:67
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ km_get_op_menu()

int km_get_op_menu ( int mtype,
const char * func )

Get the OpCode for a Function from a Menu.

Parameters
mtypeMenu Type, e.g. MENU_INDEX
funcFunction name, e.g. "exit"
Return values
numOpCode, e.g. OP_EXIT

Definition at line 198 of file menu.c.

199{
201 struct MenuDefinition **mdp = NULL;
202 ARRAY_FOREACH(mdp, &mod_data->menu_defs)
203 {
204 struct MenuDefinition *md = *mdp;
205
206 if (md->id != mtype)
207 continue;
208
209 struct SubMenu **smp = NULL;
210
211 ARRAY_FOREACH(smp, &md->submenus)
212 {
213 struct SubMenu *sm = *smp;
214
215 for (int i = 0; sm->functions[i].name; i++)
216 {
217 if (mutt_str_equal(sm->functions[i].name, func))
218 return sm->functions[i].op;
219 }
220 }
221 }
222
223 return OP_NULL;
224}
int id
Menu ID, e.g. MENU_ALIAS.
Definition menu.h:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ menu_find()

struct MenuDefinition * menu_find ( int menu)

Find a Menu Definition by Menu type.

Parameters
menuMenu Type, e.g. MENU_INDEX
Return values
ptrMenu Definition

Definition at line 231 of file menu.c.

232{
234 struct MenuDefinition **mdp = NULL;
235 ARRAY_FOREACH(mdp, &mod_data->menu_defs)
236 {
237 struct MenuDefinition *md = *mdp;
238
239 if (md->id == menu)
240 return md;
241 }
242
243 return NULL;
244}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ menu_find_by_name()

struct MenuDefinition * menu_find_by_name ( const char * name)

Find a Menu Definition by its name.

Parameters
nameMenu name, e.g. "index"
Return values
ptrMenu Definition

Definition at line 251 of file menu.c.

252{
253 if (!name)
254 return NULL;
255
257 struct MenuDefinition **mdp = NULL;
258 ARRAY_FOREACH(mdp, &mod_data->menu_defs)
259 {
260 struct MenuDefinition *md = *mdp;
261
262 if (mutt_str_equal(md->name, name))
263 return md;
264 }
265
266 return NULL;
267}
const char * name
Menu name, e.g. "alias".
Definition menu.h:79
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_bound()

bool is_bound ( const struct MenuDefinition * md,
int op )

Does a function have a keybinding?

Parameters
mdMenu Definition
opOperation, e.g. OP_DELETE
Return values
trueA key is bound to that operation

Definition at line 275 of file menu.c.

276{
277 struct SubMenu **smp = NULL;
278
279 ARRAY_FOREACH(smp, &md->submenus)
280 {
281 struct SubMenu *sm = *smp;
282
283 struct Keymap *map = NULL;
284 STAILQ_FOREACH(map, &sm->keymaps, entries)
285 {
286 if (map->op == op)
287 return true;
288 }
289 }
290
291 return false;
292}
+ Here is the caller graph for this function: