NeoMutt  2022-04-29-215-gc12b98
Teaching an old dog new tricks
DOXYGEN
icommands.c File Reference

Information commands. More...

#include "config.h"
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "mutt.h"
#include "icommands.h"
#include "menu/lib.h"
#include "pager/lib.h"
#include "functions.h"
#include "init.h"
#include "keymap.h"
#include "muttlib.h"
#include "opcodes.h"
#include "version.h"
+ Include dependency graph for icommands.c:

Go to the source code of this file.

Functions

static enum CommandResult icmd_bind (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse 'bind' and 'macro' commands - Implements ICommand::parse() More...
 
static enum CommandResult icmd_set (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse 'set' command to display config - Implements ICommand::parse() More...
 
static enum CommandResult icmd_version (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse 'version' command - Implements ICommand::parse() More...
 
enum CommandResult mutt_parse_icommand (const char *line, struct Buffer *err)
 Parse an informational command. More...
 
static void dump_bind (struct Buffer *buf, struct Mapping *menu, struct Keymap *map)
 Dump a bind map to a buffer. More...
 
static void dump_macro (struct Buffer *buf, struct Mapping *menu, struct Keymap *map)
 Dump a macro map to a buffer. More...
 
static bool dump_menu (struct Buffer *buf, struct Mapping *menu, bool bind)
 Dumps all the binds or macros maps of a menu into a buffer. More...
 
static void dump_all_menus (struct Buffer *buf, bool bind)
 Dumps all the binds or macros inside every menu. More...
 

Variables

static const struct ICommand ICommandList []
 All available informational commands. More...
 

Detailed Description

Information commands.

Authors
  • Christopher John Czettel
  • Richard Russon
  • Victor Fernandes

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

Function Documentation

◆ icmd_bind()

static enum CommandResult icmd_bind ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)
static

Parse 'bind' and 'macro' commands - Implements ICommand::parse()

Definition at line 244 of file icommands.c.

246{
247 FILE *fp_out = NULL;
248 char tempfile[PATH_MAX] = { 0 };
249 bool dump_all = false, bind = (data == 0);
250
251 if (!MoreArgs(s))
252 dump_all = true;
253 else
255
256 if (MoreArgs(s))
257 {
258 /* More arguments potentially means the user is using the
259 * ::command_t :bind command thus we delegate the task. */
260 return MUTT_CMD_ERROR;
261 }
262
263 struct Buffer filebuf = mutt_buffer_make(4096);
264 if (dump_all || mutt_istr_equal(buf->data, "all"))
265 {
266 dump_all_menus(&filebuf, bind);
267 }
268 else
269 {
270 const int menu_index = mutt_map_get_value(buf->data, MenuNames);
271 if (menu_index == -1)
272 {
273 // L10N: '%s' is the (misspelled) name of the menu, e.g. 'index' or 'pager'
274 mutt_buffer_printf(err, _("%s: no such menu"), buf->data);
275 mutt_buffer_dealloc(&filebuf);
276 return MUTT_CMD_ERROR;
277 }
278
279 struct Mapping menu = { buf->data, menu_index };
280 dump_menu(&filebuf, &menu, bind);
281 }
282
283 if (mutt_buffer_is_empty(&filebuf))
284 {
285 // L10N: '%s' is the name of the menu, e.g. 'index' or 'pager',
286 // it might also be 'all' when all menus are affected.
287 mutt_buffer_printf(err, bind ? _("%s: no binds for this menu") : _("%s: no macros for this menu"),
288 dump_all ? "all" : buf->data);
289 mutt_buffer_dealloc(&filebuf);
290 return MUTT_CMD_ERROR;
291 }
292
293 mutt_mktemp(tempfile, sizeof(tempfile));
294 fp_out = mutt_file_fopen(tempfile, "w");
295 if (!fp_out)
296 {
297 // L10N: '%s' is the file name of the temporary file
298 mutt_buffer_printf(err, _("Could not create temporary file %s"), tempfile);
299 mutt_buffer_dealloc(&filebuf);
300 return MUTT_CMD_ERROR;
301 }
302 fputs(filebuf.data, fp_out);
303
304 mutt_file_fclose(&fp_out);
305 mutt_buffer_dealloc(&filebuf);
306
307 struct PagerData pdata = { 0 };
308 struct PagerView pview = { &pdata };
309
310 pdata.fname = tempfile;
311
312 pview.banner = (bind) ? "bind" : "macro";
314 pview.mode = PAGER_MODE_OTHER;
315
316 mutt_do_pager(&pview, NULL);
317 return MUTT_CMD_SUCCESS;
318}
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:67
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:260
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:309
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:168
#define MoreArgs(buf)
Definition: buffer.h:40
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:37
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:35
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:123
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:618
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
static void dump_all_menus(struct Buffer *buf, bool bind)
Dumps all the binds or macros inside every menu.
Definition: icommands.c:226
static bool dump_menu(struct Buffer *buf, struct Mapping *menu, bool bind)
Dumps all the binds or macros maps of a menu into a buffer.
Definition: icommands.c:199
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:273
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition: mapping.c:85
#define _(a)
Definition: message.h:28
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:819
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:67
#define PATH_MAX
Definition: mutt.h:40
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:71
#define MUTT_PAGER_NO_FLAGS
No flags are set.
Definition: lib.h:58
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition: lib.h:139
String manipulation buffer.
Definition: buffer.h:34
char * data
Pointer to data.
Definition: buffer.h:35
Mapping between user-readable string and a constant.
Definition: mapping.h:32
Data to be displayed by PagerView.
Definition: lib.h:158
const char * fname
Name of the file to read.
Definition: lib.h:162
Paged view into some data.
Definition: lib.h:169
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:170
enum PagerMode mode
Pager mode.
Definition: lib.h:171
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:172
const char * banner
Title to display in status bar.
Definition: lib.h:173
const struct Mapping MenuNames[]
Menu name lookup table.
Definition: type.c:31
+ Here is the call graph for this function:

◆ icmd_set()

static enum CommandResult icmd_set ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)
static

Parse 'set' command to display config - Implements ICommand::parse()

Definition at line 506 of file icommands.c.

508{
509 const bool set = mutt_str_equal(s->data, "set");
510 const bool set_all = mutt_str_equal(s->data, "set all");
511
512 if (!set && !set_all)
513 return MUTT_CMD_ERROR;
514
515 char tempfile[PATH_MAX] = { 0 };
516 mutt_mktemp(tempfile, sizeof(tempfile));
517
518 FILE *fp_out = mutt_file_fopen(tempfile, "w");
519 if (!fp_out)
520 {
521 // L10N: '%s' is the file name of the temporary file
522 mutt_buffer_printf(err, _("Could not create temporary file %s"), tempfile);
523 return MUTT_CMD_ERROR;
524 }
525
526 if (set_all)
528 else
530
531 mutt_file_fclose(&fp_out);
532
533 struct PagerData pdata = { 0 };
534 struct PagerView pview = { &pdata };
535
536 pdata.fname = tempfile;
537
538 pview.banner = "set";
540 pview.mode = PAGER_MODE_OTHER;
541
542 mutt_do_pager(&pview, NULL);
543
544 return MUTT_CMD_SUCCESS;
545}
bool dump_config(struct ConfigSet *cs, ConfigDumpFlags flags, FILE *fp)
Write all the config to a file.
Definition: dump.c:165
#define CS_DUMP_ONLY_CHANGED
Only show config that the user has changed.
Definition: dump.h:36
#define CS_DUMP_NO_FLAGS
No flags are set.
Definition: dump.h:35
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
struct ConfigSet * cs
Parent ConfigSet.
Definition: subset.h:51
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:

◆ icmd_version()

static enum CommandResult icmd_version ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)
static

