NeoMutt  2025-12-11-911-gd8d604
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
init.c
Go to the documentation of this file.
1
22
28
29#include "config.h"
30#include <string.h>
31#include "mutt/lib.h"
32#include "config/lib.h"
33#include "core/lib.h"
34#include "gui/lib.h"
35#include "init.h"
36#include "commands.h"
37#include "keymap.h"
38#include "menu.h"
39#include "module_data.h"
40
44
48const struct Command KeyCommands[] = {
49 // clang-format off
50 { "bind", CMD_BIND, parse_bind,
51 N_("Bind a key to a function"),
52 N_("bind <map>[,<map> ... ] <key> <function>"),
53 "configuration.html#bind" },
54 { "exec", CMD_EXEC, parse_exec,
55 N_("Execute a function"),
56 N_("exec <function> [ <function> ... ]"),
57 "configuration.html#exec" },
58 { "macro", CMD_MACRO, parse_macro,
59 N_("Define a keyboard macro"),
60 N_("macro <map>[,<map> ... ] <key> <sequence> [ <description> ]"),
61 "configuration.html#macro" },
62 { "push", CMD_PUSH, parse_push,
63 N_("Push a string into NeoMutt's input queue (simulate typing)"),
64 N_("push <string>"),
65 "configuration.html#push" },
66 { "unbind", CMD_UNBIND, parse_unbind,
67 N_("Remove a key binding"),
68 N_("unbind { * | <map>[,<map> ... ] } [ <key> ]"),
69 "configuration.html#unbind" },
70 { "unmacro", CMD_UNMACRO, parse_unbind,
71 N_("Remove a keyboard `macro`"),
72 N_("unmacro { * | <map>[,<map> ... ] } [ <key> ]"),
73 "configuration.html#unmacro" },
74
75 { NULL, CMD_NONE, NULL, NULL, NULL, NULL, CF_NONE },
76 // clang-format on
77};
78
88{
90 struct SubMenu sm = { 0 };
93
94 ARRAY_ADD(&mod_data->sub_menus, sm);
95 return ARRAY_LAST(&mod_data->sub_menus);
96}
97
104struct MenuDefinition *km_register_menu(int menu, const char *name)
105{
107 struct MenuDefinition *md = MUTT_MEM_CALLOC(1, struct MenuDefinition);
108 md->id = menu;
109 md->name = mutt_str_dup(name);
110 ARRAY_INIT(&md->submenus);
111
112 ARRAY_ADD(&mod_data->menu_defs, md);
113 return *ARRAY_LAST(&mod_data->menu_defs);
114}
115
121void km_menu_add_submenu(struct MenuDefinition *md, struct SubMenu *sm)
122{
123 if (!sm->parent)
124 sm->parent = md;
125
126 ARRAY_ADD(&md->submenus, sm);
127}
128
134void km_menu_add_bindings(struct MenuDefinition *md, const struct MenuOpSeq bindings[])
135{
136 for (int i = 0; bindings[i].op != OP_NULL; i++)
137 {
138 if (bindings[i].seq)
139 {
140 km_bind(md, bindings[i].seq, bindings[i].op, NULL, NULL, NULL);
141 }
142 }
143}
144
149{
150 if (nc->event_type != NT_CONFIG)
151 return 0;
152 if (!nc->event_data)
153 return -1;
154
155 struct EventConfig *ev_c = nc->event_data;
156
157 if (!mutt_str_equal(ev_c->name, "abort_key"))
158 return 0;
159
161 km_set_abort_key(&mod_data->abort_key);
162 mutt_debug(LL_DEBUG5, "config done\n");
163 return 0;
164}
165
170void km_init(struct KeyModuleData *mod_data)
171{
172 ARRAY_INIT(&mod_data->menu_defs);
173 ARRAY_INIT(&mod_data->sub_menus);
174 mod_data->key_names = keymap_get_key_names();
175
177}
178
182static int menu_defs_sort(const void *a, const void *b, void *sdata)
183{
184 const struct MenuDefinition *md_a = *(const struct MenuDefinition **) a;
185 const struct MenuDefinition *md_b = *(const struct MenuDefinition **) b;
186
187 return mutt_str_cmp(md_a->name, md_b->name);
188}
189
193void km_sort(void)
194{
196 ARRAY_SORT(&mod_data->menu_defs, menu_defs_sort, NULL);
197}
198
203void km_cleanup(struct KeyModuleData *mod_data)
204{
205 if (NeoMutt && NeoMutt->sub)
207
208 struct MenuDefinition **mdp = NULL;
209 ARRAY_FOREACH(mdp, &mod_data->menu_defs)
210 {
211 struct MenuDefinition *md = *mdp;
212
213 FREE(&md->name);
214 ARRAY_FREE(&md->submenus);
215 FREE(&md);
216 }
217 ARRAY_FREE(&mod_data->menu_defs);
218
219 struct SubMenu *sm = NULL;
220 ARRAY_FOREACH(sm, &mod_data->sub_menus)
221 {
223 }
224 ARRAY_FREE(&mod_data->sub_menus);
225
226 ARRAY_FREE(&mod_data->macro_events);
227 ARRAY_FREE(&mod_data->unget_key_events);
228}
229
237{
238 keycode_t buf[4] = { 0 };
239 const char *const c_abort_key = cs_subset_string(NeoMutt->sub, "abort_key");
240
241 size_t len = parse_keys(c_abort_key, buf, countof(buf));
242 if (len == 0)
243 {
244 mutt_error(_("Abort key is not set, defaulting to Ctrl-G"));
245 *abort_key = ctrl('G');
246 return;
247 }
248
249 if (len > 1)
250 {
251 mutt_warning(_("Specified abort key sequence (%s) will be truncated to first key"),
252 c_abort_key);
253 }
254 *abort_key = buf[0];
255}
#define ARRAY_SORT(head, fn, sdata)
Sort an array.
Definition array.h:373
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
#define ARRAY_LAST(head)
Convenience method to get the last element.
Definition array.h:145
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
#define ARRAY_INIT(head)
Initialize an array.
Definition array.h:65
@ CF_NONE
No flags are set.
Definition command.h:49
@ CMD_EXEC
:exec
Definition command.h:77
@ CMD_UNMACRO
:unmacro
Definition command.h:138
@ CMD_MACRO
:macro
Definition command.h:93
@ CMD_PUSH
:push
Definition command.h:104
@ CMD_NONE
No Command.
Definition command.h:62
@ CMD_BIND
:bind
Definition command.h:70
@ CMD_UNBIND
:unbind
Definition command.h:131
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
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() -.
Definition commands.c:241
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() -.
Definition commands.c:788
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() -.
Definition commands.c:681
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() -.
Definition commands.c:204
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() -.
Definition commands.c:654
#define mutt_warning(...)
Definition logging2.h:92
#define mutt_error(...)
Definition logging2.h:94
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
int km_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition init.c:148
static int menu_defs_sort(const void *a, const void *b, void *sdata)
Compare two MenuDefinitions by their names - Implements sort_t -.
Definition init.c:182
Convenience wrapper for the gui headers.
void km_menu_add_submenu(struct MenuDefinition *md, struct SubMenu *sm)
Add a SubMenu to a Menu Definition.
Definition init.c:121
void km_cleanup(struct KeyModuleData *mod_data)
Free the key maps.
Definition init.c:203
void km_init(struct KeyModuleData *mod_data)
Initialise all the menu keybindings.
Definition init.c:170
struct SubMenu * km_register_submenu(const struct MenuFuncOp functions[])
Register a submenu.
Definition init.c:87
struct MenuDefinition * km_register_menu(int menu, const char *name)
Register a menu.
Definition init.c:104
void km_sort(void)
Sort all the menu keybindings.
Definition init.c:193
void km_set_abort_key(keycode_t *abort_key)
Parse the abort_key config string.
Definition init.c:236
const struct Command KeyCommands[]
All the registered Menus - moved to KeyModuleData All the registered SubMenus - moved to KeyModuleDat...
Definition init.c:48
void km_menu_add_bindings(struct MenuDefinition *md, const struct MenuOpSeq bindings[])
Add Keybindings to a Menu.
Definition init.c:134
Set up the key bindings.
Parse key binding commands.
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.
Definition menu.c:52
void keymaplist_free(struct KeymapList *kml)
Free a List of Keymaps.
Definition keymap.c:163
struct Mapping * keymap_get_key_names(void)
Get the KeyNames lookup table.
Definition keymap.c:120
size_t parse_keys(const char *str, keycode_t *d, size_t max)
Parse a key string into key codes.
Definition keymap.c:337
Key private Module data.
Keymap handling.
short keycode_t
Type for key storage, the rest of neomutt works fine with int type.
Definition keymap.h:31
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:49
#define countof(x)
Definition memory.h:49
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
Maniplate Menus and SubMenus.
@ MODULE_ID_KEY
ModuleKey, Key mappings
Definition module_api.h:73
Convenience wrapper for the library headers.
#define N_(a)
Definition message.h:32
#define _(a)
Definition message.h:28
bool notify_observer_remove(struct Notify *notify, const observer_t callback, const void *global_data)
Remove an observer from an object.
Definition notify.c:230
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition notify.c:191
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
Definition string.c:403
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:665
#define ctrl(ch)
Convert a letter to a control character (e.g., 'A' -> Ctrl-A)
Definition mutt_curses.h:52
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:663
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition notify_type.h:43
struct Notify * notify
Notifications: NotifyConfig, EventConfig.
Definition subset.h:51
A config-change event.
Definition subset.h:70
const char * name
Name of config item that changed.
Definition subset.h:72
Key private Module data.
Definition module_data.h:34
struct KeyEventArray macro_events
Macro event buffer.
Definition module_data.h:36
keycode_t abort_key
Key to abort prompts, normally Ctrl-G.
Definition module_data.h:38
struct MenuDefinitionArray menu_defs
All registered Menus.
Definition module_data.h:39
struct Mapping * key_names
Key name lookup table.
Definition module_data.h:41
struct SubMenuArray sub_menus
All registered SubMenus.
Definition module_data.h:40
struct KeyEventArray unget_key_events
Unget key event buffer.
Definition module_data.h:37
Functions for a Dialog or Window.
Definition menu.h:77
const char * name
Menu name, e.g. "alias".
Definition menu.h:79
int id
Menu ID, e.g. MENU_ALIAS.
Definition menu.h:78
struct SubMenuPArray submenus
Parts making up the Menu.
Definition menu.h:80
Mapping between a function and an operation.
Definition menu.h:35
Mapping between an operation and a key sequence.
Definition menu.h:45
int op
Operation, e.g. OP_DELETE.
Definition menu.h:46
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
Data passed to a notification function.
Definition observer.h:34
void * event_data
Data from notify_send()
Definition observer.h:38
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition observer.h:36
Collection of related functions.
Definition menu.h:65
const struct MenuFuncOp * functions
All available functions.
Definition menu.h:67
struct KeymapList keymaps
All keybindings.
Definition menu.h:68
struct MenuDefinition * parent
Primary parent.
Definition menu.h:66