NeoMutt  2025-01-09-81-g753ae0
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
dump.c
Go to the documentation of this file.
1
30#include "config.h"
31#include <stdbool.h>
32#include <stdint.h>
33#include <stdio.h>
34#include "mutt/lib.h"
35#include "config/lib.h"
36#include "core/lib.h"
37#include "gui/lib.h"
38#include "key/lib.h"
39#include "menu/lib.h"
40#include "pager/lib.h"
41#include "parse/lib.h"
42
51static bool dump_bind(struct Buffer *buf, enum MenuType menu, const char *name)
52{
53 bool empty = true;
54 struct Keymap *map = NULL;
55
56 struct Buffer *key_binding = buf_pool_get();
57
58 STAILQ_FOREACH(map, &Keymaps[menu], entries)
59 {
60 if (map->op == OP_MACRO)
61 continue;
62
63 const char *fn_name = NULL;
64
65 buf_reset(key_binding);
66 km_expand_key(map, key_binding);
67 if (map->op == OP_NULL)
68 {
69 buf_add_printf(buf, "bind %s %s noop\n", name, buf_string(key_binding));
70 continue;
71 }
72
73 /* The pager and editor menus don't use the generic map,
74 * however for other menus try generic first. */
75 if ((menu != MENU_PAGER) && (menu != MENU_EDITOR) && (menu != MENU_GENERIC))
76 {
77 fn_name = mutt_get_func(OpGeneric, map->op);
78 }
79
80 /* if it's one of the menus above or generic doesn't find
81 * the function, try with its own menu. */
82 if (!fn_name)
83 {
84 const struct MenuFuncOp *funcs = km_get_table(menu);
85 if (!funcs)
86 continue;
87
88 fn_name = mutt_get_func(funcs, map->op);
89 }
90
91 buf_add_printf(buf, "bind %s %s %s\n", name, buf_string(key_binding), fn_name);
92 empty = false;
93 }
94
95 buf_pool_release(&key_binding);
96 return empty;
97}
98
103static void dump_all_binds(struct Buffer *buf)
104{
105 for (enum MenuType i = 1; i < MENU_MAX; i++)
106 {
107 const bool empty = dump_bind(buf, i, mutt_map_get_name(i, MenuNames));
108
109 /* Add a new line for readability between menus. */
110 if (!empty && (i < (MENU_MAX - 1)))
111 buf_addch(buf, '\n');
112 }
113}
114
123static bool dump_macro(struct Buffer *buf, enum MenuType menu, const char *name)
124{
125 bool empty = true;
126 struct Keymap *map = NULL;
127
128 struct Buffer *key_binding = buf_pool_get();
129
130 STAILQ_FOREACH(map, &Keymaps[menu], entries)
131 {
132 if (map->op != OP_MACRO)
133 continue;
134
135 buf_reset(key_binding);
136 km_expand_key(map, key_binding);
137
138 struct Buffer *tmp = buf_pool_get();
139 escape_string(tmp, map->macro);
140
141 if (map->desc)
142 {
143 buf_add_printf(buf, "macro %s %s \"%s\" \"%s\"\n", name,
144 buf_string(key_binding), buf_string(tmp), map->desc);
145 }
146 else
147 {
148 buf_add_printf(buf, "macro %s %s \"%s\"\n", name, buf_string(key_binding),
149 buf_string(tmp));
150 }
151
152 buf_pool_release(&tmp);
153 empty = false;
154 }
155
156 buf_pool_release(&key_binding);
157 return empty;
158}
159
164static void dump_all_macros(struct Buffer *buf)
165{
166 for (enum MenuType i = 1; i < MENU_MAX; i++)
167 {
168 const bool empty = dump_macro(buf, i, mutt_map_get_name(i, MenuNames));
169
170 /* Add a new line for legibility between menus. */
171 if (!empty && (i < (MENU_MAX - 1)))
172 buf_addch(buf, '\n');
173 }
174}
175
179enum CommandResult dump_bind_macro(struct Buffer *buf, struct Buffer *s,
180 intptr_t data, struct Buffer *err)
181{
182 FILE *fp_out = NULL;
183 bool dump_all = false, bind = (data == 0);
184
185 if (!MoreArgs(s))
186 dump_all = true;
187 else
189
190 if (MoreArgs(s))
191 {
192 /* More arguments potentially means the user is using the
193 * ::command_t :bind command thus we delegate the task. */
194 return MUTT_CMD_ERROR;
195 }
196
197 struct Buffer *filebuf = buf_pool_get();
198 if (dump_all || mutt_istr_equal(buf_string(buf), "all"))
199 {
200 if (bind)
201 dump_all_binds(filebuf);
202 else
203 dump_all_macros(filebuf);
204 }
205 else
206 {
207 const int menu_index = mutt_map_get_value(buf_string(buf), MenuNames);
208 if (menu_index == -1)
209 {
210 // L10N: '%s' is the (misspelled) name of the menu, e.g. 'index' or 'pager'
211 buf_printf(err, _("%s: no such menu"), buf_string(buf));
212 buf_pool_release(&filebuf);
213 return MUTT_CMD_ERROR;
214 }
215
216 if (bind)
217 dump_bind(filebuf, menu_index, buf_string(buf));
218 else
219 dump_macro(filebuf, menu_index, buf_string(buf));
220 }
221
222 if (buf_is_empty(filebuf))
223 {
224 // L10N: '%s' is the name of the menu, e.g. 'index' or 'pager',
225 // it might also be 'all' when all menus are affected.
226 buf_printf(err, bind ? _("%s: no binds for this menu") : _("%s: no macros for this menu"),
227 dump_all ? "all" : buf_string(buf));
228 buf_pool_release(&filebuf);
229 return MUTT_CMD_ERROR;
230 }
231
232 struct Buffer *tempfile = buf_pool_get();
233 buf_mktemp(tempfile);
234 fp_out = mutt_file_fopen(buf_string(tempfile), "w");
235 if (!fp_out)
236 {
237 // L10N: '%s' is the file name of the temporary file
238 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
239 buf_pool_release(&filebuf);
240 buf_pool_release(&tempfile);
241 return MUTT_CMD_ERROR;
242 }
243 fputs(buf_string(filebuf), fp_out);
244
245 mutt_file_fclose(&fp_out);
246 buf_pool_release(&filebuf);
247
248 struct PagerData pdata = { 0 };
249 struct PagerView pview = { &pdata };
250
251 pdata.fname = buf_string(tempfile);
252
253 pview.banner = (bind) ? "bind" : "macro";
255 pview.mode = PAGER_MODE_OTHER;
256
257 mutt_do_pager(&pview, NULL);
258 buf_pool_release(&tempfile);
259
260 return MUTT_CMD_SUCCESS;
261}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:161
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:204
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:76
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:291
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:241
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
CommandResult
Error codes for command_t parse functions.
Definition: command.h:36
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:39
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:37
size_t escape_string(struct Buffer *buf, const char *src)
Write a string to a buffer, escaping special characters.
Definition: dump.c:48
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
int mutt_do_pager(struct PagerView *pview, struct Email *e)
Display some page-able text to the user (help or attachment)
Definition: do_pager.c:122
int parse_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: extract.c:50
#define MoreArgs(buf)
Definition: extract.h:32
#define TOKEN_NO_FLAGS
No flags are set.
Definition: extract.h:46
#define mutt_file_fclose(FP)
Definition: file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:138
enum CommandResult dump_bind_macro(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse 'bind' and 'macro' commands - Implements Command::parse() -.
Definition: dump.c:179
const struct MenuFuncOp OpGeneric[]
Functions for the Generic Menu.
Definition: functions.c:68
Convenience wrapper for the gui headers.
static void dump_all_macros(struct Buffer *buf)
Dumps all the macros inside every menu.
Definition: dump.c:164
static void dump_all_binds(struct Buffer *buf)
Dumps all the binds inside every menu.
Definition: dump.c:103
static bool dump_bind(struct Buffer *buf, enum MenuType menu, const char *name)
Dumps all the binds maps of a menu into a buffer.
Definition: dump.c:51
static bool dump_macro(struct Buffer *buf, enum MenuType menu, const char *name)
Dumps all the macros maps of a menu into a buffer.
Definition: dump.c:123
struct KeymapList Keymaps[MENU_MAX]
Array of key mappings, one for each MenuType.
Definition: lib.c:124
const char * mutt_get_func(const struct MenuFuncOp *funcs, int op)
Get the name of a function.
Definition: lib.c:320
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition: lib.c:499
bool km_expand_key(struct Keymap *map, struct Buffer *buf)
Get the key string bound to a Keymap.
Definition: lib.c:451
Manage keymappings.
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition: mapping.c:85
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
GUI present the user with a selectable list.
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:673
GUI display a file/email/help in a viewport with paging.
#define MUTT_PAGER_NO_FLAGS
No flags are set.
Definition: lib.h:60
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition: lib.h:140
Text parsing functions.
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
char * data
Pointer to data.
Definition: buffer.h:37
A keyboard mapping.
Definition: lib.h:66
char * macro
Macro expansion (op == OP_MACRO)
Definition: lib.h:67
char * desc
Description of a macro for the help menu.
Definition: lib.h:68
short op
Operation to perform.
Definition: lib.h:69
Mapping between a function and an operation.
Definition: lib.h:102
const char * name
Name of the function.
Definition: lib.h:103
Data to be displayed by PagerView.
Definition: lib.h:159
const char * fname
Name of the file to read.
Definition: lib.h:163
Paged view into some data.
Definition: lib.h:170
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:171
enum PagerMode mode
Pager mode.
Definition: lib.h:172
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:173
const char * banner
Title to display in status bar.
Definition: lib.h:174
#define buf_mktemp(buf)
Definition: tmp.h:33
const struct Mapping MenuNames[]
Menu name lookup table.
Definition: type.c:37
MenuType
Types of GUI selections.
Definition: type.h:36
@ MENU_GENERIC
Generic selection list.
Definition: type.h:46
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:52
@ MENU_MAX
Definition: type.h:57
@ MENU_EDITOR
Text entry area.
Definition: type.h:44