Parse 'version' command - Implements ICommand::parse()

Definition at line 550 of file icommands.c.

552{
553 char tempfile[PATH_MAX] = { 0 };
554 mutt_mktemp(tempfile, sizeof(tempfile));
555
556 FILE *fp_out = mutt_file_fopen(tempfile, "w");
557 if (!fp_out)
558 {
559 // L10N: '%s' is the file name of the temporary file
560 mutt_buffer_printf(err, _("Could not create temporary file %s"), tempfile);
561 return MUTT_CMD_ERROR;
562 }
563
564 print_version(fp_out);
565 mutt_file_fclose(&fp_out);
566
567 struct PagerData pdata = { 0 };
568 struct PagerView pview = { &pdata };
569
570 pdata.fname = tempfile;
571
572 pview.banner = "version";
574 pview.mode = PAGER_MODE_OTHER;
575
576 mutt_do_pager(&pview, NULL);
577 return MUTT_CMD_SUCCESS;
578}
bool print_version(FILE *fp)
Print system and compile info to a file.
Definition: version.c:408
+ Here is the call graph for this function:

◆ mutt_parse_icommand()

enum CommandResult mutt_parse_icommand ( const char *  line,
struct Buffer err 
)

Parse an informational command.

Parameters
lineCommand to execute
errBuffer for error messages
Return values
MUTT_CMD_SUCCESSSuccess
MUTT_CMD_WARNINGWarning with message: command failed
MUTT_CMD_ERROR
  • Error (no message): command not found
  • Error with message: command failed

