NeoMutt  2025-01-09-117-gace867
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 "core/lib.h"
36#include "lib.h"
37#include "menu/lib.h"
38#include "pager/lib.h"
39#include "parse/lib.h"
40
47static int print_bind(enum MenuType menu, FILE *fp)
48{
49 struct BindingInfoArray bia_bind = ARRAY_HEAD_INITIALIZER;
50
51 gather_menu(menu, &bia_bind, NULL);
52 if (ARRAY_EMPTY(&bia_bind))
53 return 0;
54
55 ARRAY_SORT(&bia_bind, binding_sort, NULL);
56 const int wb0 = measure_column(&bia_bind, 0);
57 const int wb1 = measure_column(&bia_bind, 1);
58
59 const char *menu_name = mutt_map_get_name(menu, MenuNames);
60
61 struct BindingInfo *bi = NULL;
62 ARRAY_FOREACH(bi, &bia_bind)
63 {
64 //XXX use description?
65 fprintf(fp, "bind %s %*s %*s # %s\n", menu_name, -wb0, bi->a[0], -wb1,
66 bi->a[1], bi->a[2]);
67 }
68
69 const int count = ARRAY_SIZE(&bia_bind);
70 ARRAY_FOREACH(bi, &bia_bind)
71 {
72 // we only need to free the keybinding
73 FREE(&bi->a[0]);
74 }
75
76 return count;
77}
78
84static void colon_bind(enum MenuType menu, FILE *fp)
85{
86 if (menu == MENU_MAX)
87 {
88 for (enum MenuType i = 1; i < MENU_MAX; i++)
89 {
90 print_bind(i, fp);
91
92 //XXX need to elide last blank line
93 fprintf(fp, "\n");
94 }
95 }
96 else
97 {
98 print_bind(menu, fp);
99 }
100}
101
108static int print_macro(enum MenuType menu, FILE *fp)
109{
110 struct BindingInfoArray bia_macro = ARRAY_HEAD_INITIALIZER;
111
112 gather_menu(menu, NULL, &bia_macro);
113 if (ARRAY_EMPTY(&bia_macro))
114 return 0;
115
116 ARRAY_SORT(&bia_macro, binding_sort, NULL);
117 const int wm0 = measure_column(&bia_macro, 0);
118
119 const char *menu_name = mutt_map_get_name(menu, MenuNames);
120
121 struct BindingInfo *bi = NULL;
122 ARRAY_FOREACH(bi, &bia_macro)
123 {
124 if (bi->a[2]) // description
125 {
126 fprintf(fp, "macro %s %*s \"%s\" \"%s\"\n", menu_name, -wm0, bi->a[0],
127 bi->a[1], bi->a[2]);
128 }
129 else
130 {
131 fprintf(fp, "macro %s %*s \"%s\"\n", menu_name, -wm0, bi->a[0], bi->a[1]);
132 }
133 }
134
135 const int count = ARRAY_SIZE(&bia_macro);
136 ARRAY_FOREACH(bi, &bia_macro)
137 {
138 // free the keybinding and the macro text
139 FREE(&bi->a[0]);
140 FREE(&bi->a[1]);
141 }
142
143 ARRAY_FREE(&bia_macro);
144 return count;
145}
146
152static void colon_macro(enum MenuType menu, FILE *fp)
153{
154 if (menu == MENU_MAX)
155 {
156 for (enum MenuType i = 1; i < MENU_MAX; i++)
157 {
158 if (print_macro(i, fp) > 0)
159 {
160 //XXX need to elide last blank line
161 fprintf(fp, "\n");
162 }
163 }
164 }
165 else
166 {
167 print_macro(menu, fp);
168 }
169}
170
174enum CommandResult dump_bind_macro(struct Buffer *buf, struct Buffer *s,
175 intptr_t data, struct Buffer *err)
176{
177 FILE *fp = NULL;
178 struct Buffer *tempfile = NULL;
179 bool dump_all = false;
180 bool bind = (data == 0);
181 int rc = MUTT_CMD_ERROR;
182
183 if (!MoreArgs(s))
184 dump_all = true;
185 else
187
188 if (MoreArgs(s))
189 {
190 /* More arguments potentially means the user is using the
191 * ::command_t :bind command thus we delegate the task. */
192 goto done;
193 }
194
195 tempfile = buf_pool_get();
196 buf_mktemp(tempfile);
197 fp = mutt_file_fopen(buf_string(tempfile), "w");
198 if (!fp)
199 {
200 // L10N: '%s' is the file name of the temporary file
201 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
202 goto done;
203 }
204
205 if (dump_all || mutt_istr_equal(buf_string(buf), "all"))
206 {
207 if (bind)
208 colon_bind(MENU_MAX, fp);
209 else
211 }
212 else
213 {
214 const int menu = mutt_map_get_value(buf_string(buf), MenuNames);
215 if (menu == -1)
216 {
217 // L10N: '%s' is the (misspelled) name of the menu, e.g. 'index' or 'pager'
218 buf_printf(err, _("%s: no such menu"), buf_string(buf));
219 goto done;
220 }
221
222 if (bind)
223 colon_bind(menu, fp);
224 else
225 colon_macro(menu, fp);
226 }
227
228 if (ftello(fp) == 0)
229 {
230 // L10N: '%s' is the name of the menu, e.g. 'index' or 'pager',
231 // it might also be 'all' when all menus are affected.
232 buf_printf(err, bind ? _("%s: no binds for this menu") : _("%s: no macros for this menu"),
233 dump_all ? "all" : buf_string(buf));
234 goto done;
235 }
236 mutt_file_fclose(&fp);
237
238 struct PagerData pdata = { 0 };
239 struct PagerView pview = { &pdata };
240
241 pdata.fname = buf_string(tempfile);
242
243 pview.banner = bind ? "bind" : "macro";
245 pview.mode = PAGER_MODE_OTHER;
246
247 mutt_do_pager(&pview, NULL);
248 rc = MUTT_CMD_SUCCESS;
249
250done:
251 mutt_file_fclose(&fp);
252 buf_pool_release(&tempfile);
253
254 return rc;
255}
#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_FREE(head)
Release all memory.
Definition: array.h:204
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition: array.h:58
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:161
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:35
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:38
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:36
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:49
#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:174
int binding_sort(const void *a, const void *b, void *sdata)
Compare two BindingInfo by their keybinding - Implements sort_t -.
Definition: lib.c:405
static void colon_macro(enum MenuType menu, FILE *fp)
Dump the macros.
Definition: dump.c:152
static void colon_bind(enum MenuType menu, FILE *fp)
Dump the key bindings.
Definition: dump.c:84
static int print_bind(enum MenuType menu, FILE *fp)
Display the bindings for one menu.
Definition: dump.c:47
static int print_macro(enum MenuType menu, FILE *fp)
Display the macros for one menu.
Definition: dump.c:108
int measure_column(struct BindingInfoArray *bia, int col)
Measure one column of a table.
Definition: lib.c:419
void gather_menu(enum MenuType menu, struct BindingInfoArray *bia_bind, struct BindingInfoArray *bia_macro)
Gather info about one menu.
Definition: lib.c:624
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
#define FREE(x)
Definition: memory.h:55
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
Key value store.
Info about one keybinding.
Definition: lib.h:94
const char * a[3]
Array of info.
Definition: lib.h:95
String manipulation buffer.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:37
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_MAX
Definition: type.h:53