NeoMutt  2022-04-29-70-g0c028c
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 226 of file icommands.c.

246 {
247  FILE *fp_out = NULL;
248  char tempfile[PATH_MAX];
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";
313  pview.flags = MUTT_PAGER_NO_FLAGS;
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:61
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
#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:120
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:618
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:398
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:796
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:66
#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

◆ 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 226 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];
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";
539  pview.flags = MUTT_PAGER_NO_FLAGS;
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:784
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

◆ 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 226 of file icommands.c.

552 {
553  char tempfile[PATH_MAX];
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";
573  pview.flags = MUTT_PAGER_NO_FLAGS;
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

◆ 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 1 of file icommands.c.

92 {
93  if (!line || (*line == '\0') || !err)
94  return MUTT_CMD_ERROR;
95 
96  enum CommandResult rc = MUTT_CMD_ERROR;
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 
103  mutt_buffer_reset(err);
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 
119 finish:
120  mutt_buffer_pool_release(&token);
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:225
void mutt_buffer_seek(struct Buffer *buf, size_t offset)
Set current read/write position to offset from beginning.
Definition: buffer.c:468
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
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 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];
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:203
const struct MenuFuncOp OpGeneric[]
Functions for the Generic Menu.
Definition: functions.c:287
const char * mutt_get_func(const struct MenuFuncOp *funcs, int op)
Get the name of a function.
Definition: keymap.c:518
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:929
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition: keymap.c:1231
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];
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 
188  mutt_buffer_dealloc(&tmp);
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:240
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:

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 1 of file icommands.c.