Definition at line 91 of file icommands.c.

92{
93 if (!line || (*line == '\0') || !err)
94 return MUTT_CMD_ERROR;
95
97
98 struct Buffer *token = mutt_buffer_pool_get();
99 struct Buffer expn = mutt_buffer_make(0);
100 mutt_buffer_addstr(&expn, line);
101 mutt_buffer_seek(&expn, 0);
102
104
105 SKIPWS(expn.dptr);
107 for (size_t i = 0; ICommandList[i].name; i++)
108 {
109 if (!mutt_str_equal(token->data, ICommandList[i].name))
110 continue;
111
112 rc = ICommandList[i].parse(token, &expn, ICommandList[i].data, err);
113 if (rc != MUTT_CMD_SUCCESS)
114 goto finish;
115
116 break; /* Continue with next command */
117 }
118
119finish:
121 mutt_buffer_dealloc(&expn);
122 return rc;
123}
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:233
void mutt_buffer_seek(struct Buffer *buf, size_t offset)
Set current read/write position to offset from beginning.
Definition: buffer.c:483
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:85
CommandResult
Error codes for command_t parse functions.
Definition: command.h:34
static const struct ICommand ICommandList[]
All available informational commands.
Definition: icommands.c:68
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define SKIPWS(ch)
Definition: string2.h:46
char * dptr
Current read/write position.
Definition: buffer.h:36
enum CommandResult(* parse)(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Function to parse information commands.
Definition: icommands.h:47
char * name
Name of the command.
Definition: icommands.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_bind()

static void dump_bind ( struct Buffer buf,
struct Mapping menu,
struct Keymap map 
)
static

Dump a bind map to a buffer.

Parameters
bufOutput buffer
menuMap menu
mapBind keymap

Definition at line 131 of file icommands.c.

132{
133 char key_binding[32] = { 0 };
134 const char *fn_name = NULL;
135
136 km_expand_key(key_binding, sizeof(key_binding), map);
137 if (map->op == OP_NULL)
138 {
139 mutt_buffer_add_printf(buf, "bind %s %s noop\n", menu->name, key_binding);
140 return;
141 }
142
143 /* The pager and editor menus don't use the generic map,
144 * however for other menus try generic first. */
145 if ((menu->value != MENU_PAGER) && (menu->value != MENU_EDITOR) && (menu->value != MENU_GENERIC))
146 {
147 fn_name = mutt_get_func(OpGeneric, map->op);
148 }
149
150 /* if it's one of the menus above or generic doesn't find
151 * the function, try with its own menu. */
152 if (!fn_name)
153 {
154 const struct MenuFuncOp *funcs = km_get_table(menu->value);
155 if (!funcs)
156 return;
157
158 fn_name = mutt_get_func(funcs, map->op);
159 }
160
161 mutt_buffer_add_printf(buf, "bind %s %s %s\n", menu->name, key_binding, fn_name);
162}
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:211
const struct MenuFuncOp OpGeneric[]
Functions for the Generic Menu.
Definition: functions.c:288
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:928
const char * mutt_get_func(const struct MenuFuncOp *funcs, int op)
Get the name of a function.
Definition: keymap.c:518
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition: keymap.c:1230
short op
operation to perform
Definition: keymap.h:52
int value
Integer value.
Definition: mapping.h:34
const char * name
String value.
Definition: mapping.h:33
Mapping between a function and an operation.
Definition: keymap.h:92
@ MENU_GENERIC
Generic selection list.
Definition: type.h:45
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:54
@ MENU_EDITOR
Text entry area.
Definition: type.h:43
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_macro()

static void dump_macro ( struct Buffer buf,
struct Mapping menu,
struct Keymap map 
)
static

Dump a macro map to a buffer.

Parameters
bufOutput buffer
menuMap menu
mapMacro keymap

Definition at line 170 of file icommands.c.

171{
172 char key_binding[MAX_SEQ] = { 0 };
173 km_expand_key(key_binding, MAX_SEQ, map);
174
175 struct Buffer tmp = mutt_buffer_make(0);
176 escape_string(&tmp, map->macro);
177
178 if (map->desc)
179 {
180 mutt_buffer_add_printf(buf, "macro %s %s \"%s\" \"%s\"\n", menu->name,
181 key_binding, tmp.data, map->desc);
182 }
183 else
184 {
185 mutt_buffer_add_printf(buf, "macro %s %s \"%s\"\n", menu->name, key_binding, tmp.data);
186 }
187
189}
size_t escape_string(struct Buffer *buf, const char *src)
Write a string to a buffer, escaping special characters.
Definition: dump.c:46
#define MAX_SEQ
Definition: keymap.h:36
char * macro
macro expansion (op == OP_MACRO)
Definition: keymap.h:50
char * desc
description of a macro for the help menu
Definition: keymap.h:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_menu()

static bool dump_menu ( struct Buffer buf,
struct Mapping menu,
bool  bind 
)
static

Dumps all the binds or macros maps of a menu into a buffer.

Parameters
bufOutput buffer
menuMenu to dump
bindIf true it's :bind, else :macro
Return values
trueMenu is empty
falseMenu is not empty

Definition at line 199 of file icommands.c.

200{
201 bool empty = true;
202 struct Keymap *map = NULL;
203
204 STAILQ_FOREACH(map, &Keymaps[menu->value], entries)
205 {
206 if (bind && (map->op != OP_MACRO))
207 {
208 empty = false;
209 dump_bind(buf, menu, map);
210 }
211 else if (!bind && (map->op == OP_MACRO))
212 {
213 empty = false;
214 dump_macro(buf, menu, map);
215 }
216 }
217
218 return empty;
219}
static void dump_macro(struct Buffer *buf, struct Mapping *menu, struct Keymap *map)
Dump a macro map to a buffer.
Definition: icommands.c:170
static void dump_bind(struct Buffer *buf, struct Mapping *menu, struct Keymap *map)
Dump a bind map to a buffer.
Definition: icommands.c:131
struct KeymapList Keymaps[MENU_MAX]
Array of Keymap keybindings, one for each Menu.
Definition: keymap.c:126
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
A keyboard mapping.
Definition: keymap.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_all_menus()

static void dump_all_menus ( struct Buffer buf,
bool  bind 
)
static

Dumps all the binds or macros inside every menu.

Parameters
bufOutput buffer
bindIf true it's :bind, else :macro

Definition at line 226 of file icommands.c.

227{
228 for (int i = 0; i < MENU_MAX; i++)
229 {
230 const char *menu_name = mutt_map_get_name(i, MenuNames);
231 struct Mapping menu = { menu_name, i };
232
233 const bool empty = dump_menu(buf, &menu, bind);
234
235 /* Add a new line for readability between menus. */
236 if (!empty && (i < (MENU_MAX - 1)))
237 mutt_buffer_addch(buf, '\n');
238 }
239}
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:248
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
@ MENU_MAX
Definition: type.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ ICommandList

const struct ICommand ICommandList[]
static
Initial value:
= {
{ "bind", icmd_bind, 0 },
{ "macro", icmd_bind, 1 },
{ "set", icmd_set, 0 },
{ "version", icmd_version, 0 },
{ NULL, NULL, 0 },
}
static enum CommandResult icmd_set(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse 'set' command to display config - Implements ICommand::parse()
Definition: icommands.c:506
static enum CommandResult icmd_bind(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse 'bind' and 'macro' commands - Implements ICommand::parse()
Definition: icommands.c:244
static enum CommandResult icmd_version(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse 'version' command - Implements ICommand::parse()
Definition: icommands.c:550

All available informational commands.

Note
These commands take precedence over conventional NeoMutt rc-lines

Definition at line 68 of file icommands.c.