NeoMutt  2025-12-11-58-g09398d
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
dump.c File Reference

Dump key bindings. More...

#include "config.h"
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include "mutt/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "lib.h"
#include "menu/lib.h"
#include "pager/lib.h"
#include "parse/lib.h"
+ Include dependency graph for dump.c:

Go to the source code of this file.

Functions

static int print_bind (enum MenuType menu, FILE *fp)
 Display the bindings for one menu.
 
static void colon_bind (enum MenuType menu, FILE *fp)
 Dump the key bindings.
 
static int print_macro (enum MenuType menu, FILE *fp)
 Display the macros for one menu.
 
static void colon_macro (enum MenuType menu, FILE *fp)
 Dump the macros.
 
enum CommandResult parse_bind_macro (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse 'bind' and 'macro' commands - Implements Command::parse() -.
 
int binding_sort (const void *a, const void *b, void *sdata)
 Compare two BindingInfo by their keybinding - Implements sort_t -.
 
void escape_macro (const char *macro, struct Buffer *buf)
 Escape any special characters in a macro.
 
static const char * help_lookup_function (int op, enum MenuType menu)
 Find a keybinding for an operation.
 
void gather_menu (enum MenuType menu, struct BindingInfoArray *bia_bind, struct BindingInfoArray *bia_macro)
 Gather info about one menu.
 
int measure_column (struct BindingInfoArray *bia, int col)
 Measure one column of a table.
 

Detailed Description

Dump key bindings.

Authors
  • Richard Russon
  • Dennis Schön

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

Function Documentation

◆ print_bind()

static int print_bind ( enum MenuType menu,
FILE * fp )
static

Display the bindings for one menu.

Parameters
menuMenu type
fpFile to write to
Return values
numNumber of bindings

Definition at line 50 of file dump.c.

51{
52 struct BindingInfoArray bia_bind = ARRAY_HEAD_INITIALIZER;
53
54 gather_menu(menu, &bia_bind, NULL);
55 if (ARRAY_EMPTY(&bia_bind))
56 return 0;
57
58 ARRAY_SORT(&bia_bind, binding_sort, NULL);
59 const int wb0 = measure_column(&bia_bind, 0);
60 const int wb1 = measure_column(&bia_bind, 1);
61
62 const char *menu_name = mutt_map_get_name(menu, MenuNames);
63
64 struct BindingInfo *bi = NULL;
65 ARRAY_FOREACH(bi, &bia_bind)
66 {
67 //XXX use description?
68 fprintf(fp, "bind %s %*s %*s # %s\n", menu_name, -wb0, bi->a[0], -wb1,
69 bi->a[1], bi->a[2]);
70 }
71
72 const int count = ARRAY_SIZE(&bia_bind);
73 ARRAY_FOREACH(bi, &bia_bind)
74 {
75 // we only need to free the keybinding
76 FREE(&bi->a[0]);
77 }
78
79 return count;
80}
#define ARRAY_SORT(head, fn, sdata)
Sort an array.
Definition array.h:335
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:214
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
#define ARRAY_SIZE(head)
The number of elements stored.
Definition array.h:87
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition array.h:58
int binding_sort(const void *a, const void *b, void *sdata)
Compare two BindingInfo by their keybinding - Implements sort_t -.
Definition dump.c:263
int measure_column(struct BindingInfoArray *bia, int col)
Measure one column of a table.
Definition dump.c:414
void gather_menu(enum MenuType menu, struct BindingInfoArray *bia_bind, struct BindingInfoArray *bia_macro)
Gather info about one menu.
Definition dump.c:358
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition mapping.c:42
#define FREE(x)
Definition memory.h:62
Info about one keybinding.
Definition lib.h:95
const char * a[3]
Array of info.
Definition lib.h:96
const struct Mapping MenuNames[]
Menu name lookup table.
Definition type.c:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ colon_bind()

static void colon_bind ( enum MenuType menu,
FILE * fp )
static

Dump the key bindings.

Parameters
menuMenu type
fpFile to write to

Definition at line 87 of file dump.c.

88{
89 if (menu == MENU_MAX)
90 {
91 for (enum MenuType i = 1; i < MENU_MAX; i++)
92 {
93 if (print_bind(i, fp) > 0)
94 fprintf(fp, "\n");
95 }
96 }
97 else
98 {
99 print_bind(menu, fp);
100 }
101}
static int print_bind(enum MenuType menu, FILE *fp)
Display the bindings for one menu.
Definition dump.c:50
MenuType
Types of GUI selections.
Definition type.h:35
@ MENU_MAX
Definition type.h:52
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_macro()

static int print_macro ( enum MenuType menu,
FILE * fp )
static

Display the macros for one menu.

Parameters
menuMenu type
fpFile to write to
Return values
numNumber of macros

Definition at line 109 of file dump.c.

110{
111 struct BindingInfoArray bia_macro = ARRAY_HEAD_INITIALIZER;
112
113 gather_menu(menu, NULL, &bia_macro);
114 if (ARRAY_EMPTY(&bia_macro))
115 return 0;
116
117 ARRAY_SORT(&bia_macro, binding_sort, NULL);
118 const int wm0 = measure_column(&bia_macro, 0);
119
120 const char *menu_name = mutt_map_get_name(menu, MenuNames);
121
122 struct BindingInfo *bi = NULL;
123 ARRAY_FOREACH(bi, &bia_macro)
124 {
125 if (bi->a[2]) // description
126 {
127 fprintf(fp, "macro %s %*s \"%s\" \"%s\"\n", menu_name, -wm0, bi->a[0],
128 bi->a[1], bi->a[2]);
129 }
130 else
131 {
132 fprintf(fp, "macro %s %*s \"%s\"\n", menu_name, -wm0, bi->a[0], bi->a[1]);
133 }
134 }
135
136 const int count = ARRAY_SIZE(&bia_macro);
137 ARRAY_FOREACH(bi, &bia_macro)
138 {
139 // free the keybinding and the macro text
140 FREE(&bi->a[0]);
141 FREE(&bi->a[1]);
142 }
143
144 ARRAY_FREE(&bia_macro);
145 return count;
146}
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:204
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ colon_macro()

static void colon_macro ( enum MenuType menu,
FILE * fp )
static

Dump the macros.

Parameters
menuMenu type
fpFile to write to

Definition at line 153 of file dump.c.

154{
155 if (menu == MENU_MAX)
156 {
157 for (enum MenuType i = 1; i < MENU_MAX; i++)
158 {
159 if (print_macro(i, fp) > 0)
160 {
161 //XXX need to elide last blank line
162 fprintf(fp, "\n");
163 }
164 }
165 }
166 else
167 {
168 print_macro(menu, fp);
169 }
170}
static int print_macro(enum MenuType menu, FILE *fp)
Display the macros for one menu.
Definition dump.c:109
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ escape_macro()

void escape_macro ( const char * macro,
struct Buffer * buf )

Escape any special characters in a macro.

Parameters
[in]macroMacro string
[out]bufBuffer for the result

Replace characters, such as <Enter> with the literal "\n"

Definition at line 283 of file dump.c.

284{
285 wchar_t wc = 0;
286 size_t k;
287 size_t len = mutt_str_len(macro);
288 mbstate_t mbstate1 = { 0 };
289 mbstate_t mbstate2 = { 0 };
290
291 for (; (len > 0) && (k = mbrtowc(&wc, macro, MB_LEN_MAX, &mbstate1)); macro += k, len -= k)
292 {
293 if ((k == ICONV_ILLEGAL_SEQ) || (k == ICONV_BUF_TOO_SMALL))
294 {
295 if (k == ICONV_ILLEGAL_SEQ)
296 memset(&mbstate1, 0, sizeof(mbstate1));
297 k = (k == ICONV_ILLEGAL_SEQ) ? 1 : len;
298 wc = ReplacementChar;
299 }
300
301 const int w = wcwidth(wc);
302 if (IsWPrint(wc) && (w >= 0))
303 {
304 char tmp[MB_LEN_MAX * 2] = { 0 };
305 if (wcrtomb(tmp, wc, &mbstate2) != ICONV_ILLEGAL_SEQ)
306 {
307 buf_addstr(buf, tmp);
308 }
309 }
310 else if ((wc < 0x20) || (wc == 0x7f))
311 {
312 if (wc == '\033') // Escape
313 buf_addstr(buf, "\\e");
314 else if (wc == '\n')
315 buf_addstr(buf, "\\n");
316 else if (wc == '\r')
317 buf_addstr(buf, "\\r");
318 else if (wc == '\t')
319 buf_addstr(buf, "\\t");
320 else
321 buf_add_printf(buf, "^%c", (char) ((wc + '@') & 0x7f));
322 }
323 else
324 {
325 buf_addch(buf, '?');
326 }
327 }
328}
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition buffer.c:204
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:241
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:226
#define IsWPrint(wc)
Definition mbyte.h:41
wchar_t ReplacementChar
When a Unicode character can't be displayed, use this instead.
Definition charset.c:61
#define ICONV_BUF_TOO_SMALL
Error value for iconv() - Buffer too small.
Definition charset.h:98
#define ICONV_ILLEGAL_SEQ
Error value for iconv() - Illegal sequence.
Definition charset.h:96
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:498
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ help_lookup_function()

static const char * help_lookup_function ( int op,
enum MenuType menu )
static

Find a keybinding for an operation.

Parameters
opOperation, e.g. OP_DELETE
menuCurrent Menu, e.g. MENU_PAGER
Return values
strKey binding
NULLNo key binding found

Definition at line 337 of file dump.c.

338{
339 if ((menu != MENU_PAGER) && (menu != MENU_EDITOR) && (menu != MENU_GENERIC))
340 {
341 /* first look in the generic map for the function */
342 const char *fn_name = mutt_get_func(OpGeneric, op);
343 if (fn_name)
344 return fn_name;
345 }
346
347 const struct MenuFuncOp *funcs = km_get_table(menu);
348
349 return mutt_get_func(funcs, op);
350}
const struct MenuFuncOp OpGeneric[]
Functions for the Generic Menu.
Definition functions.c:69
const char * mutt_get_func(const struct MenuFuncOp *funcs, int op)
Get the name of a function.
Definition lib.c:321
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition lib.c:485
Mapping between a function and an operation.
Definition lib.h:117
int op
Operation, e.g. OP_DELETE.
Definition lib.h:119
@ MENU_GENERIC
Generic selection list.
Definition type.h:45
@ MENU_PAGER
Pager pager (email viewer)
Definition type.h:47
@ MENU_EDITOR
Text entry area.
Definition type.h:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ gather_menu()

void gather_menu ( enum MenuType menu,
struct BindingInfoArray * bia_bind,
struct BindingInfoArray * bia_macro )

Gather info about one menu.

Parameters
menuMenu type
bia_bindArray for bind results (may be NULL)
bia_macroArray for macro results (may be NULL)

Definition at line 358 of file dump.c.

360{
361 struct Buffer *key_binding = buf_pool_get();
362 struct Buffer *macro = buf_pool_get();
363
364 struct Keymap *map = NULL;
365 STAILQ_FOREACH(map, &Keymaps[menu], entries)
366 {
367 struct BindingInfo bi = { 0 };
368
369 buf_reset(key_binding);
370 km_expand_key(map, key_binding);
371
372 if (map->op == OP_MACRO)
373 {
374 if (!bia_macro || (map->op == OP_NULL))
375 continue;
376
377 buf_reset(macro);
378 escape_macro(map->macro, macro);
379 bi.a[0] = buf_strdup(key_binding);
380 bi.a[1] = buf_strdup(macro);
381 bi.a[2] = map->desc;
382 ARRAY_ADD(bia_macro, bi);
383 }
384 else
385 {
386 if (!bia_bind)
387 continue;
388
389 if (map->op == OP_NULL)
390 {
391 bi.a[0] = buf_strdup(key_binding);
392 bi.a[1] = "noop";
393 ARRAY_ADD(bia_bind, bi);
394 continue;
395 }
396
397 bi.a[0] = buf_strdup(key_binding);
398 bi.a[1] = help_lookup_function(map->op, menu);
399 bi.a[2] = _(opcodes_get_description(map->op));
400 ARRAY_ADD(bia_bind, bi);
401 }
402 }
403
404 buf_pool_release(&key_binding);
405 buf_pool_release(&macro);
406}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:156
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:571
static const char * help_lookup_function(int op, enum MenuType menu)
Find a keybinding for an operation.
Definition dump.c:337
void escape_macro(const char *macro, struct Buffer *buf)
Escape any special characters in a macro.
Definition dump.c:283
struct KeymapList Keymaps[MENU_MAX]
Array of key mappings, one for each MenuType.
Definition lib.c:125
bool km_expand_key(struct Keymap *map, struct Buffer *buf)
Get the key string bound to a Keymap.
Definition lib.c:437
#define _(a)
Definition message.h:28
const char * opcodes_get_description(int op)
Get the description of an opcode.
Definition opcodes.c:68
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:96
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
String manipulation buffer.
Definition buffer.h:36
A keyboard mapping.
Definition lib.h:67
char * macro
Macro expansion (op == OP_MACRO)
Definition lib.h:68
char * desc
Description of a macro for the help menu.
Definition lib.h:69
short op
Operation to perform.
Definition lib.h:70
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ measure_column()

int measure_column ( struct BindingInfoArray * bia,
int col )

Measure one column of a table.

Parameters
biaArray of binding info
colColumn to measure
Return values
numWidth of widest column

Definition at line 414 of file dump.c.

415{
416 int max_width = 0;
417
418 struct BindingInfo *bi = NULL;
419 ARRAY_FOREACH(bi, bia)
420 {
421 const int col_width = mutt_strwidth(bi->a[col]);
422 max_width = MAX(max_width, col_width);
423 }
424
425 return max_width;
426}
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition curs_lib.c:445
#define MAX(a, b)
Definition memory.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function: