NeoMutt  2018-07-16 +1783-b00bd9
Teaching an old dog new tricks
DOXYGEN
icommands.c File Reference

Information commands. More...

#include "config.h"
#include <limits.h>
#include <stdio.h>
#include "mutt/mutt.h"
#include "config/lib.h"
#include "mutt.h"
#include "icommands.h"
#include "globals.h"
#include "keymap.h"
#include "muttlib.h"
#include "opcodes.h"
#include "pager.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, unsigned long data, struct Buffer *err)
 Parse 'bind' and 'macro' commands - Implements icommand_t. More...
 
static enum CommandResult icmd_set (struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err)
 Parse 'set' command to display config - Implements icommand_t. More...
 
static enum CommandResult icmd_version (struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err)
 Parse 'version' command - Implements icommand_t. More...
 
enum CommandResult mutt_parse_icommand (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

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

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

Parse 'bind' and 'macro' commands - Implements icommand_t.

Definition at line 234 of file icommands.c.

236 {
237  FILE *fp_out = NULL;
238  char tempfile[PATH_MAX];
239  bool dump_all = false, bind = (data == 0);
240 
241  if (!MoreArgs(s))
242  dump_all = true;
243  else
245 
246  if (MoreArgs(s))
247  {
248  /* More arguments potentially means the user is using the
249  * ::command_t :bind command thus we delegate the task. */
250  return MUTT_CMD_ERROR;
251  }
252 
253  struct Buffer *filebuf = mutt_buffer_alloc(4096);
254  if (dump_all || (mutt_str_strcasecmp(buf->data, "all") == 0))
255  {
256  dump_all_menus(filebuf, bind);
257  }
258  else
259  {
260  const int menu_index = mutt_map_get_value(buf->data, Menus);
261  if (menu_index == -1)
262  {
263  // L10N: '%s' is the (misspelled) name of the menu, e.g. 'index' or 'pager'
264  mutt_buffer_printf(err, _("%s: no such menu"), buf->data);
265  mutt_buffer_free(&filebuf);
266  return MUTT_CMD_ERROR;
267  }
268 
269  struct Mapping menu = { buf->data, menu_index };
270  dump_menu(filebuf, &menu, bind);
271  }
272 
273  if (mutt_buffer_is_empty(filebuf))
274  {
275  // L10N: '%s' is the name of the menu, e.g. 'index' or 'pager', it might
276  // L10N: also be 'all' when all menus are affected.
277  mutt_buffer_printf(err, bind ? _("%s: no binds for this menu") : _("%s: no macros for this menu"),
278  dump_all ? "all" : buf->data);
279  mutt_buffer_free(&filebuf);
280  return MUTT_CMD_ERROR;
281  }
282 
283  mutt_mktemp(tempfile, sizeof(tempfile));
284  fp_out = mutt_file_fopen(tempfile, "w");
285  if (!fp_out)
286  {
287  // L10N: '%s' is the file name of the temporary file
288  mutt_buffer_printf(err, _("Could not create temporary file %s"), tempfile);
289  mutt_buffer_free(&filebuf);
290  return MUTT_CMD_ERROR;
291  }
292  fputs(filebuf->data, fp_out);
293 
294  mutt_file_fclose(&fp_out);
295  mutt_buffer_free(&filebuf);
296 
297  struct Pager info = { 0 };
298  if (mutt_pager((bind) ? "bind" : "macro", tempfile, MUTT_PAGER_NO_FLAGS, &info) == -1)
299  {
300  // L10N: '%s' is the file name of the temporary file
301  mutt_buffer_printf(err, _("Could not create temporary file %s"), tempfile);
302  return MUTT_CMD_ERROR;
303  }
304 
305  return MUTT_CMD_SUCCESS;
306 }
Error: Can&#39;t help the user.
Definition: mutt_commands.h:33
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
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:186
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:200
An email being displayed.
Definition: pager.h:65
struct Buffer * mutt_buffer_alloc(size_t size)
Create a new Buffer.
Definition: buffer.c:304
#define MoreArgs(buf)
Definition: buffer.h:44
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
void mutt_buffer_free(struct Buffer **p)
Release a Buffer and its contents.
Definition: buffer.c:138
static void dump_all_menus(struct Buffer *buf, bool bind)
Dumps all the binds or macros inside every menu.
Definition: icommands.c:215
const struct Mapping Menus[]
Menu name lookup table.
Definition: keymap.c:60
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:74
#define PATH_MAX
Definition: mutt.h:49
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:2656
char * data
pointer to data
Definition: buffer.h:35
Success: Command worked.
Definition: mutt_commands.h:35
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:631
Mapping between user-readable string and a constant.
Definition: mapping.h:29
int mutt_pager(const char *banner, const char *fname, PagerFlags flags, struct Pager *extra)
Display a file, or help, in a window.
Definition: pager.c:2233
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:578
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:291
#define MUTT_PAGER_NO_FLAGS
No flags are set.
Definition: pager.h:43
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:75
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition: mapping.c:61

+ Here is the call graph for this function:

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

Parse 'set' command to display config - Implements icommand_t.

Definition at line 311 of file icommands.c.

313 {
314  char tempfile[PATH_MAX];
315  mutt_mktemp(tempfile, sizeof(tempfile));
316 
317  FILE *fp_out = mutt_file_fopen(tempfile, "w");
318  if (!fp_out)
319  {
320  // L10N: '%s' is the file name of the temporary file
321  mutt_buffer_printf(err, _("Could not create temporary file %s"), tempfile);
322  return MUTT_CMD_ERROR;
323  }
324 
325  if (mutt_str_strcmp(s->data, "set all") == 0)
326  {
328  }
329  else if (mutt_str_strcmp(s->data, "set") == 0)
330  {
332  }
333  else
334  {
335  mutt_file_fclose(&fp_out);
336  return MUTT_CMD_ERROR;
337  }
338 
339  mutt_file_fclose(&fp_out);
340 
341  struct Pager info = { 0 };
342  if (mutt_pager("set", tempfile, MUTT_PAGER_NO_FLAGS, &info) == -1)
343  {
344  // L10N: '%s' is the file name of the temporary file
345  mutt_buffer_printf(err, _("Could not create temporary file %s"), tempfile);
346  return MUTT_CMD_ERROR;
347  }
348 
349  return MUTT_CMD_SUCCESS;
350 }
#define CS_DUMP_ONLY_CHANGED
Only show config that the user has changed.
Definition: dump.h:45
Error: Can&#39;t help the user.
Definition: mutt_commands.h:33
#define _(a)
Definition: message.h:28
WHERE struct ConfigSet * Config
Wrapper around the user&#39;s config settings.
Definition: globals.h:39
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:200
An email being displayed.
Definition: pager.h:65
bool dump_config(struct ConfigSet *cs, enum CsDumpStyle style, ConfigDumpFlags flags, FILE *fp)
Write all the config to a file.
Definition: dump.c:233
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:74
#define PATH_MAX
Definition: mutt.h:49
#define CS_DUMP_NO_FLAGS
No flags are set.
Definition: dump.h:44
char * data
pointer to data
Definition: buffer.h:35
Success: Command worked.
Definition: mutt_commands.h:35
int mutt_pager(const char *banner, const char *fname, PagerFlags flags, struct Pager *extra)
Display a file, or help, in a window.
Definition: pager.c:2233
Display config in NeoMutt style.
Definition: dump.h:40
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:578
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:618
#define MUTT_PAGER_NO_FLAGS
No flags are set.
Definition: pager.h:43

+ Here is the call graph for this function:

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

Parse 'version' command - Implements icommand_t.

Definition at line 355 of file icommands.c.

357 {
358  char tempfile[PATH_MAX];
359  mutt_mktemp(tempfile, sizeof(tempfile));
360 
361  FILE *fp_out = mutt_file_fopen(tempfile, "w");
362  if (!fp_out)
363  {
364  // L10N: '%s' is the file name of the temporary file
365  mutt_buffer_printf(err, _("Could not create temporary file %s"), tempfile);
366  return MUTT_CMD_ERROR;
367  }
368 
369  print_version(fp_out);
370  mutt_file_fclose(&fp_out);
371 
372  struct Pager info = { 0 };
373  if (mutt_pager("version", tempfile, MUTT_PAGER_NO_FLAGS, &info) == -1)
374  {
375  // L10N: '%s' is the file name of the temporary file
376  mutt_buffer_printf(err, _("Could not create temporary file %s"), tempfile);
377  return MUTT_CMD_ERROR;
378  }
379 
380  return MUTT_CMD_SUCCESS;
381 }
Error: Can&#39;t help the user.
Definition: mutt_commands.h:33
void print_version(FILE *fp)
Print system and compile info to a file.
Definition: version.c:366
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:200
An email being displayed.
Definition: pager.h:65
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:74
#define PATH_MAX
Definition: mutt.h:49
Success: Command worked.
Definition: mutt_commands.h:35
int mutt_pager(const char *banner, const char *fname, PagerFlags flags, struct Pager *extra)
Display a file, or help, in a window.
Definition: pager.c:2233
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:578
#define MUTT_PAGER_NO_FLAGS
No flags are set.
Definition: pager.h:43

+ Here is the call graph for this function:

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

Parse an informational command.

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

Definition at line 73 of file icommands.c.

74 {
75  if (!line || !*line || !err)
76  return MUTT_CMD_ERROR;
77 
78  enum CommandResult rc = MUTT_CMD_ERROR;
79 
80  struct Buffer expn, token;
81 
82  mutt_buffer_init(&expn);
83  mutt_buffer_init(&token);
84 
85  expn.data = expn.dptr = line;
86  expn.dsize = mutt_str_strlen(line);
87 
88  mutt_buffer_reset(err);
89 
90  SKIPWS(expn.dptr);
91  while (*expn.dptr)
92  {
94  for (size_t i = 0; ICommandList[i].name; i++)
95  {
96  if (mutt_str_strcmp(token.data, ICommandList[i].name) != 0)
97  continue;
98 
99  rc = ICommandList[i].func(&token, &expn, ICommandList[i].data, err);
100  if (rc != 0)
101  goto finish;
102 
103  break; /* Continue with next command */
104  }
105  }
106 
107 finish:
108  if (expn.destroy)
109  FREE(&expn.data);
110  return rc;
111 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:83
CommandResult
Error codes for command_t parse functions.
Definition: mutt_commands.h:31
Error: Can&#39;t help the user.
Definition: mutt_commands.h:33
char * name
Name of the command.
Definition: icommands.h:46
const struct ICommand ICommandList[]
All available informational commands.
Definition: icommands.c:55
String manipulation buffer.
Definition: buffer.h:33
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:669
#define SKIPWS(ch)
Definition: string2.h:46
const char * line
Definition: common.c:35
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:2656
char * data
pointer to data
Definition: buffer.h:35
icommand_t * func
Function to parse the command.
Definition: icommands.h:47
#define FREE(x)
Definition: memory.h:40
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:68
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:618
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:75

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

120 {
121  char key_binding[32];
122  const char *fn_name = NULL;
123 
124  km_expand_key(key_binding, sizeof(key_binding), map);
125  if (map->op == OP_NULL)
126  {
127  mutt_buffer_add_printf(buf, "bind %s %s noop\n", menu->name, key_binding);
128  return;
129  }
130 
131  /* The pager and editor menus don't use the generic map,
132  * however for other menus try generic first. */
133  if ((menu->value != MENU_PAGER) && (menu->value != MENU_EDITOR) && (menu->value != MENU_GENERIC))
134  {
135  fn_name = mutt_get_func(OpGeneric, map->op);
136  }
137 
138  /* if it's one of the menus above or generic doesn't find
139  * the function, try with its own menu. */
140  if (!fn_name)
141  {
142  const struct Binding *bindings = km_get_table(menu->value);
143  if (!bindings)
144  return;
145 
146  fn_name = mutt_get_func(bindings, map->op);
147  }
148 
149  mutt_buffer_add_printf(buf, "bind %s %s %s\n", menu->name, key_binding, fn_name);
150 }
int value
Definition: mapping.h:32
Pager pager (email viewer)
Definition: keymap.h:77
const char * mutt_get_func(const struct Binding *bindings, int op)
Get the name of a function.
Definition: keymap.c:452
short op
operation to perform
Definition: keymap.h:53
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:242
const struct Binding * km_get_table(int menu)
Lookup a menu&#39;s keybindings.
Definition: keymap.c:1204
const struct Binding OpGeneric[]
Key bindings for the generic menu.
Definition: functions.h:52
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:769
Text entry area.
Definition: keymap.h:73
const char * name
Definition: mapping.h:31
Mapping between a user key and a function.
Definition: keymap.h:102
Generic selection list.
Definition: keymap.h:75

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

159 {
160  char key_binding[MAX_SEQ];
161  km_expand_key(key_binding, MAX_SEQ, map);
162 
163  struct Buffer *tmp = mutt_buffer_new();
164  escape_string(tmp, map->macro);
165 
166  if (map->desc)
167  {
168  mutt_buffer_add_printf(buf, "macro %s %s \"%s\" \"%s\"\n", menu->name,
169  key_binding, tmp->data, map->desc);
170  }
171  else
172  {
173  mutt_buffer_add_printf(buf, "macro %s %s \"%s\"\n", menu->name, key_binding, tmp->data);
174  }
175 
176  mutt_buffer_free(&tmp);
177 }
String manipulation buffer.
Definition: buffer.h:33
void mutt_buffer_free(struct Buffer **p)
Release a Buffer and its contents.
Definition: buffer.c:138
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:242
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:769
char * macro
macro expansion (op == OP_MACRO)
Definition: keymap.h:50
char * data
pointer to data
Definition: buffer.h:35
char * desc
description of a macro for the help menu
Definition: keymap.h:51
struct Buffer * mutt_buffer_new(void)
Create and initialise a Buffer.
Definition: buffer.c:52
#define MAX_SEQ
Definition: keymap.h:33
size_t escape_string(struct Buffer *buf, const char *src)
Write a string to a buffer, escaping special characters.
Definition: dump.c:47
const char * name
Definition: mapping.h:31

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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
booltrue if menu is empty, false if not

Definition at line 186 of file icommands.c.

187 {
188  bool empty = true;
189  struct Keymap *map = NULL, *next = NULL;
190 
191  for (map = Keymaps[menu->value]; map; map = next)
192  {
193  next = map->next;
194 
195  if (bind && (map->op != OP_MACRO))
196  {
197  empty = false;
198  dump_bind(buf, menu, map);
199  }
200  else if (!bind && (map->op == OP_MACRO))
201  {
202  empty = false;
203  dump_macro(buf, menu, map);
204  }
205  }
206 
207  return empty;
208 }
struct Keymap * Keymaps[MENU_MAX]
Array of Keymap keybindings, one for each Menu.
Definition: keymap.c:147
static void dump_bind(struct Buffer *buf, struct Mapping *menu, struct Keymap *map)
Dump a bind map to a buffer.
Definition: icommands.c:119
int value
Definition: mapping.h:32
short op
operation to perform
Definition: keymap.h:53
struct Keymap * next
next key in map
Definition: keymap.h:52
A keyboard mapping.
Definition: keymap.h:48
static void dump_macro(struct Buffer *buf, struct Mapping *menu, struct Keymap *map)
Dump a macro map to a buffer.
Definition: icommands.c:158

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

216 {
217  bool empty;
218  for (int i = 0; i < MENU_MAX; i++)
219  {
220  const char *menu_name = mutt_map_get_name(i, Menus);
221  struct Mapping menu = { menu_name, i };
222 
223  empty = dump_menu(buf, &menu, bind);
224 
225  /* Add a new line for readability between menus. */
226  if (!empty && (i < (MENU_MAX - 1)))
227  mutt_buffer_addch(buf, '\n');
228  }
229 }
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:186
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
const struct Mapping Menus[]
Menu name lookup table.
Definition: keymap.c:60
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:279
Mapping between user-readable string and a constant.
Definition: mapping.h:29

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

const struct ICommand ICommandList[]
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_bind(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err)
Parse &#39;bind&#39; and &#39;macro&#39; commands - Implements icommand_t.
Definition: icommands.c:234
static enum CommandResult icmd_version(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err)
Parse &#39;version&#39; command - Implements icommand_t.
Definition: icommands.c:355
static enum CommandResult icmd_set(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err)
Parse &#39;set&#39; command to display config - Implements icommand_t.
Definition: icommands.c:311

All available informational commands.

Note
These commands take precedence over conventional mutt rc-lines

Definition at line 55 of file icommands.c.